diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-22 09:59:21 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-26 20:53:34 -0400 |
commit | 2d8f30380ab8c706f4e0a8f1aaa22b5886e9ac8a (patch) | |
tree | b798097fd831eab39f35c8c2e5a8ccfd7a850ef5 /fs/stat.c | |
parent | 256984a83880ff7ac78055cb87baea48137f0b77 (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/stat.c')
-rw-r--r-- | fs/stat.c | 32 |
1 files changed, 16 insertions, 16 deletions
@@ -57,13 +57,13 @@ EXPORT_SYMBOL(vfs_getattr); | |||
57 | 57 | ||
58 | int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) | 58 | int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) |
59 | { | 59 | { |
60 | struct nameidata nd; | 60 | struct path path; |
61 | int error; | 61 | int error; |
62 | 62 | ||
63 | error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd); | 63 | error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path); |
64 | if (!error) { | 64 | if (!error) { |
65 | error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); | 65 | error = vfs_getattr(path.mnt, path.dentry, stat); |
66 | path_put(&nd.path); | 66 | path_put(&path); |
67 | } | 67 | } |
68 | return error; | 68 | return error; |
69 | } | 69 | } |
@@ -77,13 +77,13 @@ EXPORT_SYMBOL(vfs_stat); | |||
77 | 77 | ||
78 | int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) | 78 | int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) |
79 | { | 79 | { |
80 | struct nameidata nd; | 80 | struct path path; |
81 | int error; | 81 | int error; |
82 | 82 | ||
83 | error = __user_walk_fd(dfd, name, 0, &nd); | 83 | error = user_path_at(dfd, name, 0, &path); |
84 | if (!error) { | 84 | if (!error) { |
85 | error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); | 85 | error = vfs_getattr(path.mnt, path.dentry, stat); |
86 | path_put(&nd.path); | 86 | path_put(&path); |
87 | } | 87 | } |
88 | return error; | 88 | return error; |
89 | } | 89 | } |
@@ -291,29 +291,29 @@ asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf) | |||
291 | return error; | 291 | return error; |
292 | } | 292 | } |
293 | 293 | ||
294 | asmlinkage long sys_readlinkat(int dfd, const char __user *path, | 294 | asmlinkage long sys_readlinkat(int dfd, const char __user *pathname, |
295 | char __user *buf, int bufsiz) | 295 | char __user *buf, int bufsiz) |
296 | { | 296 | { |
297 | struct nameidata nd; | 297 | struct path path; |
298 | int error; | 298 | int error; |
299 | 299 | ||
300 | if (bufsiz <= 0) | 300 | if (bufsiz <= 0) |
301 | return -EINVAL; | 301 | return -EINVAL; |
302 | 302 | ||
303 | error = __user_walk_fd(dfd, path, 0, &nd); | 303 | error = user_path_at(dfd, pathname, 0, &path); |
304 | if (!error) { | 304 | if (!error) { |
305 | struct inode *inode = nd.path.dentry->d_inode; | 305 | struct inode *inode = path.dentry->d_inode; |
306 | 306 | ||
307 | error = -EINVAL; | 307 | error = -EINVAL; |
308 | if (inode->i_op && inode->i_op->readlink) { | 308 | if (inode->i_op && inode->i_op->readlink) { |
309 | error = security_inode_readlink(nd.path.dentry); | 309 | error = security_inode_readlink(path.dentry); |
310 | if (!error) { | 310 | if (!error) { |
311 | touch_atime(nd.path.mnt, nd.path.dentry); | 311 | touch_atime(path.mnt, path.dentry); |
312 | error = inode->i_op->readlink(nd.path.dentry, | 312 | error = inode->i_op->readlink(path.dentry, |
313 | buf, bufsiz); | 313 | buf, bufsiz); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | path_put(&nd.path); | 316 | path_put(&path); |
317 | } | 317 | } |
318 | return error; | 318 | return error; |
319 | } | 319 | } |