From 6c5289959c9811faffd66524f62cdcda16aa2d5c Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Sat, 22 Apr 2023 16:47:22 +1000 Subject: [PATCH] windows: return error if DecomposeCommandLine parameter contains NUL DecomposeCommandLine is documented to use CommandLineToArgv, and the CommandLineToArgvW system call inherently does not support strings with internal NUL bytes. This CL changes DecomposeCommandLine to reject those strings with an error instead of panicking. Fixes golang/go#58817 Change-Id: I22a026bf2e69344a21f04849c50ba19b6e7b2007 Reviewed-on: https://go-review.googlesource.com/c/sys/+/487695 TryBot-Result: Gopher Robot Reviewed-by: Ian Lance Taylor Reviewed-by: Dmitri Shuralyov Run-TryBot: Alex Brainman --- windows/exec_windows.go | 7 ++++++- windows/syscall_windows_test.go | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/windows/exec_windows.go b/windows/exec_windows.go index 75980fd44..a52e0331d 100644 --- a/windows/exec_windows.go +++ b/windows/exec_windows.go @@ -95,12 +95,17 @@ func ComposeCommandLine(args []string) string { // DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv, // as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that // command lines are passed around. +// DecomposeCommandLine returns error if commandLine contains NUL. func DecomposeCommandLine(commandLine string) ([]string, error) { if len(commandLine) == 0 { return []string{}, nil } + utf16CommandLine, err := UTF16FromString(commandLine) + if err != nil { + return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine") + } var argc int32 - argv, err := CommandLineToArgv(StringToUTF16Ptr(commandLine), &argc) + argv, err := CommandLineToArgv(&utf16CommandLine[0], &argc) if err != nil { return nil, err } diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index c72c788f0..42c01fc96 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -626,6 +626,22 @@ func TestCommandLineRecomposition(t *testing.T) { continue } } + + // check that windows.DecomposeCommandLine returns error for strings with NUL + testsWithNUL := []string{ + "\x00abcd", + "ab\x00cd", + "abcd\x00", + "\x00abcd\x00", + "\x00ab\x00cd\x00", + "\x00\x00\x00", + } + for _, test := range testsWithNUL { + _, err := windows.DecomposeCommandLine(test) + if err == nil { + t.Errorf("Failed to return error while decomposing %#q string with NUL inside", test) + } + } } func TestWinVerifyTrust(t *testing.T) {