Skip to content

Commit daf944a

Browse files
committed
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent ec3ebf7 commit daf944a

File tree

4 files changed

+19
-5
lines changed

4 files changed

+19
-5
lines changed

src/syscall/syscall_freebsd.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,21 @@ func Fstatfs(fd int, st *Statfs_t) (err error) {
267267

268268
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
269269
if supportsABI(_ino64First) {
270-
return getdirentries_freebsd12(fd, buf, basep)
270+
if unsafe.Sizeof(*basep) == 64 {
271+
return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep)))
272+
}
273+
// The freebsd12 syscall needs a 64-bit base. On 32-bit machines
274+
// we can't just use the basep passed in. See #32498.
275+
var base uint64 = uint64(*basep)
276+
n, err = getdirentries_freebsd12(fd, buf, &base)
277+
*basep = uintptr(base)
278+
if base>>32 != 0 {
279+
// We can't stuff the base back into a uintptr, so any
280+
// future calls would be suspect. Generate an error.
281+
// EIO is allowed by getdirentries.
282+
err = EIO
283+
}
284+
return
271285
}
272286

273287
// 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 {
424438
//sys Fsync(fd int) (err error)
425439
//sys Ftruncate(fd int, length int64) (err error)
426440
//sys getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
427-
//sys getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error) = _SYS_GETDIRENTRIES_FREEBSD12
441+
//sys getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error) = _SYS_GETDIRENTRIES_FREEBSD12
428442
//sys Getdtablesize() (size int)
429443
//sysnb Getegid() (egid int)
430444
//sysnb Geteuid() (uid int)

src/syscall/zsyscall_freebsd_386.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/syscall/zsyscall_freebsd_amd64.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/syscall/zsyscall_freebsd_arm.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)