From: Miklos Szeredi Add more PERM_OP_ flags to permission() calls. This allows filesystems like NFS and security modules like AppArmor to make precise decisions about whent permissions need to be checked, and when they will be checked later together with the actual operation. Signed-off-by: Miklos Szeredi --- fs/namei.c | 16 ++++++++-------- fs/nfsd/nfsfh.c | 2 +- fs/open.c | 6 +++--- fs/utimes.c | 2 +- fs/xattr.c | 2 +- include/linux/fs.h | 19 +++++++++++++++++++ 6 files changed, 33 insertions(+), 14 deletions(-) Index: linux-2.6/fs/namei.c =================================================================== --- linux-2.6.orig/fs/namei.c 2008-05-29 12:46:20.000000000 +0200 +++ linux-2.6/fs/namei.c 2008-05-29 12:46:24.000000000 +0200 @@ -492,7 +492,7 @@ static int exec_permission_lite(struct i return -EACCES; ok: - return security_inode_permission(inode, MAY_EXEC); + return security_inode_permission(inode, MAY_LOOKUP); } /* @@ -899,7 +899,7 @@ static int __link_path_walk(const char * nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode); if (err == -EAGAIN) - err = path_permission(&nd->path, MAY_EXEC); + err = path_permission(&nd->path, MAY_LOOKUP); if (err) break; @@ -1174,7 +1174,7 @@ static int do_path_lookup(int dfd, const if (!S_ISDIR(dentry->d_inode->i_mode)) goto fput_fail; - retval = file_permission(file, MAY_EXEC); + retval = file_permission(file, MAY_LOOKUP); if (retval) goto fput_fail; @@ -1347,7 +1347,7 @@ static struct dentry *lookup_hash(struct { int err; - err = path_permission(&nd->path, MAY_EXEC); + err = path_permission(&nd->path, MAY_LOOKUP); if (err) return ERR_PTR(err); return __lookup_hash(&nd->last, nd->path.dentry, nd); @@ -1395,7 +1395,7 @@ struct dentry *lookup_one_len(const char if (err) return ERR_PTR(err); - err = dentry_permission(base, MAY_EXEC); + err = dentry_permission(base, MAY_LOOKUP); if (err) return ERR_PTR(err); return __lookup_hash(&this, base, NULL); @@ -1487,7 +1487,7 @@ static int may_delete(struct dentry *dir BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(victim->d_name.name, victim, dir); - error = dentry_permission(dir_dentry, MAY_WRITE | MAY_EXEC); + error = dentry_permission(dir_dentry, MAY_DELETE); if (error) return error; if (IS_APPEND(dir)) @@ -1523,7 +1523,7 @@ static inline int may_create(struct dent return -EEXIST; if (IS_DEADDIR(dir_dentry->d_inode)) return -ENOENT; - return dentry_permission(dir_dentry, MAY_WRITE | MAY_EXEC); + return dentry_permission(dir_dentry, MAY_CREATE); } /* @@ -2687,7 +2687,7 @@ static int vfs_rename_dir(struct inode * * we'll need to flip '..'. */ if (new_dir != old_dir) { - error = dentry_permission(old_dentry, MAY_WRITE); + error = dentry_permission(old_dentry, MAY_MOVE_DIR); if (error) return error; } Index: linux-2.6/fs/nfsd/nfsfh.c =================================================================== --- linux-2.6.orig/fs/nfsd/nfsfh.c 2008-05-29 12:46:23.000000000 +0200 +++ linux-2.6/fs/nfsd/nfsfh.c 2008-05-29 12:46:24.000000000 +0200 @@ -52,7 +52,7 @@ static int nfsd_acceptable(void *expv, s int err; parent.dentry = dget_parent(tdentry); - err = path_permission(&parent, MAY_EXEC); + err = path_permission(&parent, MAY_LOOKUP); if (err < 0) { dput(parent.dentry); break; Index: linux-2.6/fs/open.c =================================================================== --- linux-2.6.orig/fs/open.c 2008-05-29 12:46:20.000000000 +0200 +++ linux-2.6/fs/open.c 2008-05-29 12:46:24.000000000 +0200 @@ -513,7 +513,7 @@ asmlinkage long sys_chdir(const char __u if (error) goto out; - error = path_permission(&nd.path, MAY_EXEC | PERM_OP_CHDIR); + error = path_permission(&nd.path, MAY_CHDIR); if (error) goto dput_and_out; @@ -542,7 +542,7 @@ asmlinkage long sys_fchdir(unsigned int if (!S_ISDIR(inode->i_mode)) goto out_putf; - error = file_permission(file, MAY_EXEC | PERM_OP_CHDIR); + error = file_permission(file, MAY_CHDIR); if (!error) set_fs_pwd(current->fs, &file->f_path); out_putf: @@ -560,7 +560,7 @@ asmlinkage long sys_chroot(const char __ if (error) goto out; - error = path_permission(&nd.path, MAY_EXEC); + error = path_permission(&nd.path, MAY_CHROOT); if (error) goto dput_and_out; Index: linux-2.6/fs/utimes.c =================================================================== --- linux-2.6.orig/fs/utimes.c 2008-05-29 12:46:20.000000000 +0200 +++ linux-2.6/fs/utimes.c 2008-05-29 12:46:24.000000000 +0200 @@ -141,7 +141,7 @@ static int do_utimes_name(int dfd, char goto out_path_put; if (!is_owner_or_cap(inode)) { - error = path_permission(&nd.path, MAY_WRITE); + error = path_permission(&nd.path, MAY_UTIMES); if (error) goto out_path_put; } Index: linux-2.6/fs/xattr.c =================================================================== --- linux-2.6.orig/fs/xattr.c 2008-05-29 12:46:20.000000000 +0200 +++ linux-2.6/fs/xattr.c 2008-05-29 12:46:24.000000000 +0200 @@ -65,7 +65,7 @@ xattr_permission(struct path *path, cons return -EPERM; } - return path_permission(path, mask); + return path_permission(path, mask | PERM_OP_XATTR); } static int Index: linux-2.6/include/linux/fs.h =================================================================== --- linux-2.6.orig/include/linux/fs.h 2008-05-29 12:46:20.000000000 +0200 +++ linux-2.6/include/linux/fs.h 2008-05-29 12:46:24.000000000 +0200 @@ -70,6 +70,25 @@ extern int dir_notify_enable; #define PERM_OP_OPEN (0x1 << 28) #define PERM_OP_ACCESS (0x2 << 28) #define PERM_OP_CHDIR (0x3 << 28) +#define PERM_OP_CHROOT (0x4 << 28) +#define PERM_OP_LOOKUP (0x5 << 28) +#define PERM_OP_CREATE (0x6 << 28) +#define PERM_OP_DELETE (0x7 << 28) +#define PERM_OP_MOVE_DIR (0x8 << 28) +#define PERM_OP_UTIMES (0x9 << 28) +#define PERM_OP_XATTR (0xa << 28) + +/* + * Combined MAY_ flags + */ +#define MAY_CHDIR (PERM_OP_CHDIR | MAY_EXEC) +#define MAY_CHROOT (PERM_OP_CHROOT | MAY_EXEC) +#define MAY_LOOKUP (PERM_OP_LOOKUP | MAY_EXEC) +#define MAY_CREATE (PERM_OP_CREATE | MAY_EXEC | MAY_WRITE) +#define MAY_DELETE (PERM_OP_DELETE | MAY_EXEC | MAY_WRITE) +#define MAY_MOVE_DIR (PERM_OP_MOVE_DIR | MAY_WRITE) +#define MAY_UTIMES (PERM_OP_UTIMES | MAY_WRITE) + #define FMODE_READ 1 #define FMODE_WRITE 2 -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/