bd1ecf5379
Running the tests we have lots of these: Openat: O_NOFOLLOW missing: flags = 0x4 -wpanic turns this warning into a panic: Openat: O_NOFOLLOW missing: flags = 0x4 panic: -wpanic turns this warning into a panic: Openat: O_NOFOLLOW missing: flags = 0x4 goroutine 114 [running]: log.(*Logger).Panic(0x14000118280, {0x14000313ca8, 0x1, 0x1}) log/log.go:224 +0x90 github.com/rfjakob/gocryptfs/v2/internal/tlog.(*toggledLogger).Printf(0x14000076780, {0x1009dc2e8, 0x27}, {0x14000313d18, 0x1, 0x1}) github.com/rfjakob/gocryptfs/v2/internal/tlog/log.go:78 +0x168 github.com/rfjakob/gocryptfs/v2/internal/syscallcompat.Openat(0x9, {0x1009d0747, 0x1}, 0x4, 0x0) github.com/rfjakob/gocryptfs/v2/internal/syscallcompat/sys_common.go:59 +0xf0 github.com/rfjakob/gocryptfs/v2/internal/fusefrontend.(*Node).getXAttr(0x14000142000, {0x1400001c140, 0x3a}) github.com/rfjakob/gocryptfs/v2/internal/fusefrontend/node_xattr_darwin.go:30 +0x8c github.com/rfjakob/gocryptfs/v2/internal/fusefrontend.(*Node).Getxattr(0x14000142000, {0x100a7eba0, 0x1400000c2e8}, {0x14000016348, 0x14}, {0x14000326000, 0x20, 0x4000}) github.com/rfjakob/gocryptfs/v2/internal/fusefrontend/node_xattr.go:65 +0x1ac github.com/hanwen/go-fuse/v2/fs.(*rawBridge).GetXAttr(0x1400008e140, 0x140001901e0, 0x140001133c0, {0x14000016348, 0x14}, {0x14000326000, 0x20, 0x4000}) github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fs/bridge.go:685 +0x114 github.com/hanwen/go-fuse/v2/fuse.doGetXAttr(0x14000144000, 0x14000113200) github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fuse/opcode.go:270 +0x224 github.com/hanwen/go-fuse/v2/fuse.(*Server).handleRequest(0x14000144000, 0x14000113200) github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fuse/server.go:499 +0x214 created by github.com/hanwen/go-fuse/v2/fuse.(*Server).loop github.com/hanwen/go-fuse/v2@v2.1.1-0.20210825171523-3ab5d95a30ae/fuse/server.go:470 +0xac https://github.com/rfjakob/gocryptfs/issues/625
108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
package fusefrontend
|
|
|
|
import (
|
|
"syscall"
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
"github.com/hanwen/go-fuse/v2/fs"
|
|
"github.com/hanwen/go-fuse/v2/fuse"
|
|
|
|
"github.com/rfjakob/gocryptfs/v2/internal/syscallcompat"
|
|
)
|
|
|
|
// On Darwin we have to unset XATTR_NOSECURITY 0x0008
|
|
func filterXattrSetFlags(flags int) int {
|
|
// See https://opensource.apple.com/source/xnu/xnu-1504.15.3/bsd/sys/xattr.h.auto.html
|
|
const XATTR_NOSECURITY = 0x0008
|
|
|
|
return flags &^ XATTR_NOSECURITY
|
|
}
|
|
|
|
func (n *Node) getXAttr(cAttr string) (out []byte, errno syscall.Errno) {
|
|
dirfd, cName, errno := n.prepareAtSyscallMyself()
|
|
if errno != 0 {
|
|
return
|
|
}
|
|
defer syscall.Close(dirfd)
|
|
|
|
// O_NONBLOCK to not block on FIFOs.
|
|
fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0)
|
|
if err != nil {
|
|
return nil, fs.ToErrno(err)
|
|
}
|
|
defer syscall.Close(fd)
|
|
|
|
cData, err := syscallcompat.Fgetxattr(fd, cAttr)
|
|
if err != nil {
|
|
return nil, fs.ToErrno(err)
|
|
}
|
|
|
|
return cData, 0
|
|
}
|
|
|
|
func (n *Node) setXAttr(context *fuse.Context, cAttr string, cData []byte, flags uint32) (errno syscall.Errno) {
|
|
dirfd, cName, errno := n.prepareAtSyscallMyself()
|
|
if errno != 0 {
|
|
return
|
|
}
|
|
defer syscall.Close(dirfd)
|
|
|
|
// O_NONBLOCK to not block on FIFOs.
|
|
fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_WRONLY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0)
|
|
// Directories cannot be opened read-write. Retry.
|
|
if err == syscall.EISDIR {
|
|
fd, err = syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0)
|
|
}
|
|
if err != nil {
|
|
fs.ToErrno(err)
|
|
}
|
|
defer syscall.Close(fd)
|
|
|
|
err = unix.Fsetxattr(fd, cAttr, cData, int(flags))
|
|
return fs.ToErrno(err)
|
|
}
|
|
|
|
func (n *Node) removeXAttr(cAttr string) (errno syscall.Errno) {
|
|
dirfd, cName, errno := n.prepareAtSyscallMyself()
|
|
if errno != 0 {
|
|
return
|
|
}
|
|
defer syscall.Close(dirfd)
|
|
|
|
// O_NONBLOCK to not block on FIFOs.
|
|
fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_WRONLY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0)
|
|
// Directories cannot be opened read-write. Retry.
|
|
if err == syscall.EISDIR {
|
|
fd, err = syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_DIRECTORY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0)
|
|
}
|
|
if err != nil {
|
|
return fs.ToErrno(err)
|
|
}
|
|
defer syscall.Close(fd)
|
|
|
|
err = unix.Fremovexattr(fd, cAttr)
|
|
return fs.ToErrno(err)
|
|
}
|
|
|
|
func (n *Node) listXAttr() (out []string, errno syscall.Errno) {
|
|
dirfd, cName, errno := n.prepareAtSyscallMyself()
|
|
if errno != 0 {
|
|
return
|
|
}
|
|
defer syscall.Close(dirfd)
|
|
|
|
// O_NONBLOCK to not block on FIFOs.
|
|
fd, err := syscallcompat.Openat(dirfd, cName, syscall.O_RDONLY|syscall.O_NONBLOCK|syscall.O_NOFOLLOW, 0)
|
|
if err != nil {
|
|
return nil, fs.ToErrno(err)
|
|
}
|
|
defer syscall.Close(fd)
|
|
|
|
cNames, err := syscallcompat.Flistxattr(fd)
|
|
if err != nil {
|
|
return nil, fs.ToErrno(err)
|
|
}
|
|
return cNames, 0
|
|
}
|