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