Skip to content

Commit b051320

Browse files
committed
Merge tag 'vfs-6.11.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull misc vfs updates from Christian Brauner: "Features: - Support passing NULL along AT_EMPTY_PATH for statx(). NULL paths with any flag value other than AT_EMPTY_PATH go the usual route and end up with -EFAULT to retain compatibility (Rust is abusing calls of the sort to detect availability of statx) This avoids path lookup code, lockref management, memory allocation and in case of NULL path userspace memory access (which can be quite expensive with SMAP on x86_64) - Don't block i_writecount during exec. Remove the deny_write_access() mechanism for executables - Relax open_by_handle_at() permissions in specific cases where we can prove that the caller had sufficient privileges to open a file - Switch timespec64 fields in struct inode to discrete integers freeing up 4 bytes Fixes: - Fix false positive circular locking warning in hfsplus - Initialize hfs_inode_info after hfs_alloc_inode() in hfs - Avoid accidental overflows in vfs_fallocate() - Don't interrupt fallocate with EINTR in tmpfs to avoid constantly restarting shmem_fallocate() - Add missing quote in comment in fs/readdir Cleanups: - Don't assign and test in an if statement in mqueue. Move the assignment out of the if statement - Reflow the logic in may_create_in_sticky() - Remove the usage of the deprecated ida_simple_xx() API from procfs - Reject FSCONFIG_CMD_CREATE_EXCL requets that depend on the new mount api early - Rename variables in copy_tree() to make it easier to understand - Replace WARN(down_read_trylock, ...) abuse with proper asserts in various places in the VFS - Get rid of user_path_at_empty() and drop the empty argument from getname_flags() - Check for error while copying and no path in one branch in getname_flags() - Avoid redundant smp_mb() for THP handling in do_dentry_open() - Rename parent_ino to d_parent_ino and make it use RCU - Remove unused header include in fs/readdir - Export in_group_capable() helper and switch f2fs and fuse over to it instead of open-coding the logic in both places" * tag 'vfs-6.11.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (27 commits) ipc: mqueue: remove assignment from IS_ERR argument vfs: rename parent_ino to d_parent_ino and make it use RCU vfs: support statx(..., NULL, AT_EMPTY_PATH, ...) stat: use vfs_empty_path() helper fs: new helper vfs_empty_path() fs: reflow may_create_in_sticky() vfs: remove redundant smp_mb for thp handling in do_dentry_open fuse: Use in_group_or_capable() helper f2fs: Use in_group_or_capable() helper fs: Export in_group_or_capable() vfs: reorder checks in may_create_in_sticky hfs: fix to initialize fields of hfs_inode_info after hfs_alloc_inode() proc: Remove usage of the deprecated ida_simple_xx() API hfsplus: fix to avoid false alarm of circular locking Improve readability of copy_tree vfs: shave a branch in getname_flags vfs: retire user_path_at_empty and drop empty arg from getname_flags vfs: stop using user_path_at_empty in do_readlinkat tmpfs: don't interrupt fallocate with EINTR fs: don't block i_writecount during exec ...
2 parents 2ffd45d + b80cc4d commit b051320

38 files changed

+539
-329
lines changed

fs/attr.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
1717
#include <linux/filelock.h>
1818
#include <linux/security.h>
1919

20-
#include "internal.h"
21-
2220
/**
2321
* setattr_should_drop_sgid - determine whether the setgid bit needs to be
2422
* removed

fs/binfmt_elf.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
12161216
}
12171217
reloc_func_desc = interp_load_addr;
12181218

1219-
allow_write_access(interpreter);
12201219
fput(interpreter);
12211220

12221221
kfree(interp_elf_ex);
@@ -1308,7 +1307,6 @@ static int load_elf_binary(struct linux_binprm *bprm)
13081307
kfree(interp_elf_ex);
13091308
kfree(interp_elf_phdata);
13101309
out_free_file:
1311-
allow_write_access(interpreter);
13121310
if (interpreter)
13131311
fput(interpreter);
13141312
out_free_ph:

fs/binfmt_elf_fdpic.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
394394
goto error;
395395
}
396396

397-
allow_write_access(interpreter);
398397
fput(interpreter);
399398
interpreter = NULL;
400399
}
@@ -466,10 +465,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm)
466465
retval = 0;
467466

468467
error:
469-
if (interpreter) {
470-
allow_write_access(interpreter);
468+
if (interpreter)
471469
fput(interpreter);
472-
}
473470
kfree(interpreter_name);
474471
kfree(exec_params.phdrs);
475472
kfree(exec_params.loadmap);

fs/binfmt_misc.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,13 +247,10 @@ static int load_misc_binary(struct linux_binprm *bprm)
247247
if (retval < 0)
248248
goto ret;
249249

250-
if (fmt->flags & MISC_FMT_OPEN_FILE) {
250+
if (fmt->flags & MISC_FMT_OPEN_FILE)
251251
interp_file = file_clone_open(fmt->interp_file);
252-
if (!IS_ERR(interp_file))
253-
deny_write_access(interp_file);
254-
} else {
252+
else
255253
interp_file = open_exec(fmt->interpreter);
256-
}
257254
retval = PTR_ERR(interp_file);
258255
if (IS_ERR(interp_file))
259256
goto ret;

fs/dcache.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1555,7 +1555,7 @@ void shrink_dcache_for_umount(struct super_block *sb)
15551555
{
15561556
struct dentry *dentry;
15571557

1558-
WARN(down_read_trylock(&sb->s_umount), "s_umount should've been locked");
1558+
rwsem_assert_held_write(&sb->s_umount);
15591559

15601560
dentry = sb->s_root;
15611561
sb->s_root = NULL;
@@ -3106,6 +3106,34 @@ void d_tmpfile(struct file *file, struct inode *inode)
31063106
}
31073107
EXPORT_SYMBOL(d_tmpfile);
31083108

3109+
/*
3110+
* Obtain inode number of the parent dentry.
3111+
*/
3112+
ino_t d_parent_ino(struct dentry *dentry)
3113+
{
3114+
struct dentry *parent;
3115+
struct inode *iparent;
3116+
unsigned seq;
3117+
ino_t ret;
3118+
3119+
scoped_guard(rcu) {
3120+
seq = raw_seqcount_begin(&dentry->d_seq);
3121+
parent = READ_ONCE(dentry->d_parent);
3122+
iparent = d_inode_rcu(parent);
3123+
if (likely(iparent)) {
3124+
ret = iparent->i_ino;
3125+
if (!read_seqcount_retry(&dentry->d_seq, seq))
3126+
return ret;
3127+
}
3128+
}
3129+
3130+
spin_lock(&dentry->d_lock);
3131+
ret = dentry->d_parent->d_inode->i_ino;
3132+
spin_unlock(&dentry->d_lock);
3133+
return ret;
3134+
}
3135+
EXPORT_SYMBOL(d_parent_ino);
3136+
31093137
static __initdata unsigned long dhash_entries;
31103138
static int __init set_dhash_entries(char *str)
31113139
{

fs/exec.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -952,10 +952,6 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
952952
path_noexec(&file->f_path)))
953953
goto exit;
954954

955-
err = deny_write_access(file);
956-
if (err)
957-
goto exit;
958-
959955
out:
960956
return file;
961957

@@ -971,8 +967,7 @@ static struct file *do_open_execat(int fd, struct filename *name, int flags)
971967
*
972968
* Returns ERR_PTR on failure or allocated struct file on success.
973969
*
974-
* As this is a wrapper for the internal do_open_execat(), callers
975-
* must call allow_write_access() before fput() on release. Also see
970+
* As this is a wrapper for the internal do_open_execat(). Also see
976971
* do_close_execat().
977972
*/
978973
struct file *open_exec(const char *name)
@@ -1524,10 +1519,8 @@ static int prepare_bprm_creds(struct linux_binprm *bprm)
15241519
/* Matches do_open_execat() */
15251520
static void do_close_execat(struct file *file)
15261521
{
1527-
if (!file)
1528-
return;
1529-
allow_write_access(file);
1530-
fput(file);
1522+
if (file)
1523+
fput(file);
15311524
}
15321525

15331526
static void free_bprm(struct linux_binprm *bprm)
@@ -1846,7 +1839,6 @@ static int exec_binprm(struct linux_binprm *bprm)
18461839
bprm->file = bprm->interpreter;
18471840
bprm->interpreter = NULL;
18481841

1849-
allow_write_access(exec);
18501842
if (unlikely(bprm->have_execfd)) {
18511843
if (bprm->executable) {
18521844
fput(exec);

fs/exportfs/expfs.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ EXPORT_SYMBOL_GPL(exportfs_encode_fh);
427427

428428
struct dentry *
429429
exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len,
430-
int fileid_type,
430+
int fileid_type, unsigned int flags,
431431
int (*acceptable)(void *, struct dentry *),
432432
void *context)
433433
{
@@ -445,6 +445,11 @@ exportfs_decode_fh_raw(struct vfsmount *mnt, struct fid *fid, int fh_len,
445445
if (IS_ERR_OR_NULL(result))
446446
return result;
447447

448+
if ((flags & EXPORT_FH_DIR_ONLY) && !d_is_dir(result)) {
449+
err = -ENOTDIR;
450+
goto err_result;
451+
}
452+
448453
/*
449454
* If no acceptance criteria was specified by caller, a disconnected
450455
* dentry is also accepatable. Callers may use this mode to query if
@@ -581,7 +586,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
581586
{
582587
struct dentry *ret;
583588

584-
ret = exportfs_decode_fh_raw(mnt, fid, fh_len, fileid_type,
589+
ret = exportfs_decode_fh_raw(mnt, fid, fh_len, fileid_type, 0,
585590
acceptable, context);
586591
if (IS_ERR_OR_NULL(ret)) {
587592
if (ret == ERR_PTR(-ENOMEM))

fs/f2fs/acl.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,7 @@ static int f2fs_acl_update_mode(struct mnt_idmap *idmap,
219219
return error;
220220
if (error == 0)
221221
*acl = NULL;
222-
if (!vfsgid_in_group_p(i_gid_into_vfsgid(idmap, inode)) &&
223-
!capable_wrt_inode_uidgid(idmap, inode, CAP_FSETID))
222+
if (!in_group_or_capable(idmap, inode, i_gid_into_vfsgid(idmap, inode)))
224223
mode &= ~S_ISGID;
225224
*mode_p = mode;
226225
return 0;

fs/f2fs/file.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ static int get_parent_ino(struct inode *inode, nid_t *pino)
185185
if (!dentry)
186186
return 0;
187187

188-
*pino = parent_ino(dentry);
188+
*pino = d_parent_ino(dentry);
189189
dput(dentry);
190190
return 1;
191191
}
@@ -923,10 +923,8 @@ static void __setattr_copy(struct mnt_idmap *idmap,
923923
inode_set_ctime_to_ts(inode, attr->ia_ctime);
924924
if (ia_valid & ATTR_MODE) {
925925
umode_t mode = attr->ia_mode;
926-
vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
927926

928-
if (!vfsgid_in_group_p(vfsgid) &&
929-
!capable_wrt_inode_uidgid(idmap, inode, CAP_FSETID))
927+
if (!in_group_or_capable(idmap, inode, i_gid_into_vfsgid(idmap, inode)))
930928
mode &= ~S_ISGID;
931929
set_acl_inode(inode, mode);
932930
}

0 commit comments

Comments
 (0)