aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2008-07-17 09:19:08 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-07-26 20:53:21 -0400
commita110343f0d6d41f68b7cf8c00b57a3172c67f816 (patch)
tree04f57e3454e796765a7395d2ece4739cf536ae9f
parent7f2da1e7d0330395e5e9e350b879b98a1ea495df (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.c2
-rw-r--r--fs/namei.c2
-rw-r--r--fs/open.c10
-rw-r--r--include/linux/fs.h3
-rw-r--r--include/linux/namei.h1
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 }
diff --git a/fs/open.c b/fs/open.c
index d3a2a00f52dc..3317e1909b2c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -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);
540out_putf: 540out_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
58extern int __user_walk(const char __user *, unsigned, struct nameidata *); 57extern int __user_walk(const char __user *, unsigned, struct nameidata *);
59extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *); 58extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *);