diff options
author | Bernd Schubert <bschubert@ddn.com> | 2024-03-28 15:18:14 +0100 |
---|---|---|
committer | Bernd Schubert <bernd.schubert@fastmail.fm> | 2024-03-29 13:04:45 +0100 |
commit | 3e283a1bcbc4ec78fb45c4a8b3f683b8e3082c53 (patch) | |
tree | cf00051abd35fc7edba7d8014e9d41952acf37fb | |
parent | 67d4db405059f83d3c2f4ee577a712c424b481db (diff) | |
download | libfuse-3e283a1bcbc4ec78fb45c4a8b3f683b8e3082c53.tar.gz |
Add support for FUSE_CAP_HANDLE_KILLPRIV_V2
This just adds in the basic handler, but does not
use it yet in examples.
-rw-r--r-- | example/printcap.c | 8 | ||||
-rw-r--r-- | include/fuse_common.h | 17 | ||||
-rw-r--r-- | lib/fuse_lowlevel.c | 4 |
3 files changed, 29 insertions, 0 deletions
diff --git a/example/printcap.c b/example/printcap.c index 30e2057..bbbc1b8 100644 --- a/example/printcap.c +++ b/example/printcap.c @@ -81,6 +81,14 @@ static void pc_init(void *userdata, printf("\tFUSE_CAP_EXPLICIT_INVAL_DATA\n"); if(conn->capable & FUSE_CAP_EXPIRE_ONLY) printf("\tFUSE_CAP_EXPIRE_ONLY\n"); + if(conn->capable & FUSE_CAP_SETXATTR_EXT) + printf("\tFUSE_CAP_SETXATTR_EXT\n"); + if(conn->capable & FUSE_CAP_HANDLE_KILLPRIV) + printf("\tFUSE_CAP_HANDLE_KILLPRIV\n"); + if(conn->capable & FUSE_CAP_HANDLE_KILLPRIV_V2) + printf("\tFUSE_CAP_HANDLE_KILLPRIV_V2\n"); + if(conn->capable & FUSE_CAP_DIRECT_IO_ALLOW_MMAP) + printf("\tFUSE_CAP_DIRECT_IO_ALLOW_MMAP\n"); fuse_session_exit(se); } diff --git a/include/fuse_common.h b/include/fuse_common.h index 52b691a..f052b67 100644 --- a/include/fuse_common.h +++ b/include/fuse_common.h @@ -368,6 +368,23 @@ struct fuse_loop_config_v1 { #define FUSE_CAP_HANDLE_KILLPRIV (1 << 20) /** + * Indicates that the filesystem is responsible for unsetting + * setuid and setgid bit and additionally cap (stored as xattr) when a + * file is written, truncated, or its owner is changed. + * Upon write/truncate suid/sgid is only killed if caller + * does not have CAP_FSETID. Additionally upon + * write/truncate sgid is killed only if file has group + * execute permission. (Same as Linux VFS behavior). + * KILLPRIV_V2 requires handling of + * - FUSE_OPEN_KILL_SUIDGID (set in struct fuse_create_in::open_flags) + * - FATTR_KILL_SUIDGID (set in struct fuse_setattr_in::valid) + * - FUSE_WRITE_KILL_SUIDGID (set in struct fuse_write_in::write_flags) + * + * This feature is disabled by default. + */ +#define FUSE_CAP_HANDLE_KILLPRIV_V2 (1 << 21) + +/** * Indicates that the kernel supports caching symlinks in its page cache. * * When this feature is enabled, symlink targets are saved in the page cache. diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index 26e5699..d9844b0 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -2001,6 +2001,8 @@ void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) se->conn.capable |= FUSE_CAP_POSIX_ACL; if (inargflags & FUSE_HANDLE_KILLPRIV) se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV; + if (inargflags & FUSE_HANDLE_KILLPRIV_V2) + se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV_V2; if (inargflags & FUSE_CACHE_SYMLINKS) se->conn.capable |= FUSE_CAP_CACHE_SYMLINKS; if (inargflags & FUSE_NO_OPENDIR_SUPPORT) @@ -2145,6 +2147,8 @@ void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) outargflags |= FUSE_POSIX_ACL; if (se->conn.want & FUSE_CAP_HANDLE_KILLPRIV) outargflags |= FUSE_HANDLE_KILLPRIV; + if (se->conn.want & FUSE_CAP_HANDLE_KILLPRIV_V2) + outargflags |= FUSE_HANDLE_KILLPRIV_V2; if (se->conn.want & FUSE_CAP_CACHE_SYMLINKS) outargflags |= FUSE_CACHE_SYMLINKS; if (se->conn.want & FUSE_CAP_EXPLICIT_INVAL_DATA) |