Эх сурвалжийг харах

[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>
Al Viro 17 жил өмнө
parent
commit
a110343f0d

+ 1 - 1
fs/fuse/dir.c

@@ -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)) {

+ 0 - 2
fs/namei.c

@@ -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;
 		}
 		}

+ 5 - 5
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);
 			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)
 	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)
 	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)
 	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;
 
 

+ 1 - 2
include/linux/fs.h

@@ -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 64
+#define MAY_OPEN 32
 
 
 #define FMODE_READ 1
 #define FMODE_READ 1
 #define FMODE_WRITE 2
 #define FMODE_WRITE 2

+ 0 - 1
include/linux/namei.h

@@ -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 *);