]> Git Repo - linux.git/commitdiff
fs: add file and path permissions helpers
authorChristian Brauner <[email protected]>
Thu, 21 Jan 2021 13:19:22 +0000 (14:19 +0100)
committerChristian Brauner <[email protected]>
Sun, 24 Jan 2021 13:27:16 +0000 (14:27 +0100)
Add two simple helpers to check permissions on a file and path
respectively and convert over some callers. It simplifies quite a few
codepaths and also reduces the churn in later patches quite a bit.
Christoph also correctly points out that this makes codepaths (e.g.
ioctls) way easier to follow that would otherwise have to do more
complex argument passing than necessary.

Link: https://lore.kernel.org/r/[email protected]
Cc: David Howells <[email protected]>
Cc: Al Viro <[email protected]>
Cc: [email protected]
Suggested-by: Christoph Hellwig <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
Reviewed-by: James Morris <[email protected]>
Signed-off-by: Christian Brauner <[email protected]>
13 files changed:
fs/init.c
fs/notify/fanotify/fanotify_user.c
fs/notify/inotify/inotify_user.c
fs/open.c
fs/udf/file.c
fs/verity/enable.c
include/linux/fs.h
kernel/bpf/inode.c
kernel/sys.c
mm/madvise.c
mm/memcontrol.c
mm/mincore.c
net/unix/af_unix.c

index e9c320a48cf157dd5ad1ffe5f9d40f20bd75656e..02723bea8499004b7e112b14c797432027973db8 100644 (file)
--- a/fs/init.c
+++ b/fs/init.c
@@ -49,7 +49,7 @@ int __init init_chdir(const char *filename)
        error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
        if (error)
                return error;
-       error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
+       error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
        if (!error)
                set_fs_pwd(current->fs, &path);
        path_put(&path);
@@ -64,7 +64,7 @@ int __init init_chroot(const char *filename)
        error = kern_path(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
        if (error)
                return error;
-       error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
+       error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
        if (error)
                goto dput_and_out;
        error = -EPERM;
@@ -118,7 +118,7 @@ int __init init_eaccess(const char *filename)
        error = kern_path(filename, LOOKUP_FOLLOW, &path);
        if (error)
                return error;
-       error = inode_permission(d_inode(path.dentry), MAY_ACCESS);
+       error = path_permission(&path, MAY_ACCESS);
        path_put(&path);
        return error;
 }
index dcab112e1f0012073456c56b52b1ce4ac261d9a4..64cfc1a3015d7545a9a1e2e69dc77c80cdd08742 100644 (file)
@@ -702,7 +702,7 @@ static int fanotify_find_path(int dfd, const char __user *filename,
        }
 
        /* you can only watch an inode if you have read permissions on it */
-       ret = inode_permission(path->dentry->d_inode, MAY_READ);
+       ret = path_permission(path, MAY_READ);
        if (ret) {
                path_put(path);
                goto out;
index 59c177011a0f9aca7d7560d13d270c948d3f788b..e1155d32ef6f2d613267ed512faf26d229a92138 100644 (file)
@@ -352,7 +352,7 @@ static int inotify_find_inode(const char __user *dirname, struct path *path,
        if (error)
                return error;
        /* you can only watch an inode if you have read permissions on it */
-       error = inode_permission(path->dentry->d_inode, MAY_READ);
+       error = path_permission(path, MAY_READ);
        if (error) {
                path_put(path);
                return error;
index 1e06e443a5651adca7e114aeebb02044b7e24803..cd1efd254cad5f29a3d2ccfedc8f0c8d0624bccf 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -492,7 +492,7 @@ retry:
        if (error)
                goto out;
 
-       error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
+       error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
        if (error)
                goto dput_and_out;
 
@@ -521,7 +521,7 @@ SYSCALL_DEFINE1(fchdir, unsigned int, fd)
        if (!d_can_lookup(f.file->f_path.dentry))
                goto out_putf;
 
-       error = inode_permission(file_inode(f.file), MAY_EXEC | MAY_CHDIR);
+       error = file_permission(f.file, MAY_EXEC | MAY_CHDIR);
        if (!error)
                set_fs_pwd(current->fs, &f.file->f_path);
 out_putf:
@@ -540,7 +540,7 @@ retry:
        if (error)
                goto out;
 
-       error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
+       error = path_permission(&path, MAY_EXEC | MAY_CHDIR);
        if (error)
                goto dput_and_out;
 
index ad8eefad27d7f031d937aef7fdd5bb09083c2712..3671a40ed3c3ef19b82e95c48a31834aa7575b68 100644 (file)
@@ -183,7 +183,7 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        long old_block, new_block;
        int result;
 
-       if (inode_permission(inode, MAY_READ) != 0) {
+       if (file_permission(filp, MAY_READ) != 0) {
                udf_debug("no permission to access inode %lu\n", inode->i_ino);
                return -EPERM;
        }
index f7e997a01ad07c4699d435223057af0b7fc49b82..77e159a0346b17078701dd1b3bf2cc5416f9e4e4 100644 (file)
@@ -369,7 +369,7 @@ int fsverity_ioctl_enable(struct file *filp, const void __user *uarg)
         * has verity enabled, and to stabilize the data being hashed.
         */
 
-       err = inode_permission(inode, MAY_WRITE);
+       err = file_permission(filp, MAY_WRITE);
        if (err)
                return err;
 
index 3165998e2294f360219f6878c7b3572d0a630747..bcd17097d441eed004002cd2c27a09c8f8f00cd6 100644 (file)
@@ -2812,6 +2812,14 @@ static inline int bmap(struct inode *inode,  sector_t *block)
 extern int notify_change(struct dentry *, struct iattr *, struct inode **);
 extern int inode_permission(struct inode *, int);
 extern int generic_permission(struct inode *, int);
+static inline int file_permission(struct file *file, int mask)
+{
+       return inode_permission(file_inode(file), mask);
+}
+static inline int path_permission(const struct path *path, int mask)
+{
+       return inode_permission(d_inode(path->dentry), mask);
+}
 extern int __check_sticky(struct inode *dir, struct inode *inode);
 
 static inline bool execute_ok(struct inode *inode)
index dd4b7fd60ee7dbb9dea1ed09e91cc789a0a7bbc5..8962f139521ec374ac9d9093d2d3939cebe598e8 100644 (file)
@@ -507,7 +507,7 @@ static void *bpf_obj_do_get(const char __user *pathname,
                return ERR_PTR(ret);
 
        inode = d_backing_inode(path.dentry);
-       ret = inode_permission(inode, ACC_MODE(flags));
+       ret = path_permission(&path, ACC_MODE(flags));
        if (ret)
                goto out;
 
index 51f00fe20e4d15fbf37a38d4a66d2a62166f8cce..138fb253b344bcada63e4807f2d4debd3dc666dd 100644 (file)
@@ -1848,7 +1848,7 @@ static int prctl_set_mm_exe_file(struct mm_struct *mm, unsigned int fd)
        if (!S_ISREG(inode->i_mode) || path_noexec(&exe.file->f_path))
                goto exit;
 
-       err = inode_permission(inode, MAY_EXEC);
+       err = file_permission(exe.file, MAY_EXEC);
        if (err)
                goto exit;
 
index 6a660858784b8410287a2250778c2a4197ae21a1..175c5582d8a93585dd83bbc4e30fad8eccd28c3f 100644 (file)
@@ -540,7 +540,7 @@ static inline bool can_do_pageout(struct vm_area_struct *vma)
         * opens a side channel.
         */
        return inode_owner_or_capable(file_inode(vma->vm_file)) ||
-               inode_permission(file_inode(vma->vm_file), MAY_WRITE) == 0;
+              file_permission(vma->vm_file, MAY_WRITE) == 0;
 }
 
 static long madvise_pageout(struct vm_area_struct *vma,
index 605f671203efbbe13cdd88163f4c71b68863acf8..cf9076f585821709f02290ef7d590ef73606ea7a 100644 (file)
@@ -4899,7 +4899,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of,
 
        /* the process need read permission on control file */
        /* AV: shouldn't we check that it's been opened for read instead? */
-       ret = inode_permission(file_inode(cfile.file), MAY_READ);
+       ret = file_permission(cfile.file, MAY_READ);
        if (ret < 0)
                goto out_put_cfile;
 
index 02db1a834021b8d38a341769809ca22979ade6e7..7bdb4673f776ab8e9a6ea34af7727d0fbb7326d2 100644 (file)
@@ -167,7 +167,7 @@ static inline bool can_do_mincore(struct vm_area_struct *vma)
         * mappings, which opens a side channel.
         */
        return inode_owner_or_capable(file_inode(vma->vm_file)) ||
-               inode_permission(file_inode(vma->vm_file), MAY_WRITE) == 0;
+              file_permission(vma->vm_file, MAY_WRITE) == 0;
 }
 
 static const struct mm_walk_ops mincore_walk_ops = {
index 41c3303c33577df55d1b5b2a70c5a69a78025afe..18453d15dddf1c8f92cbbc3fb476699236d0635a 100644 (file)
@@ -936,7 +936,7 @@ static struct sock *unix_find_other(struct net *net,
                if (err)
                        goto fail;
                inode = d_backing_inode(path.dentry);
-               err = inode_permission(inode, MAY_WRITE);
+               err = path_permission(&path, MAY_WRITE);
                if (err)
                        goto put_fail;
 
This page took 0.07717 seconds and 4 git commands to generate.