diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 160 |
1 files changed, 97 insertions, 63 deletions
diff --git a/fs/namei.c b/fs/namei.c index af3783fff1de..f05bed242422 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 | */ | ||
229 | int inode_permission(struct inode *inode, int mask) | 239 | int inode_permission(struct inode *inode, int mask) |
230 | { | 240 | { |
231 | int retval; | 241 | int retval; |
@@ -247,8 +257,7 @@ 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. */ | 260 | if (inode->i_op->permission) |
251 | 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 |
254 | retval = generic_permission(inode, mask, NULL); | 263 | retval = generic_permission(inode, mask, NULL); |
@@ -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 | */ | ||
277 | int 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 | */ |
294 | int file_permission(struct file *file, int mask) | 288 | int file_permission(struct file *file, int mask) |
295 | { | 289 | { |
@@ -438,7 +432,7 @@ static int exec_permission_lite(struct inode *inode) | |||
438 | { | 432 | { |
439 | umode_t mode = inode->i_mode; | 433 | umode_t mode = inode->i_mode; |
440 | 434 | ||
441 | if (inode->i_op && inode->i_op->permission) | 435 | if (inode->i_op->permission) |
442 | return -EAGAIN; | 436 | return -EAGAIN; |
443 | 437 | ||
444 | if (current_fsuid() == inode->i_uid) | 438 | if (current_fsuid() == inode->i_uid) |
@@ -527,18 +521,6 @@ out_unlock: | |||
527 | return result; | 521 | return result; |
528 | } | 522 | } |
529 | 523 | ||
530 | /* SMP-safe */ | ||
531 | static __always_inline void | ||
532 | walk_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 | ||
@@ -918,9 +908,6 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
918 | inode = next.dentry->d_inode; | 908 | inode = next.dentry->d_inode; |
919 | if (!inode) | 909 | if (!inode) |
920 | goto out_dput; | 910 | goto out_dput; |
921 | err = -ENOTDIR; | ||
922 | if (!inode->i_op) | ||
923 | goto out_dput; | ||
924 | 911 | ||
925 | if (inode->i_op->follow_link) { | 912 | if (inode->i_op->follow_link) { |
926 | err = do_follow_link(&next, nd); | 913 | err = do_follow_link(&next, nd); |
@@ -930,9 +917,6 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
930 | inode = nd->path.dentry->d_inode; | 917 | inode = nd->path.dentry->d_inode; |
931 | if (!inode) | 918 | if (!inode) |
932 | break; | 919 | break; |
933 | err = -ENOTDIR; | ||
934 | if (!inode->i_op) | ||
935 | break; | ||
936 | } else | 920 | } else |
937 | path_to_nameidata(&next, nd); | 921 | path_to_nameidata(&next, nd); |
938 | err = -ENOTDIR; | 922 | err = -ENOTDIR; |
@@ -971,7 +955,7 @@ last_component: | |||
971 | break; | 955 | break; |
972 | inode = next.dentry->d_inode; | 956 | inode = next.dentry->d_inode; |
973 | if ((lookup_flags & LOOKUP_FOLLOW) | 957 | if ((lookup_flags & LOOKUP_FOLLOW) |
974 | && inode && inode->i_op && inode->i_op->follow_link) { | 958 | && inode && inode->i_op->follow_link) { |
975 | err = do_follow_link(&next, nd); | 959 | err = do_follow_link(&next, nd); |
976 | if (err) | 960 | if (err) |
977 | goto return_err; | 961 | goto return_err; |
@@ -983,7 +967,7 @@ last_component: | |||
983 | break; | 967 | break; |
984 | if (lookup_flags & LOOKUP_DIRECTORY) { | 968 | if (lookup_flags & LOOKUP_DIRECTORY) { |
985 | err = -ENOTDIR; | 969 | err = -ENOTDIR; |
986 | if (!inode->i_op || !inode->i_op->lookup) | 970 | if (!inode->i_op->lookup) |
987 | break; | 971 | break; |
988 | } | 972 | } |
989 | goto return_base; | 973 | goto return_base; |
@@ -1479,7 +1463,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1479 | if (error) | 1463 | if (error) |
1480 | return error; | 1464 | return error; |
1481 | 1465 | ||
1482 | if (!dir->i_op || !dir->i_op->create) | 1466 | if (!dir->i_op->create) |
1483 | return -EACCES; /* shouldn't it be ENOSYS? */ | 1467 | return -EACCES; /* shouldn't it be ENOSYS? */ |
1484 | mode &= S_IALLUGO; | 1468 | mode &= S_IALLUGO; |
1485 | mode |= S_IFREG; | 1469 | mode |= S_IFREG; |
@@ -1493,9 +1477,9 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1493 | return error; | 1477 | return error; |
1494 | } | 1478 | } |
1495 | 1479 | ||
1496 | int may_open(struct nameidata *nd, int acc_mode, int flag) | 1480 | int may_open(struct path *path, int acc_mode, int flag) |
1497 | { | 1481 | { |
1498 | struct dentry *dentry = nd->path.dentry; | 1482 | struct dentry *dentry = path->dentry; |
1499 | struct inode *inode = dentry->d_inode; | 1483 | struct inode *inode = dentry->d_inode; |
1500 | int error; | 1484 | int error; |
1501 | 1485 | ||
@@ -1516,13 +1500,13 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1516 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | 1500 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { |
1517 | flag &= ~O_TRUNC; | 1501 | flag &= ~O_TRUNC; |
1518 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { | 1502 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { |
1519 | if (nd->path.mnt->mnt_flags & MNT_NODEV) | 1503 | if (path->mnt->mnt_flags & MNT_NODEV) |
1520 | return -EACCES; | 1504 | return -EACCES; |
1521 | 1505 | ||
1522 | flag &= ~O_TRUNC; | 1506 | flag &= ~O_TRUNC; |
1523 | } | 1507 | } |
1524 | 1508 | ||
1525 | error = vfs_permission(nd, acc_mode); | 1509 | error = inode_permission(inode, acc_mode); |
1526 | if (error) | 1510 | if (error) |
1527 | return error; | 1511 | return error; |
1528 | /* | 1512 | /* |
@@ -1556,6 +1540,9 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
1556 | * Refuse to truncate files with mandatory locks held on them. | 1540 | * Refuse to truncate files with mandatory locks held on them. |
1557 | */ | 1541 | */ |
1558 | error = locks_verify_locked(inode); | 1542 | error = locks_verify_locked(inode); |
1543 | if (!error) | ||
1544 | error = security_path_truncate(path, 0, | ||
1545 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); | ||
1559 | if (!error) { | 1546 | if (!error) { |
1560 | DQUOT_INIT(inode); | 1547 | DQUOT_INIT(inode); |
1561 | 1548 | ||
@@ -1586,14 +1573,18 @@ static int __open_namei_create(struct nameidata *nd, struct path *path, | |||
1586 | 1573 | ||
1587 | if (!IS_POSIXACL(dir->d_inode)) | 1574 | if (!IS_POSIXACL(dir->d_inode)) |
1588 | mode &= ~current->fs->umask; | 1575 | mode &= ~current->fs->umask; |
1576 | error = security_path_mknod(&nd->path, path->dentry, mode, 0); | ||
1577 | if (error) | ||
1578 | goto out_unlock; | ||
1589 | error = vfs_create(dir->d_inode, path->dentry, mode, nd); | 1579 | error = vfs_create(dir->d_inode, path->dentry, mode, nd); |
1580 | out_unlock: | ||
1590 | mutex_unlock(&dir->d_inode->i_mutex); | 1581 | mutex_unlock(&dir->d_inode->i_mutex); |
1591 | dput(nd->path.dentry); | 1582 | dput(nd->path.dentry); |
1592 | nd->path.dentry = path->dentry; | 1583 | nd->path.dentry = path->dentry; |
1593 | if (error) | 1584 | if (error) |
1594 | return error; | 1585 | return error; |
1595 | /* Don't check for write permission, don't truncate */ | 1586 | /* Don't check for write permission, don't truncate */ |
1596 | return may_open(nd, 0, flag & ~O_TRUNC); | 1587 | return may_open(&nd->path, 0, flag & ~O_TRUNC); |
1597 | } | 1588 | } |
1598 | 1589 | ||
1599 | /* | 1590 | /* |
@@ -1755,7 +1746,7 @@ do_last: | |||
1755 | error = -ENOENT; | 1746 | error = -ENOENT; |
1756 | if (!path.dentry->d_inode) | 1747 | if (!path.dentry->d_inode) |
1757 | goto exit_dput; | 1748 | goto exit_dput; |
1758 | if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) | 1749 | if (path.dentry->d_inode->i_op->follow_link) |
1759 | goto do_link; | 1750 | goto do_link; |
1760 | 1751 | ||
1761 | path_to_nameidata(&path, &nd); | 1752 | path_to_nameidata(&path, &nd); |
@@ -1779,7 +1770,7 @@ ok: | |||
1779 | if (error) | 1770 | if (error) |
1780 | goto exit; | 1771 | goto exit; |
1781 | } | 1772 | } |
1782 | error = may_open(&nd, acc_mode, flag); | 1773 | error = may_open(&nd.path, acc_mode, flag); |
1783 | if (error) { | 1774 | if (error) { |
1784 | if (will_write) | 1775 | if (will_write) |
1785 | mnt_drop_write(nd.path.mnt); | 1776 | mnt_drop_write(nd.path.mnt); |
@@ -1936,7 +1927,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1936 | if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) | 1927 | if ((S_ISCHR(mode) || S_ISBLK(mode)) && !capable(CAP_MKNOD)) |
1937 | return -EPERM; | 1928 | return -EPERM; |
1938 | 1929 | ||
1939 | if (!dir->i_op || !dir->i_op->mknod) | 1930 | if (!dir->i_op->mknod) |
1940 | return -EPERM; | 1931 | return -EPERM; |
1941 | 1932 | ||
1942 | error = devcgroup_inode_mknod(mode, dev); | 1933 | error = devcgroup_inode_mknod(mode, dev); |
@@ -1999,6 +1990,9 @@ asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, | |||
1999 | error = mnt_want_write(nd.path.mnt); | 1990 | error = mnt_want_write(nd.path.mnt); |
2000 | if (error) | 1991 | if (error) |
2001 | goto out_dput; | 1992 | goto out_dput; |
1993 | error = security_path_mknod(&nd.path, dentry, mode, dev); | ||
1994 | if (error) | ||
1995 | goto out_drop_write; | ||
2002 | switch (mode & S_IFMT) { | 1996 | switch (mode & S_IFMT) { |
2003 | case 0: case S_IFREG: | 1997 | case 0: case S_IFREG: |
2004 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); | 1998 | error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); |
@@ -2011,6 +2005,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); | 2005 | error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); |
2012 | break; | 2006 | break; |
2013 | } | 2007 | } |
2008 | out_drop_write: | ||
2014 | mnt_drop_write(nd.path.mnt); | 2009 | mnt_drop_write(nd.path.mnt); |
2015 | out_dput: | 2010 | out_dput: |
2016 | dput(dentry); | 2011 | dput(dentry); |
@@ -2034,7 +2029,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
2034 | if (error) | 2029 | if (error) |
2035 | return error; | 2030 | return error; |
2036 | 2031 | ||
2037 | if (!dir->i_op || !dir->i_op->mkdir) | 2032 | if (!dir->i_op->mkdir) |
2038 | return -EPERM; | 2033 | return -EPERM; |
2039 | 2034 | ||
2040 | mode &= (S_IRWXUGO|S_ISVTX); | 2035 | mode &= (S_IRWXUGO|S_ISVTX); |
@@ -2070,7 +2065,11 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode) | |||
2070 | error = mnt_want_write(nd.path.mnt); | 2065 | error = mnt_want_write(nd.path.mnt); |
2071 | if (error) | 2066 | if (error) |
2072 | goto out_dput; | 2067 | goto out_dput; |
2068 | error = security_path_mkdir(&nd.path, dentry, mode); | ||
2069 | if (error) | ||
2070 | goto out_drop_write; | ||
2073 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); | 2071 | error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); |
2072 | out_drop_write: | ||
2074 | mnt_drop_write(nd.path.mnt); | 2073 | mnt_drop_write(nd.path.mnt); |
2075 | out_dput: | 2074 | out_dput: |
2076 | dput(dentry); | 2075 | dput(dentry); |
@@ -2121,7 +2120,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2121 | if (error) | 2120 | if (error) |
2122 | return error; | 2121 | return error; |
2123 | 2122 | ||
2124 | if (!dir->i_op || !dir->i_op->rmdir) | 2123 | if (!dir->i_op->rmdir) |
2125 | return -EPERM; | 2124 | return -EPERM; |
2126 | 2125 | ||
2127 | DQUOT_INIT(dir); | 2126 | DQUOT_INIT(dir); |
@@ -2180,7 +2179,11 @@ static long do_rmdir(int dfd, const char __user *pathname) | |||
2180 | error = mnt_want_write(nd.path.mnt); | 2179 | error = mnt_want_write(nd.path.mnt); |
2181 | if (error) | 2180 | if (error) |
2182 | goto exit3; | 2181 | goto exit3; |
2182 | error = security_path_rmdir(&nd.path, dentry); | ||
2183 | if (error) | ||
2184 | goto exit4; | ||
2183 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); | 2185 | error = vfs_rmdir(nd.path.dentry->d_inode, dentry); |
2186 | exit4: | ||
2184 | mnt_drop_write(nd.path.mnt); | 2187 | mnt_drop_write(nd.path.mnt); |
2185 | exit3: | 2188 | exit3: |
2186 | dput(dentry); | 2189 | dput(dentry); |
@@ -2204,7 +2207,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2204 | if (error) | 2207 | if (error) |
2205 | return error; | 2208 | return error; |
2206 | 2209 | ||
2207 | if (!dir->i_op || !dir->i_op->unlink) | 2210 | if (!dir->i_op->unlink) |
2208 | return -EPERM; | 2211 | return -EPERM; |
2209 | 2212 | ||
2210 | DQUOT_INIT(dir); | 2213 | DQUOT_INIT(dir); |
@@ -2265,7 +2268,11 @@ static long do_unlinkat(int dfd, const char __user *pathname) | |||
2265 | error = mnt_want_write(nd.path.mnt); | 2268 | error = mnt_want_write(nd.path.mnt); |
2266 | if (error) | 2269 | if (error) |
2267 | goto exit2; | 2270 | goto exit2; |
2271 | error = security_path_unlink(&nd.path, dentry); | ||
2272 | if (error) | ||
2273 | goto exit3; | ||
2268 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); | 2274 | error = vfs_unlink(nd.path.dentry->d_inode, dentry); |
2275 | exit3: | ||
2269 | mnt_drop_write(nd.path.mnt); | 2276 | mnt_drop_write(nd.path.mnt); |
2270 | exit2: | 2277 | exit2: |
2271 | dput(dentry); | 2278 | dput(dentry); |
@@ -2307,7 +2314,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) | |||
2307 | if (error) | 2314 | if (error) |
2308 | return error; | 2315 | return error; |
2309 | 2316 | ||
2310 | if (!dir->i_op || !dir->i_op->symlink) | 2317 | if (!dir->i_op->symlink) |
2311 | return -EPERM; | 2318 | return -EPERM; |
2312 | 2319 | ||
2313 | error = security_inode_symlink(dir, dentry, oldname); | 2320 | error = security_inode_symlink(dir, dentry, oldname); |
@@ -2346,7 +2353,11 @@ asmlinkage long sys_symlinkat(const char __user *oldname, | |||
2346 | error = mnt_want_write(nd.path.mnt); | 2353 | error = mnt_want_write(nd.path.mnt); |
2347 | if (error) | 2354 | if (error) |
2348 | goto out_dput; | 2355 | goto out_dput; |
2356 | error = security_path_symlink(&nd.path, dentry, from); | ||
2357 | if (error) | ||
2358 | goto out_drop_write; | ||
2349 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); | 2359 | error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); |
2360 | out_drop_write: | ||
2350 | mnt_drop_write(nd.path.mnt); | 2361 | mnt_drop_write(nd.path.mnt); |
2351 | out_dput: | 2362 | out_dput: |
2352 | dput(dentry); | 2363 | dput(dentry); |
@@ -2384,7 +2395,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2384 | */ | 2395 | */ |
2385 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 2396 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
2386 | return -EPERM; | 2397 | return -EPERM; |
2387 | if (!dir->i_op || !dir->i_op->link) | 2398 | if (!dir->i_op->link) |
2388 | return -EPERM; | 2399 | return -EPERM; |
2389 | if (S_ISDIR(inode->i_mode)) | 2400 | if (S_ISDIR(inode->i_mode)) |
2390 | return -EPERM; | 2401 | return -EPERM; |
@@ -2443,7 +2454,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname, | |||
2443 | error = mnt_want_write(nd.path.mnt); | 2454 | error = mnt_want_write(nd.path.mnt); |
2444 | if (error) | 2455 | if (error) |
2445 | goto out_dput; | 2456 | goto out_dput; |
2457 | error = security_path_link(old_path.dentry, &nd.path, new_dentry); | ||
2458 | if (error) | ||
2459 | goto out_drop_write; | ||
2446 | error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); | 2460 | error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); |
2461 | out_drop_write: | ||
2447 | mnt_drop_write(nd.path.mnt); | 2462 | mnt_drop_write(nd.path.mnt); |
2448 | out_dput: | 2463 | out_dput: |
2449 | dput(new_dentry); | 2464 | dput(new_dentry); |
@@ -2587,7 +2602,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2587 | if (error) | 2602 | if (error) |
2588 | return error; | 2603 | return error; |
2589 | 2604 | ||
2590 | if (!old_dir->i_op || !old_dir->i_op->rename) | 2605 | if (!old_dir->i_op->rename) |
2591 | return -EPERM; | 2606 | return -EPERM; |
2592 | 2607 | ||
2593 | DQUOT_INIT(old_dir); | 2608 | DQUOT_INIT(old_dir); |
@@ -2679,8 +2694,13 @@ asmlinkage long sys_renameat(int olddfd, const char __user *oldname, | |||
2679 | error = mnt_want_write(oldnd.path.mnt); | 2694 | error = mnt_want_write(oldnd.path.mnt); |
2680 | if (error) | 2695 | if (error) |
2681 | goto exit5; | 2696 | goto exit5; |
2697 | error = security_path_rename(&oldnd.path, old_dentry, | ||
2698 | &newnd.path, new_dentry); | ||
2699 | if (error) | ||
2700 | goto exit6; | ||
2682 | error = vfs_rename(old_dir->d_inode, old_dentry, | 2701 | error = vfs_rename(old_dir->d_inode, old_dentry, |
2683 | new_dir->d_inode, new_dentry); | 2702 | new_dir->d_inode, new_dentry); |
2703 | exit6: | ||
2684 | mnt_drop_write(oldnd.path.mnt); | 2704 | mnt_drop_write(oldnd.path.mnt); |
2685 | exit5: | 2705 | exit5: |
2686 | dput(new_dentry); | 2706 | dput(new_dentry); |
@@ -2750,13 +2770,16 @@ int vfs_follow_link(struct nameidata *nd, const char *link) | |||
2750 | /* get the link contents into pagecache */ | 2770 | /* get the link contents into pagecache */ |
2751 | static char *page_getlink(struct dentry * dentry, struct page **ppage) | 2771 | static char *page_getlink(struct dentry * dentry, struct page **ppage) |
2752 | { | 2772 | { |
2753 | struct page * page; | 2773 | char *kaddr; |
2774 | struct page *page; | ||
2754 | struct address_space *mapping = dentry->d_inode->i_mapping; | 2775 | struct address_space *mapping = dentry->d_inode->i_mapping; |
2755 | page = read_mapping_page(mapping, 0, NULL); | 2776 | page = read_mapping_page(mapping, 0, NULL); |
2756 | if (IS_ERR(page)) | 2777 | if (IS_ERR(page)) |
2757 | return (char*)page; | 2778 | return (char*)page; |
2758 | *ppage = page; | 2779 | *ppage = page; |
2759 | return kmap(page); | 2780 | kaddr = kmap(page); |
2781 | nd_terminate_link(kaddr, dentry->d_inode->i_size, PAGE_SIZE - 1); | ||
2782 | return kaddr; | ||
2760 | } | 2783 | } |
2761 | 2784 | ||
2762 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 2785 | int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) |
@@ -2788,18 +2811,23 @@ void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) | |||
2788 | } | 2811 | } |
2789 | } | 2812 | } |
2790 | 2813 | ||
2791 | int __page_symlink(struct inode *inode, const char *symname, int len, | 2814 | /* |
2792 | gfp_t gfp_mask) | 2815 | * The nofs argument instructs pagecache_write_begin to pass AOP_FLAG_NOFS |
2816 | */ | ||
2817 | int __page_symlink(struct inode *inode, const char *symname, int len, int nofs) | ||
2793 | { | 2818 | { |
2794 | struct address_space *mapping = inode->i_mapping; | 2819 | struct address_space *mapping = inode->i_mapping; |
2795 | struct page *page; | 2820 | struct page *page; |
2796 | void *fsdata; | 2821 | void *fsdata; |
2797 | int err; | 2822 | int err; |
2798 | char *kaddr; | 2823 | char *kaddr; |
2824 | unsigned int flags = AOP_FLAG_UNINTERRUPTIBLE; | ||
2825 | if (nofs) | ||
2826 | flags |= AOP_FLAG_NOFS; | ||
2799 | 2827 | ||
2800 | retry: | 2828 | retry: |
2801 | err = pagecache_write_begin(NULL, mapping, 0, len-1, | 2829 | err = pagecache_write_begin(NULL, mapping, 0, len-1, |
2802 | AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata); | 2830 | flags, &page, &fsdata); |
2803 | if (err) | 2831 | if (err) |
2804 | goto fail; | 2832 | goto fail; |
2805 | 2833 | ||
@@ -2823,7 +2851,7 @@ fail: | |||
2823 | int page_symlink(struct inode *inode, const char *symname, int len) | 2851 | int page_symlink(struct inode *inode, const char *symname, int len) |
2824 | { | 2852 | { |
2825 | return __page_symlink(inode, symname, len, | 2853 | return __page_symlink(inode, symname, len, |
2826 | mapping_gfp_mask(inode->i_mapping)); | 2854 | !(mapping_gfp_mask(inode->i_mapping) & __GFP_FS)); |
2827 | } | 2855 | } |
2828 | 2856 | ||
2829 | const struct inode_operations page_symlink_inode_operations = { | 2857 | const struct inode_operations page_symlink_inode_operations = { |
@@ -2849,7 +2877,6 @@ EXPORT_SYMBOL(path_lookup); | |||
2849 | EXPORT_SYMBOL(kern_path); | 2877 | EXPORT_SYMBOL(kern_path); |
2850 | EXPORT_SYMBOL(vfs_path_lookup); | 2878 | EXPORT_SYMBOL(vfs_path_lookup); |
2851 | EXPORT_SYMBOL(inode_permission); | 2879 | EXPORT_SYMBOL(inode_permission); |
2852 | EXPORT_SYMBOL(vfs_permission); | ||
2853 | EXPORT_SYMBOL(file_permission); | 2880 | EXPORT_SYMBOL(file_permission); |
2854 | EXPORT_SYMBOL(unlock_rename); | 2881 | EXPORT_SYMBOL(unlock_rename); |
2855 | EXPORT_SYMBOL(vfs_create); | 2882 | EXPORT_SYMBOL(vfs_create); |
@@ -2865,3 +2892,10 @@ EXPORT_SYMBOL(vfs_symlink); | |||
2865 | EXPORT_SYMBOL(vfs_unlink); | 2892 | EXPORT_SYMBOL(vfs_unlink); |
2866 | EXPORT_SYMBOL(dentry_unhash); | 2893 | EXPORT_SYMBOL(dentry_unhash); |
2867 | EXPORT_SYMBOL(generic_readlink); | 2894 | EXPORT_SYMBOL(generic_readlink); |
2895 | |||
2896 | /* to be mentioned only in INIT_TASK */ | ||
2897 | struct fs_struct init_fs = { | ||
2898 | .count = ATOMIC_INIT(1), | ||
2899 | .lock = __RW_LOCK_UNLOCKED(init_fs.lock), | ||
2900 | .umask = 0022, | ||
2901 | }; | ||