aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c115
1 files changed, 75 insertions, 40 deletions
diff --git a/fs/namei.c b/fs/namei.c
index af3783fff1de..dd5c9f0bf829 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -226,6 +226,16 @@ int generic_permission(struct inode *inode, int mask,
226 return -EACCES; 226 return -EACCES;
227} 227}
228 228
229/**
230 * inode_permission - check for access rights to a given inode
231 * @inode: inode to check permission on
232 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
233 *
234 * Used to check for read/write/execute permissions on an inode.
235 * We use "fsuid" for this, letting us set arbitrary permissions
236 * for filesystem access without changing the "normal" uids which
237 * are used for other things.
238 */
229int inode_permission(struct inode *inode, int mask) 239int inode_permission(struct inode *inode, int mask)
230{ 240{
231 int retval; 241 int retval;
@@ -247,7 +257,6 @@ int inode_permission(struct inode *inode, int mask)
247 return -EACCES; 257 return -EACCES;
248 } 258 }
249 259
250 /* Ordinary permission routines do not understand MAY_APPEND. */
251 if (inode->i_op && inode->i_op->permission) 260 if (inode->i_op && inode->i_op->permission)
252 retval = inode->i_op->permission(inode, mask); 261 retval = inode->i_op->permission(inode, mask);
253 else 262 else
@@ -265,21 +274,6 @@ int inode_permission(struct inode *inode, int mask)
265} 274}
266 275
267/** 276/**
268 * vfs_permission - check for access rights to a given path
269 * @nd: lookup result that describes the path
270 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
271 *
272 * Used to check for read/write/execute permissions on a path.
273 * We use "fsuid" for this, letting us set arbitrary permissions
274 * for filesystem access without changing the "normal" uids which
275 * are used for other things.
276 */
277int vfs_permission(struct nameidata *nd, int mask)
278{
279 return inode_permission(nd->path.dentry->d_inode, mask);
280}
281
282/**
283 * file_permission - check for additional access rights to a given file 277 * file_permission - check for additional access rights to a given file
284 * @file: file to check access rights for 278 * @file: file to check access rights for
285 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) 279 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
@@ -289,7 +283,7 @@ int vfs_permission(struct nameidata *nd, int mask)
289 * 283 *
290 * Note: 284 * Note:
291 * Do not use this function in new code. All access checks should 285 * Do not use this function in new code. All access checks should
292 * be done using vfs_permission(). 286 * be done using inode_permission().
293 */ 287 */
294int file_permission(struct file *file, int mask) 288int file_permission(struct file *file, int mask)
295{ 289{
@@ -527,18 +521,6 @@ out_unlock:
527 return result; 521 return result;
528} 522}
529 523
530/* SMP-safe */
531static __always_inline void
532walk_init_root(const char *name, struct nameidata *nd)
533{
534 struct fs_struct *fs = current->fs;
535
536 read_lock(&fs->lock);
537 nd->path = fs->root;
538 path_get(&fs->root);
539 read_unlock(&fs->lock);
540}
541
542/* 524/*
543 * Wrapper to retry pathname resolution whenever the underlying 525 * Wrapper to retry pathname resolution whenever the underlying
544 * file system returns an ESTALE. 526 * file system returns an ESTALE.
@@ -576,9 +558,16 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
576 goto fail; 558 goto fail;
577 559
578 if (*link == '/') { 560 if (*link == '/') {
561 struct fs_struct *fs = current->fs;
562
579 path_put(&nd->path); 563 path_put(&nd->path);
580 walk_init_root(link, nd); 564
565 read_lock(&fs->lock);
566 nd->path = fs->root;
567 path_get(&fs->root);
568 read_unlock(&fs->lock);
581 } 569 }
570
582 res = link_path_walk(link, nd); 571 res = link_path_walk(link, nd);
583 if (nd->depth || res || nd->last_type!=LAST_NORM) 572 if (nd->depth || res || nd->last_type!=LAST_NORM)
584 return res; 573 return res;
@@ -859,7 +848,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
859 nd->flags |= LOOKUP_CONTINUE; 848 nd->flags |= LOOKUP_CONTINUE;
860 err = exec_permission_lite(inode); 849 err = exec_permission_lite(inode);
861 if (err == -EAGAIN) 850 if (err == -EAGAIN)
862 err = vfs_permission(nd, MAY_EXEC); 851 err = inode_permission(nd->path.dentry->d_inode,
852 MAY_EXEC);
863 if (err) 853 if (err)
864 break; 854 break;
865 855
@@ -1493,9 +1483,9 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
1493 return error; 1483 return error;
1494} 1484}
1495 1485
1496int may_open(struct nameidata *nd, int acc_mode, int flag) 1486int may_open(struct path *path, int acc_mode, int flag)
1497{ 1487{
1498 struct dentry *dentry = nd->path.dentry; 1488 struct dentry *dentry = path->dentry;
1499 struct inode *inode = dentry->d_inode; 1489 struct inode *inode = dentry->d_inode;
1500 int error; 1490 int error;
1501 1491
@@ -1516,13 +1506,13 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1516 if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { 1506 if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
1517 flag &= ~O_TRUNC; 1507 flag &= ~O_TRUNC;
1518 } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { 1508 } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
1519 if (nd->path.mnt->mnt_flags & MNT_NODEV) 1509 if (path->mnt->mnt_flags & MNT_NODEV)
1520 return -EACCES; 1510 return -EACCES;
1521 1511
1522 flag &= ~O_TRUNC; 1512 flag &= ~O_TRUNC;
1523 } 1513 }
1524 1514
1525 error = vfs_permission(nd, acc_mode); 1515 error = inode_permission(inode, acc_mode);
1526 if (error) 1516 if (error)
1527 return error; 1517 return error;
1528 /* 1518 /*
@@ -1556,6 +1546,9 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1556 * Refuse to truncate files with mandatory locks held on them. 1546 * Refuse to truncate files with mandatory locks held on them.
1557 */ 1547 */
1558 error = locks_verify_locked(inode); 1548 error = locks_verify_locked(inode);
1549 if (!error)
1550 error = security_path_truncate(path, 0,
1551 ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
1559 if (!error) { 1552 if (!error) {
1560 DQUOT_INIT(inode); 1553 DQUOT_INIT(inode);
1561 1554
@@ -1586,14 +1579,18 @@ static int __open_namei_create(struct nameidata *nd, struct path *path,
1586 1579
1587 if (!IS_POSIXACL(dir->d_inode)) 1580 if (!IS_POSIXACL(dir->d_inode))
1588 mode &= ~current->fs->umask; 1581 mode &= ~current->fs->umask;
1582 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
1583 if (error)
1584 goto out_unlock;
1589 error = vfs_create(dir->d_inode, path->dentry, mode, nd); 1585 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
1586out_unlock:
1590 mutex_unlock(&dir->d_inode->i_mutex); 1587 mutex_unlock(&dir->d_inode->i_mutex);
1591 dput(nd->path.dentry); 1588 dput(nd->path.dentry);
1592 nd->path.dentry = path->dentry; 1589 nd->path.dentry = path->dentry;
1593 if (error) 1590 if (error)
1594 return error; 1591 return error;
1595 /* Don't check for write permission, don't truncate */ 1592 /* Don't check for write permission, don't truncate */
1596 return may_open(nd, 0, flag & ~O_TRUNC); 1593 return may_open(&nd->path, 0, flag & ~O_TRUNC);
1597} 1594}
1598 1595
1599/* 1596/*
@@ -1779,7 +1776,7 @@ ok:
1779 if (error) 1776 if (error)
1780 goto exit; 1777 goto exit;
1781 } 1778 }
1782 error = may_open(&nd, acc_mode, flag); 1779 error = may_open(&nd.path, acc_mode, flag);
1783 if (error) { 1780 if (error) {
1784 if (will_write) 1781 if (will_write)
1785 mnt_drop_write(nd.path.mnt); 1782 mnt_drop_write(nd.path.mnt);
@@ -1999,6 +1996,9 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
1999 error = mnt_want_write(nd.path.mnt); 1996 error = mnt_want_write(nd.path.mnt);
2000 if (error) 1997 if (error)
2001 goto out_dput; 1998 goto out_dput;
1999 error = security_path_mknod(&nd.path, dentry, mode, dev);
2000 if (error)
2001 goto out_drop_write;
2002 switch (mode & S_IFMT) { 2002 switch (mode & S_IFMT) {
2003 case 0: case S_IFREG: 2003 case 0: case S_IFREG:
2004 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); 2004 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
@@ -2011,6 +2011,7 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
2011 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); 2011 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
2012 break; 2012 break;
2013 } 2013 }
2014out_drop_write:
2014 mnt_drop_write(nd.path.mnt); 2015 mnt_drop_write(nd.path.mnt);
2015out_dput: 2016out_dput:
2016 dput(dentry); 2017 dput(dentry);
@@ -2070,7 +2071,11 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
2070 error = mnt_want_write(nd.path.mnt); 2071 error = mnt_want_write(nd.path.mnt);
2071 if (error) 2072 if (error)
2072 goto out_dput; 2073 goto out_dput;
2074 error = security_path_mkdir(&nd.path, dentry, mode);
2075 if (error)
2076 goto out_drop_write;
2073 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); 2077 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
2078out_drop_write:
2074 mnt_drop_write(nd.path.mnt); 2079 mnt_drop_write(nd.path.mnt);
2075out_dput: 2080out_dput:
2076 dput(dentry); 2081 dput(dentry);
@@ -2180,7 +2185,11 @@ static long do_rmdir(int dfd, const char __user *pathname)
2180 error = mnt_want_write(nd.path.mnt); 2185 error = mnt_want_write(nd.path.mnt);
2181 if (error) 2186 if (error)
2182 goto exit3; 2187 goto exit3;
2188 error = security_path_rmdir(&nd.path, dentry);
2189 if (error)
2190 goto exit4;
2183 error = vfs_rmdir(nd.path.dentry->d_inode, dentry); 2191 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
2192exit4:
2184 mnt_drop_write(nd.path.mnt); 2193 mnt_drop_write(nd.path.mnt);
2185exit3: 2194exit3:
2186 dput(dentry); 2195 dput(dentry);
@@ -2265,7 +2274,11 @@ static long do_unlinkat(int dfd, const char __user *pathname)
2265 error = mnt_want_write(nd.path.mnt); 2274 error = mnt_want_write(nd.path.mnt);
2266 if (error) 2275 if (error)
2267 goto exit2; 2276 goto exit2;
2277 error = security_path_unlink(&nd.path, dentry);
2278 if (error)
2279 goto exit3;
2268 error = vfs_unlink(nd.path.dentry->d_inode, dentry); 2280 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
2281exit3:
2269 mnt_drop_write(nd.path.mnt); 2282 mnt_drop_write(nd.path.mnt);
2270 exit2: 2283 exit2:
2271 dput(dentry); 2284 dput(dentry);
@@ -2346,7 +2359,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
2346 error = mnt_want_write(nd.path.mnt); 2359 error = mnt_want_write(nd.path.mnt);
2347 if (error) 2360 if (error)
2348 goto out_dput; 2361 goto out_dput;
2362 error = security_path_symlink(&nd.path, dentry, from);
2363 if (error)
2364 goto out_drop_write;
2349 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); 2365 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
2366out_drop_write:
2350 mnt_drop_write(nd.path.mnt); 2367 mnt_drop_write(nd.path.mnt);
2351out_dput: 2368out_dput:
2352 dput(dentry); 2369 dput(dentry);
@@ -2443,7 +2460,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2443 error = mnt_want_write(nd.path.mnt); 2460 error = mnt_want_write(nd.path.mnt);
2444 if (error) 2461 if (error)
2445 goto out_dput; 2462 goto out_dput;
2463 error = security_path_link(old_path.dentry, &nd.path, new_dentry);
2464 if (error)
2465 goto out_drop_write;
2446 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); 2466 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
2467out_drop_write:
2447 mnt_drop_write(nd.path.mnt); 2468 mnt_drop_write(nd.path.mnt);
2448out_dput: 2469out_dput:
2449 dput(new_dentry); 2470 dput(new_dentry);
@@ -2679,8 +2700,13 @@ asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2679 error = mnt_want_write(oldnd.path.mnt); 2700 error = mnt_want_write(oldnd.path.mnt);
2680 if (error) 2701 if (error)
2681 goto exit5; 2702 goto exit5;
2703 error = security_path_rename(&oldnd.path, old_dentry,
2704 &newnd.path, new_dentry);
2705 if (error)
2706 goto exit6;
2682 error = vfs_rename(old_dir->d_inode, old_dentry, 2707 error = vfs_rename(old_dir->d_inode, old_dentry,
2683 new_dir->d_inode, new_dentry); 2708 new_dir->d_inode, new_dentry);
2709exit6:
2684 mnt_drop_write(oldnd.path.mnt); 2710 mnt_drop_write(oldnd.path.mnt);
2685exit5: 2711exit5:
2686 dput(new_dentry); 2712 dput(new_dentry);
@@ -2750,13 +2776,16 @@ int vfs_follow_link(struct nameidata *nd, const char *link)
2750/* get the link contents into pagecache */ 2776/* get the link contents into pagecache */
2751static char *page_getlink(struct dentry * dentry, struct page **ppage) 2777static char *page_getlink(struct dentry * dentry, struct page **ppage)
2752{ 2778{
2753 struct page * page; 2779 char *kaddr;
2780 struct page *page;
2754 struct address_space *mapping = dentry->d_inode->i_mapping; 2781 struct address_space *mapping = dentry->d_inode->i_mapping;
2755 page = read_mapping_page(mapping, 0, NULL); 2782 page = read_mapping_page(mapping, 0, NULL);
2756 if (IS_ERR(page)) 2783 if (IS_ERR(page))
2757 return (char*)page; 2784 return (char*)page;
2758 *ppage = page; 2785 *ppage = page;
2759 return kmap(page); 2786 kaddr = kmap(page);
2787 nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1);
2788 return kaddr;
2760} 2789}
2761 2790
2762int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) 2791int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
@@ -2849,7 +2878,6 @@ EXPORT_SYMBOL(path_lookup);
2849EXPORT_SYMBOL(kern_path); 2878EXPORT_SYMBOL(kern_path);
2850EXPORT_SYMBOL(vfs_path_lookup); 2879EXPORT_SYMBOL(vfs_path_lookup);
2851EXPORT_SYMBOL(inode_permission); 2880EXPORT_SYMBOL(inode_permission);
2852EXPORT_SYMBOL(vfs_permission);
2853EXPORT_SYMBOL(file_permission); 2881EXPORT_SYMBOL(file_permission);
2854EXPORT_SYMBOL(unlock_rename); 2882EXPORT_SYMBOL(unlock_rename);
2855EXPORT_SYMBOL(vfs_create); 2883EXPORT_SYMBOL(vfs_create);
@@ -2865,3 +2893,10 @@ EXPORT_SYMBOL(vfs_symlink);
2865EXPORT_SYMBOL(vfs_unlink); 2893EXPORT_SYMBOL(vfs_unlink);
2866EXPORT_SYMBOL(dentry_unhash); 2894EXPORT_SYMBOL(dentry_unhash);
2867EXPORT_SYMBOL(generic_readlink); 2895EXPORT_SYMBOL(generic_readlink);
2896
2897/* to be mentioned only in INIT_TASK */
2898struct fs_struct init_fs = {
2899 .count = ATOMIC_INIT(1),
2900 .lock = __RW_LOCK_UNLOCKED(init_fs.lock),
2901 .umask = 0022,
2902};