aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-07-23 11:43:51 -0400
committerJames Morris <jmorris@namei.org>2010-08-02 01:35:06 -0400
commit9cfcac810e8993fa7a5bfd24b1a21f1dbbb03a7b (patch)
tree86fae80c744e46b15b8eb9aa23fead7e63a64159
parent692a8a231b212dfc68f612956d63f34abf098e0f (diff)
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>
-rw-r--r--fs/fuse/dir.c2
-rw-r--r--fs/nfs/dir.c2
-rw-r--r--fs/open.c6
-rw-r--r--include/linux/fs.h1
4 files changed, 6 insertions, 5 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 3cdc5f78a406..431be0795b6b 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1016,7 +1016,7 @@ static int fuse_permission(struct inode *inode, int mask)
1016 exist. So if permissions are revoked this won't be 1016 exist. So if permissions are revoked this won't be
1017 noticed immediately, only after the attribute 1017 noticed immediately, only after the attribute
1018 timeout has expired */ 1018 timeout has expired */
1019 } else if (mask & MAY_ACCESS) { 1019 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
1020 err = fuse_access(inode, mask); 1020 err = fuse_access(inode, mask);
1021 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { 1021 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1022 if (!(inode->i_mode & S_IXUGO)) { 1022 if (!(inode->i_mode & S_IXUGO)) {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e60416d3f818..832e9e239324 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1953,7 +1953,7 @@ int nfs_permission(struct inode *inode, int mask)
1953 if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) 1953 if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
1954 goto out; 1954 goto out;
1955 /* Is this sys_access() ? */ 1955 /* Is this sys_access() ? */
1956 if (mask & MAY_ACCESS) 1956 if (mask & (MAY_ACCESS | MAY_CHDIR))
1957 goto force_lookup; 1957 goto force_lookup;
1958 1958
1959 switch (inode->i_mode & S_IFMT) { 1959 switch (inode->i_mode & S_IFMT) {
diff --git a/fs/open.c b/fs/open.c
index a54ed85209c1..0d1fa3dc0efb 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -366,7 +366,7 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename)
366 if (error) 366 if (error)
367 goto out; 367 goto out;
368 368
369 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); 369 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
370 if (error) 370 if (error)
371 goto dput_and_out; 371 goto dput_and_out;
372 372
@@ -395,7 +395,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
395 if (!S_ISDIR(inode->i_mode)) 395 if (!S_ISDIR(inode->i_mode))
396 goto out_putf; 396 goto out_putf;
397 397
398 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS); 398 error = inode_permission(inode, MAY_EXEC | MAY_CHDIR);
399 if (!error) 399 if (!error)
400 set_fs_pwd(current->fs, &file->f_path); 400 set_fs_pwd(current->fs, &file->f_path);
401out_putf: 401out_putf:
@@ -413,7 +413,7 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
413 if (error) 413 if (error)
414 goto out; 414 goto out;
415 415
416 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); 416 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
417 if (error) 417 if (error)
418 goto dput_and_out; 418 goto dput_and_out;
419 419
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 68ca1b0491af..7d94b72f0346 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -53,6 +53,7 @@ struct inodes_stat_t {
53#define MAY_APPEND 8 53#define MAY_APPEND 8
54#define MAY_ACCESS 16 54#define MAY_ACCESS 16
55#define MAY_OPEN 32 55#define MAY_OPEN 32
56#define MAY_CHDIR 64
56 57
57/* 58/*
58 * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond 59 * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond