aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-07-22 09:59:21 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-07-26 20:53:34 -0400
commit2d8f30380ab8c706f4e0a8f1aaa22b5886e9ac8a (patch)
treeb798097fd831eab39f35c8c2e5a8ccfd7a850ef5 /fs/namei.c
parent256984a83880ff7ac78055cb87baea48137f0b77 (diff)
[PATCH] sanitize __user_walk_fd() et.al.
* do not pass nameidata; struct path is all the callers want. * switch to new helpers: user_path_at(dfd, pathname, flags, &path) user_path(pathname, &path) user_lpath(pathname, &path) user_path_dir(pathname, &path) (fail if not a directory) The last 3 are trivial macro wrappers for the first one. * remove nameidata in callers. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 5029b93ebbd5..edb5e973f9b3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1334,24 +1334,24 @@ struct dentry *lookup_one_noperm(const char *name, struct dentry *base)
1334 return __lookup_hash(&this, base, NULL); 1334 return __lookup_hash(&this, base, NULL);
1335} 1335}
1336 1336
1337int __user_walk_fd(int dfd, const char __user *name, unsigned flags, 1337int user_path_at(int dfd, const char __user *name, unsigned flags,
1338 struct nameidata *nd) 1338 struct path *path)
1339{ 1339{
1340 struct nameidata nd;
1340 char *tmp = getname(name); 1341 char *tmp = getname(name);
1341 int err = PTR_ERR(tmp); 1342 int err = PTR_ERR(tmp);
1342
1343 if (!IS_ERR(tmp)) { 1343 if (!IS_ERR(tmp)) {
1344 err = do_path_lookup(dfd, tmp, flags, nd); 1344
1345 BUG_ON(flags & LOOKUP_PARENT);
1346
1347 err = do_path_lookup(dfd, tmp, flags, &nd);
1345 putname(tmp); 1348 putname(tmp);
1349 if (!err)
1350 *path = nd.path;
1346 } 1351 }
1347 return err; 1352 return err;
1348} 1353}
1349 1354
1350int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
1351{
1352 return __user_walk_fd(AT_FDCWD, name, flags, nd);
1353}
1354
1355/* 1355/*
1356 * It's inline, so penalty for filesystems that don't use sticky bit is 1356 * It's inline, so penalty for filesystems that don't use sticky bit is
1357 * minimal. 1357 * minimal.
@@ -2446,7 +2446,8 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2446 int flags) 2446 int flags)
2447{ 2447{
2448 struct dentry *new_dentry; 2448 struct dentry *new_dentry;
2449 struct nameidata nd, old_nd; 2449 struct nameidata nd;
2450 struct path old_path;
2450 int error; 2451 int error;
2451 char * to; 2452 char * to;
2452 2453
@@ -2457,16 +2458,16 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2457 if (IS_ERR(to)) 2458 if (IS_ERR(to))
2458 return PTR_ERR(to); 2459 return PTR_ERR(to);
2459 2460
2460 error = __user_walk_fd(olddfd, oldname, 2461 error = user_path_at(olddfd, oldname,
2461 flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0, 2462 flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
2462 &old_nd); 2463 &old_path);
2463 if (error) 2464 if (error)
2464 goto exit; 2465 goto exit;
2465 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); 2466 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
2466 if (error) 2467 if (error)
2467 goto out; 2468 goto out;
2468 error = -EXDEV; 2469 error = -EXDEV;
2469 if (old_nd.path.mnt != nd.path.mnt) 2470 if (old_path.mnt != nd.path.mnt)
2470 goto out_release; 2471 goto out_release;
2471 new_dentry = lookup_create(&nd, 0); 2472 new_dentry = lookup_create(&nd, 0);
2472 error = PTR_ERR(new_dentry); 2473 error = PTR_ERR(new_dentry);
@@ -2475,7 +2476,7 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2475 error = mnt_want_write(nd.path.mnt); 2476 error = mnt_want_write(nd.path.mnt);
2476 if (error) 2477 if (error)
2477 goto out_dput; 2478 goto out_dput;
2478 error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); 2479 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
2479 mnt_drop_write(nd.path.mnt); 2480 mnt_drop_write(nd.path.mnt);
2480out_dput: 2481out_dput:
2481 dput(new_dentry); 2482 dput(new_dentry);
@@ -2484,7 +2485,7 @@ out_unlock:
2484out_release: 2485out_release:
2485 path_put(&nd.path); 2486 path_put(&nd.path);
2486out: 2487out:
2487 path_put(&old_nd.path); 2488 path_put(&old_path);
2488exit: 2489exit:
2489 putname(to); 2490 putname(to);
2490 2491
@@ -2877,8 +2878,7 @@ const struct inode_operations page_symlink_inode_operations = {
2877 .put_link = page_put_link, 2878 .put_link = page_put_link,
2878}; 2879};
2879 2880
2880EXPORT_SYMBOL(__user_walk); 2881EXPORT_SYMBOL(user_path_at);
2881EXPORT_SYMBOL(__user_walk_fd);
2882EXPORT_SYMBOL(follow_down); 2882EXPORT_SYMBOL(follow_down);
2883EXPORT_SYMBOL(follow_up); 2883EXPORT_SYMBOL(follow_up);
2884EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ 2884EXPORT_SYMBOL(get_write_access); /* binfmt_aout */