[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>
This commit is contained in:
		
							parent
							
								
									7f2da1e7d0
								
							
						
					
					
						commit
						a110343f0d
					
				| @ -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)) { | ||||
|  | ||||
| @ -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; | ||||
| 		} | ||||
|  | ||||
							
								
								
									
										10
									
								
								fs/open.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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; | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 *); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user