Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ func (c *Connection) Init() error {
c.protocol = initOp.Kernel
}

if c.debugLogger != nil {
c.debugLogger.Printf("Kernel protocol version major: %v, minor: %v\n", initOp.Kernel.Major, initOp.Kernel.Minor)
c.debugLogger.Printf("Protocol version major: %v, minor: %v\n", c.protocol.Major, c.protocol.Minor)
}

cacheSymlinks := initOp.Flags&fusekernel.InitCacheSymlinks > 0
noOpenSupport := initOp.Flags&fusekernel.InitNoOpenSupport > 0
noOpendirSupport := initOp.Flags&fusekernel.InitNoOpendirSupport > 0
Expand Down Expand Up @@ -229,6 +234,14 @@ func (c *Connection) Init() error {
}
}

if c.cfg.EnableHandleKillpriv {
initOp.Flags |= fusekernel.InitHandleKillpriv
}

if c.cfg.EnableHandleKillprivV2 {
initOp.Flags |= fusekernel.InitHandleKillprivV2
}

return c.Reply(ctx, nil)
}

Expand Down
28 changes: 25 additions & 3 deletions conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ func convertInMessage(
to.Handle = &t
}

if valid.KillSuidgid() {
to.KillSuidgid = true
}

case fusekernel.OpForget:
type input fusekernel.ForgetIn
in := (*input)(inMsg.Consume(unsafe.Sizeof(input{})))
Expand Down Expand Up @@ -236,7 +240,7 @@ func convertInMessage(
}
name = name[:i]

o = &fuseops.CreateFileOp{
createOp := &fuseops.CreateFileOp{
Parent: fuseops.InodeID(inMsg.Header().Nodeid),
Name: string(name),
Mode: ConvertFileMode(in.Mode),
Expand All @@ -248,6 +252,12 @@ func convertInMessage(
OpenFlags: fusekernel.OpenFlags(in.Flags),
}

if fusekernel.OpenRequestFlags(in.OpenFlags)&fusekernel.OpenKillSuidgid != 0 {
createOp.KillSuidgid = true
}

o = createOp

case fusekernel.OpSymlink:
// The message is "newName\0target\0".
names := inMsg.ConsumeBytes(inMsg.Len())
Expand Down Expand Up @@ -358,7 +368,7 @@ func convertInMessage(
return nil, errors.New("Corrupt OpOpen")
}

o = &fuseops.OpenFileOp{
openOp := &fuseops.OpenFileOp{
Inode: fuseops.InodeID(inMsg.Header().Nodeid),
OpenFlags: fusekernel.OpenFlags(in.Flags),
OpContext: fuseops.OpContext{
Expand All @@ -368,6 +378,12 @@ func convertInMessage(
},
}

if fusekernel.OpenRequestFlags(in.OpenFlags)&fusekernel.OpenKillSuidgid != 0 {
openOp.KillSuidgid = true
}

o = openOp

case fusekernel.OpOpendir:
o = &fuseops.OpenDirOp{
Inode: fuseops.InodeID(inMsg.Header().Nodeid),
Expand Down Expand Up @@ -503,7 +519,7 @@ func convertInMessage(
return nil, errors.New("Corrupt OpWrite")
}

o = &fuseops.WriteFileOp{
writeOp := &fuseops.WriteFileOp{
Inode: fuseops.InodeID(inMsg.Header().Nodeid),
Handle: fuseops.HandleID(in.Fh),
Data: buf,
Expand All @@ -515,6 +531,12 @@ func convertInMessage(
},
}

if fusekernel.WriteFlags(in.WriteFlags)&fusekernel.WriteKillSuidgid != 0 {
writeOp.KillSuidgid = true
}

o = writeOp

case fusekernel.OpFsync, fusekernel.OpFsyncdir:
type input fusekernel.FsyncIn
in := (*input)(inMsg.Consume(unsafe.Sizeof(input{})))
Expand Down
19 changes: 18 additions & 1 deletion fuseops/ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ type SetInodeAttributesOp struct {
Atime *time.Time
Mtime *time.Time

// When HANDLE_KILLPRIV_V2 is enabled, this indicates whether the kernel
// requests the filesystem to clear setuid/setgid bits.
KillSuidgid bool

// Set by the file system: the new attributes for the inode, and the time at
// which they should expire. See notes on
// ChildInodeEntry.AttributesExpiration for more.
Expand Down Expand Up @@ -340,6 +344,10 @@ type CreateFileOp struct {
Name string
Mode os.FileMode

// When HANDLE_KILLPRIV_V2 is enabled, this indicates whether the kernel
// requests the filesystem to clear setuid/setgid bits when creating the file.
KillSuidgid bool

// Set by the file system: information about the inode that was created.
//
// The lookup count for the inode is implicitly incremented. See notes on
Expand Down Expand Up @@ -689,6 +697,10 @@ type OpenFileOp struct {
// to the FUSE daemon.
OpenFlags fusekernel.OpenFlags

// When HANDLE_KILLPRIV_V2 is enabled, this indicates whether the kernel
// requests the filesystem to clear setuid/setgid bits when opening the file.
KillSuidgid bool

OpContext OpContext
}

Expand Down Expand Up @@ -795,7 +807,12 @@ type WriteFileOp struct {
// be written, except on error (https://tinyurl.com/yuruk5tx). This appears
// to be because it uses file mmapping machinery
// (https://tinyurl.com/avxy3dvm) to write a page at a time.
Data []byte
Data []byte

// When HANDLE_KILLPRIV_V2 is enabled, this indicates whether the kernel
// requests the filesystem to clear setuid/setgid bits during this write.
KillSuidgid bool

OpContext OpContext

// If set, this function will be invoked after the operation response has been
Expand Down
79 changes: 53 additions & 26 deletions internal/fusekernel/fuse_kernel.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ const (
SetattrHandle SetattrValid = 1 << 6

// Linux only(?)
SetattrAtimeNow SetattrValid = 1 << 7
SetattrMtimeNow SetattrValid = 1 << 8
SetattrLockOwner SetattrValid = 1 << 9 // http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg27852.html
SetattrAtimeNow SetattrValid = 1 << 7
SetattrMtimeNow SetattrValid = 1 << 8
SetattrLockOwner SetattrValid = 1 << 9 // http://www.mail-archive.com/git-commits-head@vger.kernel.org/msg27852.html
SetattrKillSuidgid SetattrValid = 1 << 11 // Clear setuid/setgid bits (used with HANDLE_KILLPRIV_V2)

// OS X only
SetattrCrtime SetattrValid = 1 << 28
Expand All @@ -114,20 +115,21 @@ const (
SetattrFlags SetattrValid = 1 << 31
)

func (fl SetattrValid) Mode() bool { return fl&SetattrMode != 0 }
func (fl SetattrValid) Uid() bool { return fl&SetattrUid != 0 }
func (fl SetattrValid) Gid() bool { return fl&SetattrGid != 0 }
func (fl SetattrValid) Size() bool { return fl&SetattrSize != 0 }
func (fl SetattrValid) Atime() bool { return fl&SetattrAtime != 0 }
func (fl SetattrValid) Mtime() bool { return fl&SetattrMtime != 0 }
func (fl SetattrValid) Handle() bool { return fl&SetattrHandle != 0 }
func (fl SetattrValid) AtimeNow() bool { return fl&SetattrAtimeNow != 0 }
func (fl SetattrValid) MtimeNow() bool { return fl&SetattrMtimeNow != 0 }
func (fl SetattrValid) LockOwner() bool { return fl&SetattrLockOwner != 0 }
func (fl SetattrValid) Crtime() bool { return fl&SetattrCrtime != 0 }
func (fl SetattrValid) Chgtime() bool { return fl&SetattrChgtime != 0 }
func (fl SetattrValid) Bkuptime() bool { return fl&SetattrBkuptime != 0 }
func (fl SetattrValid) Flags() bool { return fl&SetattrFlags != 0 }
func (fl SetattrValid) Mode() bool { return fl&SetattrMode != 0 }
func (fl SetattrValid) Uid() bool { return fl&SetattrUid != 0 }
func (fl SetattrValid) Gid() bool { return fl&SetattrGid != 0 }
func (fl SetattrValid) Size() bool { return fl&SetattrSize != 0 }
func (fl SetattrValid) Atime() bool { return fl&SetattrAtime != 0 }
func (fl SetattrValid) Mtime() bool { return fl&SetattrMtime != 0 }
func (fl SetattrValid) Handle() bool { return fl&SetattrHandle != 0 }
func (fl SetattrValid) AtimeNow() bool { return fl&SetattrAtimeNow != 0 }
func (fl SetattrValid) MtimeNow() bool { return fl&SetattrMtimeNow != 0 }
func (fl SetattrValid) LockOwner() bool { return fl&SetattrLockOwner != 0 }
func (fl SetattrValid) KillSuidgid() bool { return fl&SetattrKillSuidgid != 0 }
func (fl SetattrValid) Crtime() bool { return fl&SetattrCrtime != 0 }
func (fl SetattrValid) Chgtime() bool { return fl&SetattrChgtime != 0 }
func (fl SetattrValid) Bkuptime() bool { return fl&SetattrBkuptime != 0 }
func (fl SetattrValid) Flags() bool { return fl&SetattrFlags != 0 }

func (fl SetattrValid) String() string {
return flagString(uint32(fl), setattrValidNames)
Expand All @@ -144,6 +146,7 @@ var setattrValidNames = []flagName{
{uint32(SetattrAtimeNow), "SetattrAtimeNow"},
{uint32(SetattrMtimeNow), "SetattrMtimeNow"},
{uint32(SetattrLockOwner), "SetattrLockOwner"},
{uint32(SetattrKillSuidgid), "SetattrKillSuidgid"},
{uint32(SetattrCrtime), "SetattrCrtime"},
{uint32(SetattrChgtime), "SetattrChgtime"},
{uint32(SetattrBkuptime), "SetattrBkuptime"},
Expand Down Expand Up @@ -274,9 +277,11 @@ const (
InitWritebackCache InitFlags = 1 << 16
InitNoOpenSupport InitFlags = 1 << 17
InitParallelDirOps InitFlags = 1 << 18
InitHandleKillpriv InitFlags = 1 << 19
InitMaxPages InitFlags = 1 << 22
InitCacheSymlinks InitFlags = 1 << 23
InitNoOpendirSupport InitFlags = 1 << 24
InitHandleKillprivV2 InitFlags = 1 << 28

InitCaseSensitive InitFlags = 1 << 29 // OS X only
InitVolRename InitFlags = 1 << 30 // OS X only
Expand Down Expand Up @@ -310,6 +315,8 @@ var initFlagNames = []flagName{
{uint32(InitNoOpenSupport), "InitNoOpenSupport"},
{uint32(InitCacheSymlinks), "InitCacheSymlinks"},
{uint32(InitNoOpendirSupport), "InitNoOpendirSupport"},
{uint32(InitHandleKillpriv), "InitHandleKillpriv"},
{uint32(InitHandleKillprivV2), "InitHandleKillprivV2"},

{uint32(InitCaseSensitive), "InitCaseSensitive"},
{uint32(InitVolRename), "InitVolRename"},
Expand Down Expand Up @@ -542,8 +549,8 @@ type setattrInCommon struct {
}

type OpenIn struct {
Flags uint32
Unused uint32
Flags uint32 // User-space O_RDONLY/O_WRONLY/etc flags
OpenFlags uint32 // Kernel FUSE_OPEN_* flags (e.g., FUSE_OPEN_KILL_SUIDGID)
}

type OpenOut struct {
Expand All @@ -553,10 +560,29 @@ type OpenOut struct {
}

type CreateIn struct {
Flags uint32
Mode uint32
Umask uint32
padding uint32
Flags uint32 // User-space O_RDONLY/O_WRONLY/etc flags
Mode uint32
Umask uint32
OpenFlags uint32 // Kernel FUSE_OPEN_* flags (e.g., FUSE_OPEN_KILL_SUIDGID)
}

// OpenRequestFlags are kernel-level flags sent from the kernel to the filesystem
// in OpenIn.OpenFlags or CreateIn.OpenFlags (not to be confused with the Flags
// field which contains user-space O_RDONLY/O_WRONLY/etc flags, or OpenResponseFlags
// which are returned by the filesystem in OpenOut).
type OpenRequestFlags uint32

const (
// Clear setuid/setgid bits when opening file (used with HANDLE_KILLPRIV_V2)
OpenKillSuidgid OpenRequestFlags = 1 << 0
)

var openRequestFlagNames = []flagName{
{uint32(OpenKillSuidgid), "OpenKillSuidgid"},
}

func (fl OpenRequestFlags) String() string {
return flagString(uint32(fl), openRequestFlagNames)
}

func CreateInSize(p Protocol) uintptr {
Expand Down Expand Up @@ -645,14 +671,15 @@ type WriteOut struct {
type WriteFlags uint32

const (
WriteCache WriteFlags = 1 << 0
// LockOwner field is valid.
WriteLockOwner WriteFlags = 1 << 1
WriteCache WriteFlags = 1 << 0
WriteLockOwner WriteFlags = 1 << 1 // LockOwner field is valid
WriteKillSuidgid WriteFlags = 1 << 2 // Clear setuid/setgid bits (used with HANDLE_KILLPRIV_V2)
)

var writeFlagNames = []flagName{
{uint32(WriteCache), "WriteCache"},
{uint32(WriteLockOwner), "WriteLockOwner"},
{uint32(WriteKillSuidgid), "WriteKillSuidgid"},
}

func (fl WriteFlags) String() string {
Expand Down
Loading