aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c66
1 files changed, 50 insertions, 16 deletions
diff --git a/fs/namei.c b/fs/namei.c
index b3f8a1966c9c..6dbbd42d8b95 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -256,6 +256,38 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
256 return security_inode_permission(inode, mask, nd); 256 return security_inode_permission(inode, mask, nd);
257} 257}
258 258
259/**
260 * vfs_permission - check for access rights to a given path
261 * @nd: lookup result that describes the path
262 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
263 *
264 * Used to check for read/write/execute permissions on a path.
265 * We use "fsuid" for this, letting us set arbitrary permissions
266 * for filesystem access without changing the "normal" uids which
267 * are used for other things.
268 */
269int vfs_permission(struct nameidata *nd, int mask)
270{
271 return permission(nd->dentry->d_inode, mask, nd);
272}
273
274/**
275 * file_permission - check for additional access rights to a given file
276 * @file: file to check access rights for
277 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
278 *
279 * Used to check for read/write/execute permissions on an already opened
280 * file.
281 *
282 * Note:
283 * Do not use this function in new code. All access checks should
284 * be done using vfs_permission().
285 */
286int file_permission(struct file *file, int mask)
287{
288 return permission(file->f_dentry->d_inode, mask, NULL);
289}
290
259/* 291/*
260 * get_write_access() gets write permission for a file. 292 * get_write_access() gets write permission for a file.
261 * put_write_access() releases this write permission. 293 * put_write_access() releases this write permission.
@@ -765,9 +797,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)
765 797
766 nd->flags |= LOOKUP_CONTINUE; 798 nd->flags |= LOOKUP_CONTINUE;
767 err = exec_permission_lite(inode, nd); 799 err = exec_permission_lite(inode, nd);
768 if (err == -EAGAIN) { 800 if (err == -EAGAIN)
769 err = permission(inode, MAY_EXEC, nd); 801 err = vfs_permission(nd, MAY_EXEC);
770 }
771 if (err) 802 if (err)
772 break; 803 break;
773 804
@@ -1109,8 +1140,9 @@ int path_lookup_open(const char *name, unsigned int lookup_flags,
1109 * @open_flags: open intent flags 1140 * @open_flags: open intent flags
1110 * @create_mode: create intent flags 1141 * @create_mode: create intent flags
1111 */ 1142 */
1112int path_lookup_create(const char *name, unsigned int lookup_flags, 1143static int path_lookup_create(const char *name, unsigned int lookup_flags,
1113 struct nameidata *nd, int open_flags, int create_mode) 1144 struct nameidata *nd, int open_flags,
1145 int create_mode)
1114{ 1146{
1115 return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd, 1147 return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd,
1116 open_flags, create_mode); 1148 open_flags, create_mode);
@@ -1173,9 +1205,9 @@ out:
1173 return dentry; 1205 return dentry;
1174} 1206}
1175 1207
1176struct dentry * lookup_hash(struct qstr *name, struct dentry * base) 1208struct dentry * lookup_hash(struct nameidata *nd)
1177{ 1209{
1178 return __lookup_hash(name, base, NULL); 1210 return __lookup_hash(&nd->last, nd->dentry, nd);
1179} 1211}
1180 1212
1181/* SMP-safe */ 1213/* SMP-safe */
@@ -1199,7 +1231,7 @@ struct dentry * lookup_one_len(const char * name, struct dentry * base, int len)
1199 } 1231 }
1200 this.hash = end_name_hash(hash); 1232 this.hash = end_name_hash(hash);
1201 1233
1202 return lookup_hash(&this, base); 1234 return __lookup_hash(&this, base, NULL);
1203access: 1235access:
1204 return ERR_PTR(-EACCES); 1236 return ERR_PTR(-EACCES);
1205} 1237}
@@ -1407,7 +1439,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1407 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE)) 1439 if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
1408 return -EISDIR; 1440 return -EISDIR;
1409 1441
1410 error = permission(inode, acc_mode, nd); 1442 error = vfs_permission(nd, acc_mode);
1411 if (error) 1443 if (error)
1412 return error; 1444 return error;
1413 1445
@@ -1532,7 +1564,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1532 dir = nd->dentry; 1564 dir = nd->dentry;
1533 nd->flags &= ~LOOKUP_PARENT; 1565 nd->flags &= ~LOOKUP_PARENT;
1534 down(&dir->d_inode->i_sem); 1566 down(&dir->d_inode->i_sem);
1535 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1567 path.dentry = lookup_hash(nd);
1536 path.mnt = nd->mnt; 1568 path.mnt = nd->mnt;
1537 1569
1538do_last: 1570do_last:
@@ -1634,7 +1666,7 @@ do_link:
1634 } 1666 }
1635 dir = nd->dentry; 1667 dir = nd->dentry;
1636 down(&dir->d_inode->i_sem); 1668 down(&dir->d_inode->i_sem);
1637 path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); 1669 path.dentry = lookup_hash(nd);
1638 path.mnt = nd->mnt; 1670 path.mnt = nd->mnt;
1639 __putname(nd->last.name); 1671 __putname(nd->last.name);
1640 goto do_last; 1672 goto do_last;
@@ -1666,7 +1698,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
1666 /* 1698 /*
1667 * Do the final lookup. 1699 * Do the final lookup.
1668 */ 1700 */
1669 dentry = lookup_hash(&nd->last, nd->dentry); 1701 dentry = lookup_hash(nd);
1670 if (IS_ERR(dentry)) 1702 if (IS_ERR(dentry))
1671 goto fail; 1703 goto fail;
1672 1704
@@ -1901,7 +1933,7 @@ asmlinkage long sys_rmdir(const char __user * pathname)
1901 goto exit1; 1933 goto exit1;
1902 } 1934 }
1903 down(&nd.dentry->d_inode->i_sem); 1935 down(&nd.dentry->d_inode->i_sem);
1904 dentry = lookup_hash(&nd.last, nd.dentry); 1936 dentry = lookup_hash(&nd);
1905 error = PTR_ERR(dentry); 1937 error = PTR_ERR(dentry);
1906 if (!IS_ERR(dentry)) { 1938 if (!IS_ERR(dentry)) {
1907 error = vfs_rmdir(nd.dentry->d_inode, dentry); 1939 error = vfs_rmdir(nd.dentry->d_inode, dentry);
@@ -1970,7 +2002,7 @@ asmlinkage long sys_unlink(const char __user * pathname)
1970 if (nd.last_type != LAST_NORM) 2002 if (nd.last_type != LAST_NORM)
1971 goto exit1; 2003 goto exit1;
1972 down(&nd.dentry->d_inode->i_sem); 2004 down(&nd.dentry->d_inode->i_sem);
1973 dentry = lookup_hash(&nd.last, nd.dentry); 2005 dentry = lookup_hash(&nd);
1974 error = PTR_ERR(dentry); 2006 error = PTR_ERR(dentry);
1975 if (!IS_ERR(dentry)) { 2007 if (!IS_ERR(dentry)) {
1976 /* Why not before? Because we want correct error value */ 2008 /* Why not before? Because we want correct error value */
@@ -2313,7 +2345,7 @@ static inline int do_rename(const char * oldname, const char * newname)
2313 2345
2314 trap = lock_rename(new_dir, old_dir); 2346 trap = lock_rename(new_dir, old_dir);
2315 2347
2316 old_dentry = lookup_hash(&oldnd.last, old_dir); 2348 old_dentry = lookup_hash(&oldnd);
2317 error = PTR_ERR(old_dentry); 2349 error = PTR_ERR(old_dentry);
2318 if (IS_ERR(old_dentry)) 2350 if (IS_ERR(old_dentry))
2319 goto exit3; 2351 goto exit3;
@@ -2333,7 +2365,7 @@ static inline int do_rename(const char * oldname, const char * newname)
2333 error = -EINVAL; 2365 error = -EINVAL;
2334 if (old_dentry == trap) 2366 if (old_dentry == trap)
2335 goto exit4; 2367 goto exit4;
2336 new_dentry = lookup_hash(&newnd.last, new_dir); 2368 new_dentry = lookup_hash(&newnd);
2337 error = PTR_ERR(new_dentry); 2369 error = PTR_ERR(new_dentry);
2338 if (IS_ERR(new_dentry)) 2370 if (IS_ERR(new_dentry))
2339 goto exit4; 2371 goto exit4;
@@ -2536,6 +2568,8 @@ EXPORT_SYMBOL(path_lookup);
2536EXPORT_SYMBOL(path_release); 2568EXPORT_SYMBOL(path_release);
2537EXPORT_SYMBOL(path_walk); 2569EXPORT_SYMBOL(path_walk);
2538EXPORT_SYMBOL(permission); 2570EXPORT_SYMBOL(permission);
2571EXPORT_SYMBOL(vfs_permission);
2572EXPORT_SYMBOL(file_permission);
2539EXPORT_SYMBOL(unlock_rename); 2573EXPORT_SYMBOL(unlock_rename);
2540EXPORT_SYMBOL(vfs_create); 2574EXPORT_SYMBOL(vfs_create);
2541EXPORT_SYMBOL(vfs_follow_link); 2575EXPORT_SYMBOL(vfs_follow_link);