diff options
| author | Keith Randall <keithr@alum.mit.edu> | 2019-06-08 12:57:59 -0400 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2019-06-10 16:18:32 +0000 |
| commit | daf944a531fecf2431b60da608e70680f4927412 (patch) | |
| tree | 2b8041f4ee6da222304e271b9c11b2ec93f5aafc /src/syscall | |
| parent | ec3ebf7bc31271b52c82b3fac193139b2788ed68 (diff) | |
| download | go-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.go | 18 | ||||
| -rw-r--r-- | src/syscall/zsyscall_freebsd_386.go | 2 | ||||
| -rw-r--r-- | src/syscall/zsyscall_freebsd_amd64.go | 2 | ||||
| -rw-r--r-- | src/syscall/zsyscall_freebsd_arm.go | 2 |
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]) |
