[release-branch.go1.17] syscall: 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.
Updates #50057
Change-Id: Ie8955025dbd20702fabadc9bbe1d1a5ac0f36305
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1291271
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/370535
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
diff --git a/src/syscall/syscall_aix.go b/src/syscall/syscall_aix.go
index 9c6afba..db289fd 100644
--- a/src/syscall/syscall_aix.go
+++ b/src/syscall/syscall_aix.go
@@ -64,8 +64,10 @@
}
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/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go
index a4fe4f1..ce69464 100644
--- a/src/syscall/syscall_darwin.go
+++ b/src/syscall/syscall_darwin.go
@@ -96,8 +96,10 @@
}
var q [2]int32
err = pipe(&q)
- p[0] = int(q[0])
- p[1] = int(q[1])
+ if err == nil {
+ p[0] = int(q[0])
+ p[1] = int(q[1])
+ }
return
}
diff --git a/src/syscall/syscall_dragonfly.go b/src/syscall/syscall_dragonfly.go
index b01a4ad..5ff7f99 100644
--- a/src/syscall/syscall_dragonfly.go
+++ b/src/syscall/syscall_dragonfly.go
@@ -96,8 +96,11 @@
if len(p) != 2 {
return EINVAL
}
- p[0], p[1], err = pipe()
- return
+ r, w, err := pipe()
+ if err == nil {
+ p[0], p[1] = r, w
+ }
+ return err
}
//sysnb pipe2(p *[2]_C_int, flags int) (r int, w int, err error)
@@ -109,7 +112,10 @@
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/src/syscall/syscall_freebsd.go b/src/syscall/syscall_freebsd.go
index 7c7b89a..ad904d6 100644
--- a/src/syscall/syscall_freebsd.go
+++ b/src/syscall/syscall_freebsd.go
@@ -105,8 +105,10 @@
}
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/src/syscall/syscall_linux_386.go b/src/syscall/syscall_linux_386.go
index 0db0374..26bdb9b 100644
--- a/src/syscall/syscall_linux_386.go
+++ b/src/syscall/syscall_linux_386.go
@@ -30,8 +30,10 @@
}
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
}
@@ -43,8 +45,10 @@
}
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
}
diff --git a/src/syscall/syscall_linux_amd64.go b/src/syscall/syscall_linux_amd64.go
index 5df3f79..896117a 100644
--- a/src/syscall/syscall_linux_amd64.go
+++ b/src/syscall/syscall_linux_amd64.go
@@ -118,8 +118,10 @@
}
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
}
@@ -131,8 +133,10 @@
}
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
}
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
index e887cf7..79c201a 100644
--- a/src/syscall/syscall_linux_arm.go
+++ b/src/syscall/syscall_linux_arm.go
@@ -34,8 +34,10 @@
if err == ENOSYS {
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
}
@@ -47,8 +49,10 @@
}
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
}
diff --git a/src/syscall/syscall_linux_arm64.go b/src/syscall/syscall_linux_arm64.go
index f575c84..bfa7be9 100644
--- a/src/syscall/syscall_linux_arm64.go
+++ b/src/syscall/syscall_linux_arm64.go
@@ -152,8 +152,10 @@
}
var pp [2]_C_int
err = pipe2(&pp, 0)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
@@ -165,8 +167,10 @@
}
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
}
diff --git a/src/syscall/syscall_linux_mips64x.go b/src/syscall/syscall_linux_mips64x.go
index 5feb03e..43f9411 100644
--- a/src/syscall/syscall_linux_mips64x.go
+++ b/src/syscall/syscall_linux_mips64x.go
@@ -109,8 +109,10 @@
}
var pp [2]_C_int
err = pipe2(&pp, 0)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
@@ -122,8 +124,10 @@
}
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
}
diff --git a/src/syscall/syscall_linux_mipsx.go b/src/syscall/syscall_linux_mipsx.go
index 39104d7..1ab452e 100644
--- a/src/syscall/syscall_linux_mipsx.go
+++ b/src/syscall/syscall_linux_mipsx.go
@@ -120,8 +120,10 @@
}
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
}
@@ -131,8 +133,11 @@
if len(p) != 2 {
return EINVAL
}
- p[0], p[1], err = pipe()
- return
+ r, w, err := pipe()
+ if err == nil {
+ p[0], p[1] = r, w
+ }
+ return err
}
//sys mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
diff --git a/src/syscall/syscall_linux_ppc64x.go b/src/syscall/syscall_linux_ppc64x.go
index 495ae29..8a69eb5 100644
--- a/src/syscall/syscall_linux_ppc64x.go
+++ b/src/syscall/syscall_linux_ppc64x.go
@@ -88,8 +88,10 @@
}
var pp [2]_C_int
err = pipe2(&pp, 0)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
@@ -101,8 +103,10 @@
}
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
}
diff --git a/src/syscall/syscall_linux_riscv64.go b/src/syscall/syscall_linux_riscv64.go
index 2a0fe64..dd48f7c 100644
--- a/src/syscall/syscall_linux_riscv64.go
+++ b/src/syscall/syscall_linux_riscv64.go
@@ -155,8 +155,10 @@
}
var pp [2]_C_int
err = pipe2(&pp, 0)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
@@ -168,8 +170,10 @@
}
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
}
diff --git a/src/syscall/syscall_linux_s390x.go b/src/syscall/syscall_linux_s390x.go
index 0f6f627..08e6613 100644
--- a/src/syscall/syscall_linux_s390x.go
+++ b/src/syscall/syscall_linux_s390x.go
@@ -80,8 +80,10 @@
}
var pp [2]_C_int
err = pipe2(&pp, 0)
- p[0] = int(pp[0])
- p[1] = int(pp[1])
+ if err == nil {
+ p[0] = int(pp[0])
+ p[1] = int(pp[1])
+ }
return
}
@@ -93,8 +95,10 @@
}
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
}
diff --git a/src/syscall/syscall_netbsd.go b/src/syscall/syscall_netbsd.go
index fc13b70..0754bad 100644
--- a/src/syscall/syscall_netbsd.go
+++ b/src/syscall/syscall_netbsd.go
@@ -112,8 +112,10 @@
}
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/src/syscall/syscall_openbsd.go b/src/syscall/syscall_openbsd.go
index 5a5ba5a..18eafe3 100644
--- a/src/syscall/syscall_openbsd.go
+++ b/src/syscall/syscall_openbsd.go
@@ -72,8 +72,10 @@
}
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/src/syscall/syscall_plan9.go b/src/syscall/syscall_plan9.go
index d16cad4..6a8ab97 100644
--- a/src/syscall/syscall_plan9.go
+++ b/src/syscall/syscall_plan9.go
@@ -198,8 +198,10 @@
}
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/src/syscall/syscall_solaris.go b/src/syscall/syscall_solaris.go
index daa4b88..7640aac 100644
--- a/src/syscall/syscall_solaris.go
+++ b/src/syscall/syscall_solaris.go
@@ -55,7 +55,9 @@
if e1 != 0 {
err = Errno(e1)
}
- p[0], p[1] = int(r0), int(w0)
+ if err == nil {
+ p[0], p[1] = int(r0), int(w0)
+ }
return
}