Commit 90605253 authored by Jakob Unterwurzacher's avatar Jakob Unterwurzacher Committed by Han-Wen Nienhuys

Switch from syscall.Getdents to unix.Getdents

On mips64le, syscall.Getdents() and struct syscall.Dirent do
not fit together, causing our parseDirents() implementation to
return garbage ( see https://github.com/rfjakob/gocryptfs/issues/200
and https://github.com/golang/go/issues/23624 ).

Switch to unix.Getdents which does not have this problem -
the next Go release with the syscall package fixes is too
far away, and will take time to trickle into distros.

This issue has been reported by Debian maintainer
Felix Lechner.
parent 6975cb38
...@@ -11,6 +11,8 @@ import ( ...@@ -11,6 +11,8 @@ import (
"testing" "testing"
"time" "time"
"golang.org/x/sys/unix"
"github.com/hanwen/go-fuse/fuse" "github.com/hanwen/go-fuse/fuse"
) )
...@@ -143,7 +145,7 @@ func TestFallocate(t *testing.T) { ...@@ -143,7 +145,7 @@ func TestFallocate(t *testing.T) {
} }
} }
// Check that "." and ".." exists. syscall.Getdents is linux specific. // Check that "." and ".." exists. unix.Getdents is linux specific.
func TestSpecialEntries(t *testing.T) { func TestSpecialEntries(t *testing.T) {
tc := NewTestCase(t) tc := NewTestCase(t)
defer tc.Cleanup() defer tc.Cleanup()
...@@ -154,7 +156,7 @@ func TestSpecialEntries(t *testing.T) { ...@@ -154,7 +156,7 @@ func TestSpecialEntries(t *testing.T) {
} }
defer d.Close() defer d.Close()
buf := make([]byte, 100) buf := make([]byte, 100)
n, err := syscall.Getdents(int(d.Fd()), buf) n, err := unix.Getdents(int(d.Fd()), buf)
if n == 0 { if n == 0 {
t.Errorf("directory is empty, entries '.' and '..' are missing") t.Errorf("directory is empty, entries '.' and '..' are missing")
} }
...@@ -180,7 +182,7 @@ func TestReaddirInodes(t *testing.T) { ...@@ -180,7 +182,7 @@ func TestReaddirInodes(t *testing.T) {
buf := make([]byte, 100) buf := make([]byte, 100)
// readdir(3) use getdents64(2) internally which returns linux_dirent64 // readdir(3) use getdents64(2) internally which returns linux_dirent64
// structures. We don't have readdir(3) so we call getdents64(2) directly. // structures. We don't have readdir(3) so we call getdents64(2) directly.
n, err := syscall.Getdents(int(d.Fd()), buf) n, err := unix.Getdents(int(d.Fd()), buf)
if n == 0 { if n == 0 {
t.Error("empty directory - we need at least one file") t.Error("empty directory - we need at least one file")
} }
......
...@@ -13,6 +13,8 @@ import ( ...@@ -13,6 +13,8 @@ import (
"syscall" "syscall"
"testing" "testing"
"unsafe" "unsafe"
"golang.org/x/sys/unix"
) )
func clen(n []byte) int { func clen(n []byte) int {
...@@ -34,7 +36,7 @@ type CDirent struct { ...@@ -34,7 +36,7 @@ type CDirent struct {
func parseDirents(buf []byte) []CDirent { func parseDirents(buf []byte) []CDirent {
var result []CDirent var result []CDirent
for len(buf) > 0 { for len(buf) > 0 {
de := *(*syscall.Dirent)(unsafe.Pointer(&buf[0])) de := *(*unix.Dirent)(unsafe.Pointer(&buf[0]))
buf = buf[de.Reclen:] buf = buf[de.Reclen:]
bytes := (*[10000]byte)(unsafe.Pointer(&de.Name[0])) bytes := (*[10000]byte)(unsafe.Pointer(&de.Name[0]))
var name = string(bytes[0:clen(bytes[:])]) var name = string(bytes[0:clen(bytes[:])])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment