syscall: return EINVAL when string arguments have NUL characters
Since NUL usually terminates strings in underlying syscalls, allowing
it when converting string arguments is a security risk, especially
when dealing with filenames. For example, a program might reason that
filename like "/root/..\x00/" is a subdirectory or "/root/" and allow
access to it, while underlying syscall will treat "\x00" as an end of
that string and the actual filename will be "/root/..", which might
be unexpected. Returning EINVAL when string arguments have NUL in
them makes sure this attack vector is unusable.
R=golang-dev, r, bradfitz, fullung, rsc, minux.ma
CC=golang-dev
https://golang.org/cl/6458050
diff --git a/src/pkg/syscall/exec_windows.go b/src/pkg/syscall/exec_windows.go
index 9f1f174..82abc07 100644
--- a/src/pkg/syscall/exec_windows.go
+++ b/src/pkg/syscall/exec_windows.go
@@ -132,7 +132,10 @@
// getFullPath retrieves the full path of the specified file.
// Just a wrapper for Windows GetFullPathName api.
func getFullPath(name string) (path string, err error) {
- p := StringToUTF16Ptr(name)
+ p, err := UTF16PtrFromString(name)
+ if err != nil {
+ return "", err
+ }
buf := make([]uint16, 100)
n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
if err != nil {
@@ -262,7 +265,10 @@
return 0, 0, err
}
}
- argv0p := StringToUTF16Ptr(argv0)
+ argv0p, err := UTF16PtrFromString(argv0)
+ if err != nil {
+ return 0, 0, err
+ }
var cmdline string
// Windows CreateProcess takes the command line as a single string:
@@ -276,12 +282,18 @@
var argvp *uint16
if len(cmdline) != 0 {
- argvp = StringToUTF16Ptr(cmdline)
+ argvp, err = UTF16PtrFromString(cmdline)
+ if err != nil {
+ return 0, 0, err
+ }
}
var dirp *uint16
if len(attr.Dir) != 0 {
- dirp = StringToUTF16Ptr(attr.Dir)
+ dirp, err = UTF16PtrFromString(attr.Dir)
+ if err != nil {
+ return 0, 0, err
+ }
}
// Acquire the fork lock so that no other threads