Description
Hi,
This is from Debian packaging. On i386 the Getdents
test in version 1.4.2 fails because the syscall.Dirent
data structure gocryptfs uses has inconsistent sizes between architectures.
While the inode
and offset
members can vary in scenarios like this, they are not the issue here. The golang runtime uses only the getdents64
syscall and via cgo tweaks struct dirent
to its liking (although I might have preferred struct dirent64
). The issue here are the data types for name length
and file type
, as well as the padding for alignment.
On all architectures, both go-fuse
and libfuse
return at most 280 bytes. On amd64, that size matches the syscall.Dirent
data type gocryptfs uses, but on i386 the latter drops to 276 bytes. It causes an error in internal/syscallcompat/getdents_linux.go
:
if int(s.Reclen) > sizeofDirent {
tlog.Warn.Printf("Getdents: corrupt entry #%d: Reclen=%d > %d. Returning EBADR",
numEntries, s.Reclen, sizeofDirent)
return nil, syscall.EBADR
}
Here is a small program to illustrate the various sizes. This is the output for amd64:
gocryptfs
unsafe.Sizeof (syscall.Dirent{}) = 280
go-fuse
unsafe.Sizeof (gofuse_Dirent{}) + 256 = 280
libfuse
sizeof (struct libfuse_dirent) + 256 = 280
readdir(3), provided by libc
sizeof (struct dirent) = 280
sizeof (struct dirent64) = 280
getdents(3) syscall, not wrapped by libc
sizeof (struct linux_dirent) with 256[] = 280
proposal to bring go-fuse in line with gocryptfs
unsafe.Sizeof (PROPOSED_gofuse_Dirent{}) + 256 = 280
For i386, the sizes are not nearly as consistent:
gocryptfs
unsafe.Sizeof (syscall.Dirent{}) = 276
go-fuse
unsafe.Sizeof (gofuse_Dirent{}) + 256 = 280
libfuse
sizeof (struct libfuse_dirent) + 256 = 280
readdir(3), provided by libc
sizeof (struct dirent) = 276
sizeof (struct dirent64) = 276
getdents(3) syscall, not wrapped by libc
sizeof (struct linux_dirent) with 256[] = 268
proposal to bring go-fuse in line with gocryptfs
unsafe.Sizeof (PROPOSED_gofuse_Dirent{}) + 256 = 276
Which data structure should be used in gocryptfs? Bonus question: Is FUSE safe on i386? Thank you!