[PATCH] fix MAY_CHDIR/MAY_ACCESS/LOOKUP_ACCESS mess
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 17 Jul 2008 13:19:08 +0000 (09:19 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sun, 27 Jul 2008 00:53:21 +0000 (20:53 -0400)
* 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>
fs/fuse/dir.c
fs/namei.c
fs/open.c
include/linux/fs.h
include/linux/namei.h

index 48a7934..fd03330 100644 (file)
@@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask)
                   exist.  So if permissions are revoked this won't be
                   noticed immediately, only after the attribute
                   timeout has expired */
-       } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
+       } else if (mask & MAY_ACCESS) {
                err = fuse_access(inode, mask);
        } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
                if (!(inode->i_mode & S_IXUGO)) {
index 0958180..33dcaf0 100644 (file)
@@ -265,8 +265,6 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
        if (inode->i_op && inode->i_op->permission) {
                int extra = 0;
                if (nd) {
-                       if (nd->flags & LOOKUP_ACCESS)
-                               extra |= MAY_ACCESS;
                        if (nd->flags & LOOKUP_OPEN)
                                extra |= MAY_OPEN;
                }
index d3a2a00..3317e19 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -457,11 +457,11 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
                        old_cap = cap_set_effective(current->cap_permitted);
        }
 
-       res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
+       res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd);
        if (res)
                goto out;
 
-       res = vfs_permission(&nd, mode);
+       res = vfs_permission(&nd, mode | MAY_ACCESS);
        /* SuS v2 requires we report a read only fs too */
        if(res || !(mode & S_IWOTH) ||
           special_file(nd.path.dentry->d_inode->i_mode))
@@ -505,7 +505,7 @@ asmlinkage long sys_chdir(const char __user * filename)
        if (error)
                goto out;
 
-       error = vfs_permission(&nd, MAY_EXEC | MAY_CHDIR);
+       error = vfs_permission(&nd, MAY_EXEC | MAY_ACCESS);
        if (error)
                goto dput_and_out;
 
@@ -534,7 +534,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
        if (!S_ISDIR(inode->i_mode))
                goto out_putf;
 
-       error = file_permission(file, MAY_EXEC);
+       error = file_permission(file, MAY_EXEC | MAY_ACCESS);
        if (!error)
                set_fs_pwd(current->fs, &file->f_path);
 out_putf:
@@ -552,7 +552,7 @@ asmlinkage long sys_chroot(const char __user * filename)
        if (error)
                goto out;
 
-       error = vfs_permission(&nd, MAY_EXEC);
+       error = vfs_permission(&nd, MAY_EXEC | MAY_ACCESS);
        if (error)
                goto dput_and_out;
 
index 25998e8..d8721e8 100644 (file)
@@ -61,8 +61,7 @@ extern int dir_notify_enable;
 #define MAY_READ 4
 #define MAY_APPEND 8
 #define MAY_ACCESS 16
-#define MAY_CHDIR 32
-#define MAY_OPEN 64
+#define MAY_OPEN 32
 
 #define FMODE_READ 1
 #define FMODE_WRITE 2
index 768773d..60e35a0 100644 (file)
@@ -53,7 +53,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
  */
 #define LOOKUP_OPEN            (0x0100)
 #define LOOKUP_CREATE          (0x0200)
-#define LOOKUP_ACCESS          (0x0400)
 
 extern int __user_walk(const char __user *, unsigned, struct nameidata *);
 extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *);