aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2009-02-05 19:01:45 -0500
committerJames Morris <jmorris@namei.org>2009-02-05 19:01:45 -0500
commitcb5629b10d64a8006622ce3a52bc887d91057d69 (patch)
tree7c06d8f30783115e3384721046258ce615b129c5 /fs/namei.c
parent8920d5ad6ba74ae8ab020e90cc4d976980e68701 (diff)
parentf01d1d546abb2f4028b5299092f529eefb01253a (diff)
Merge branch 'master' into next
Conflicts: fs/namei.c Manually merged per: diff --cc fs/namei.c index 734f2b5,bbc15c2..0000000 --- a/fs/namei.c +++ b/fs/namei.c @@@ -860,9 -848,8 +849,10 @@@ static int __link_path_walk(const char nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode); if (err == -EAGAIN) - err = vfs_permission(nd, MAY_EXEC); + err = inode_permission(nd->path.dentry->d_inode, + MAY_EXEC); + if (!err) + err = ima_path_check(&nd->path, MAY_EXEC); if (err) break; @@@ -1525,14 -1506,9 +1509,14 @@@ int may_open(struct path *path, int acc flag &= ~O_TRUNC; } - error = vfs_permission(nd, acc_mode); + error = inode_permission(inode, acc_mode); if (error) return error; + - error = ima_path_check(&nd->path, ++ error = ima_path_check(path, + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); + if (error) + return error; /* * An append-only file must be opened in append mode for writing. */ Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c197
1 files changed, 115 insertions, 82 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 734f2b5591bf..199317642ad6 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -227,6 +227,16 @@ int generic_permission(struct inode *inode, int mask,
227 return -EACCES; 227 return -EACCES;
228} 228}
229 229
230/**
231 * inode_permission - check for access rights to a given inode
232 * @inode: inode to check permission on
233 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
234 *
235 * Used to check for read/write/execute permissions on an inode.
236 * We use "fsuid" for this, letting us set arbitrary permissions
237 * for filesystem access without changing the "normal" uids which
238 * are used for other things.
239 */
230int inode_permission(struct inode *inode, int mask) 240int inode_permission(struct inode *inode, int mask)
231{ 241{
232 int retval; 242 int retval;
@@ -248,8 +258,7 @@ int inode_permission(struct inode *inode, int mask)
248 return -EACCES; 258 return -EACCES;
249 } 259 }
250 260
251 /* Ordinary permission routines do not understand MAY_APPEND. */ 261 if (inode->i_op->permission)
252 if (inode->i_op && inode->i_op->permission)
253 retval = inode->i_op->permission(inode, mask); 262 retval = inode->i_op->permission(inode, mask);
254 else 263 else
255 retval = generic_permission(inode, mask, NULL); 264 retval = generic_permission(inode, mask, NULL);
@@ -266,21 +275,6 @@ int inode_permission(struct inode *inode, int mask)
266} 275}
267 276
268/** 277/**
269 * vfs_permission - check for access rights to a given path
270 * @nd: lookup result that describes the path
271 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
272 *
273 * Used to check for read/write/execute permissions on a path.
274 * We use "fsuid" for this, letting us set arbitrary permissions
275 * for filesystem access without changing the "normal" uids which
276 * are used for other things.
277 */
278int vfs_permission(struct nameidata *nd, int mask)
279{
280 return inode_permission(nd->path.dentry->d_inode, mask);
281}
282
283/**
284 * file_permission - check for additional access rights to a given file 278 * file_permission - check for additional access rights to a given file
285 * @file: file to check access rights for 279 * @file: file to check access rights for
286 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) 280 * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
@@ -290,7 +284,7 @@ int vfs_permission(struct nameidata *nd, int mask)
290 * 284 *
291 * Note: 285 * Note:
292 * Do not use this function in new code. All access checks should 286 * Do not use this function in new code. All access checks should
293 * be done using vfs_permission(). 287 * be done using inode_permission().
294 */ 288 */
295int file_permission(struct file *file, int mask) 289int file_permission(struct file *file, int mask)
296{ 290{
@@ -439,7 +433,7 @@ static int exec_permission_lite(struct inode *inode)
439{ 433{
440 umode_t mode = inode->i_mode; 434 umode_t mode = inode->i_mode;
441 435
442 if (inode->i_op && inode->i_op->permission) 436 if (inode->i_op->permission)
443 return -EAGAIN; 437 return -EAGAIN;
444 438
445 if (current_fsuid() == inode->i_uid) 439 if (current_fsuid() == inode->i_uid)
@@ -528,18 +522,6 @@ out_unlock:
528 return result; 522 return result;
529} 523}
530 524
531/* SMP-safe */
532static __always_inline void
533walk_init_root(const char *name, struct nameidata *nd)
534{
535 struct fs_struct *fs = current->fs;
536
537 read_lock(&fs->lock);
538 nd->path = fs->root;
539 path_get(&fs->root);
540 read_unlock(&fs->lock);
541}
542
543/* 525/*
544 * Wrapper to retry pathname resolution whenever the underlying 526 * Wrapper to retry pathname resolution whenever the underlying
545 * file system returns an ESTALE. 527 * file system returns an ESTALE.
@@ -577,9 +559,16 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
577 goto fail; 559 goto fail;
578 560
579 if (*link == '/') { 561 if (*link == '/') {
562 struct fs_struct *fs = current->fs;
563
580 path_put(&nd->path); 564 path_put(&nd->path);
581 walk_init_root(link, nd); 565
566 read_lock(&fs->lock);
567 nd->path = fs->root;
568 path_get(&fs->root);
569 read_unlock(&fs->lock);
582 } 570 }
571
583 res = link_path_walk(link, nd); 572 res = link_path_walk(link, nd);
584 if (nd->depth || res || nd->last_type!=LAST_NORM) 573 if (nd->depth || res || nd->last_type!=LAST_NORM)
585 return res; 574 return res;
@@ -860,7 +849,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
860 nd->flags |= LOOKUP_CONTINUE; 849 nd->flags |= LOOKUP_CONTINUE;
861 err = exec_permission_lite(inode); 850 err = exec_permission_lite(inode);
862 if (err == -EAGAIN) 851 if (err == -EAGAIN)
863 err = vfs_permission(nd, MAY_EXEC); 852 err = inode_permission(nd->path.dentry->d_inode,
853 MAY_EXEC);
864 if (!err) 854 if (!err)
865 err = ima_path_check(&nd->path, MAY_EXEC); 855 err = ima_path_check(&nd->path, MAY_EXEC);
866 if (err) 856 if (err)
@@ -921,9 +911,6 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
921 inode = next.dentry->d_inode; 911 inode = next.dentry->d_inode;
922 if (!inode) 912 if (!inode)
923 goto out_dput; 913 goto out_dput;
924 err = -ENOTDIR;
925 if (!inode->i_op)
926 goto out_dput;
927 914
928 if (inode->i_op->follow_link) { 915 if (inode->i_op->follow_link) {
929 err = do_follow_link(&next, nd); 916 err = do_follow_link(&next, nd);
@@ -933,9 +920,6 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
933 inode = nd->path.dentry->d_inode; 920 inode = nd->path.dentry->d_inode;
934 if (!inode) 921 if (!inode)
935 break; 922 break;
936 err = -ENOTDIR;
937 if (!inode->i_op)
938 break;
939 } else 923 } else
940 path_to_nameidata(&next, nd); 924 path_to_nameidata(&next, nd);
941 err = -ENOTDIR; 925 err = -ENOTDIR;
@@ -974,7 +958,7 @@ last_component:
974 break; 958 break;
975 inode = next.dentry->d_inode; 959 inode = next.dentry->d_inode;
976 if ((lookup_flags & LOOKUP_FOLLOW) 960 if ((lookup_flags & LOOKUP_FOLLOW)
977 && inode && inode->i_op && inode->i_op->follow_link) { 961 && inode && inode->i_op->follow_link) {
978 err = do_follow_link(&next, nd); 962 err = do_follow_link(&next, nd);
979 if (err) 963 if (err)
980 goto return_err; 964 goto return_err;
@@ -986,7 +970,7 @@ last_component:
986 break; 970 break;
987 if (lookup_flags & LOOKUP_DIRECTORY) { 971 if (lookup_flags & LOOKUP_DIRECTORY) {
988 err = -ENOTDIR; 972 err = -ENOTDIR;
989 if (!inode->i_op || !inode->i_op->lookup) 973 if (!inode->i_op->lookup)
990 break; 974 break;
991 } 975 }
992 goto return_base; 976 goto return_base;
@@ -1482,7 +1466,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
1482 if (error) 1466 if (error)
1483 return error; 1467 return error;
1484 1468
1485 if (!dir->i_op || !dir->i_op->create) 1469 if (!dir->i_op->create)
1486 return -EACCES; /* shouldn't it be ENOSYS? */ 1470 return -EACCES; /* shouldn't it be ENOSYS? */
1487 mode &= S_IALLUGO; 1471 mode &= S_IALLUGO;
1488 mode |= S_IFREG; 1472 mode |= S_IFREG;
@@ -1496,9 +1480,9 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
1496 return error; 1480 return error;
1497} 1481}
1498 1482
1499int may_open(struct nameidata *nd, int acc_mode, int flag) 1483int may_open(struct path *path, int acc_mode, int flag)
1500{ 1484{
1501 struct dentry *dentry = nd->path.dentry; 1485 struct dentry *dentry = path->dentry;
1502 struct inode *inode = dentry->d_inode; 1486 struct inode *inode = dentry->d_inode;
1503 int error; 1487 int error;
1504 1488
@@ -1519,17 +1503,17 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1519 if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { 1503 if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
1520 flag &= ~O_TRUNC; 1504 flag &= ~O_TRUNC;
1521 } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { 1505 } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
1522 if (nd->path.mnt->mnt_flags & MNT_NODEV) 1506 if (path->mnt->mnt_flags & MNT_NODEV)
1523 return -EACCES; 1507 return -EACCES;
1524 1508
1525 flag &= ~O_TRUNC; 1509 flag &= ~O_TRUNC;
1526 } 1510 }
1527 1511
1528 error = vfs_permission(nd, acc_mode); 1512 error = inode_permission(inode, acc_mode);
1529 if (error) 1513 if (error)
1530 return error; 1514 return error;
1531 1515
1532 error = ima_path_check(&nd->path, 1516 error = ima_path_check(path,
1533 acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); 1517 acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
1534 if (error) 1518 if (error)
1535 return error; 1519 return error;
@@ -1564,6 +1548,9 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1564 * Refuse to truncate files with mandatory locks held on them. 1548 * Refuse to truncate files with mandatory locks held on them.
1565 */ 1549 */
1566 error = locks_verify_locked(inode); 1550 error = locks_verify_locked(inode);
1551 if (!error)
1552 error = security_path_truncate(path, 0,
1553 ATTR_MTIME|ATTR_CTIME|ATTR_OPEN);
1567 if (!error) { 1554 if (!error) {
1568 DQUOT_INIT(inode); 1555 DQUOT_INIT(inode);
1569 1556
@@ -1594,14 +1581,18 @@ static int __open_namei_create(struct nameidata *nd, struct path *path,
1594 1581
1595 if (!IS_POSIXACL(dir->d_inode)) 1582 if (!IS_POSIXACL(dir->d_inode))
1596 mode &= ~current->fs->umask; 1583 mode &= ~current->fs->umask;
1584 error = security_path_mknod(&nd->path, path->dentry, mode, 0);
1585 if (error)
1586 goto out_unlock;
1597 error = vfs_create(dir->d_inode, path->dentry, mode, nd); 1587 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
1588out_unlock:
1598 mutex_unlock(&dir->d_inode->i_mutex); 1589 mutex_unlock(&dir->d_inode->i_mutex);
1599 dput(nd->path.dentry); 1590 dput(nd->path.dentry);
1600 nd->path.dentry = path->dentry; 1591 nd->path.dentry = path->dentry;
1601 if (error) 1592 if (error)
1602 return error; 1593 return error;
1603 /* Don't check for write permission, don't truncate */ 1594 /* Don't check for write permission, don't truncate */
1604 return may_open(nd, 0, flag & ~O_TRUNC); 1595 return may_open(&nd->path, 0, flag & ~O_TRUNC);
1605} 1596}
1606 1597
1607/* 1598/*
@@ -1763,7 +1754,7 @@ do_last:
1763 error = -ENOENT; 1754 error = -ENOENT;
1764 if (!path.dentry->d_inode) 1755 if (!path.dentry->d_inode)
1765 goto exit_dput; 1756 goto exit_dput;
1766 if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) 1757 if (path.dentry->d_inode->i_op->follow_link)
1767 goto do_link; 1758 goto do_link;
1768 1759
1769 path_to_nameidata(&path, &nd); 1760 path_to_nameidata(&path, &nd);
@@ -1787,7 +1778,7 @@ ok:
1787 if (error) 1778 if (error)
1788 goto exit; 1779 goto exit;
1789 } 1780 }
1790 error = may_open(&nd, acc_mode, flag); 1781 error = may_open(&nd.path, acc_mode, flag);
1791 if (error) { 1782 if (error) {
1792 if (will_write) 1783 if (will_write)
1793 mnt_drop_write(nd.path.mnt); 1784 mnt_drop_write(nd.path.mnt);
@@ -1944,7 +1935,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1944 if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) 1935 if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD))
1945 return -EPERM; 1936 return -EPERM;
1946 1937
1947 if (!dir->i_op || !dir->i_op->mknod) 1938 if (!dir->i_op->mknod)
1948 return -EPERM; 1939 return -EPERM;
1949 1940
1950 error = devcgroup_inode_mknod(mode, dev); 1941 error = devcgroup_inode_mknod(mode, dev);
@@ -1979,8 +1970,8 @@ static int may_mknod(mode_t mode)
1979 } 1970 }
1980} 1971}
1981 1972
1982asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, 1973SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode,
1983 unsigned dev) 1974 unsigned, dev)
1984{ 1975{
1985 int error; 1976 int error;
1986 char *tmp; 1977 char *tmp;
@@ -2007,6 +1998,9 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
2007 error = mnt_want_write(nd.path.mnt); 1998 error = mnt_want_write(nd.path.mnt);
2008 if (error) 1999 if (error)
2009 goto out_dput; 2000 goto out_dput;
2001 error = security_path_mknod(&nd.path, dentry, mode, dev);
2002 if (error)
2003 goto out_drop_write;
2010 switch (mode & S_IFMT) { 2004 switch (mode & S_IFMT) {
2011 case 0: case S_IFREG: 2005 case 0: case S_IFREG:
2012 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); 2006 error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
@@ -2019,6 +2013,7 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
2019 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); 2013 error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
2020 break; 2014 break;
2021 } 2015 }
2016out_drop_write:
2022 mnt_drop_write(nd.path.mnt); 2017 mnt_drop_write(nd.path.mnt);
2023out_dput: 2018out_dput:
2024 dput(dentry); 2019 dput(dentry);
@@ -2030,7 +2025,7 @@ out_unlock:
2030 return error; 2025 return error;
2031} 2026}
2032 2027
2033asmlinkage long sys_mknod(const char __user *filename, int mode, unsigned dev) 2028SYSCALL_DEFINE3(mknod, const char __user *, filename, int, mode, unsigned, dev)
2034{ 2029{
2035 return sys_mknodat(AT_FDCWD, filename, mode, dev); 2030 return sys_mknodat(AT_FDCWD, filename, mode, dev);
2036} 2031}
@@ -2042,7 +2037,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2042 if (error) 2037 if (error)
2043 return error; 2038 return error;
2044 2039
2045 if (!dir->i_op || !dir->i_op->mkdir) 2040 if (!dir->i_op->mkdir)
2046 return -EPERM; 2041 return -EPERM;
2047 2042
2048 mode &= (S_IRWXUGO|S_ISVTX); 2043 mode &= (S_IRWXUGO|S_ISVTX);
@@ -2057,7 +2052,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2057 return error; 2052 return error;
2058} 2053}
2059 2054
2060asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) 2055SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
2061{ 2056{
2062 int error = 0; 2057 int error = 0;
2063 char * tmp; 2058 char * tmp;
@@ -2078,7 +2073,11 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
2078 error = mnt_want_write(nd.path.mnt); 2073 error = mnt_want_write(nd.path.mnt);
2079 if (error) 2074 if (error)
2080 goto out_dput; 2075 goto out_dput;
2076 error = security_path_mkdir(&nd.path, dentry, mode);
2077 if (error)
2078 goto out_drop_write;
2081 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); 2079 error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
2080out_drop_write:
2082 mnt_drop_write(nd.path.mnt); 2081 mnt_drop_write(nd.path.mnt);
2083out_dput: 2082out_dput:
2084 dput(dentry); 2083 dput(dentry);
@@ -2090,7 +2089,7 @@ out_err:
2090 return error; 2089 return error;
2091} 2090}
2092 2091
2093asmlinkage long sys_mkdir(const char __user *pathname, int mode) 2092SYSCALL_DEFINE2(mkdir, const char __user *, pathname, int, mode)
2094{ 2093{
2095 return sys_mkdirat(AT_FDCWD, pathname, mode); 2094 return sys_mkdirat(AT_FDCWD, pathname, mode);
2096} 2095}
@@ -2129,7 +2128,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
2129 if (error) 2128 if (error)
2130 return error; 2129 return error;
2131 2130
2132 if (!dir->i_op || !dir->i_op->rmdir) 2131 if (!dir->i_op->rmdir)
2133 return -EPERM; 2132 return -EPERM;
2134 2133
2135 DQUOT_INIT(dir); 2134 DQUOT_INIT(dir);
@@ -2188,7 +2187,11 @@ static long do_rmdir(int dfd, const char __user *pathname)
2188 error = mnt_want_write(nd.path.mnt); 2187 error = mnt_want_write(nd.path.mnt);
2189 if (error) 2188 if (error)
2190 goto exit3; 2189 goto exit3;
2190 error = security_path_rmdir(&nd.path, dentry);
2191 if (error)
2192 goto exit4;
2191 error = vfs_rmdir(nd.path.dentry->d_inode, dentry); 2193 error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
2194exit4:
2192 mnt_drop_write(nd.path.mnt); 2195 mnt_drop_write(nd.path.mnt);
2193exit3: 2196exit3:
2194 dput(dentry); 2197 dput(dentry);
@@ -2200,7 +2203,7 @@ exit1:
2200 return error; 2203 return error;
2201} 2204}
2202 2205
2203asmlinkage long sys_rmdir(const char __user *pathname) 2206SYSCALL_DEFINE1(rmdir, const char __user *, pathname)
2204{ 2207{
2205 return do_rmdir(AT_FDCWD, pathname); 2208 return do_rmdir(AT_FDCWD, pathname);
2206} 2209}
@@ -2212,7 +2215,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
2212 if (error) 2215 if (error)
2213 return error; 2216 return error;
2214 2217
2215 if (!dir->i_op || !dir->i_op->unlink) 2218 if (!dir->i_op->unlink)
2216 return -EPERM; 2219 return -EPERM;
2217 2220
2218 DQUOT_INIT(dir); 2221 DQUOT_INIT(dir);
@@ -2273,7 +2276,11 @@ static long do_unlinkat(int dfd, const char __user *pathname)
2273 error = mnt_want_write(nd.path.mnt); 2276 error = mnt_want_write(nd.path.mnt);
2274 if (error) 2277 if (error)
2275 goto exit2; 2278 goto exit2;
2279 error = security_path_unlink(&nd.path, dentry);
2280 if (error)
2281 goto exit3;
2276 error = vfs_unlink(nd.path.dentry->d_inode, dentry); 2282 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
2283exit3:
2277 mnt_drop_write(nd.path.mnt); 2284 mnt_drop_write(nd.path.mnt);
2278 exit2: 2285 exit2:
2279 dput(dentry); 2286 dput(dentry);
@@ -2292,7 +2299,7 @@ slashes:
2292 goto exit2; 2299 goto exit2;
2293} 2300}
2294 2301
2295asmlinkage long sys_unlinkat(int dfd, const char __user *pathname, int flag) 2302SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
2296{ 2303{
2297 if ((flag & ~AT_REMOVEDIR) != 0) 2304 if ((flag & ~AT_REMOVEDIR) != 0)
2298 return -EINVAL; 2305 return -EINVAL;
@@ -2303,7 +2310,7 @@ asmlinkage long sys_unlinkat(int dfd, const char __user *pathname, int flag)
2303 return do_unlinkat(dfd, pathname); 2310 return do_unlinkat(dfd, pathname);
2304} 2311}
2305 2312
2306asmlinkage long sys_unlink(const char __user *pathname) 2313SYSCALL_DEFINE1(unlink, const char __user *, pathname)
2307{ 2314{
2308 return do_unlinkat(AT_FDCWD, pathname); 2315 return do_unlinkat(AT_FDCWD, pathname);
2309} 2316}
@@ -2315,7 +2322,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
2315 if (error) 2322 if (error)
2316 return error; 2323 return error;
2317 2324
2318 if (!dir->i_op || !dir->i_op->symlink) 2325 if (!dir->i_op->symlink)
2319 return -EPERM; 2326 return -EPERM;
2320 2327
2321 error = security_inode_symlink(dir, dentry, oldname); 2328 error = security_inode_symlink(dir, dentry, oldname);
@@ -2329,8 +2336,8 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
2329 return error; 2336 return error;
2330} 2337}
2331 2338
2332asmlinkage long sys_symlinkat(const char __user *oldname, 2339SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
2333 int newdfd, const char __user *newname) 2340 int, newdfd, const char __user *, newname)
2334{ 2341{
2335 int error; 2342 int error;
2336 char *from; 2343 char *from;
@@ -2354,7 +2361,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
2354 error = mnt_want_write(nd.path.mnt); 2361 error = mnt_want_write(nd.path.mnt);
2355 if (error) 2362 if (error)
2356 goto out_dput; 2363 goto out_dput;
2364 error = security_path_symlink(&nd.path, dentry, from);
2365 if (error)
2366 goto out_drop_write;
2357 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); 2367 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
2368out_drop_write:
2358 mnt_drop_write(nd.path.mnt); 2369 mnt_drop_write(nd.path.mnt);
2359out_dput: 2370out_dput:
2360 dput(dentry); 2371 dput(dentry);
@@ -2367,7 +2378,7 @@ out_putname:
2367 return error; 2378 return error;
2368} 2379}
2369 2380
2370asmlinkage long sys_symlink(const char __user *oldname, const char __user *newname) 2381SYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
2371{ 2382{
2372 return sys_symlinkat(oldname, AT_FDCWD, newname); 2383 return sys_symlinkat(oldname, AT_FDCWD, newname);
2373} 2384}
@@ -2392,7 +2403,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2392 */ 2403 */
2393 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) 2404 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
2394 return -EPERM; 2405 return -EPERM;
2395 if (!dir->i_op || !dir->i_op->link) 2406 if (!dir->i_op->link)
2396 return -EPERM; 2407 return -EPERM;
2397 if (S_ISDIR(inode->i_mode)) 2408 if (S_ISDIR(inode->i_mode))
2398 return -EPERM; 2409 return -EPERM;
@@ -2419,9 +2430,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2419 * with linux 2.0, and to avoid hard-linking to directories 2430 * with linux 2.0, and to avoid hard-linking to directories
2420 * and other special files. --ADM 2431 * and other special files. --ADM
2421 */ 2432 */
2422asmlinkage long sys_linkat(int olddfd, const char __user *oldname, 2433SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
2423 int newdfd, const char __user *newname, 2434 int, newdfd, const char __user *, newname, int, flags)
2424 int flags)
2425{ 2435{
2426 struct dentry *new_dentry; 2436 struct dentry *new_dentry;
2427 struct nameidata nd; 2437 struct nameidata nd;
@@ -2451,7 +2461,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2451 error = mnt_want_write(nd.path.mnt); 2461 error = mnt_want_write(nd.path.mnt);
2452 if (error) 2462 if (error)
2453 goto out_dput; 2463 goto out_dput;
2464 error = security_path_link(old_path.dentry, &nd.path, new_dentry);
2465 if (error)
2466 goto out_drop_write;
2454 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); 2467 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
2468out_drop_write:
2455 mnt_drop_write(nd.path.mnt); 2469 mnt_drop_write(nd.path.mnt);
2456out_dput: 2470out_dput:
2457 dput(new_dentry); 2471 dput(new_dentry);
@@ -2466,7 +2480,7 @@ out:
2466 return error; 2480 return error;
2467} 2481}
2468 2482
2469asmlinkage long sys_link(const char __user *oldname, const char __user *newname) 2483SYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname)
2470{ 2484{
2471 return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0); 2485 return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname, 0);
2472} 2486}
@@ -2595,7 +2609,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2595 if (error) 2609 if (error)
2596 return error; 2610 return error;
2597 2611
2598 if (!old_dir->i_op || !old_dir->i_op->rename) 2612 if (!old_dir->i_op->rename)
2599 return -EPERM; 2613 return -EPERM;
2600 2614
2601 DQUOT_INIT(old_dir); 2615 DQUOT_INIT(old_dir);
@@ -2617,8 +2631,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2617 return error; 2631 return error;
2618} 2632}
2619 2633
2620asmlinkage long sys_renameat(int olddfd, const char __user *oldname, 2634SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
2621 int newdfd, const char __user *newname) 2635 int, newdfd, const char __user *, newname)
2622{ 2636{
2623 struct dentry *old_dir, *new_dir; 2637 struct dentry *old_dir, *new_dir;
2624 struct dentry *old_dentry, *new_dentry; 2638 struct dentry *old_dentry, *new_dentry;
@@ -2687,8 +2701,13 @@ asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2687 error = mnt_want_write(oldnd.path.mnt); 2701 error = mnt_want_write(oldnd.path.mnt);
2688 if (error) 2702 if (error)
2689 goto exit5; 2703 goto exit5;
2704 error = security_path_rename(&oldnd.path, old_dentry,
2705 &newnd.path, new_dentry);
2706 if (error)
2707 goto exit6;
2690 error = vfs_rename(old_dir->d_inode, old_dentry, 2708 error = vfs_rename(old_dir->d_inode, old_dentry,
2691 new_dir->d_inode, new_dentry); 2709 new_dir->d_inode, new_dentry);
2710exit6:
2692 mnt_drop_write(oldnd.path.mnt); 2711 mnt_drop_write(oldnd.path.mnt);
2693exit5: 2712exit5:
2694 dput(new_dentry); 2713 dput(new_dentry);
@@ -2706,7 +2725,7 @@ exit:
2706 return error; 2725 return error;
2707} 2726}
2708 2727
2709asmlinkage long sys_rename(const char __user *oldname, const char __user *newname) 2728SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
2710{ 2729{
2711 return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname); 2730 return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
2712} 2731}
@@ -2758,13 +2777,16 @@ int vfs_follow_link(struct nameidata *nd, const char *link)
2758/* get the link contents into pagecache */ 2777/* get the link contents into pagecache */
2759static char *page_getlink(struct dentry * dentry, struct page **ppage) 2778static char *page_getlink(struct dentry * dentry, struct page **ppage)
2760{ 2779{
2761 struct page * page; 2780 char *kaddr;
2781 struct page *page;
2762 struct address_space *mapping = dentry->d_inode->i_mapping; 2782 struct address_space *mapping = dentry->d_inode->i_mapping;
2763 page = read_mapping_page(mapping, 0, NULL); 2783 page = read_mapping_page(mapping, 0, NULL);
2764 if (IS_ERR(page)) 2784 if (IS_ERR(page))
2765 return (char*)page; 2785 return (char*)page;
2766 *ppage = page; 2786 *ppage = page;
2767 return kmap(page); 2787 kaddr = kmap(page);
2788 nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1);
2789 return kaddr;
2768} 2790}
2769 2791
2770int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) 2792int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
@@ -2796,18 +2818,23 @@ void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
2796 } 2818 }
2797} 2819}
2798 2820
2799int __page_symlink(struct inode *inode, const char *symname, int len, 2821/*
2800 gfp_t gfp_mask) 2822 * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS
2823 */
2824int __page_symlink(struct inode *inode, const char *symname, int len, int nofs)
2801{ 2825{
2802 struct address_space *mapping = inode->i_mapping; 2826 struct address_space *mapping = inode->i_mapping;
2803 struct page *page; 2827 struct page *page;
2804 void *fsdata; 2828 void *fsdata;
2805 int err; 2829 int err;
2806 char *kaddr; 2830 char *kaddr;
2831 unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE;
2832 if (nofs)
2833 flags |= AOP_FLAG_NOFS;
2807 2834
2808retry: 2835retry:
2809 err = pagecache_write_begin(NULL, mapping, 0, len-1, 2836 err = pagecache_write_begin(NULL, mapping, 0, len-1,
2810 AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata); 2837 flags, &page, &fsdata);
2811 if (err) 2838 if (err)
2812 goto fail; 2839 goto fail;
2813 2840
@@ -2831,7 +2858,7 @@ fail:
2831int page_symlink(struct inode *inode, const char *symname, int len) 2858int page_symlink(struct inode *inode, const char *symname, int len)
2832{ 2859{
2833 return __page_symlink(inode, symname, len, 2860 return __page_symlink(inode, symname, len,
2834 mapping_gfp_mask(inode->i_mapping)); 2861 !(mapping_gfp_mask(inode->i_mapping) & __GFP_FS));
2835} 2862}
2836 2863
2837const struct inode_operations page_symlink_inode_operations = { 2864const struct inode_operations page_symlink_inode_operations = {
@@ -2857,7 +2884,6 @@ EXPORT_SYMBOL(path_lookup);
2857EXPORT_SYMBOL(kern_path); 2884EXPORT_SYMBOL(kern_path);
2858EXPORT_SYMBOL(vfs_path_lookup); 2885EXPORT_SYMBOL(vfs_path_lookup);
2859EXPORT_SYMBOL(inode_permission); 2886EXPORT_SYMBOL(inode_permission);
2860EXPORT_SYMBOL(vfs_permission);
2861EXPORT_SYMBOL(file_permission); 2887EXPORT_SYMBOL(file_permission);
2862EXPORT_SYMBOL(unlock_rename); 2888EXPORT_SYMBOL(unlock_rename);
2863EXPORT_SYMBOL(vfs_create); 2889EXPORT_SYMBOL(vfs_create);
@@ -2873,3 +2899,10 @@ EXPORT_SYMBOL(vfs_symlink);
2873EXPORT_SYMBOL(vfs_unlink); 2899EXPORT_SYMBOL(vfs_unlink);
2874EXPORT_SYMBOL(dentry_unhash); 2900EXPORT_SYMBOL(dentry_unhash);
2875EXPORT_SYMBOL(generic_readlink); 2901EXPORT_SYMBOL(generic_readlink);
2902
2903/* to be mentioned only in INIT_TASK */
2904struct fs_struct init_fs = {
2905 .count = ATOMIC_INIT(1),
2906 .lock = __RW_LOCK_UNLOCKED(init_fs.lock),
2907 .umask = 0022,
2908};