Commit 643a666a authored by Vivek Goyal's avatar Vivek Goyal Committed by Miklos Szeredi
Browse files

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: default avatarVivek Goyal <vgoyal@redhat.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 8981bdfd
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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;
+9 −2
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@
 *
 *  7.33
 *  - add FUSE_HANDLE_KILLPRIV_V2, FUSE_WRITE_KILL_SUIDGID, FATTR_KILL_SUIDGID
 *  - add FUSE_OPEN_KILL_SUIDGID
 */

#ifndef _LINUX_FUSE_H
@@ -444,6 +445,12 @@ struct fuse_file_lock {
 */
#define FUSE_ATTR_SUBMOUNT      (1 << 0)

/**
 * Open flags
 * FUSE_OPEN_KILL_SUIDGID: Kill suid and sgid if executable
 */
#define FUSE_OPEN_KILL_SUIDGID	(1 << 0)

enum fuse_opcode {
	FUSE_LOOKUP		= 1,
	FUSE_FORGET		= 2,  /* no reply */
@@ -605,14 +612,14 @@ struct fuse_setattr_in {

struct fuse_open_in {
	uint32_t	flags;
	uint32_t	unused;
	uint32_t	open_flags;	/* FUSE_OPEN_... */
};

struct fuse_create_in {
	uint32_t	flags;
	uint32_t	mode;
	uint32_t	umask;
	uint32_t	padding;
	uint32_t	open_flags;	/* FUSE_OPEN_... */
};

struct fuse_open_out {