diff options
author | Vivek Goyal <vgoyal@redhat.com> | 2020-10-09 14:15:11 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2020-11-11 17:22:33 +0100 |
commit | 643a666a89c358ef588d2b3ef9f2dc1efc421e61 (patch) | |
tree | 6e9065257d8d01110e3aa26e8cfc5a87295b32dd /fs | |
parent | 8981bdfda7445af5d5a8c277c923bf91873a0c98 (diff) |
fuse: add a flag FUSE_OPEN_KILL_SUIDGID for open() request
With FUSE_HANDLE_KILLPRIV_V2 support, server will need to kill suid/sgid/
security.capability on open(O_TRUNC), if server supports
FUSE_ATOMIC_O_TRUNC.
But server needs to kill suid/sgid only if caller does not have CAP_FSETID.
Given server does not have this information, client needs to send this info
to server.
So add a flag FUSE_OPEN_KILL_SUIDGID to fuse_open_in request which tells
server to kill suid/sgid (only if group execute is set).
This flag is added to the FUSE_OPEN request, as well as the FUSE_CREATE
request if the create was non-exclusive, since that might result in an
existing file being opened/truncated.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fuse/dir.c | 6 | ||||
-rw-r--r-- | fs/fuse/file.c | 6 |
2 files changed, 12 insertions, 0 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 778367d125f9..5d43af1169b7 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -541,6 +541,12 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, inarg.flags = flags; inarg.mode = mode; inarg.umask = current_umask(); + + if (fm->fc->handle_killpriv_v2 && (flags & O_TRUNC) && + !(flags & O_EXCL) && !capable(CAP_FSETID)) { + inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID; + } + args.opcode = FUSE_CREATE; args.nodeid = get_node_id(dir); args.in_numargs = 2; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index aa0a44f7028f..349885353036 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -42,6 +42,12 @@ static int fuse_send_open(struct fuse_mount *fm, u64 nodeid, struct file *file, inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); if (!fm->fc->atomic_o_trunc) inarg.flags &= ~O_TRUNC; + + if (fm->fc->handle_killpriv_v2 && + (inarg.flags & O_TRUNC) && !capable(CAP_FSETID)) { + inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID; + } + args.opcode = opcode; args.nodeid = nodeid; args.in_numargs = 1; |