From 798191bca9151949f4c0d825e443b0371f41d4d3 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Thu, 9 Dec 2021 08:27:52 -0500 Subject: [PATCH] unix, plan9: avoid writing to p when Pipe(p) fails Generally speaking Go functions make no guarantees about what has happened to result parameters on error, and Pipe is no exception: callers should avoid looking at p if Pipe returns an error. However, we had a bug in which ForkExec was using the content of p after a failed Pipe, and others may too. As a robustness fix, make Pipe avoid writing to p on failure. windows.Pipe already avoided writing to p on failure. For golang/go#50057. Change-Id: I93ed06b06a9981793c119c1d7df689fbe79b4116 Reviewed-on: https://go-review.googlesource.com/c/sys/+/370614 Trust: Russ Cox Reviewed-by: Filippo Valsorda Run-TryBot: Russ Cox TryBot-Result: Gopher Robot --- plan9/syscall_plan9.go | 6 ++++-- unix/syscall_aix.go | 6 ++++-- unix/syscall_darwin.go | 6 ++++-- unix/syscall_dragonfly.go | 10 ++++++++-- unix/syscall_freebsd.go | 6 ++++-- unix/syscall_linux.go | 6 ++++-- unix/syscall_netbsd.go | 6 ++++-- unix/syscall_openbsd.go | 6 ++++-- unix/syscall_solaris.go | 12 ++++++++---- unix/syscall_zos_s390x.go | 6 ++++-- 10 files changed, 48 insertions(+), 22 deletions(-) diff --git a/plan9/syscall_plan9.go b/plan9/syscall_plan9.go index 84e14714..723b1f40 100644 --- a/plan9/syscall_plan9.go +++ b/plan9/syscall_plan9.go @@ -132,8 +132,10 @@ func Pipe(p []int) (err error) { } var pp [2]int32 err = pipe(&pp) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return } diff --git a/unix/syscall_aix.go b/unix/syscall_aix.go index 6192750c..4f55c8d9 100644 --- a/unix/syscall_aix.go +++ b/unix/syscall_aix.go @@ -519,8 +519,10 @@ func Pipe(p []int) (err error) { } var pp [2]_C_int err = pipe(&pp) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return } diff --git a/unix/syscall_darwin.go b/unix/syscall_darwin.go index 8826f414..0eaab913 100644 --- a/unix/syscall_darwin.go +++ b/unix/syscall_darwin.go @@ -159,8 +159,10 @@ func Pipe(p []int) (err error) { } var x [2]int32 err = pipe(&x) - p[0] = int(x[0]) - p[1] = int(x[1]) + if err == nil { + p[0] = int(x[0]) + p[1] = int(x[1]) + } return } diff --git a/unix/syscall_dragonfly.go b/unix/syscall_dragonfly.go index 5af108a5..2e37c316 100644 --- a/unix/syscall_dragonfly.go +++ b/unix/syscall_dragonfly.go @@ -101,7 +101,10 @@ func Pipe(p []int) (err error) { if len(p) != 2 { return EINVAL } - p[0], p[1], err = pipe() + r, w, err := pipe() + if err == nil { + p[0], p[1] = r, w + } return } @@ -114,7 +117,10 @@ func Pipe2(p []int, flags int) (err error) { var pp [2]_C_int // pipe2 on dragonfly takes an fds array as an argument, but still // returns the file descriptors. - p[0], p[1], err = pipe2(&pp, flags) + r, w, err := pipe2(&pp, flags) + if err == nil { + p[0], p[1] = r, w + } return err } diff --git a/unix/syscall_freebsd.go b/unix/syscall_freebsd.go index 18c392cf..2f650ae6 100644 --- a/unix/syscall_freebsd.go +++ b/unix/syscall_freebsd.go @@ -110,8 +110,10 @@ func Pipe2(p []int, flags int) error { } var pp [2]_C_int err := pipe2(&pp, flags) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return err } diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 4bc5baf7..f432b068 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go @@ -131,8 +131,10 @@ func Pipe2(p []int, flags int) error { } var pp [2]_C_int err := pipe2(&pp, flags) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return err } diff --git a/unix/syscall_netbsd.go b/unix/syscall_netbsd.go index 853d5f0f..4e06c0b3 100644 --- a/unix/syscall_netbsd.go +++ b/unix/syscall_netbsd.go @@ -128,8 +128,10 @@ func Pipe2(p []int, flags int) error { } var pp [2]_C_int err := pipe2(&pp, flags) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return err } diff --git a/unix/syscall_openbsd.go b/unix/syscall_openbsd.go index 22b55038..11b1d419 100644 --- a/unix/syscall_openbsd.go +++ b/unix/syscall_openbsd.go @@ -87,8 +87,10 @@ func Pipe2(p []int, flags int) error { } var pp [2]_C_int err := pipe2(&pp, flags) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return err } diff --git a/unix/syscall_solaris.go b/unix/syscall_solaris.go index 8b88ac21..5c813921 100644 --- a/unix/syscall_solaris.go +++ b/unix/syscall_solaris.go @@ -66,8 +66,10 @@ func Pipe(p []int) (err error) { if n != 0 { return err } - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return nil } @@ -79,8 +81,10 @@ func Pipe2(p []int, flags int) error { } var pp [2]_C_int err := pipe2(&pp, flags) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return err } diff --git a/unix/syscall_zos_s390x.go b/unix/syscall_zos_s390x.go index 5fb76a14..f8616f45 100644 --- a/unix/syscall_zos_s390x.go +++ b/unix/syscall_zos_s390x.go @@ -579,8 +579,10 @@ func Pipe(p []int) (err error) { } var pp [2]_C_int err = pipe(&pp) - p[0] = int(pp[0]) - p[1] = int(pp[1]) + if err == nil { + p[0] = int(pp[0]) + p[1] = int(pp[1]) + } return }