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 <rsc@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Russ Cox 2021-12-09 08:27:52 -05:00
Родитель 97ca703d54
Коммит 798191bca9
10 изменённых файлов: 48 добавлений и 22 удалений

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}

Просмотреть файл

@ -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
}