aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorKeith Randall <keithr@alum.mit.edu>2019-06-08 12:57:59 -0400
committerKeith Randall <khr@golang.org>2019-06-10 16:18:32 +0000
commitdaf944a531fecf2431b60da608e70680f4927412 (patch)
tree2b8041f4ee6da222304e271b9c11b2ec93f5aafc /src/syscall
parentec3ebf7bc31271b52c82b3fac193139b2788ed68 (diff)
downloadgo-daf944a531fecf2431b60da608e70680f4927412.tar.xz
syscall: fix Getdirentries on 32-bit freebsd 12
On freebsd 12, the system call for getdirentries writes 64 bits to *basep, even on 32-bit systems. Accomodate that by providing a uint64 to the system call and copy the base to/from that uint64. The uint64 seems to be a virtual file offset, so failing if the high bits are not zero should be fine for reasonable-sized directories. Fixes #32498 Change-Id: Ie22c0d301c6091bd20e813432928b24ab95cc314 Reviewed-on: https://go-review.googlesource.com/c/go/+/181377 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/syscall_freebsd.go18
-rw-r--r--src/syscall/zsyscall_freebsd_386.go2
-rw-r--r--src/syscall/zsyscall_freebsd_amd64.go2
-rw-r--r--src/syscall/zsyscall_freebsd_arm.go2
4 files changed, 19 insertions, 5 deletions
diff --git a/src/syscall/syscall_freebsd.go b/src/syscall/syscall_freebsd.go
index 87a27b1ff7..725fe51eb9 100644
--- a/src/syscall/syscall_freebsd.go
+++ b/src/syscall/syscall_freebsd.go
@@ -267,7 +267,21 @@ func Fstatfs(fd int, st *Statfs_t) (err error) {
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
if supportsABI(_ino64First) {
- return getdirentries_freebsd12(fd, buf, basep)
+ if unsafe.Sizeof(*basep) == 64 {
+ return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep)))
+ }
+ // The freebsd12 syscall needs a 64-bit base. On 32-bit machines
+ // we can't just use the basep passed in. See #32498.
+ var base uint64 = uint64(*basep)
+ n, err = getdirentries_freebsd12(fd, buf, &base)
+ *basep = uintptr(base)
+ if base>>32 != 0 {
+ // We can't stuff the base back into a uintptr, so any
+ // future calls would be suspect. Generate an error.
+ // EIO is allowed by getdirentries.
+ err = EIO
+ }
+ return
}
// The old syscall entries are smaller than the new. Use 1/4 of the original
@@ -424,7 +438,7 @@ func convertFromDirents11(buf []byte, old []byte) int {
//sys Fsync(fd int) (err error)
//sys Ftruncate(fd int, length int64) (err error)
//sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
-//sys getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) = _SYS_GETDIRENTRIES_FREEBSD12
+//sys getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) = _SYS_GETDIRENTRIES_FREEBSD12
//sys Getdtablesize() (size int)
//sysnb Getegid() (egid int)
//sysnb Geteuid() (uid int)
diff --git a/src/syscall/zsyscall_freebsd_386.go b/src/syscall/zsyscall_freebsd_386.go
index 8f4234c7e9..ddc265f190 100644
--- a/src/syscall/zsyscall_freebsd_386.go
+++ b/src/syscall/zsyscall_freebsd_386.go
@@ -570,7 +570,7 @@ func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
diff --git a/src/syscall/zsyscall_freebsd_amd64.go b/src/syscall/zsyscall_freebsd_amd64.go
index baa7d68a7d..a0f79522b9 100644
--- a/src/syscall/zsyscall_freebsd_amd64.go
+++ b/src/syscall/zsyscall_freebsd_amd64.go
@@ -570,7 +570,7 @@ func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])
diff --git a/src/syscall/zsyscall_freebsd_arm.go b/src/syscall/zsyscall_freebsd_arm.go
index 16e4bc5414..2cd23d3db6 100644
--- a/src/syscall/zsyscall_freebsd_arm.go
+++ b/src/syscall/zsyscall_freebsd_arm.go
@@ -570,7 +570,7 @@ func getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-func getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) {
+func getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) {
var _p0 unsafe.Pointer
if len(buf) > 0 {
_p0 = unsafe.Pointer(&buf[0])