]> Cypherpunks repositories - gostls13.git/commitdiff
syscall: fix Getdirentries on 32-bit freebsd 12
authorKeith Randall <keithr@alum.mit.edu>
Sat, 8 Jun 2019 16:57:59 +0000 (12:57 -0400)
committerKeith Randall <khr@golang.org>
Mon, 10 Jun 2019 16:18:32 +0000 (16:18 +0000)
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>
src/syscall/syscall_freebsd.go
src/syscall/zsyscall_freebsd_386.go
src/syscall/zsyscall_freebsd_amd64.go
src/syscall/zsyscall_freebsd_arm.go

index 87a27b1ff74c21da15366b7151f75b280ca15ce6..725fe51eb9f54461d6bea9dc878b144fa1e169c7 100644 (file)
@@ -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)
index 8f4234c7e9d206c319e382fbbdbae4a0e18224af..ddc265f1901111da7c16859e16487dcf76da037f 100644 (file)
@@ -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])
index baa7d68a7d2e6550bdea142f6726271f83391a85..a0f79522b98d0cfe2ac377479cbf65e4c806f05a 100644 (file)
@@ -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])
index 16e4bc5414438cad50ef71cac6be3aed5b86122b..2cd23d3db63bd598d4b449fe554cd3f561469bc9 100644 (file)
@@ -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])