Initial commit
Proof-of-concept implementation. Bugs will occur.
This commit is contained in:
60
vendor/github.com/hanwen/go-fuse/v2/internal/access.go
generated
vendored
Normal file
60
vendor/github.com/hanwen/go-fuse/v2/internal/access.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2019 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package internal
|
||||
|
||||
import (
|
||||
"os/user"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// HasAccess tests if a caller can access a file with permissions
|
||||
// `perm` in mode `mask`
|
||||
func HasAccess(callerUid, callerGid, fileUid, fileGid uint32, perm uint32, mask uint32) bool {
|
||||
if callerUid == 0 {
|
||||
// root can do anything.
|
||||
return true
|
||||
}
|
||||
mask = mask & 7
|
||||
if mask == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
if callerUid == fileUid {
|
||||
if perm&(mask<<6) != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if callerGid == fileGid {
|
||||
if perm&(mask<<3) != 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if perm&mask != 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check other groups.
|
||||
if perm&(mask<<3) == 0 {
|
||||
// avoid expensive lookup if it's not allowed anyway
|
||||
return false
|
||||
}
|
||||
|
||||
u, err := user.LookupId(strconv.Itoa(int(callerUid)))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
gs, err := u.GroupIds()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
fileGidStr := strconv.Itoa(int(fileGid))
|
||||
for _, gidStr := range gs {
|
||||
if gidStr == fileGidStr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
9
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate.go
generated
vendored
Normal file
9
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
package fallocate
|
||||
|
||||
// Fallocate is a wrapper around fallocate syscall.
|
||||
// On Linux, it is a wrapper around fallocate(2).
|
||||
// On Darwin, it is a wrapper around fnctl(2).
|
||||
// On FreeBSD, it is a wrapper around posix_fallocate(2).
|
||||
func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
|
||||
return fallocate(fd, mode, off, len)
|
||||
}
|
||||
56
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate_darwin.go
generated
vendored
Normal file
56
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
package fallocate
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func fallocate(fd int, mode uint32, off int64, len int64) error {
|
||||
// TODO: Handle `mode` parameter.
|
||||
_ = mode
|
||||
|
||||
// From `man fcntl` on OSX:
|
||||
// The F_PREALLOCATE command operates on the following structure:
|
||||
//
|
||||
// typedef struct fstore {
|
||||
// u_int32_t fst_flags; /* IN: flags word */
|
||||
// int fst_posmode; /* IN: indicates offset field */
|
||||
// off_t fst_offset; /* IN: start of the region */
|
||||
// off_t fst_length; /* IN: size of the region */
|
||||
// off_t fst_bytesalloc; /* OUT: number of bytes allocated */
|
||||
// } fstore_t;
|
||||
//
|
||||
// The flags (fst_flags) for the F_PREALLOCATE command are as follows:
|
||||
//
|
||||
// F_ALLOCATECONTIG Allocate contiguous space.
|
||||
//
|
||||
// F_ALLOCATEALL Allocate all requested space or no space at all.
|
||||
//
|
||||
// The position modes (fst_posmode) for the F_PREALLOCATE command indicate how to use the offset field. The modes are as fol-
|
||||
// lows:
|
||||
//
|
||||
// F_PEOFPOSMODE Allocate from the physical end of file.
|
||||
//
|
||||
// F_VOLPOSMODE Allocate from the volume offset.
|
||||
|
||||
k := struct {
|
||||
Flags uint32 // u_int32_t
|
||||
Posmode int64 // int
|
||||
Offset int64 // off_t
|
||||
Length int64 // off_t
|
||||
Bytesalloc int64 // off_t
|
||||
}{
|
||||
0,
|
||||
0,
|
||||
int64(off),
|
||||
int64(len),
|
||||
0,
|
||||
}
|
||||
_, _, errno := unix.Syscall(syscall.SYS_FCNTL, uintptr(fd), uintptr(unix.F_PREALLOCATE), uintptr(unsafe.Pointer(&k)))
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
}
|
||||
15
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate_freebsd.go
generated
vendored
Normal file
15
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
package fallocate
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func fallocate(fd int, mode uint32, off int64, len int64) error {
|
||||
// Ignore mode
|
||||
_ = mode
|
||||
ret, _, _ := unix.Syscall(unix.SYS_POSIX_FALLOCATE, uintptr(fd), uintptr(off), uintptr(len))
|
||||
if ret != 0 {
|
||||
return unix.Errno(ret)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
7
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate_linux.go
generated
vendored
Normal file
7
vendor/github.com/hanwen/go-fuse/v2/internal/fallocate/fallocate_linux.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package fallocate
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
func fallocate(fd int, mode uint32, off int64, len int64) error {
|
||||
return unix.Fallocate(fd, mode, off, len)
|
||||
}
|
||||
45
vendor/github.com/hanwen/go-fuse/v2/internal/ioctl/ioctl.go
generated
vendored
Normal file
45
vendor/github.com/hanwen/go-fuse/v2/internal/ioctl/ioctl.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package ioctl
|
||||
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/ioctl.h
|
||||
|
||||
const (
|
||||
NONE = 0x0
|
||||
READ = 0x1
|
||||
WRITE = 0x2
|
||||
)
|
||||
|
||||
// The ioctl command. It encodes direction (read/write), argument size
|
||||
// and a type/number, where type should be globally unique and number
|
||||
// is unique to the driver.
|
||||
type Command uint32
|
||||
|
||||
// New constructs an ioctl command. size should be less than 16kb.
|
||||
func New(dir byte, typ byte, nr byte, size uintptr) Command {
|
||||
if size >= (1 << 14) {
|
||||
panic("invalid ioctl sizeof")
|
||||
}
|
||||
return Command(dir)<<(14+16) |
|
||||
Command(size)<<16 |
|
||||
Command(typ)<<8 |
|
||||
Command(nr)
|
||||
}
|
||||
|
||||
// Read returns true if the ioctl reads data
|
||||
func (c Command) Read() bool {
|
||||
return (c>>(14+16))&READ != 0
|
||||
}
|
||||
|
||||
// Write returns true if the ioctl writes data
|
||||
func (c Command) Write() bool {
|
||||
return (c>>(14+16))&WRITE != 0
|
||||
}
|
||||
|
||||
// Number returns the lower 8 bits of the command
|
||||
func (c Command) Number() byte {
|
||||
return byte(c & 0xff)
|
||||
}
|
||||
|
||||
// Type returns the upper 8 bits of the command
|
||||
func (c Command) Type() byte {
|
||||
return byte((c >> 8) & 0xff)
|
||||
}
|
||||
35
vendor/github.com/hanwen/go-fuse/v2/internal/openat/openat.go
generated
vendored
Normal file
35
vendor/github.com/hanwen/go-fuse/v2/internal/openat/openat.go
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
package openat
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// OpenSymlinkAware is a symlink-aware syscall.Open replacement.
|
||||
//
|
||||
// What it does:
|
||||
//
|
||||
// 1. Open baseDir (usually an absolute path), following symlinks.
|
||||
//
|
||||
// The user may have set up the directory tree with symlinks,
|
||||
// that's not neccessarily malicous, but a normal use case.
|
||||
//
|
||||
// 2. Open path (must be a relative path) within baseDir, rejecting symlinks with ELOOP.
|
||||
//
|
||||
// On Linux, it calls openat2(2) with RESOLVE_NO_SYMLINKS. This prevents following
|
||||
// symlinks in any component of the path.
|
||||
//
|
||||
// On other platforms, it calls openat(2) with O_NOFOLLOW.
|
||||
// TODO: This is insecure as O_NOFOLLOW only affects the final path component.
|
||||
func OpenSymlinkAware(baseDir string, path string, flags int, mode uint32) (fd int, err error) {
|
||||
// Passing an absolute path is a bug in the caller
|
||||
if len(path) > 0 && path[0] == '/' {
|
||||
return -1, unix.EINVAL
|
||||
}
|
||||
baseFd, err := unix.Open(baseDir, unix.O_RDONLY|unix.O_DIRECTORY|unix.O_CLOEXEC, 0)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
defer unix.Close(baseFd)
|
||||
|
||||
return openatNoSymlinks(baseFd, path, flags, mode)
|
||||
}
|
||||
20
vendor/github.com/hanwen/go-fuse/v2/internal/openat/openat_linux.go
generated
vendored
Normal file
20
vendor/github.com/hanwen/go-fuse/v2/internal/openat/openat_linux.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
package openat
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func openatNoSymlinks(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
|
||||
how := unix.OpenHow{
|
||||
// os/exec expects all fds to have O_CLOEXEC or it will leak them to subprocesses.
|
||||
Flags: uint64(flags) | unix.O_CLOEXEC,
|
||||
Mode: uint64(mode),
|
||||
Resolve: unix.RESOLVE_NO_SYMLINKS,
|
||||
}
|
||||
fd, err = unix.Openat2(dirfd, path, &how)
|
||||
if err != nil && err == unix.ENOSYS {
|
||||
flags |= unix.O_NOFOLLOW | unix.O_CLOEXEC
|
||||
fd, err = unix.Openat(dirfd, path, flags, mode)
|
||||
}
|
||||
return fd, err
|
||||
}
|
||||
15
vendor/github.com/hanwen/go-fuse/v2/internal/openat/openat_unix.go
generated
vendored
Normal file
15
vendor/github.com/hanwen/go-fuse/v2/internal/openat/openat_unix.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
//go:build !linux
|
||||
|
||||
package openat
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// TODO: This is insecure as O_NOFOLLOW only affects the final path component.
|
||||
// See https://github.com/rfjakob/gocryptfs/issues/165 for how this could be handled.
|
||||
func openatNoSymlinks(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
|
||||
// os/exec expects all fds to have O_CLOEXEC or it will leak them to subprocesses.
|
||||
flags |= unix.O_NOFOLLOW | unix.O_CLOEXEC
|
||||
return unix.Openat(dirfd, path, flags, mode)
|
||||
}
|
||||
9
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat.go
generated
vendored
Normal file
9
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
package renameat
|
||||
|
||||
// Renameat is a wrapper around renameat syscall.
|
||||
// On Linux, it is a wrapper around renameat2(2).
|
||||
// On Darwin, it is a wrapper around renameatx_np(2).
|
||||
// On FreeBSD, it is a wrapper around renameat(2).
|
||||
func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) {
|
||||
return renameat(olddirfd, oldpath, newdirfd, newpath, flags)
|
||||
}
|
||||
38
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat_darwin.go
generated
vendored
Normal file
38
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package renameat
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
SYS_RENAMEATX_NP = 488
|
||||
RENAME_SWAP = 0x2
|
||||
RENAME_EXCHANGE = RENAME_SWAP
|
||||
)
|
||||
|
||||
func renameat(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) error {
|
||||
oldpathCString, err := syscall.BytePtrFromString(oldpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newpathCString, err := syscall.BytePtrFromString(newpath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _, errno := syscall.Syscall6(
|
||||
SYS_RENAMEATX_NP,
|
||||
uintptr(olddirfd),
|
||||
uintptr(unsafe.Pointer(oldpathCString)),
|
||||
uintptr(newdirfd),
|
||||
uintptr(unsafe.Pointer(newpathCString)),
|
||||
uintptr(flags),
|
||||
0,
|
||||
)
|
||||
|
||||
if errno != 0 {
|
||||
return errno
|
||||
}
|
||||
return nil
|
||||
}
|
||||
17
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat_freebsd.go
generated
vendored
Normal file
17
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package renameat
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const (
|
||||
// Since FreeBSD does not currently privode renameat syscall
|
||||
// beyond POSIX standard like Linux and Darwin do, we borrow
|
||||
// the defination from Linux but reject these non-POSIX flags.
|
||||
RENAME_EXCHANGE = (1 << 1)
|
||||
)
|
||||
|
||||
func renameat(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) {
|
||||
if flags != 0 {
|
||||
return unix.ENOSYS
|
||||
}
|
||||
return unix.Renameat(olddirfd, oldpath, newdirfd, newpath)
|
||||
}
|
||||
11
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat_linux.go
generated
vendored
Normal file
11
vendor/github.com/hanwen/go-fuse/v2/internal/renameat/renameat_linux.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package renameat
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const (
|
||||
RENAME_EXCHANGE = unix.RENAME_EXCHANGE
|
||||
)
|
||||
|
||||
func renameat(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error) {
|
||||
return unix.Renameat2(olddirfd, oldpath, newdirfd, newpath, flags)
|
||||
}
|
||||
40
vendor/github.com/hanwen/go-fuse/v2/internal/utimens/utimens_darwin.go
generated
vendored
Normal file
40
vendor/github.com/hanwen/go-fuse/v2/internal/utimens/utimens_darwin.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2018 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package utimens
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
// timeToTimeval converts time.Time to syscall.Timeval
|
||||
func timeToTimeval(t *time.Time) syscall.Timeval {
|
||||
// Note: This does not use syscall.NsecToTimespec because
|
||||
// that does not work properly for times before 1970,
|
||||
// see https://github.com/golang/go/issues/12777
|
||||
var tv syscall.Timeval
|
||||
tv.Usec = int32(t.Nanosecond() / 1000)
|
||||
tv.Sec = t.Unix()
|
||||
return tv
|
||||
}
|
||||
|
||||
// Fill converts a and m to a syscall.Timeval slice that can be passed
|
||||
// to syscall.Utimes. Missing values (if any) are taken from attr
|
||||
func Fill(a *time.Time, m *time.Time, attr *fuse.Attr) []syscall.Timeval {
|
||||
if a == nil {
|
||||
a2 := time.Unix(int64(attr.Atime), int64(attr.Atimensec))
|
||||
a = &a2
|
||||
}
|
||||
if m == nil {
|
||||
m2 := time.Unix(int64(attr.Mtime), int64(attr.Mtimensec))
|
||||
m = &m2
|
||||
}
|
||||
tv := make([]syscall.Timeval, 2)
|
||||
tv[0] = timeToTimeval(a)
|
||||
tv[1] = timeToTimeval(m)
|
||||
return tv
|
||||
}
|
||||
7
vendor/github.com/hanwen/go-fuse/v2/internal/utimens/utimens_linux.go
generated
vendored
Normal file
7
vendor/github.com/hanwen/go-fuse/v2/internal/utimens/utimens_linux.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2018 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package utimens
|
||||
|
||||
// placeholder file so this package exists on all platforms.
|
||||
10
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/constants_linux.go
generated
vendored
Normal file
10
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/constants_linux.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// Copyright 2024 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xattr
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
// ENOATTR indicates that an extended attribute was not present.
|
||||
const ENOATTR = unix.ENODATA
|
||||
11
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/constants_unix.go
generated
vendored
Normal file
11
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/constants_unix.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
//go:build !linux
|
||||
|
||||
// Copyright 2024 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xattr
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const ENOATTR = unix.ENOATTR
|
||||
9
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/xattr.go
generated
vendored
Normal file
9
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/xattr.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2024 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xattr
|
||||
|
||||
func ParseAttrNames(buf []byte) [][]byte {
|
||||
return parseAttrNames(buf)
|
||||
}
|
||||
20
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/xattr_freebsd.go
generated
vendored
Normal file
20
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/xattr_freebsd.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2024 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xattr
|
||||
|
||||
// BSDs syscall use different convention of data buf retrieved
|
||||
// through syscall `unix.Listxattr`.
|
||||
// Ref: extattr_list_file(2)
|
||||
func parseAttrNames(buf []byte) [][]byte {
|
||||
var attrList [][]byte
|
||||
for p := 0; p < len(buf); {
|
||||
attrNameLen := int(buf[p])
|
||||
p++
|
||||
attrName := buf[p : p+attrNameLen]
|
||||
attrList = append(attrList, attrName)
|
||||
p += attrNameLen
|
||||
}
|
||||
return attrList
|
||||
}
|
||||
13
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/xattr_unix.go
generated
vendored
Normal file
13
vendor/github.com/hanwen/go-fuse/v2/internal/xattr/xattr_unix.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
//go:build !freebsd
|
||||
|
||||
// Copyright 2024 the Go-FUSE Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package xattr
|
||||
|
||||
import "bytes"
|
||||
|
||||
func parseAttrNames(buf []byte) [][]byte {
|
||||
return bytes.Split(buf, []byte{0})
|
||||
}
|
||||
Reference in New Issue
Block a user