From 486a600fa15b1e4551f0f8ae5a7966efeb03b8b8 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Sat, 16 Dec 2023 17:17:33 +0000 Subject: [PATCH] squashfs: set Mode bits correctly in FileInfo --- filesystem/squashfs/directoryentry.go | 41 ++++++++++++++++++++++++++- filesystem/squashfs/squashfs_test.go | 13 +++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/filesystem/squashfs/directoryentry.go b/filesystem/squashfs/directoryentry.go index cc5beb75..44e1aa96 100644 --- a/filesystem/squashfs/directoryentry.go +++ b/filesystem/squashfs/directoryentry.go @@ -107,7 +107,46 @@ func (d *directoryEntry) ModTime() time.Time { // Mode FileMode // file mode bits func (d *directoryEntry) Mode() os.FileMode { - return d.mode + mode := d.mode + + // We need to adjust the Linux mode into a Go mode + // The bottom 3*3 bits are the traditional unix permissions. + + // Clear the non permissions bits + mode &= os.ModePerm + + if d.inode == nil { + return mode + } + switch d.inode.inodeType() { + case inodeBasicDirectory, inodeExtendedDirectory: + mode |= os.ModeDir // d: is a directory + case inodeBasicFile, inodeExtendedFile: + // zero mode + case inodeBasicSymlink, inodeExtendedSymlink: + mode |= os.ModeSymlink // L: symbolic link + case inodeBasicBlock, inodeExtendedBlock: + mode |= os.ModeDevice // D: device file + case inodeBasicChar, inodeExtendedChar: + mode |= os.ModeDevice // D: device file + mode |= os.ModeCharDevice // c: Unix character device, when ModeDevice is set + case inodeBasicFifo, inodeExtendedFifo: + mode |= os.ModeNamedPipe // p: named pipe (FIFO) + case inodeBasicSocket, inodeExtendedSocket: + mode |= os.ModeSocket // S: Unix domain socket + default: + mode |= os.ModeIrregular // ?: non-regular file; nothing else is known about this file + } + + // Not currently translated + // mode |= os.ModeAppend // a: append-only + // mode |= os.ModeExclusive // l: exclusive use + // mode |= os.ModeTemporary // T: temporary file; Plan 9 only + // mode |= os.ModeSetuid // u: setuid + // mode |= os.ModeSetgid // g: setgid + // mode |= os.ModeSticky // t: sticky + + return mode } // Sys interface{} // underlying data source (can return nil) diff --git a/filesystem/squashfs/squashfs_test.go b/filesystem/squashfs/squashfs_test.go index 90c5ef0d..0051b248 100644 --- a/filesystem/squashfs/squashfs_test.go +++ b/filesystem/squashfs/squashfs_test.go @@ -349,6 +349,19 @@ func TestSquashfsCheckListing(t *testing.T) { if fi.IsDir() { list(p) } + // Check the type + var wantMode = os.FileMode(0) + if fi.IsDir() { + wantMode |= os.ModeDir + } + switch p { + case "/symlink", "/goodlink", "/emptylink": + wantMode |= os.ModeSymlink + } + gotMode := fi.Mode() + if (gotMode & os.ModeType) != wantMode { + t.Errorf("%s: want mode 0o%o got mode 0o%o", p, wantMode, gotMode&os.ModeType) + } } }