mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
vfs: pass S_IFDIR mode to vfs_prepare_mode()
There is a comment in vfs_prepare_mode() that says: Note that it's currently valid for @type to be 0 if a directory is created. Filesystems raise that flag individually and we need to check whether each filesystem can deal with receiving S_IFDIR from the vfs before we enforce a non-zero type. It is safe to do this clean-up except that three filesystems (fuse, cifs, and coda) forward the mkdir @mode unchanged to something outside the kernel. Mask S_IFDIR back out in coda_mkdir(), fuse_mkdir() and cifs_mkdir() so that what is sent outside the kernel is unchanged. Their maintainers can drop the mask once they have confirmed it is safe. Assisted-by: LLM Signed-off-by: Jori Koolstra <jkoolstra@xs4all.nl> Link: https://patch.msgid.link/20260630105400.68459-2-jkoolstra@xs4all.nl Reviewed-by: NeilBrown <neil@brown.name> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
parent
af695109e8
commit
2f3a7a488c
|
|
@ -179,7 +179,12 @@ static struct dentry *coda_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
if (is_root_inode(dir) && coda_iscontrol(name, len))
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
attrs.va_mode = mode;
|
||||
/*
|
||||
* vfs_mkdir() now passes S_IFDIR in @mode, but @mode is forwarded
|
||||
* verbatim to userspace, which has only ever been given the permission
|
||||
* bits. Strip the type bit until venus is known to cope with it.
|
||||
*/
|
||||
attrs.va_mode = mode & ~S_IFDIR;
|
||||
error = venus_mkdir(dir->i_sb, coda_i2f(dir),
|
||||
name, len, &newfid, &attrs);
|
||||
if (error)
|
||||
|
|
|
|||
|
|
@ -1117,6 +1117,14 @@ static struct dentry *fuse_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
if (!fm->fc->dont_mask)
|
||||
mode &= ~current_umask();
|
||||
|
||||
/*
|
||||
* vfs_mkdir() now passes S_IFDIR in @mode, but @mode is forwarded
|
||||
* verbatim to the userspace server which has only ever been given the
|
||||
* permission bits. Strip the type bit until the protocol is known to
|
||||
* cope with it.
|
||||
*/
|
||||
mode &= ~S_IFDIR;
|
||||
|
||||
memset(&inarg, 0, sizeof(inarg));
|
||||
inarg.mode = mode;
|
||||
inarg.umask = current_umask();
|
||||
|
|
|
|||
|
|
@ -4140,11 +4140,6 @@ EXPORT_SYMBOL(end_renaming);
|
|||
* after setgid stripping allows the same ordering for both non-POSIX ACL and
|
||||
* POSIX ACL supporting filesystems.
|
||||
*
|
||||
* Note that it's currently valid for @type to be 0 if a directory is created.
|
||||
* Filesystems raise that flag individually and we need to check whether each
|
||||
* filesystem can deal with receiving S_IFDIR from the vfs before we enforce a
|
||||
* non-zero type.
|
||||
*
|
||||
* Returns: mode to be passed to the filesystem
|
||||
*/
|
||||
static inline umode_t vfs_prepare_mode(struct mnt_idmap *idmap,
|
||||
|
|
@ -5256,7 +5251,7 @@ struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
|
|||
if (!dir->i_op->mkdir)
|
||||
goto err;
|
||||
|
||||
mode = vfs_prepare_mode(idmap, dir, mode, S_IRWXUGO | S_ISVTX, 0);
|
||||
mode = vfs_prepare_mode(idmap, dir, mode, S_IRWXUGO | S_ISVTX, S_IFDIR);
|
||||
error = security_inode_mkdir(dir, dentry, mode);
|
||||
if (error)
|
||||
goto err;
|
||||
|
|
|
|||
|
|
@ -2282,6 +2282,13 @@ struct dentry *cifs_mkdir(struct mnt_idmap *idmap, struct inode *inode,
|
|||
const char *full_path;
|
||||
void *page;
|
||||
|
||||
/*
|
||||
* vfs_mkdir() now passes S_IFDIR in @mode, but @mode is forwarded
|
||||
* verbatim to the server and in the past only contained permission
|
||||
* bits. Strip the type bit until SMB is verified to deal with it.
|
||||
*/
|
||||
mode &= ~S_IFDIR;
|
||||
|
||||
cifs_dbg(FYI, "In cifs_mkdir, mode = %04ho inode = 0x%p\n",
|
||||
mode, inode);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user