diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 70 |
1 files changed, 35 insertions, 35 deletions
diff --git a/fs/namei.c b/fs/namei.c index bbc15c237558..b8433ebfae05 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/fsnotify.h> | 24 | #include <linux/fsnotify.h> |
25 | #include <linux/personality.h> | 25 | #include <linux/personality.h> |
26 | #include <linux/security.h> | 26 | #include <linux/security.h> |
27 | #include <linux/ima.h> | ||
27 | #include <linux/syscalls.h> | 28 | #include <linux/syscalls.h> |
28 | #include <linux/mount.h> | 29 | #include <linux/mount.h> |
29 | #include <linux/audit.h> | 30 | #include <linux/audit.h> |
@@ -31,6 +32,7 @@ | |||
31 | #include <linux/file.h> | 32 | #include <linux/file.h> |
32 | #include <linux/fcntl.h> | 33 | #include <linux/fcntl.h> |
33 | #include <linux/device_cgroup.h> | 34 | #include <linux/device_cgroup.h> |
35 | #include <linux/fs_struct.h> | ||
34 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
35 | 37 | ||
36 | #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) | 38 | #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) |
@@ -850,6 +852,8 @@ static int __link_path_walk(const char *name, struct nameidata *nd) | |||
850 | if (err == -EAGAIN) | 852 | if (err == -EAGAIN) |
851 | err = inode_permission(nd->path.dentry->d_inode, | 853 | err = inode_permission(nd->path.dentry->d_inode, |
852 | MAY_EXEC); | 854 | MAY_EXEC); |
855 | if (!err) | ||
856 | err = ima_path_check(&nd->path, MAY_EXEC); | ||
853 | if (err) | 857 | if (err) |
854 | break; | 858 | break; |
855 | 859 | ||
@@ -1470,7 +1474,7 @@ int vfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
1470 | error = security_inode_create(dir, dentry, mode); | 1474 | error = security_inode_create(dir, dentry, mode); |
1471 | if (error) | 1475 | if (error) |
1472 | return error; | 1476 | return error; |
1473 | DQUOT_INIT(dir); | 1477 | vfs_dq_init(dir); |
1474 | error = dir->i_op->create(dir, dentry, mode, nd); | 1478 | error = dir->i_op->create(dir, dentry, mode, nd); |
1475 | if (!error) | 1479 | if (!error) |
1476 | fsnotify_create(dir, dentry); | 1480 | fsnotify_create(dir, dentry); |
@@ -1486,29 +1490,32 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1486 | if (!inode) | 1490 | if (!inode) |
1487 | return -ENOENT; | 1491 | return -ENOENT; |
1488 | 1492 | ||
1489 | if (S_ISLNK(inode->i_mode)) | 1493 | switch (inode->i_mode & S_IFMT) { |
1494 | case S_IFLNK: | ||
1490 | return -ELOOP; | 1495 | return -ELOOP; |
1491 | 1496 | case S_IFDIR: | |
1492 | if (S_ISDIR(inode->i_mode) && (acc_mode & MAY_WRITE)) | 1497 | if (acc_mode & MAY_WRITE) |
1493 | return -EISDIR; | 1498 | return -EISDIR; |
1494 | 1499 | break; | |
1495 | /* | 1500 | case S_IFBLK: |
1496 | * FIFO's, sockets and device files are special: they don't | 1501 | case S_IFCHR: |
1497 | * actually live on the filesystem itself, and as such you | ||
1498 | * can write to them even if the filesystem is read-only. | ||
1499 | */ | ||
1500 | if (S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { | ||
1501 | flag &= ~O_TRUNC; | ||
1502 | } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { | ||
1503 | if (path->mnt->mnt_flags & MNT_NODEV) | 1502 | if (path->mnt->mnt_flags & MNT_NODEV) |
1504 | return -EACCES; | 1503 | return -EACCES; |
1505 | 1504 | /*FALLTHRU*/ | |
1505 | case S_IFIFO: | ||
1506 | case S_IFSOCK: | ||
1506 | flag &= ~O_TRUNC; | 1507 | flag &= ~O_TRUNC; |
1508 | break; | ||
1507 | } | 1509 | } |
1508 | 1510 | ||
1509 | error = inode_permission(inode, acc_mode); | 1511 | error = inode_permission(inode, acc_mode); |
1510 | if (error) | 1512 | if (error) |
1511 | return error; | 1513 | return error; |
1514 | |||
1515 | error = ima_path_check(path, | ||
1516 | acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); | ||
1517 | if (error) | ||
1518 | return error; | ||
1512 | /* | 1519 | /* |
1513 | * An append-only file must be opened in append mode for writing. | 1520 | * An append-only file must be opened in append mode for writing. |
1514 | */ | 1521 | */ |
@@ -1544,7 +1551,7 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1544 | error = security_path_truncate(path, 0, | 1551 | error = security_path_truncate(path, 0, |
1545 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); | 1552 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN); |
1546 | if (!error) { | 1553 | if (!error) { |
1547 | DQUOT_INIT(inode); | 1554 | vfs_dq_init(inode); |
1548 | 1555 | ||
1549 | error = do_truncate(dentry, 0, | 1556 | error = do_truncate(dentry, 0, |
1550 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, | 1557 | ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, |
@@ -1555,7 +1562,7 @@ int may_open(struct path *path, int acc_mode, int flag) | |||
1555 | return error; | 1562 | return error; |
1556 | } else | 1563 | } else |
1557 | if (flag & FMODE_WRITE) | 1564 | if (flag & FMODE_WRITE) |
1558 | DQUOT_INIT(inode); | 1565 | vfs_dq_init(inode); |
1559 | 1566 | ||
1560 | return 0; | 1567 | return 0; |
1561 | } | 1568 | } |
@@ -1572,7 +1579,7 @@ static int __open_namei_create(struct nameidata *nd, struct path *path, | |||
1572 | struct dentry *dir = nd->path.dentry; | 1579 | struct dentry *dir = nd->path.dentry; |
1573 | 1580 | ||
1574 | if (!IS_POSIXACL(dir->d_inode)) | 1581 | if (!IS_POSIXACL(dir->d_inode)) |
1575 | mode &= ~current->fs->umask; | 1582 | mode &= ~current_umask(); |
1576 | error = security_path_mknod(&nd->path, path->dentry, mode, 0); | 1583 | error = security_path_mknod(&nd->path, path->dentry, mode, 0); |
1577 | if (error) | 1584 | if (error) |
1578 | goto out_unlock; | 1585 | goto out_unlock; |
@@ -1938,7 +1945,7 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
1938 | if (error) | 1945 | if (error) |
1939 | return error; | 1946 | return error; |
1940 | 1947 | ||
1941 | DQUOT_INIT(dir); | 1948 | vfs_dq_init(dir); |
1942 | error = dir->i_op->mknod(dir, dentry, mode, dev); | 1949 | error = dir->i_op->mknod(dir, dentry, mode, dev); |
1943 | if (!error) | 1950 | if (!error) |
1944 | fsnotify_create(dir, dentry); | 1951 | fsnotify_create(dir, dentry); |
@@ -1983,7 +1990,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, | |||
1983 | goto out_unlock; | 1990 | goto out_unlock; |
1984 | } | 1991 | } |
1985 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 1992 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
1986 | mode &= ~current->fs->umask; | 1993 | mode &= ~current_umask(); |
1987 | error = may_mknod(mode); | 1994 | error = may_mknod(mode); |
1988 | if (error) | 1995 | if (error) |
1989 | goto out_dput; | 1996 | goto out_dput; |
@@ -2037,7 +2044,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
2037 | if (error) | 2044 | if (error) |
2038 | return error; | 2045 | return error; |
2039 | 2046 | ||
2040 | DQUOT_INIT(dir); | 2047 | vfs_dq_init(dir); |
2041 | error = dir->i_op->mkdir(dir, dentry, mode); | 2048 | error = dir->i_op->mkdir(dir, dentry, mode); |
2042 | if (!error) | 2049 | if (!error) |
2043 | fsnotify_mkdir(dir, dentry); | 2050 | fsnotify_mkdir(dir, dentry); |
@@ -2061,7 +2068,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) | |||
2061 | goto out_unlock; | 2068 | goto out_unlock; |
2062 | 2069 | ||
2063 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 2070 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
2064 | mode &= ~current->fs->umask; | 2071 | mode &= ~current_umask(); |
2065 | error = mnt_want_write(nd.path.mnt); | 2072 | error = mnt_want_write(nd.path.mnt); |
2066 | if (error) | 2073 | if (error) |
2067 | goto out_dput; | 2074 | goto out_dput; |
@@ -2123,7 +2130,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2123 | if (!dir->i_op->rmdir) | 2130 | if (!dir->i_op->rmdir) |
2124 | return -EPERM; | 2131 | return -EPERM; |
2125 | 2132 | ||
2126 | DQUOT_INIT(dir); | 2133 | vfs_dq_init(dir); |
2127 | 2134 | ||
2128 | mutex_lock(&dentry->d_inode->i_mutex); | 2135 | mutex_lock(&dentry->d_inode->i_mutex); |
2129 | dentry_unhash(dentry); | 2136 | dentry_unhash(dentry); |
@@ -2210,7 +2217,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2210 | if (!dir->i_op->unlink) | 2217 | if (!dir->i_op->unlink) |
2211 | return -EPERM; | 2218 | return -EPERM; |
2212 | 2219 | ||
2213 | DQUOT_INIT(dir); | 2220 | vfs_dq_init(dir); |
2214 | 2221 | ||
2215 | mutex_lock(&dentry->d_inode->i_mutex); | 2222 | mutex_lock(&dentry->d_inode->i_mutex); |
2216 | if (d_mountpoint(dentry)) | 2223 | if (d_mountpoint(dentry)) |
@@ -2321,7 +2328,7 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) | |||
2321 | if (error) | 2328 | if (error) |
2322 | return error; | 2329 | return error; |
2323 | 2330 | ||
2324 | DQUOT_INIT(dir); | 2331 | vfs_dq_init(dir); |
2325 | error = dir->i_op->symlink(dir, dentry, oldname); | 2332 | error = dir->i_op->symlink(dir, dentry, oldname); |
2326 | if (!error) | 2333 | if (!error) |
2327 | fsnotify_create(dir, dentry); | 2334 | fsnotify_create(dir, dentry); |
@@ -2405,7 +2412,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2405 | return error; | 2412 | return error; |
2406 | 2413 | ||
2407 | mutex_lock(&inode->i_mutex); | 2414 | mutex_lock(&inode->i_mutex); |
2408 | DQUOT_INIT(dir); | 2415 | vfs_dq_init(dir); |
2409 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2416 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
2410 | mutex_unlock(&inode->i_mutex); | 2417 | mutex_unlock(&inode->i_mutex); |
2411 | if (!error) | 2418 | if (!error) |
@@ -2604,8 +2611,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2604 | if (!old_dir->i_op->rename) | 2611 | if (!old_dir->i_op->rename) |
2605 | return -EPERM; | 2612 | return -EPERM; |
2606 | 2613 | ||
2607 | DQUOT_INIT(old_dir); | 2614 | vfs_dq_init(old_dir); |
2608 | DQUOT_INIT(new_dir); | 2615 | vfs_dq_init(new_dir); |
2609 | 2616 | ||
2610 | old_name = fsnotify_oldname_init(old_dentry->d_name.name); | 2617 | old_name = fsnotify_oldname_init(old_dentry->d_name.name); |
2611 | 2618 | ||
@@ -2891,10 +2898,3 @@ EXPORT_SYMBOL(vfs_symlink); | |||
2891 | EXPORT_SYMBOL(vfs_unlink); | 2898 | EXPORT_SYMBOL(vfs_unlink); |
2892 | EXPORT_SYMBOL(dentry_unhash); | 2899 | EXPORT_SYMBOL(dentry_unhash); |
2893 | EXPORT_SYMBOL(generic_readlink); | 2900 | EXPORT_SYMBOL(generic_readlink); |
2894 | |||
2895 | /* to be mentioned only in INIT_TASK */ | ||
2896 | struct fs_struct init_fs = { | ||
2897 | .count = ATOMIC_INIT(1), | ||
2898 | .lock = __RW_LOCK_UNLOCKED(init_fs.lock), | ||
2899 | .umask = 0022, | ||
2900 | }; | ||