Commit a110343f authored by Al Viro's avatar Al Viro

[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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 7f2da1e7
...@@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask) ...@@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask)
exist. So if permissions are revoked this won't be exist. So if permissions are revoked this won't be
noticed immediately, only after the attribute noticed immediately, only after the attribute
timeout has expired */ timeout has expired */
} else if (mask & (MAY_ACCESS | MAY_CHDIR)) { } else if (mask & MAY_ACCESS) {
err = fuse_access(inode, mask); err = fuse_access(inode, mask);
} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
if (!(inode->i_mode & S_IXUGO)) { if (!(inode->i_mode & S_IXUGO)) {
......
...@@ -265,8 +265,6 @@ int permission(struct inode *inode, int mask, struct nameidata *nd) ...@@ -265,8 +265,6 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
if (inode->i_op && inode->i_op->permission) { if (inode->i_op && inode->i_op->permission) {
int extra = 0; int extra = 0;
if (nd) { if (nd) {
if (nd->flags & LOOKUP_ACCESS)
extra |= MAY_ACCESS;
if (nd->flags & LOOKUP_OPEN) if (nd->flags & LOOKUP_OPEN)
extra |= MAY_OPEN; extra |= MAY_OPEN;
} }
......
...@@ -457,11 +457,11 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) ...@@ -457,11 +457,11 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
old_cap = cap_set_effective(current->cap_permitted); 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) if (res)
goto out; goto out;
res = vfs_permission(&nd, mode); res = vfs_permission(&nd, mode | MAY_ACCESS);
/* SuS v2 requires we report a read only fs too */ /* SuS v2 requires we report a read only fs too */
if(res || !(mode & S_IWOTH) || if(res || !(mode & S_IWOTH) ||
special_file(nd.path.dentry->d_inode->i_mode)) special_file(nd.path.dentry->d_inode->i_mode))
...@@ -505,7 +505,7 @@ asmlinkage long sys_chdir(const char __user * filename) ...@@ -505,7 +505,7 @@ asmlinkage long sys_chdir(const char __user * filename)
if (error) if (error)
goto out; goto out;
error = vfs_permission(&nd, MAY_EXEC | MAY_CHDIR); error = vfs_permission(&nd, MAY_EXEC | MAY_ACCESS);
if (error) if (error)
goto dput_and_out; goto dput_and_out;
...@@ -534,7 +534,7 @@ asmlinkage long sys_fchdir(unsigned int fd) ...@@ -534,7 +534,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
if (!S_ISDIR(inode->i_mode)) if (!S_ISDIR(inode->i_mode))
goto out_putf; goto out_putf;
error = file_permission(file, MAY_EXEC); error = file_permission(file, MAY_EXEC | MAY_ACCESS);
if (!error) if (!error)
set_fs_pwd(current->fs, &file->f_path); set_fs_pwd(current->fs, &file->f_path);
out_putf: out_putf:
...@@ -552,7 +552,7 @@ asmlinkage long sys_chroot(const char __user * filename) ...@@ -552,7 +552,7 @@ asmlinkage long sys_chroot(const char __user * filename)
if (error) if (error)
goto out; goto out;
error = vfs_permission(&nd, MAY_EXEC); error = vfs_permission(&nd, MAY_EXEC | MAY_ACCESS);
if (error) if (error)
goto dput_and_out; goto dput_and_out;
......
...@@ -61,8 +61,7 @@ extern int dir_notify_enable; ...@@ -61,8 +61,7 @@ extern int dir_notify_enable;
#define MAY_READ 4 #define MAY_READ 4
#define MAY_APPEND 8 #define MAY_APPEND 8
#define MAY_ACCESS 16 #define MAY_ACCESS 16
#define MAY_CHDIR 32 #define MAY_OPEN 32
#define MAY_OPEN 64
#define FMODE_READ 1 #define FMODE_READ 1
#define FMODE_WRITE 2 #define FMODE_WRITE 2
......
...@@ -53,7 +53,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; ...@@ -53,7 +53,6 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
*/ */
#define LOOKUP_OPEN (0x0100) #define LOOKUP_OPEN (0x0100)
#define LOOKUP_CREATE (0x0200) #define LOOKUP_CREATE (0x0200)
#define LOOKUP_ACCESS (0x0400)
extern int __user_walk(const char __user *, unsigned, struct nameidata *); extern int __user_walk(const char __user *, unsigned, struct nameidata *);
extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *); extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment