VFS: rename lookup_one_len family to lookup_noperm and remove permission check
authorNeilBrown <neil@brown.name>
Wed, 19 Mar 2025 03:01:35 +0000 (14:01 +1100)
committerChristian Brauner <brauner@kernel.org>
Tue, 8 Apr 2025 09:24:36 +0000 (11:24 +0200)
The lookup_one_len family of functions is (now) only used internally by
a filesystem on itself either
- in a context where permission checking is irrelevant such as by a
  virtual filesystem populating itself, or xfs accessing its ORPHANAGE
  or dquota accessing the quota file; or
- in a context where a permission check (MAY_EXEC on the parent) has just
  been performed such as a network filesystem finding in "silly-rename"
  file in the same directory.  This is also the context after the
  _parentat() functions where currently lookup_one_qstr_excl() is used.

So the permission check is pointless.

The name "one_len" is unhelpful in understanding the purpose of these
functions and should be changed.  Most of the callers pass the len as
"strlen()" so using a qstr and QSTR() can simplify the code.

This patch renames these functions (include lookup_positive_unlocked()
which is part of the family despite the name) to have a name based on
"lookup_noperm".  They are changed to receive a 'struct qstr' instead
of separate name and len.  In a few cases the use of QSTR() results in a
new call to strlen().

try_lookup_noperm() takes a pointer to a qstr instead of the whole
qstr.  This is consistent with d_hash_and_lookup() (which is nearly
identical) and useful for lookup_noperm_unlocked().

The new lookup_noperm_common() doesn't take a qstr yet.  That will be
tidied up in a subsequent patch.

Signed-off-by: NeilBrown <neil@brown.name>
Link: https://lore.kernel.org/r/20250319031545.2999807-5-neil@brown.name
Signed-off-by: Christian Brauner <brauner@kernel.org>
25 files changed:
Documentation/filesystems/porting.rst
arch/s390/hypfs/inode.c
drivers/android/binderfs.c
drivers/infiniband/hw/qib/qib_fs.c
fs/afs/dir.c
fs/afs/dir_silly.c
fs/autofs/dev-ioctl.c
fs/binfmt_misc.c
fs/debugfs/inode.c
fs/ecryptfs/inode.c
fs/kernfs/mount.c
fs/namei.c
fs/nfs/unlink.c
fs/overlayfs/export.c
fs/overlayfs/namei.c
fs/quota/dquot.c
fs/smb/client/cached_dir.c
fs/smb/client/cifsfs.c
fs/tracefs/inode.c
fs/xfs/scrub/orphanage.c
include/linux/namei.h
ipc/mqueue.c
kernel/bpf/inode.c
security/apparmor/apparmorfs.c
security/inode.c

index 57dcba6de7434fc5de563fc046a7900685cf45f3..9150de7f64f142b1067abc3eda2f8c4cb1fc76ab 100644 (file)
@@ -1212,3 +1212,23 @@ lookup_one(), lookup_one_unlocked(), lookup_one_positive_unlocked() now
 take a qstr instead of a name and len.  These, not the "one_len"
 versions, should be used whenever accessing a filesystem from outside
 that filesysmtem, through a mount point - which will have a mnt_idmap.
+
+---
+
+** mandatory**
+
+Functions try_lookup_one_len(), lookup_one_len(),
+lookup_one_len_unlocked() and lookup_positive_unlocked() have been
+renamed to try_lookup_noperm(), lookup_noperm(),
+lookup_noperm_unlocked(), lookup_noperm_positive_unlocked().  They now
+take a qstr instead of separate name and length.  QSTR() can be used
+when strlen() is needed for the length.
+
+For try_lookup_noperm() a reference to the qstr is passed in case the
+hash might subsequently be needed.
+
+These function no longer do any permission checking - they previously
+checked that the caller has 'X' permission on the parent.  They must
+ONLY be used internally by a filesystem on itself when it knows that
+permissions are irrelevant or in a context where permission checks have
+already been performed such as after vfs_path_parent_lookup()
index 04ea1c03a5ff25a6e2bc5c9af321bc3b4b80acfc..96409573c75dd5f71543be3baa8a67fb0c9a38a9 100644 (file)
@@ -342,7 +342,7 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name,
        struct inode *inode;
 
        inode_lock(d_inode(parent));
-       dentry = lookup_one_len(name, parent, strlen(name));
+       dentry = lookup_noperm(&QSTR(name), parent);
        if (IS_ERR(dentry)) {
                dentry = ERR_PTR(-ENOMEM);
                goto fail;
index 94c6446604fc95e4e70a083e98b1b44eedf613dd..98da8c4eea59dce8fe7aa8cb01a93297ce65d5f5 100644 (file)
@@ -187,7 +187,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
        inode_lock(d_inode(root));
 
        /* look it up */
-       dentry = lookup_one_len(name, root, name_len);
+       dentry = lookup_noperm(&QSTR(name), root);
        if (IS_ERR(dentry)) {
                inode_unlock(d_inode(root));
                ret = PTR_ERR(dentry);
@@ -487,7 +487,7 @@ static struct dentry *binderfs_create_dentry(struct dentry *parent,
 {
        struct dentry *dentry;
 
-       dentry = lookup_one_len(name, parent, strlen(name));
+       dentry = lookup_noperm(&QSTR(name), parent);
        if (IS_ERR(dentry))
                return dentry;
 
index b9f4a2937c3acc2dc31d42ce22f5369debdba194..2098de762bf5e7c2b1d341ada35bcc82c2657eb8 100644 (file)
@@ -90,7 +90,7 @@ static int create_file(const char *name, umode_t mode,
        int error;
 
        inode_lock(d_inode(parent));
-       *dentry = lookup_one_len(name, parent, strlen(name));
+       *dentry = lookup_noperm(&QSTR(name), parent);
        if (!IS_ERR(*dentry))
                error = qibfs_mknod(d_inode(parent), *dentry,
                                    mode, fops, data);
@@ -433,7 +433,7 @@ static int remove_device_files(struct super_block *sb,
        char unit[10];
 
        snprintf(unit, sizeof(unit), "%u", dd->unit);
-       dir = lookup_one_len_unlocked(unit, sb->s_root, strlen(unit));
+       dir = lookup_noperm_unlocked(&QSTR(unit), sb->s_root);
 
        if (IS_ERR(dir)) {
                pr_err("Lookup of %s failed\n", unit);
index 9e7b1fe82c27fc2eafb887d9a42d738e6b2e4afd..bfb69e0666728b89c93ebe1ece3b438caad3af28 100644 (file)
@@ -943,7 +943,7 @@ static struct dentry *afs_lookup_atsys(struct inode *dir, struct dentry *dentry)
                }
 
                strcpy(p, name);
-               ret = lookup_one_len(buf, dentry->d_parent, len);
+               ret = lookup_noperm(&QSTR(buf), dentry->d_parent);
                if (IS_ERR(ret) || d_is_positive(ret))
                        goto out_s;
                dput(ret);
index a1e581946b93000ade2de2efd6a66eb3667520cc..0b80eb93fa40b81abdaa14f3b01779ccaea6f550 100644 (file)
@@ -113,16 +113,14 @@ int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode,
 
        sdentry = NULL;
        do {
-               int slen;
-
                dput(sdentry);
                sillycounter++;
 
                /* Create a silly name.  Note that the ".__afs" prefix is
                 * understood by the salvager and must not be changed.
                 */
-               slen = scnprintf(silly, sizeof(silly), ".__afs%04X", sillycounter);
-               sdentry = lookup_one_len(silly, dentry->d_parent, slen);
+               scnprintf(silly, sizeof(silly), ".__afs%04X", sillycounter);
+               sdentry = lookup_noperm(&QSTR(silly), dentry->d_parent);
 
                /* N.B. Better to return EBUSY here ... it could be dangerous
                 * to delete the file while it's in use.
index c5a6aae12d2c5d3e3d10ee2e2d8e1acf23f7cbdf..d8dd150cbd7489a9230ac0f8ce6ccbfd9ee9fef1 100644 (file)
@@ -459,7 +459,8 @@ static int autofs_dev_ioctl_timeout(struct file *fp,
                                "the parent autofs mount timeout which could "
                                "prevent shutdown\n");
 
-               dentry = try_lookup_one_len(param->path, base, path_len);
+               dentry = try_lookup_noperm(&QSTR_LEN(param->path, path_len),
+                                          base);
                if (IS_ERR_OR_NULL(dentry))
                        return dentry ? PTR_ERR(dentry) : -ENOENT;
                ino = autofs_dentry_ino(dentry);
index 5a7ebd160724dc708bf516562ce991e7bc8f8916..432fbf4fc33413877228d290999d71b820c1b296 100644 (file)
@@ -842,7 +842,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
        }
 
        inode_lock(d_inode(root));
-       dentry = lookup_one_len(e->name, root, strlen(e->name));
+       dentry = lookup_noperm(&QSTR(e->name), root);
        err = PTR_ERR(dentry);
        if (IS_ERR(dentry))
                goto out;
index 75715d8877eedf7c500a69c648cb577c930106eb..30c4944e18622dcccee5c4dbc845ddcaecae5012 100644 (file)
@@ -346,7 +346,7 @@ struct dentry *debugfs_lookup(const char *name, struct dentry *parent)
        if (!parent)
                parent = debugfs_mount->mnt_root;
 
-       dentry = lookup_positive_unlocked(name, parent, strlen(name));
+       dentry = lookup_noperm_positive_unlocked(&QSTR(name), parent);
        if (IS_ERR(dentry))
                return NULL;
        return dentry;
@@ -388,7 +388,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
        if (unlikely(IS_DEADDIR(d_inode(parent))))
                dentry = ERR_PTR(-ENOENT);
        else
-               dentry = lookup_one_len(name, parent, strlen(name));
+               dentry = lookup_noperm(&QSTR(name), parent);
        if (!IS_ERR(dentry) && d_really_is_positive(dentry)) {
                if (d_is_dir(dentry))
                        pr_err("Directory '%s' with parent '%s' already present!\n",
@@ -872,7 +872,7 @@ int __printf(2, 3) debugfs_change_name(struct dentry *dentry, const char *fmt, .
        }
        if (strcmp(old_name.name.name, new_name) == 0)
                goto out;
-       target = lookup_one_len(new_name, parent, strlen(new_name));
+       target = lookup_noperm(&QSTR(new_name), parent);
        if (IS_ERR(target)) {
                error = PTR_ERR(target);
                goto out;
index 51a5c54eb74026d8b2deec6e0608f3d2b3e9c092..493d7f19495616f97d2e37efd43c19b773a2ed02 100644 (file)
@@ -394,8 +394,8 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        char *encrypted_and_encoded_name = NULL;
        struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
        struct dentry *lower_dir_dentry, *lower_dentry;
-       const char *name = ecryptfs_dentry->d_name.name;
-       size_t len = ecryptfs_dentry->d_name.len;
+       struct qstr qname = QSTR_INIT(ecryptfs_dentry->d_name.name,
+                                     ecryptfs_dentry->d_name.len);
        struct dentry *res;
        int rc = 0;
 
@@ -404,23 +404,25 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
        mount_crypt_stat = &ecryptfs_superblock_to_private(
                                ecryptfs_dentry->d_sb)->mount_crypt_stat;
        if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
+               size_t len = qname.len;
                rc = ecryptfs_encrypt_and_encode_filename(
                        &encrypted_and_encoded_name, &len,
-                       mount_crypt_stat, name, len);
+                       mount_crypt_stat, qname.name, len);
                if (rc) {
                        printk(KERN_ERR "%s: Error attempting to encrypt and encode "
                               "filename; rc = [%d]\n", __func__, rc);
                        return ERR_PTR(rc);
                }
-               name = encrypted_and_encoded_name;
+               qname.name = encrypted_and_encoded_name;
+               qname.len = len;
        }
 
-       lower_dentry = lookup_one_len_unlocked(name, lower_dir_dentry, len);
+       lower_dentry = lookup_noperm_unlocked(&qname, lower_dir_dentry);
        if (IS_ERR(lower_dentry)) {
-               ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
+               ecryptfs_printk(KERN_DEBUG, "%s: lookup_noperm() returned "
                                "[%ld] on lower_dentry = [%s]\n", __func__,
                                PTR_ERR(lower_dentry),
-                               name);
+                               qname.name);
                res = ERR_CAST(lower_dentry);
        } else {
                res = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry);
index 5124e196c2bfd8862be0ee7dfae1eda06a95bbc6..a82fbce25c28701ef729c1e33920408de725ff2b 100644 (file)
@@ -255,7 +255,7 @@ struct dentry *kernfs_node_dentry(struct kernfs_node *kn,
                        dput(dentry);
                        return ERR_PTR(-ENOMEM);
                }
-               dtmp = lookup_positive_unlocked(name, dentry, strlen(name));
+               dtmp = lookup_noperm_positive_unlocked(&QSTR(name), dentry);
                dput(dentry);
                kfree(name);
                if (IS_ERR(dtmp))
index e499fb609271bbb2a0f165bfbde41221dd9661a0..f397ab5704e7ce9290b12fa067290325672383c4 100644 (file)
@@ -2834,9 +2834,9 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
 }
 EXPORT_SYMBOL(vfs_path_lookup);
 
-static int lookup_one_common(struct mnt_idmap *idmap,
-                            const char *name, struct dentry *base, int len,
-                            struct qstr *this)
+static int lookup_noperm_common(const char *name, struct dentry *base,
+                                 int len,
+                                 struct qstr *this)
 {
        this->name = name;
        this->len = len;
@@ -2861,50 +2861,58 @@ static int lookup_one_common(struct mnt_idmap *idmap,
                if (err < 0)
                        return err;
        }
+       return 0;
+}
 
+static int lookup_one_common(struct mnt_idmap *idmap,
+                            const char *name, struct dentry *base, int len,
+                            struct qstr *this) {
+       int err;
+       err = lookup_noperm_common(name, base, len, this);
+       if (err < 0)
+               return err;
        return inode_permission(idmap, base->d_inode, MAY_EXEC);
 }
 
 /**
- * try_lookup_one_len - filesystem helper to lookup single pathname component
- * @name:      pathname component to lookup
+ * try_lookup_noperm - filesystem helper to lookup single pathname component
+ * @name:      qstr storing pathname component to lookup
  * @base:      base directory to lookup from
- * @len:       maximum length @len should be interpreted to
  *
  * 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.
  *
  * Note that this routine is purely a helper for filesystem usage and should
- * not be called by generic code.
+ * not be called by generic code.  It does no permission checking.
  *
  * No locks need be held - only a counted reference to @base is needed.
  *
  */
-struct dentry *try_lookup_one_len(const char *name, struct dentry *base, int len)
+struct dentry *try_lookup_noperm(struct qstr *name, struct dentry *base)
 {
        struct qstr this;
        int err;
 
-       err = lookup_one_common(&nop_mnt_idmap, name, base, len, &this);
+       err = lookup_noperm_common(name->name, base, name->len, &this);
        if (err)
                return ERR_PTR(err);
 
-       return lookup_dcache(&this, base, 0);
+       name->hash = this.hash;
+       return lookup_dcache(name, base, 0);
 }
-EXPORT_SYMBOL(try_lookup_one_len);
+EXPORT_SYMBOL(try_lookup_noperm);
 
 /**
- * lookup_one_len - filesystem helper to lookup single pathname component
- * @name:      pathname component to lookup
+ * lookup_noperm - filesystem helper to lookup single pathname component
+ * @name:      qstr storing pathname component to lookup
  * @base:      base directory to lookup from
- * @len:       maximum length @len should be interpreted to
  *
  * Note that this routine is purely a helper for filesystem usage and should
- * not be called by generic code.
+ * not be called by generic code.  It does no permission checking.
  *
  * The caller must hold base->i_mutex.
  */
-struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
+struct dentry *lookup_noperm(struct qstr *name, struct dentry *base)
 {
        struct dentry *dentry;
        struct qstr this;
@@ -2912,14 +2920,14 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
 
        WARN_ON_ONCE(!inode_is_locked(base->d_inode));
 
-       err = lookup_one_common(&nop_mnt_idmap, name, base, len, &this);
+       err = lookup_noperm_common(name->name, base, name->len, &this);
        if (err)
                return ERR_PTR(err);
 
        dentry = lookup_dcache(&this, base, 0);
        return dentry ? dentry : __lookup_slow(&this, base, 0);
 }
-EXPORT_SYMBOL(lookup_one_len);
+EXPORT_SYMBOL(lookup_noperm);
 
 /**
  * lookup_one - lookup single pathname component
@@ -2957,7 +2965,7 @@ EXPORT_SYMBOL(lookup_one);
  *
  * This can be used for in-kernel filesystem clients such as file servers.
  *
- * Unlike lookup_one_len, it should be called without the parent
+ * Unlike lookup_one, it should be called without the parent
  * i_rwsem held, and will take the i_rwsem itself if necessary.
  */
 struct dentry *lookup_one_unlocked(struct mnt_idmap *idmap,
@@ -3010,39 +3018,48 @@ struct dentry *lookup_one_positive_unlocked(struct mnt_idmap *idmap,
 EXPORT_SYMBOL(lookup_one_positive_unlocked);
 
 /**
- * lookup_one_len_unlocked - filesystem helper to lookup single pathname component
+ * lookup_noperm_unlocked - filesystem helper to lookup single pathname component
  * @name:      pathname component to lookup
  * @base:      base directory to lookup from
- * @len:       maximum length @len should be interpreted to
  *
  * Note that this routine is purely a helper for filesystem usage and should
- * not be called by generic code.
+ * not be called by generic code. It does no permission checking.
  *
- * Unlike lookup_one_len, it should be called without the parent
- * i_mutex held, and will take the i_mutex itself if necessary.
+ * Unlike lookup_noperm, it should be called without the parent
+ * i_rwsem held, and will take the i_rwsem itself if necessary.
  */
-struct dentry *lookup_one_len_unlocked(const char *name,
-                                      struct dentry *base, int len)
+struct dentry *lookup_noperm_unlocked(struct qstr *name, struct dentry *base)
 {
-       return lookup_one_unlocked(&nop_mnt_idmap, &QSTR_LEN(name, len), base);
+       struct dentry *ret;
+
+       ret = try_lookup_noperm(name, base);
+       if (!ret)
+               ret = lookup_slow(name, base, 0);
+       return ret;
 }
-EXPORT_SYMBOL(lookup_one_len_unlocked);
+EXPORT_SYMBOL(lookup_noperm_unlocked);
 
 /*
- * Like lookup_one_len_unlocked(), except that it yields ERR_PTR(-ENOENT)
+ * Like lookup_noperm_unlocked(), except that it yields ERR_PTR(-ENOENT)
  * on negatives.  Returns known positive or ERR_PTR(); that's what
  * most of the users want.  Note that pinned negative with unlocked parent
- * _can_ become positive at any time, so callers of lookup_one_len_unlocked()
+ * _can_ become positive at any time, so callers of lookup_noperm_unlocked()
  * need to be very careful; pinned positives have ->d_inode stable, so
  * this one avoids such problems.
  */
-struct dentry *lookup_positive_unlocked(const char *name,
-                                      struct dentry *base, int len)
+struct dentry *lookup_noperm_positive_unlocked(struct qstr *name,
+                                              struct dentry *base)
 {
-       return lookup_one_positive_unlocked(&nop_mnt_idmap,
-                                           &QSTR_LEN(name, len), base);
+       struct dentry *ret;
+
+       ret = lookup_noperm_unlocked(name, base);
+       if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) {
+               dput(ret);
+               ret = ERR_PTR(-ENOENT);
+       }
+       return ret;
 }
-EXPORT_SYMBOL(lookup_positive_unlocked);
+EXPORT_SYMBOL(lookup_noperm_positive_unlocked);
 
 #ifdef CONFIG_UNIX98_PTYS
 int path_pts(struct path *path)
index bf77399696a767571d484ceb1c84937ed7256555..b55467911648d00ea73177fdcea390ba45c59aee 100644 (file)
@@ -464,18 +464,17 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
 
        sdentry = NULL;
        do {
-               int slen;
                dput(sdentry);
                sillycounter++;
-               slen = scnprintf(silly, sizeof(silly),
-                               SILLYNAME_PREFIX "%0*llx%0*x",
-                               SILLYNAME_FILEID_LEN, fileid,
-                               SILLYNAME_COUNTER_LEN, sillycounter);
+               scnprintf(silly, sizeof(silly),
+                         SILLYNAME_PREFIX "%0*llx%0*x",
+                         SILLYNAME_FILEID_LEN, fileid,
+                         SILLYNAME_COUNTER_LEN, sillycounter);
 
                dfprintk(VFS, "NFS: trying to rename %pd to %s\n",
                                dentry, silly);
 
-               sdentry = lookup_one_len(silly, dentry->d_parent, slen);
+               sdentry = lookup_noperm(&QSTR(silly), dentry->d_parent);
                /*
                 * N.B. Better to return EBUSY here ... it could be
                 * dangerous to delete the file while it's in use.
index 444aeeccb6daf992ecf4f130da36250d70d3da30..83f80fdb156749e65a4ea0ab708cbff338dacdad 100644 (file)
@@ -385,11 +385,9 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected,
         */
        take_dentry_name_snapshot(&name, real);
        /*
-        * No idmap handling here: it's an internal lookup.  Could skip
-        * permission checking altogether, but for now just use non-idmap
-        * transformed ids.
+        * No idmap handling here: it's an internal lookup.
         */
-       this = lookup_one_len(name.name.name, connected, name.name.len);
+       this = lookup_noperm(&name.name, connected);
        release_dentry_name_snapshot(&name);
        err = PTR_ERR(this);
        if (IS_ERR(this)) {
index ac6e893e846a0ed977e570ddae931e0b66d8820a..bf722daf19a952ed75edd5e9f9cac9286ae5e50d 100644 (file)
@@ -757,7 +757,7 @@ struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh)
        if (err)
                return ERR_PTR(err);
 
-       index = lookup_positive_unlocked(name.name, ofs->workdir, name.len);
+       index = lookup_noperm_positive_unlocked(&name, ofs->workdir);
        kfree(name.name);
        if (IS_ERR(index)) {
                if (PTR_ERR(index) == -ENOENT)
index 825c5c2e09621caa8151d6f32a527516a3dd204e..df4a9b34876965553fb959691e1d58e05592f9d8 100644 (file)
@@ -2560,7 +2560,7 @@ int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
        struct dentry *dentry;
        int error;
 
-       dentry = lookup_positive_unlocked(qf_name, sb->s_root, strlen(qf_name));
+       dentry = lookup_noperm_positive_unlocked(&QSTR(qf_name), sb->s_root);
        if (IS_ERR(dentry))
                return PTR_ERR(dentry);
 
index fe738623cf1ba91ee44e23de346c60460cbc647d..e6fc92667d412d4d5b63d829251e2a1b2d28458e 100644 (file)
@@ -109,7 +109,8 @@ path_to_dentry(struct cifs_sb_info *cifs_sb, const char *path)
                while (*s && *s != sep)
                        s++;
 
-               child = lookup_positive_unlocked(p, dentry, s - p);
+               child = lookup_noperm_positive_unlocked(&QSTR_LEN(p, s - p),
+                                                       dentry);
                dput(dentry);
                dentry = child;
        } while (!IS_ERR(dentry));
@@ -207,7 +208,7 @@ replay_again:
        spin_unlock(&cfids->cfid_list_lock);
 
        /*
-        * Skip any prefix paths in @path as lookup_positive_unlocked() ends up
+        * Skip any prefix paths in @path as lookup_noperm_positive_unlocked() ends up
         * calling ->lookup() which already adds those through
         * build_path_from_dentry().  Also, do it earlier as we might reconnect
         * below when trying to send compounded request and then potentially
index a08c42363ffc84ecae2446121573f1777841e3c7..fb04e263611cadaea210f5c1d90c05bea37fb496 100644 (file)
@@ -929,7 +929,8 @@ cifs_get_root(struct smb3_fs_context *ctx, struct super_block *sb)
                while (*s && *s != sep)
                        s++;
 
-               child = lookup_positive_unlocked(p, dentry, s - p);
+               child = lookup_noperm_positive_unlocked(&QSTR_LEN(p, s - p),
+                                                       dentry);
                dput(dentry);
                dentry = child;
        } while (!IS_ERR(dentry));
index cb1af30b49f5803eb9a2ef04884b052232766e1f..a3fd3cc591bd8884de4c05e6cd569331dc69df5b 100644 (file)
@@ -555,7 +555,7 @@ struct dentry *tracefs_start_creating(const char *name, struct dentry *parent)
        if (unlikely(IS_DEADDIR(d_inode(parent))))
                dentry = ERR_PTR(-ENOENT);
        else
-               dentry = lookup_one_len(name, parent, strlen(name));
+               dentry = lookup_noperm(&QSTR(name), parent);
        if (!IS_ERR(dentry) && d_inode(dentry)) {
                dput(dentry);
                dentry = ERR_PTR(-EEXIST);
index 3537f3cca6d5eaf2f76bbe094c71183f423945dd..475bb899b2c6a7cfb428bf1ef5d74e228d6a3277 100644 (file)
@@ -153,8 +153,7 @@ xrep_orphanage_create(
 
        /* Try to find the orphanage directory. */
        inode_lock_nested(root_inode, I_MUTEX_PARENT);
-       orphanage_dentry = lookup_one_len(ORPHANAGE, root_dentry,
-                       strlen(ORPHANAGE));
+       orphanage_dentry = lookup_noperm(&QSTR(ORPHANAGE), root_dentry);
        if (IS_ERR(orphanage_dentry)) {
                error = PTR_ERR(orphanage_dentry);
                goto out_unlock_root;
index ba02304a2a8a0227bfb2560898ba8d22bc9063a5..cb6ce97782e0346105b92501d8c1dbea05187f0a 100644 (file)
@@ -69,10 +69,10 @@ int vfs_path_parent_lookup(struct filename *filename, unsigned int flags,
 int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *,
                    unsigned int, struct path *);
 
-extern struct dentry *try_lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
-extern struct dentry *lookup_one_len_unlocked(const char *, struct dentry *, int);
-extern struct dentry *lookup_positive_unlocked(const char *, struct dentry *, int);
+extern struct dentry *try_lookup_noperm(struct qstr *, struct dentry *);
+extern struct dentry *lookup_noperm(struct qstr *, struct dentry *);
+extern struct dentry *lookup_noperm_unlocked(struct qstr *, struct dentry *);
+extern struct dentry *lookup_noperm_positive_unlocked(struct qstr *, struct dentry *);
 struct dentry *lookup_one(struct mnt_idmap *, struct qstr *, struct dentry *);
 struct dentry *lookup_one_unlocked(struct mnt_idmap *idmap,
                                   struct qstr *name, struct dentry *base);
index 35b4f8659904cd0eaf0d9c6d25dca1efd7fe903c..82ed2d3c98463ebfedb2a476b251b51abacf97a3 100644 (file)
@@ -913,7 +913,7 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
 
        ro = mnt_want_write(mnt);       /* we'll drop it in any case */
        inode_lock(d_inode(root));
-       path.dentry = lookup_one_len(name->name, root, strlen(name->name));
+       path.dentry = lookup_noperm(&QSTR(name->name), root);
        if (IS_ERR(path.dentry)) {
                error = PTR_ERR(path.dentry);
                goto out_putfd;
@@ -969,8 +969,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
        if (err)
                goto out_name;
        inode_lock_nested(d_inode(mnt->mnt_root), I_MUTEX_PARENT);
-       dentry = lookup_one_len(name->name, mnt->mnt_root,
-                               strlen(name->name));
+       dentry = lookup_noperm(&QSTR(name->name), mnt->mnt_root);
        if (IS_ERR(dentry)) {
                err = PTR_ERR(dentry);
                goto out_unlock;
index dc3aa91a6ba03105bf97a43637650eda5b1a35ce..5c2e96b19392ae919732674fc7726de07d88ee2e 100644 (file)
@@ -421,7 +421,7 @@ static int bpf_iter_link_pin_kernel(struct dentry *parent,
        int ret;
 
        inode_lock(parent->d_inode);
-       dentry = lookup_one_len(name, parent, strlen(name));
+       dentry = lookup_noperm(&QSTR(name), parent);
        if (IS_ERR(dentry)) {
                inode_unlock(parent->d_inode);
                return PTR_ERR(dentry);
index 6039afae4bfc9bd6b135cc8be561bd9b4a842ad8..0aef34b9609bcc46d38dcb85d69412e28d2f6c16 100644 (file)
@@ -283,7 +283,7 @@ static struct dentry *aafs_create(const char *name, umode_t mode,
        dir = d_inode(parent);
 
        inode_lock(dir);
-       dentry = lookup_one_len(name, parent, strlen(name));
+       dentry = lookup_noperm(&QSTR(name), parent);
        if (IS_ERR(dentry)) {
                error = PTR_ERR(dentry);
                goto fail_lock;
@@ -2551,7 +2551,7 @@ static int aa_mk_null_file(struct dentry *parent)
                return error;
 
        inode_lock(d_inode(parent));
-       dentry = lookup_one_len(NULL_FILE_NAME, parent, strlen(NULL_FILE_NAME));
+       dentry = lookup_noperm(&QSTR(NULL_FILE_NAME), parent);
        if (IS_ERR(dentry)) {
                error = PTR_ERR(dentry);
                goto out;
index da3ab44c8e571f5e1e10fc892ce6883ee924e93f..3913501621fa9de538d488e5c4a4b6416be53422 100644 (file)
@@ -128,7 +128,7 @@ static struct dentry *securityfs_create_dentry(const char *name, umode_t mode,
        dir = d_inode(parent);
 
        inode_lock(dir);
-       dentry = lookup_one_len(name, parent, strlen(name));
+       dentry = lookup_noperm(&QSTR(name), parent);
        if (IS_ERR(dentry))
                goto out;