Loading fs/fuse/dir.c +27 −17 Original line number Diff line number Diff line Loading @@ -1703,6 +1703,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, static int fuse_setattr(struct dentry *entry, struct iattr *attr) { struct inode *inode = d_inode(entry); struct fuse_conn *fc = get_fuse_conn(inode); struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; int ret; Loading @@ -1710,13 +1711,21 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) return -EACCES; if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { int kill; attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE); /* * The only sane way to reliably kill suid/sgid is to do it in * the userspace filesystem * * This should be done on write(), truncate() and chown(). */ if (!fc->handle_killpriv) { int kill; /* * ia_mode calculation may have used stale i_mode. Refresh and * recalculate. * ia_mode calculation may have used stale i_mode. * Refresh and recalculate. */ ret = fuse_do_getattr(inode, NULL, file); if (ret) Loading @@ -1733,6 +1742,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) attr->ia_mode &= ~S_ISGID; } } } if (!attr->ia_valid) return 0; Loading fs/fuse/fuse_i.h +3 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,9 @@ struct fuse_conn { /** allow parallel lookups and readdir (default is serialized) */ unsigned parallel_dirops:1; /** handle fs handles killing suid/sgid/cap on write/chown/trunc */ unsigned handle_killpriv:1; /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction Loading fs/fuse/inode.c +3 −1 Original line number Diff line number Diff line Loading @@ -910,6 +910,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->writeback_cache = 1; if (arg->flags & FUSE_PARALLEL_DIROPS) fc->parallel_dirops = 1; if (arg->flags & FUSE_HANDLE_KILLPRIV) fc->handle_killpriv = 1; if (arg->time_gran && arg->time_gran <= 1000000000) fc->sb->s_time_gran = arg->time_gran; } else { Loading Loading @@ -941,7 +943,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA | FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO | FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | FUSE_PARALLEL_DIROPS; FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV; req->in.h.opcode = FUSE_INIT; req->in.numargs = 1; req->in.args[0].size = sizeof(*arg); Loading include/uapi/linux/fuse.h +6 −1 Original line number Diff line number Diff line Loading @@ -108,6 +108,9 @@ * * 7.25 * - add FUSE_PARALLEL_DIROPS * * 7.26 * - add FUSE_HANDLE_KILLPRIV */ #ifndef _LINUX_FUSE_H Loading Loading @@ -143,7 +146,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ #define FUSE_KERNEL_MINOR_VERSION 25 #define FUSE_KERNEL_MINOR_VERSION 26 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 Loading Loading @@ -238,6 +241,7 @@ struct fuse_file_lock { * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) Loading @@ -258,6 +262,7 @@ struct fuse_file_lock { #define FUSE_WRITEBACK_CACHE (1 << 16) #define FUSE_NO_OPEN_SUPPORT (1 << 17) #define FUSE_PARALLEL_DIROPS (1 << 18) #define FUSE_HANDLE_KILLPRIV (1 << 19) /** * CUSE INIT request/reply flags Loading Loading
fs/fuse/dir.c +27 −17 Original line number Diff line number Diff line Loading @@ -1703,6 +1703,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, static int fuse_setattr(struct dentry *entry, struct iattr *attr) { struct inode *inode = d_inode(entry); struct fuse_conn *fc = get_fuse_conn(inode); struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL; int ret; Loading @@ -1710,13 +1711,21 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) return -EACCES; if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) { int kill; attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE); /* * The only sane way to reliably kill suid/sgid is to do it in * the userspace filesystem * * This should be done on write(), truncate() and chown(). */ if (!fc->handle_killpriv) { int kill; /* * ia_mode calculation may have used stale i_mode. Refresh and * recalculate. * ia_mode calculation may have used stale i_mode. * Refresh and recalculate. */ ret = fuse_do_getattr(inode, NULL, file); if (ret) Loading @@ -1733,6 +1742,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) attr->ia_mode &= ~S_ISGID; } } } if (!attr->ia_valid) return 0; Loading
fs/fuse/fuse_i.h +3 −0 Original line number Diff line number Diff line Loading @@ -547,6 +547,9 @@ struct fuse_conn { /** allow parallel lookups and readdir (default is serialized) */ unsigned parallel_dirops:1; /** handle fs handles killing suid/sgid/cap on write/chown/trunc */ unsigned handle_killpriv:1; /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction Loading
fs/fuse/inode.c +3 −1 Original line number Diff line number Diff line Loading @@ -910,6 +910,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->writeback_cache = 1; if (arg->flags & FUSE_PARALLEL_DIROPS) fc->parallel_dirops = 1; if (arg->flags & FUSE_HANDLE_KILLPRIV) fc->handle_killpriv = 1; if (arg->time_gran && arg->time_gran <= 1000000000) fc->sb->s_time_gran = arg->time_gran; } else { Loading Loading @@ -941,7 +943,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA | FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO | FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT | FUSE_PARALLEL_DIROPS; FUSE_PARALLEL_DIROPS | FUSE_HANDLE_KILLPRIV; req->in.h.opcode = FUSE_INIT; req->in.numargs = 1; req->in.args[0].size = sizeof(*arg); Loading
include/uapi/linux/fuse.h +6 −1 Original line number Diff line number Diff line Loading @@ -108,6 +108,9 @@ * * 7.25 * - add FUSE_PARALLEL_DIROPS * * 7.26 * - add FUSE_HANDLE_KILLPRIV */ #ifndef _LINUX_FUSE_H Loading Loading @@ -143,7 +146,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ #define FUSE_KERNEL_MINOR_VERSION 25 #define FUSE_KERNEL_MINOR_VERSION 26 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 Loading Loading @@ -238,6 +241,7 @@ struct fuse_file_lock { * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes * FUSE_NO_OPEN_SUPPORT: kernel supports zero-message opens * FUSE_PARALLEL_DIROPS: allow parallel lookups and readdir * FUSE_HANDLE_KILLPRIV: fs handles killing suid/sgid/cap on write/chown/trunc */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) Loading @@ -258,6 +262,7 @@ struct fuse_file_lock { #define FUSE_WRITEBACK_CACHE (1 << 16) #define FUSE_NO_OPEN_SUPPORT (1 << 17) #define FUSE_PARALLEL_DIROPS (1 << 18) #define FUSE_HANDLE_KILLPRIV (1 << 19) /** * CUSE INIT request/reply flags Loading