History

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.

Vivek Goyal committed 6 years ago

Commit 643a6661 parent 8981bdf3 files · +21 −2Browse files

Unified · Split

3 files
  1. fs/fuse/dir.c +6 −0
  2. fs/fuse/file.c +6 −0
  3. include/uapi/linux/fuse.h +9 −2
fs/fuse/dir.c+6−0
@@ -541,6 +541,12 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, · 540 unmodified lines
541 inarg.flags = flags;541 inarg.flags = flags;
542 inarg.mode = mode;542 inarg.mode = mode;
543 inarg.umask = current_umask();543 inarg.umask = current_umask();
544
545 if (fm->fc->handle_killpriv_v2 && (flags & O_TRUNC) &&
546 !(flags & O_EXCL) && !capable(CAP_FSETID)) {
547 inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
548 }
549
544 args.opcode = FUSE_CREATE;550 args.opcode = FUSE_CREATE;
545 args.nodeid = get_node_id(dir);551 args.nodeid = get_node_id(dir);
546 args.in_numargs = 2;552 args.in_numargs = 2;
fs/fuse/file.c+6−0
@@ -42,6 +42,12 @@ static int fuse_send_open(struct fuse_mount *fm, u64 nodeid, struct file *file, · 41 unmodified lines
42 inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);42 inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
43 if (!fm->fc->atomic_o_trunc)43 if (!fm->fc->atomic_o_trunc)
44 inarg.flags &= ~O_TRUNC;44 inarg.flags &= ~O_TRUNC;
45
46 if (fm->fc->handle_killpriv_v2 &&
47 (inarg.flags & O_TRUNC) && !capable(CAP_FSETID)) {
48 inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
49 }
50
45 args.opcode = opcode;51 args.opcode = opcode;
46 args.nodeid = nodeid;52 args.nodeid = nodeid;
47 args.in_numargs = 1;53 args.in_numargs = 1;
include/uapi/linux/fuse.h+9−2
@@ -178,6 +178,7 @@ · 177 unmodified lines
178 *178 *
179 * 7.33179 * 7.33
180 * - add FUSE_HANDLE_KILLPRIV_V2, FUSE_WRITE_KILL_SUIDGID, FATTR_KILL_SUIDGID180 * - add FUSE_HANDLE_KILLPRIV_V2, FUSE_WRITE_KILL_SUIDGID, FATTR_KILL_SUIDGID
181 * - add FUSE_OPEN_KILL_SUIDGID
181 */182 */
182 183
183#ifndef _LINUX_FUSE_H184#ifndef _LINUX_FUSE_H
@@ -444,6 +445,12 @@ struct fuse_file_lock { · 260 unmodified lines
444 */445 */
445#define FUSE_ATTR_SUBMOUNT (1 << 0)446#define FUSE_ATTR_SUBMOUNT (1 << 0)
446 447
448/**
449 * Open flags
450 * FUSE_OPEN_KILL_SUIDGID: Kill suid and sgid if executable
451 */
452#define FUSE_OPEN_KILL_SUIDGID (1 << 0)
453
447enum fuse_opcode {454enum fuse_opcode {
448 FUSE_LOOKUP = 1,455 FUSE_LOOKUP = 1,
449 FUSE_FORGET = 2, /* no reply */456 FUSE_FORGET = 2, /* no reply */
@@ -605,14 +612,14 @@ struct fuse_setattr_in { · 155 unmodified lines
605 612
606struct fuse_open_in {613struct fuse_open_in {
607 uint32_t flags;614 uint32_t flags;
608 uint32_t unused;615 uint32_t open_flags; /* FUSE_OPEN_... */
609};616};
610 617
611struct fuse_create_in {618struct fuse_create_in {
612 uint32_t flags;619 uint32_t flags;
613 uint32_t mode;620 uint32_t mode;
614 uint32_t umask;621 uint32_t umask;
615 uint32_t padding;622 uint32_t open_flags; /* FUSE_OPEN_... */
616};623};
617 624
618struct fuse_open_out {625struct fuse_open_out {