Skip to content

Commit fa6fe07

Browse files
neilbrownbrauner
authored andcommitted
VFS: rename lookup_one_len family to lookup_noperm and remove permission check
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 2011067 commit fa6fe07

File tree

25 files changed

+122
-87
lines changed

25 files changed

+122
-87
lines changed

Documentation/filesystems/porting.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,3 +1212,23 @@ lookup_one(), lookup_one_unlocked(), lookup_one_positive_unlocked() now
12121212
take a qstr instead of a name and len. These, not the "one_len"
12131213
versions, should be used whenever accessing a filesystem from outside
12141214
that filesysmtem, through a mount point - which will have a mnt_idmap.
1215+
1216+
---
1217+
1218+
** mandatory**
1219+
1220+
Functions try_lookup_one_len(), lookup_one_len(),
1221+
lookup_one_len_unlocked() and lookup_positive_unlocked() have been
1222+
renamed to try_lookup_noperm(), lookup_noperm(),
1223+
lookup_noperm_unlocked(), lookup_noperm_positive_unlocked(). They now
1224+
take a qstr instead of separate name and length. QSTR() can be used
1225+
when strlen() is needed for the length.
1226+
1227+
For try_lookup_noperm() a reference to the qstr is passed in case the
1228+
hash might subsequently be needed.
1229+
1230+
These function no longer do any permission checking - they previously
1231+
checked that the caller has 'X' permission on the parent. They must
1232+
ONLY be used internally by a filesystem on itself when it knows that
1233+
permissions are irrelevant or in a context where permission checks have
1234+
already been performed such as after vfs_path_parent_lookup()

arch/s390/hypfs/inode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ static struct dentry *hypfs_create_file(struct dentry *parent, const char *name,
342342
struct inode *inode;
343343

344344
inode_lock(d_inode(parent));
345-
dentry = lookup_one_len(name, parent, strlen(name));
345+
dentry = lookup_noperm(&QSTR(name), parent);
346346
if (IS_ERR(dentry)) {
347347
dentry = ERR_PTR(-ENOMEM);
348348
goto fail;

drivers/android/binderfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode,
187187
inode_lock(d_inode(root));
188188

189189
/* look it up */
190-
dentry = lookup_one_len(name, root, name_len);
190+
dentry = lookup_noperm(&QSTR(name), root);
191191
if (IS_ERR(dentry)) {
192192
inode_unlock(d_inode(root));
193193
ret = PTR_ERR(dentry);
@@ -487,7 +487,7 @@ static struct dentry *binderfs_create_dentry(struct dentry *parent,
487487
{
488488
struct dentry *dentry;
489489

490-
dentry = lookup_one_len(name, parent, strlen(name));
490+
dentry = lookup_noperm(&QSTR(name), parent);
491491
if (IS_ERR(dentry))
492492
return dentry;
493493

drivers/infiniband/hw/qib/qib_fs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static int create_file(const char *name, umode_t mode,
9090
int error;
9191

9292
inode_lock(d_inode(parent));
93-
*dentry = lookup_one_len(name, parent, strlen(name));
93+
*dentry = lookup_noperm(&QSTR(name), parent);
9494
if (!IS_ERR(*dentry))
9595
error = qibfs_mknod(d_inode(parent), *dentry,
9696
mode, fops, data);
@@ -433,7 +433,7 @@ static int remove_device_files(struct super_block *sb,
433433
char unit[10];
434434

435435
snprintf(unit, sizeof(unit), "%u", dd->unit);
436-
dir = lookup_one_len_unlocked(unit, sb->s_root, strlen(unit));
436+
dir = lookup_noperm_unlocked(&QSTR(unit), sb->s_root);
437437

438438
if (IS_ERR(dir)) {
439439
pr_err("Lookup of %s failed\n", unit);

fs/afs/dir.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ static struct dentry *afs_lookup_atsys(struct inode *dir, struct dentry *dentry)
943943
}
944944

945945
strcpy(p, name);
946-
ret = lookup_one_len(buf, dentry->d_parent, len);
946+
ret = lookup_noperm(&QSTR(buf), dentry->d_parent);
947947
if (IS_ERR(ret) || d_is_positive(ret))
948948
goto out_s;
949949
dput(ret);

fs/afs/dir_silly.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,16 +113,14 @@ int afs_sillyrename(struct afs_vnode *dvnode, struct afs_vnode *vnode,
113113

114114
sdentry = NULL;
115115
do {
116-
int slen;
117-
118116
dput(sdentry);
119117
sillycounter++;
120118

121119
/* Create a silly name. Note that the ".__afs" prefix is
122120
* understood by the salvager and must not be changed.
123121
*/
124-
slen = scnprintf(silly, sizeof(silly), ".__afs%04X", sillycounter);
125-
sdentry = lookup_one_len(silly, dentry->d_parent, slen);
122+
scnprintf(silly, sizeof(silly), ".__afs%04X", sillycounter);
123+
sdentry = lookup_noperm(&QSTR(silly), dentry->d_parent);
126124

127125
/* N.B. Better to return EBUSY here ... it could be dangerous
128126
* to delete the file while it's in use.

fs/autofs/dev-ioctl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,8 @@ static int autofs_dev_ioctl_timeout(struct file *fp,
459459
"the parent autofs mount timeout which could "
460460
"prevent shutdown\n");
461461

462-
dentry = try_lookup_one_len(param->path, base, path_len);
462+
dentry = try_lookup_noperm(&QSTR_LEN(param->path, path_len),
463+
base);
463464
if (IS_ERR_OR_NULL(dentry))
464465
return dentry ? PTR_ERR(dentry) : -ENOENT;
465466
ino = autofs_dentry_ino(dentry);

fs/binfmt_misc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ static ssize_t bm_register_write(struct file *file, const char __user *buffer,
842842
}
843843

844844
inode_lock(d_inode(root));
845-
dentry = lookup_one_len(e->name, root, strlen(e->name));
845+
dentry = lookup_noperm(&QSTR(e->name), root);
846846
err = PTR_ERR(dentry);
847847
if (IS_ERR(dentry))
848848
goto out;

fs/debugfs/inode.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ struct dentry *debugfs_lookup(const char *name, struct dentry *parent)
346346
if (!parent)
347347
parent = debugfs_mount->mnt_root;
348348

349-
dentry = lookup_positive_unlocked(name, parent, strlen(name));
349+
dentry = lookup_noperm_positive_unlocked(&QSTR(name), parent);
350350
if (IS_ERR(dentry))
351351
return NULL;
352352
return dentry;
@@ -388,7 +388,7 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
388388
if (unlikely(IS_DEADDIR(d_inode(parent))))
389389
dentry = ERR_PTR(-ENOENT);
390390
else
391-
dentry = lookup_one_len(name, parent, strlen(name));
391+
dentry = lookup_noperm(&QSTR(name), parent);
392392
if (!IS_ERR(dentry) && d_really_is_positive(dentry)) {
393393
if (d_is_dir(dentry))
394394
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, .
872872
}
873873
if (strcmp(old_name.name.name, new_name) == 0)
874874
goto out;
875-
target = lookup_one_len(new_name, parent, strlen(new_name));
875+
target = lookup_noperm(&QSTR(new_name), parent);
876876
if (IS_ERR(target)) {
877877
error = PTR_ERR(target);
878878
goto out;

fs/ecryptfs/inode.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,8 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
394394
char *encrypted_and_encoded_name = NULL;
395395
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
396396
struct dentry *lower_dir_dentry, *lower_dentry;
397-
const char *name = ecryptfs_dentry->d_name.name;
398-
size_t len = ecryptfs_dentry->d_name.len;
397+
struct qstr qname = QSTR_INIT(ecryptfs_dentry->d_name.name,
398+
ecryptfs_dentry->d_name.len);
399399
struct dentry *res;
400400
int rc = 0;
401401

@@ -404,23 +404,25 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
404404
mount_crypt_stat = &ecryptfs_superblock_to_private(
405405
ecryptfs_dentry->d_sb)->mount_crypt_stat;
406406
if (mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) {
407+
size_t len = qname.len;
407408
rc = ecryptfs_encrypt_and_encode_filename(
408409
&encrypted_and_encoded_name, &len,
409-
mount_crypt_stat, name, len);
410+
mount_crypt_stat, qname.name, len);
410411
if (rc) {
411412
printk(KERN_ERR "%s: Error attempting to encrypt and encode "
412413
"filename; rc = [%d]\n", __func__, rc);
413414
return ERR_PTR(rc);
414415
}
415-
name = encrypted_and_encoded_name;
416+
qname.name = encrypted_and_encoded_name;
417+
qname.len = len;
416418
}
417419

418-
lower_dentry = lookup_one_len_unlocked(name, lower_dir_dentry, len);
420+
lower_dentry = lookup_noperm_unlocked(&qname, lower_dir_dentry);
419421
if (IS_ERR(lower_dentry)) {
420-
ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned "
422+
ecryptfs_printk(KERN_DEBUG, "%s: lookup_noperm() returned "
421423
"[%ld] on lower_dentry = [%s]\n", __func__,
422424
PTR_ERR(lower_dentry),
423-
name);
425+
qname.name);
424426
res = ERR_CAST(lower_dentry);
425427
} else {
426428
res = ecryptfs_lookup_interpose(ecryptfs_dentry, lower_dentry);

0 commit comments

Comments
 (0)