@@ -745,23 +745,27 @@ func minInt(a, b int) int {
745
745
// dedupEnv returns a copy of env with any duplicates removed, in favor of
746
746
// later values.
747
747
// Items not of the normal environment "key=value" form are preserved unchanged.
748
- // Items containing NUL characters are removed, and an error is returned along with
749
- // the remaining values.
748
+ // Except on Plan 9, items containing NUL characters are removed, and
749
+ // an error is returned along with the remaining values.
750
750
func dedupEnv (env []string ) ([]string , error ) {
751
- return dedupEnvCase (runtime .GOOS == "windows" , env )
751
+ return dedupEnvCase (runtime .GOOS == "windows" , runtime . GOOS == "plan9" , env )
752
752
}
753
753
754
754
// dedupEnvCase is dedupEnv with a case option for testing.
755
755
// If caseInsensitive is true, the case of keys is ignored.
756
- func dedupEnvCase (caseInsensitive bool , env []string ) ([]string , error ) {
756
+ // If nulOK is false, items containing NUL characters are allowed.
757
+ func dedupEnvCase (caseInsensitive , nulOK bool , env []string ) ([]string , error ) {
757
758
var err error
758
759
out := make ([]string , 0 , len (env ))
759
760
saw := make (map [string ]int , len (env )) // key => index into out
760
761
for _ , kv := range env {
761
- if strings .IndexByte (kv , 0 ) != - 1 {
762
+ // Reject NUL in environment variables to prevent security issues (#56284);
763
+ // except on Plan 9, which uses NUL as os.PathListSeparator (#56544).
764
+ if ! nulOK && strings .IndexByte (kv , 0 ) != - 1 {
762
765
err = errors .New ("exec: environment variable contains NUL" )
763
766
continue
764
767
}
768
+
765
769
k , _ , ok := strings .Cut (kv , "=" )
766
770
if ! ok {
767
771
out = append (out , kv )
0 commit comments