Skip to content

Commit fdfc346

Browse files
committed
Merge branch 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull namei updates from Al Viro: "Clearing fallout from mkdirat in io_uring series. The fix in the kern_path_locked() patch plus associated cleanups" * 'misc.namei' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: putname(): IS_ERR_OR_NULL() is wrong here namei: Standardize callers of filename_create() namei: Standardize callers of filename_lookup() rename __filename_parentat() to filename_parentat() namei: Fix use after free in kern_path_locked
2 parents 8d4a0b5 + ea47ab1 commit fdfc346

File tree

2 files changed

+58
-59
lines changed

2 files changed

+58
-59
lines changed

fs/fs_parser.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ int fs_lookup_param(struct fs_context *fc,
165165
return invalf(fc, "%s: not usable as path", param->key);
166166
}
167167

168-
f->refcnt++; /* filename_lookup() drops our ref. */
169168
ret = filename_lookup(param->dirfd, f, flags, _path, NULL);
170169
if (ret < 0) {
171170
errorf(fc, "%s: Lookup failure for '%s'", param->key, f->name);

fs/namei.c

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ getname_kernel(const char * filename)
255255

256256
void putname(struct filename *name)
257257
{
258-
if (IS_ERR_OR_NULL(name))
258+
if (IS_ERR(name))
259259
return;
260260

261261
BUG_ON(name->refcnt <= 0);
@@ -2467,7 +2467,7 @@ static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path
24672467
return err;
24682468
}
24692469

2470-
static int __filename_lookup(int dfd, struct filename *name, unsigned flags,
2470+
int filename_lookup(int dfd, struct filename *name, unsigned flags,
24712471
struct path *path, struct path *root)
24722472
{
24732473
int retval;
@@ -2488,15 +2488,6 @@ static int __filename_lookup(int dfd, struct filename *name, unsigned flags,
24882488
return retval;
24892489
}
24902490

2491-
int filename_lookup(int dfd, struct filename *name, unsigned flags,
2492-
struct path *path, struct path *root)
2493-
{
2494-
int retval = __filename_lookup(dfd, name, flags, path, root);
2495-
2496-
putname(name);
2497-
return retval;
2498-
}
2499-
25002491
/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
25012492
static int path_parentat(struct nameidata *nd, unsigned flags,
25022493
struct path *parent)
@@ -2514,9 +2505,10 @@ static int path_parentat(struct nameidata *nd, unsigned flags,
25142505
return err;
25152506
}
25162507

2517-
static int __filename_parentat(int dfd, struct filename *name,
2518-
unsigned int flags, struct path *parent,
2519-
struct qstr *last, int *type)
2508+
/* Note: this does not consume "name" */
2509+
static int filename_parentat(int dfd, struct filename *name,
2510+
unsigned int flags, struct path *parent,
2511+
struct qstr *last, int *type)
25202512
{
25212513
int retval;
25222514
struct nameidata nd;
@@ -2538,25 +2530,14 @@ static int __filename_parentat(int dfd, struct filename *name,
25382530
return retval;
25392531
}
25402532

2541-
static int filename_parentat(int dfd, struct filename *name,
2542-
unsigned int flags, struct path *parent,
2543-
struct qstr *last, int *type)
2544-
{
2545-
int retval = __filename_parentat(dfd, name, flags, parent, last, type);
2546-
2547-
putname(name);
2548-
return retval;
2549-
}
2550-
25512533
/* does lookup, returns the object with parent locked */
2552-
struct dentry *kern_path_locked(const char *name, struct path *path)
2534+
static struct dentry *__kern_path_locked(struct filename *name, struct path *path)
25532535
{
25542536
struct dentry *d;
25552537
struct qstr last;
25562538
int type, error;
25572539

2558-
error = filename_parentat(AT_FDCWD, getname_kernel(name), 0, path,
2559-
&last, &type);
2540+
error = filename_parentat(AT_FDCWD, name, 0, path, &last, &type);
25602541
if (error)
25612542
return ERR_PTR(error);
25622543
if (unlikely(type != LAST_NORM)) {
@@ -2572,10 +2553,23 @@ struct dentry *kern_path_locked(const char *name, struct path *path)
25722553
return d;
25732554
}
25742555

2556+
struct dentry *kern_path_locked(const char *name, struct path *path)
2557+
{
2558+
struct filename *filename = getname_kernel(name);
2559+
struct dentry *res = __kern_path_locked(filename, path);
2560+
2561+
putname(filename);
2562+
return res;
2563+
}
2564+
25752565
int kern_path(const char *name, unsigned int flags, struct path *path)
25762566
{
2577-
return filename_lookup(AT_FDCWD, getname_kernel(name),
2578-
flags, path, NULL);
2567+
struct filename *filename = getname_kernel(name);
2568+
int ret = filename_lookup(AT_FDCWD, filename, flags, path, NULL);
2569+
2570+
putname(filename);
2571+
return ret;
2572+
25792573
}
25802574
EXPORT_SYMBOL(kern_path);
25812575

@@ -2591,10 +2585,15 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
25912585
const char *name, unsigned int flags,
25922586
struct path *path)
25932587
{
2588+
struct filename *filename;
25942589
struct path root = {.mnt = mnt, .dentry = dentry};
2590+
int ret;
2591+
2592+
filename = getname_kernel(name);
25952593
/* the first argument of filename_lookup() is ignored with root */
2596-
return filename_lookup(AT_FDCWD, getname_kernel(name),
2597-
flags , path, &root);
2594+
ret = filename_lookup(AT_FDCWD, filename, flags, path, &root);
2595+
putname(filename);
2596+
return ret;
25982597
}
25992598
EXPORT_SYMBOL(vfs_path_lookup);
26002599

@@ -2798,8 +2797,11 @@ int path_pts(struct path *path)
27982797
int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
27992798
struct path *path, int *empty)
28002799
{
2801-
return filename_lookup(dfd, getname_flags(name, flags, empty),
2802-
flags, path, NULL);
2800+
struct filename *filename = getname_flags(name, flags, empty);
2801+
int ret = filename_lookup(dfd, filename, flags, path, NULL);
2802+
2803+
putname(filename);
2804+
return ret;
28032805
}
28042806
EXPORT_SYMBOL(user_path_at_empty);
28052807

@@ -3618,8 +3620,8 @@ struct file *do_file_open_root(const struct path *root,
36183620
return file;
36193621
}
36203622

3621-
static struct dentry *__filename_create(int dfd, struct filename *name,
3622-
struct path *path, unsigned int lookup_flags)
3623+
static struct dentry *filename_create(int dfd, struct filename *name,
3624+
struct path *path, unsigned int lookup_flags)
36233625
{
36243626
struct dentry *dentry = ERR_PTR(-EEXIST);
36253627
struct qstr last;
@@ -3634,7 +3636,7 @@ static struct dentry *__filename_create(int dfd, struct filename *name,
36343636
*/
36353637
lookup_flags &= LOOKUP_REVAL;
36363638

3637-
error = __filename_parentat(dfd, name, lookup_flags, path, &last, &type);
3639+
error = filename_parentat(dfd, name, lookup_flags, path, &last, &type);
36383640
if (error)
36393641
return ERR_PTR(error);
36403642

@@ -3687,21 +3689,15 @@ static struct dentry *__filename_create(int dfd, struct filename *name,
36873689
return dentry;
36883690
}
36893691

3690-
static inline struct dentry *filename_create(int dfd, struct filename *name,
3692+
struct dentry *kern_path_create(int dfd, const char *pathname,
36913693
struct path *path, unsigned int lookup_flags)
36923694
{
3693-
struct dentry *res = __filename_create(dfd, name, path, lookup_flags);
3695+
struct filename *filename = getname_kernel(pathname);
3696+
struct dentry *res = filename_create(dfd, filename, path, lookup_flags);
36943697

3695-
putname(name);
3698+
putname(filename);
36963699
return res;
36973700
}
3698-
3699-
struct dentry *kern_path_create(int dfd, const char *pathname,
3700-
struct path *path, unsigned int lookup_flags)
3701-
{
3702-
return filename_create(dfd, getname_kernel(pathname),
3703-
path, lookup_flags);
3704-
}
37053701
EXPORT_SYMBOL(kern_path_create);
37063702

37073703
void done_path_create(struct path *path, struct dentry *dentry)
@@ -3716,7 +3712,11 @@ EXPORT_SYMBOL(done_path_create);
37163712
inline struct dentry *user_path_create(int dfd, const char __user *pathname,
37173713
struct path *path, unsigned int lookup_flags)
37183714
{
3719-
return filename_create(dfd, getname(pathname), path, lookup_flags);
3715+
struct filename *filename = getname(pathname);
3716+
struct dentry *res = filename_create(dfd, filename, path, lookup_flags);
3717+
3718+
putname(filename);
3719+
return res;
37203720
}
37213721
EXPORT_SYMBOL(user_path_create);
37223722

@@ -3797,7 +3797,7 @@ static int do_mknodat(int dfd, struct filename *name, umode_t mode,
37973797
if (error)
37983798
goto out1;
37993799
retry:
3800-
dentry = __filename_create(dfd, name, &path, lookup_flags);
3800+
dentry = filename_create(dfd, name, &path, lookup_flags);
38013801
error = PTR_ERR(dentry);
38023802
if (IS_ERR(dentry))
38033803
goto out1;
@@ -3897,7 +3897,7 @@ int do_mkdirat(int dfd, struct filename *name, umode_t mode)
38973897
unsigned int lookup_flags = LOOKUP_DIRECTORY;
38983898

38993899
retry:
3900-
dentry = __filename_create(dfd, name, &path, lookup_flags);
3900+
dentry = filename_create(dfd, name, &path, lookup_flags);
39013901
error = PTR_ERR(dentry);
39023902
if (IS_ERR(dentry))
39033903
goto out_putname;
@@ -3996,7 +3996,7 @@ int do_rmdir(int dfd, struct filename *name)
39963996
int type;
39973997
unsigned int lookup_flags = 0;
39983998
retry:
3999-
error = __filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
3999+
error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
40004000
if (error)
40014001
goto exit1;
40024002

@@ -4137,7 +4137,7 @@ int do_unlinkat(int dfd, struct filename *name)
41374137
struct inode *delegated_inode = NULL;
41384138
unsigned int lookup_flags = 0;
41394139
retry:
4140-
error = __filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
4140+
error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
41414141
if (error)
41424142
goto exit1;
41434143

@@ -4266,7 +4266,7 @@ int do_symlinkat(struct filename *from, int newdfd, struct filename *to)
42664266
goto out_putnames;
42674267
}
42684268
retry:
4269-
dentry = __filename_create(newdfd, to, &path, lookup_flags);
4269+
dentry = filename_create(newdfd, to, &path, lookup_flags);
42704270
error = PTR_ERR(dentry);
42714271
if (IS_ERR(dentry))
42724272
goto out_putnames;
@@ -4426,11 +4426,11 @@ int do_linkat(int olddfd, struct filename *old, int newdfd,
44264426
if (flags & AT_SYMLINK_FOLLOW)
44274427
how |= LOOKUP_FOLLOW;
44284428
retry:
4429-
error = __filename_lookup(olddfd, old, how, &old_path, NULL);
4429+
error = filename_lookup(olddfd, old, how, &old_path, NULL);
44304430
if (error)
44314431
goto out_putnames;
44324432

4433-
new_dentry = __filename_create(newdfd, new, &new_path,
4433+
new_dentry = filename_create(newdfd, new, &new_path,
44344434
(how & LOOKUP_REVAL));
44354435
error = PTR_ERR(new_dentry);
44364436
if (IS_ERR(new_dentry))
@@ -4689,13 +4689,13 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
46894689
target_flags = 0;
46904690

46914691
retry:
4692-
error = __filename_parentat(olddfd, from, lookup_flags, &old_path,
4693-
&old_last, &old_type);
4692+
error = filename_parentat(olddfd, from, lookup_flags, &old_path,
4693+
&old_last, &old_type);
46944694
if (error)
46954695
goto put_names;
46964696

4697-
error = __filename_parentat(newdfd, to, lookup_flags, &new_path, &new_last,
4698-
&new_type);
4697+
error = filename_parentat(newdfd, to, lookup_flags, &new_path, &new_last,
4698+
&new_type);
46994699
if (error)
47004700
goto exit1;
47014701

0 commit comments

Comments
 (0)