vfs-6.16-rc3.fixes

-----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCaE/PTwAKCRCRxhvAZXjc
 oo7dAQDCEgd22Of2ibYK0wza1RE17Qjm1Qljt0tHUxki/3Gr/QD9EAJyIhEjplMj
 ntEQrlByWVw8aOVWwtSjFVq55mMLrgI=
 =SNXv
 -----END PGP SIGNATURE-----

Merge tag 'vfs-6.16-rc3.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs fixes from Christian Brauner:

 - Fix a regression in overlayfs caused by reworking the lookup_one*()
   set of helpers

 - Make sure that the name of the dentry is printed in overlayfs'
   mkdir() helper

 - Add missing iocb values to TRACE_IOCB_STRINGS define

 - Unlock the superblock during iterate_supers_type(). This was an
   accidental internal api change

 - Drop a misleading assert in file_seek_cur_needs_f_lock() helper

 - Never refuse to return PIDFD_GET_INGO when parent pid is zero

   That can trivially happen in container scenarios where the parent
   process might be located in an ancestor pid namespace

 - Don't revalidate in try_lookup_noperm() as that causes regression for
   filesystems such as cifs

 - Fix simple_xattr_list() and reset the err variable after
   security_inode_listsecurity() got called so as not to confuse
   userspace about the length of the xattr

* tag 'vfs-6.16-rc3.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  fs: drop assert in file_seek_cur_needs_f_lock
  fs: unlock the superblock during iterate_supers_type
  ovl: fix debug print in case of mkdir error
  VFS: change try_lookup_noperm() to skip revalidation
  fs: add missing values to TRACE_IOCB_STRINGS
  fs/xattr.c: fix simple_xattr_list()
  ovl: fix regression caused by lookup helpers API changes
  pidfs: never refuse ppid == 0 in PIDFD_GET_INFO
This commit is contained in:
Linus Torvalds 2025-06-16 08:18:43 -07:00
commit fe78e02600
8 changed files with 40 additions and 14 deletions

View file

@ -1198,8 +1198,12 @@ bool file_seek_cur_needs_f_lock(struct file *file)
if (!(file->f_mode & FMODE_ATOMIC_POS) && !file->f_op->iterate_shared)
return false;
VFS_WARN_ON_ONCE((file_count(file) > 1) &&
!mutex_is_locked(&file->f_pos_lock));
/*
* Note that we are not guaranteed to be called after fdget_pos() on
* this file obj, in which case the caller is expected to provide the
* appropriate locking.
*/
return true;
}

View file

@ -2917,7 +2917,8 @@ static int lookup_one_common(struct mnt_idmap *idmap,
* @base: base directory to lookup from
*
* Look up a dentry by name in the dcache, returning NULL if it does not
* currently exist. The function does not try to create a dentry.
* currently exist. The function does not try to create a dentry and if one
* is found it doesn't try to revalidate it.
*
* Note that this routine is purely a helper for filesystem usage and should
* not be called by generic code. It does no permission checking.
@ -2933,7 +2934,7 @@ struct dentry *try_lookup_noperm(struct qstr *name, struct dentry *base)
if (err)
return ERR_PTR(err);
return lookup_dcache(name, base, 0);
return d_lookup(base, name);
}
EXPORT_SYMBOL(try_lookup_noperm);
@ -3057,14 +3058,22 @@ EXPORT_SYMBOL(lookup_one_positive_unlocked);
* Note that this routine is purely a helper for filesystem usage and should
* not be called by generic code. It does no permission checking.
*
* Unlike lookup_noperm, it should be called without the parent
* Unlike lookup_noperm(), it should be called without the parent
* i_rwsem held, and will take the i_rwsem itself if necessary.
*
* Unlike try_lookup_noperm() it *does* revalidate the dentry if it already
* existed.
*/
struct dentry *lookup_noperm_unlocked(struct qstr *name, struct dentry *base)
{
struct dentry *ret;
int err;
ret = try_lookup_noperm(name, base);
err = lookup_noperm_common(name, base);
if (err)
return ERR_PTR(err);
ret = lookup_dcache(name, base, 0);
if (!ret)
ret = lookup_slow(name, base, 0);
return ret;

View file

@ -1393,7 +1393,7 @@ out:
bool ovl_lower_positive(struct dentry *dentry)
{
struct ovl_entry *poe = OVL_E(dentry->d_parent);
struct qstr *name = &dentry->d_name;
const struct qstr *name = &dentry->d_name;
const struct cred *old_cred;
unsigned int i;
bool positive = false;
@ -1416,9 +1416,15 @@ bool ovl_lower_positive(struct dentry *dentry)
struct dentry *this;
struct ovl_path *parentpath = &ovl_lowerstack(poe)[i];
/*
* We need to make a non-const copy of dentry->d_name,
* because lookup_one_positive_unlocked() will hash name
* with parentpath base, which is on another (lower fs).
*/
this = lookup_one_positive_unlocked(
mnt_idmap(parentpath->layer->mnt),
name, parentpath->dentry);
&QSTR_LEN(name->name, name->len),
parentpath->dentry);
if (IS_ERR(this)) {
switch (PTR_ERR(this)) {
case -ENOENT:

View file

@ -246,9 +246,11 @@ static inline struct dentry *ovl_do_mkdir(struct ovl_fs *ofs,
struct dentry *dentry,
umode_t mode)
{
dentry = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode);
pr_debug("mkdir(%pd2, 0%o) = %i\n", dentry, mode, PTR_ERR_OR_ZERO(dentry));
return dentry;
struct dentry *ret;
ret = vfs_mkdir(ovl_upper_mnt_idmap(ofs), dir, dentry, mode);
pr_debug("mkdir(%pd2, 0%o) = %i\n", dentry, mode, PTR_ERR_OR_ZERO(ret));
return ret;
}
static inline int ovl_do_mknod(struct ovl_fs *ofs,

View file

@ -366,7 +366,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
kinfo.pid = task_pid_vnr(task);
kinfo.mask |= PIDFD_INFO_PID;
if (kinfo.pid == 0 || kinfo.tgid == 0 || (kinfo.ppid == 0 && kinfo.pid != 1))
if (kinfo.pid == 0 || kinfo.tgid == 0)
return -ESRCH;
copy_out:

View file

@ -964,8 +964,10 @@ void iterate_supers_type(struct file_system_type *type,
spin_unlock(&sb_lock);
locked = super_lock_shared(sb);
if (locked)
if (locked) {
f(sb, arg);
super_unlock_shared(sb);
}
spin_lock(&sb_lock);
if (p)

View file

@ -1479,6 +1479,7 @@ ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
buffer += err;
}
remaining_size -= err;
err = 0;
read_lock(&xattrs->lock);
for (rbp = rb_first(&xattrs->rb_root); rbp; rbp = rb_next(rbp)) {

View file

@ -399,7 +399,9 @@ struct readahead_control;
{ IOCB_WAITQ, "WAITQ" }, \
{ IOCB_NOIO, "NOIO" }, \
{ IOCB_ALLOC_CACHE, "ALLOC_CACHE" }, \
{ IOCB_DIO_CALLER_COMP, "CALLER_COMP" }
{ IOCB_DIO_CALLER_COMP, "CALLER_COMP" }, \
{ IOCB_AIO_RW, "AIO_RW" }, \
{ IOCB_HAS_METADATA, "AIO_HAS_METADATA" }
struct kiocb {
struct file *ki_filp;