浏览代码

vfs: re-introduce MAY_CHDIR

Currently MAY_ACCESS means that filesystems must check the permissions
right then and not rely on cached results or the results of future
operations on the object.  This can be because of a call to sys_access() or
because of a call to chdir() which needs to check search without relying on
any future operations inside that dir.  I plan to use MAY_ACCESS for other
purposes in the security system, so I split the MAY_ACCESS and the
MAY_CHDIR cases.

Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by:  Stephen D. Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
Eric Paris 15 年之前
父节点
当前提交
9cfcac810e
共有 4 个文件被更改,包括 6 次插入5 次删除
  1. 1 1
      fs/fuse/dir.c
  2. 1 1
      fs/nfs/dir.c
  3. 3 3
      fs/open.c
  4. 1 0
      include/linux/fs.h

+ 1 - 1
fs/fuse/dir.c

@@ -1016,7 +1016,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) {
+	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
 		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)) {

+ 1 - 1
fs/nfs/dir.c

@@ -1953,7 +1953,7 @@ int nfs_permission(struct inode *inode, int mask)
 	if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
 	if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
 		goto out;
 		goto out;
 	/* Is this sys_access() ? */
 	/* Is this sys_access() ? */
-	if (mask & MAY_ACCESS)
+	if (mask & (MAY_ACCESS | MAY_CHDIR))
 		goto force_lookup;
 		goto force_lookup;
 
 
 	switch (inode->i_mode & S_IFMT) {
 	switch (inode->i_mode & S_IFMT) {

+ 3 - 3
fs/open.c

@@ -366,7 +366,7 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename)
 	if (error)
 	if (error)
 		goto out;
 		goto out;
 
 
-	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
+	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
 	if (error)
 	if (error)
 		goto dput_and_out;
 		goto dput_and_out;
 
 
@@ -395,7 +395,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
 	if (!S_ISDIR(inode->i_mode))
 	if (!S_ISDIR(inode->i_mode))
 		goto out_putf;
 		goto out_putf;
 
 
-	error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
+	error = inode_permission(inode, MAY_EXEC | MAY_CHDIR);
 	if (!error)
 	if (!error)
 		set_fs_pwd(current->fs, &file->f_path);
 		set_fs_pwd(current->fs, &file->f_path);
 out_putf:
 out_putf:
@@ -413,7 +413,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
 	if (error)
 	if (error)
 		goto out;
 		goto out;
 
 
-	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
+	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
 	if (error)
 	if (error)
 		goto dput_and_out;
 		goto dput_and_out;
 
 

+ 1 - 0
include/linux/fs.h

@@ -53,6 +53,7 @@ struct inodes_stat_t {
 #define MAY_APPEND 8
 #define MAY_APPEND 8
 #define MAY_ACCESS 16
 #define MAY_ACCESS 16
 #define MAY_OPEN 32
 #define MAY_OPEN 32
+#define MAY_CHDIR 64
 
 
 /*
 /*
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond
  * flags in file.f_mode.  Note that FMODE_READ and FMODE_WRITE must correspond