diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-17 09:19:08 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-26 20:53:21 -0400 |
commit | a110343f0d6d41f68b7cf8c00b57a3172c67f816 (patch) | |
tree | 04f57e3454e796765a7395d2ece4739cf536ae9f | |
parent | 7f2da1e7d0330395e5e9e350b879b98a1ea495df (diff) |
[PATCH] fix MAY_CHDIR/MAY_ACCESS/LOOKUP_ACCESS mess
* MAY_CHDIR is redundant - it's an equivalent of MAY_ACCESS
* MAY_ACCESS on fuse should affect only the last step of pathname resolution
* fchdir() and chroot() should pass MAY_ACCESS, for the same reason why
chdir() needs that.
* now that we pass MAY_ACCESS explicitly in all cases, LOOKUP_ACCESS can be
removed; it has no business being in nameidata.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/fuse/dir.c | 2 | ||||
-rw-r--r-- | fs/namei.c | 2 | ||||
-rw-r--r-- | fs/open.c | 10 | ||||
-rw-r--r-- | include/linux/fs.h | 3 | ||||
-rw-r--r-- | include/linux/namei.h | 1 |
5 files changed, 7 insertions, 11 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 48a7934cb950..fd03330cadeb 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask) | |||
962 | exist. So if permissions are revoked this won't be | 962 | exist. So if permissions are revoked this won't be |
963 | noticed immediately, only after the attribute | 963 | noticed immediately, only after the attribute |
964 | timeout has expired */ | 964 | timeout has expired */ |
965 | } else if (mask & (MAY_ACCESS | MAY_CHDIR)) { | 965 | } else if (mask & MAY_ACCESS) { |
966 | err = fuse_access(inode, mask); | 966 | err = fuse_access(inode, mask); |
967 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { | 967 | } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { |
968 | if (!(inode->i_mode & S_IXUGO)) { | 968 | if (!(inode->i_mode & S_IXUGO)) { |
diff --git a/fs/namei.c b/fs/namei.c index 095818089ac1..33dcaf025c49 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -265,8 +265,6 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) | |||
265 | if (inode->i_op && inode->i_op->permission) { | 265 | if (inode->i_op && inode->i_op->permission) { |
266 | int extra = 0; | 266 | int extra = 0; |
267 | if (nd) { | 267 | if (nd) { |
268 | if (nd->flags & LOOKUP_ACCESS) | ||
269 | extra |= MAY_ACCESS; | ||
270 | if (nd->flags & LOOKUP_OPEN) | 268 | if (nd->flags & LOOKUP_OPEN) |
271 | extra |= MAY_OPEN; | 269 | extra |= MAY_OPEN; |
272 | } | 270 | } |
@@ -457,11 +457,11 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) | |||
457 | old_cap = cap_set_effective(current->cap_permitted); | 457 | old_cap = cap_set_effective(current->cap_permitted); |
458 | } | 458 | } |
459 | 459 | ||
460 | res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); | 460 | res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); |
461 | if (res) | 461 | if (res) |
462 | goto out; | 462 | goto out; |
463 | 463 | ||
464 | res = vfs_permission(&nd, mode); | 464 | res = vfs_permission(&nd, mode | MAY_ACCESS); |
465 | /* SuS v2 requires we report a read only fs too */ | 465 | /* SuS v2 requires we report a read only fs too */ |
466 | if(res || !(mode & S_IWOTH) || | 466 | if(res || !(mode & S_IWOTH) || |
467 | special_file(nd.path.dentry->d_inode->i_mode)) | 467 | special_file(nd.path.dentry->d_inode->i_mode)) |
@@ -505,7 +505,7 @@ asmlinkage long sys_chdir(const char __user * filename) | |||
505 | if (error) | 505 | if (error) |
506 | goto out; | 506 | goto out; |
507 | 507 | ||
508 | error = vfs_permission(&nd, MAY_EXEC | MAY_CHDIR); | 508 | error = vfs_permission(&nd, MAY_EXEC | MAY_ACCESS); |
509 | if (error) | 509 | if (error) |
510 | goto dput_and_out; | 510 | goto dput_and_out; |
511 | 511 | ||
@@ -534,7 +534,7 @@ asmlinkage long sys_fchdir(unsigned int fd) | |||
534 | if (!S_ISDIR(inode->i_mode)) | 534 | if (!S_ISDIR(inode->i_mode)) |
535 | goto out_putf; | 535 | goto out_putf; |
536 | 536 | ||
537 | error = file_permission(file, MAY_EXEC); | 537 | error = file_permission(file, MAY_EXEC | MAY_ACCESS); |
538 | if (!error) | 538 | if (!error) |
539 | set_fs_pwd(current->fs, &file->f_path); | 539 | set_fs_pwd(current->fs, &file->f_path); |
540 | out_putf: | 540 | out_putf: |
@@ -552,7 +552,7 @@ asmlinkage long sys_chroot(const char __user * filename) | |||
552 | if (error) | 552 | if (error) |
553 | goto out; | 553 | goto out; |
554 | 554 | ||
555 | error = vfs_permission(&nd, MAY_EXEC); | 555 | error = vfs_permission(&nd, MAY_EXEC | MAY_ACCESS); |
556 | if (error) | 556 | if (error) |
557 | goto dput_and_out; | 557 | goto dput_and_out; |
558 | 558 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 25998e803fc2..d8721e818b45 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -61,8 +61,7 @@ extern int dir_notify_enable; | |||
61 | #define MAY_READ 4 | 61 | #define MAY_READ 4 |
62 | #define MAY_APPEND 8 | 62 | #define MAY_APPEND 8 |
63 | #define MAY_ACCESS 16 | 63 | #define MAY_ACCESS 16 |
64 | #define MAY_CHDIR 32 | 64 | #define MAY_OPEN 32 |
65 | #define MAY_OPEN 64 | ||
66 | 65 | ||
67 | #define FMODE_READ 1 | 66 | #define FMODE_READ 1 |
68 | #define FMODE_WRITE 2 | 67 | #define FMODE_WRITE 2 |
diff --git a/include/linux/namei.h b/include/linux/namei.h index 768773d57857..60e35a02f6cb 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h | |||
@@ -53,7 +53,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; | |||
53 | */ | 53 | */ |
54 | #define LOOKUP_OPEN (0x0100) | 54 | #define LOOKUP_OPEN (0x0100) |
55 | #define LOOKUP_CREATE (0x0200) | 55 | #define LOOKUP_CREATE (0x0200) |
56 | #define LOOKUP_ACCESS (0x0400) | ||
57 | 56 | ||
58 | extern int __user_walk(const char __user *, unsigned, struct nameidata *); | 57 | extern int __user_walk(const char __user *, unsigned, struct nameidata *); |
59 | extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *); | 58 | extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *); |