diff options
author | Russ Cox <rsc@golang.org> | 2021-12-08 18:05:11 -0500 |
---|---|---|
committer | Filippo Valsorda <filippo@golang.org> | 2021-12-09 12:28:39 +0000 |
commit | e46abcb816fb20663483f84fe52e370790a99bee (patch) | |
tree | 183dade1b426a79c0ee0fb6a5267396085d4fa2a | |
parent | 61317ef99e015600704ee580a370f356f1bb4a6b (diff) | |
download | go-git-e46abcb816fb20663483f84fe52e370790a99bee.tar.gz |
[release-branch.go1.17] syscall: fix ForkLock spurious close(0) on pipe failure
Pipe (and therefore forkLockPipe) does not make any guarantees
about the state of p after a failed Pipe(p). Avoid that assumption
and the too-clever goto, so that we don't accidentally Close a real fd
if the failed pipe leaves p[0] or p[1] set >= 0.
Updates #50057
Fixes CVE-2021-44717
Change-Id: Iff8e19a6efbba0c73cc8b13ecfae381c87600bb4
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1291270
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/370534
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
-rw-r--r-- | src/syscall/exec_unix.go | 20 |
1 files changed, 6 insertions, 14 deletions
diff --git a/src/syscall/exec_unix.go b/src/syscall/exec_unix.go index 54b18dccd7..c9c9d1abf3 100644 --- a/src/syscall/exec_unix.go +++ b/src/syscall/exec_unix.go @@ -153,9 +153,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) sys = &zeroSysProcAttr } - p[0] = -1 - p[1] = -1 - // Convert args to C form. argv0p, err := BytePtrFromString(argv0) if err != nil { @@ -205,14 +202,17 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) // Allocate child status pipe close on exec. if err = forkExecPipe(p[:]); err != nil { - goto error + ForkLock.Unlock() + return 0, err } // Kick off child. pid, err1 = forkAndExecInChild(argv0p, argvp, envvp, chroot, dir, attr, sys, p[1]) if err1 != 0 { - err = Errno(err1) - goto error + Close(p[0]) + Close(p[1]) + ForkLock.Unlock() + return 0, Errno(err1) } ForkLock.Unlock() @@ -244,14 +244,6 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error) // Read got EOF, so pipe closed on exec, so exec succeeded. return pid, nil - -error: - if p[0] >= 0 { - Close(p[0]) - Close(p[1]) - } - ForkLock.Unlock() - return 0, err } // Combination of fork and exec, careful to be thread safe. |