fuse: add FUSE_WRITE_KILL_PRIV
In the FOPEN_DIRECT_IO case the write path doesn't call file_remove_privs() and that means setuid bit is not cleared if unpriviliged user writes to a file with setuid bit set. pjdfstest chmod test 12.t tests this and fails. Fix this by adding a flag to the FUSE_WRITE message that requests clearing privileges on the given file. This needs This better than just calling fuse_remove_privs(), because the attributes may not be up to date, so in that case a write may miss clearing the privileges. Test case: $ passthrough_ll /mnt/pasthrough-mnt -o default_permissions,allow_other,cache=never $ mkdir /mnt/pasthrough-mnt/testdir $ cd /mnt/pasthrough-mnt/testdir $ prove -rv pjdfstests/tests/chmod/12.t Reported-by: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Tested-by: Vivek Goyal <vgoyal@redhat.com>
This commit is contained in:
parent
35d6fcbb7c
commit
4a2abf99f9
|
@ -1377,10 +1377,17 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
|
|||
if (err && !nbytes)
|
||||
break;
|
||||
|
||||
if (write)
|
||||
if (write) {
|
||||
if (!capable(CAP_FSETID)) {
|
||||
struct fuse_write_in *inarg;
|
||||
|
||||
inarg = &req->misc.write.in;
|
||||
inarg->write_flags |= FUSE_WRITE_KILL_PRIV;
|
||||
}
|
||||
nres = fuse_send_write(req, io, pos, nbytes, owner);
|
||||
else
|
||||
} else {
|
||||
nres = fuse_send_read(req, io, pos, nbytes, owner);
|
||||
}
|
||||
|
||||
if (!io->async)
|
||||
fuse_release_user_pages(req, io->should_dirty);
|
||||
|
|
|
@ -130,6 +130,9 @@
|
|||
* 7.30
|
||||
* - add FUSE_EXPLICIT_INVAL_DATA
|
||||
* - add FUSE_IOCTL_COMPAT_X32
|
||||
*
|
||||
* 7.31
|
||||
* - add FUSE_WRITE_KILL_PRIV flag
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FUSE_H
|
||||
|
@ -165,7 +168,7 @@
|
|||
#define FUSE_KERNEL_VERSION 7
|
||||
|
||||
/** Minor version number of this interface */
|
||||
#define FUSE_KERNEL_MINOR_VERSION 30
|
||||
#define FUSE_KERNEL_MINOR_VERSION 31
|
||||
|
||||
/** The node ID of the root inode */
|
||||
#define FUSE_ROOT_ID 1
|
||||
|
@ -327,9 +330,11 @@ struct fuse_file_lock {
|
|||
*
|
||||
* FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed
|
||||
* FUSE_WRITE_LOCKOWNER: lock_owner field is valid
|
||||
* FUSE_WRITE_KILL_PRIV: kill suid and sgid bits
|
||||
*/
|
||||
#define FUSE_WRITE_CACHE (1 << 0)
|
||||
#define FUSE_WRITE_LOCKOWNER (1 << 1)
|
||||
#define FUSE_WRITE_KILL_PRIV (1 << 2)
|
||||
|
||||
/**
|
||||
* Read flags
|
||||
|
|
Loading…
Reference in New Issue