unix: pass fcntl data as unsafe.Pointer in FcntlF{lock,store} on darwin
FcntlF{lock,store} on Darwin convert their data pointer argument to
uintptr before passing it to the fcntl wrapper. Per the unsafe.Pointer
rules, the conversion is only safe in the call expression itself.
Otherwise, GC could free or move the underlying struct while the syscall
was still using it.
Fix this by adding an unexported fcntlPtr func that takes its arg
argument as unsafe.Pointer and switch FcntlF{lock,store} to call it
instead.
Inspired by CL 836665
Change-Id: I5b662f531a48a02cd7e872c94e3f958d33d6ea7b
Reviewed-on: https://go-review.googlesource.com/c/sys/+/841845
Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
diff --git a/unix/fcntl_darwin.go b/unix/fcntl_darwin.go
index a9911c7..78c28a3 100644
--- a/unix/fcntl_darwin.go
+++ b/unix/fcntl_darwin.go
@@ -13,12 +13,12 @@
// FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command.
func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error {
- _, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(lk))))
+ _, err := fcntlPtr(int(fd), cmd, unsafe.Pointer(lk))
return err
}
// FcntlFstore performs a fcntl syscall for the F_PREALLOCATE command.
func FcntlFstore(fd uintptr, cmd int, fstore *Fstore_t) error {
- _, err := fcntl(int(fd), cmd, int(uintptr(unsafe.Pointer(fstore))))
+ _, err := fcntlPtr(int(fd), cmd, unsafe.Pointer(fstore))
return err
}
diff --git a/unix/syscall_darwin.go b/unix/syscall_darwin.go
index 38590ca..cb9d0a1 100644
--- a/unix/syscall_darwin.go
+++ b/unix/syscall_darwin.go
@@ -369,6 +369,7 @@
*/
//sys fcntl(fd int, cmd int, arg int) (val int, err error)
+//sys fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) = SYS_FCNTL
//sys kill(pid int, signum int, posix int) (err error)
diff --git a/unix/zsyscall_darwin_amd64.go b/unix/zsyscall_darwin_amd64.go
index 813c05b..7db9bf5 100644
--- a/unix/zsyscall_darwin_amd64.go
+++ b/unix/zsyscall_darwin_amd64.go
@@ -702,6 +702,17 @@
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func kill(pid int, signum int, posix int) (err error) {
_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), uintptr(posix))
if e1 != 0 {
diff --git a/unix/zsyscall_darwin_arm64.go b/unix/zsyscall_darwin_arm64.go
index e6f58f3..2a65805 100644
--- a/unix/zsyscall_darwin_arm64.go
+++ b/unix/zsyscall_darwin_arm64.go
@@ -702,6 +702,17 @@
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func fcntlPtr(fd int, cmd int, arg unsafe.Pointer) (val int, err error) {
+ r0, _, e1 := syscall_syscall(libc_fcntl_trampoline_addr, uintptr(fd), uintptr(cmd), uintptr(arg))
+ val = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func kill(pid int, signum int, posix int) (err error) {
_, _, e1 := syscall_syscall(libc_kill_trampoline_addr, uintptr(pid), uintptr(signum), uintptr(posix))
if e1 != 0 {