vfs: split out access_override_creds()
authorMiklos Szeredi <mszeredi@redhat.com>
Thu, 14 May 2020 14:44:24 +0000 (16:44 +0200)
committerMiklos Szeredi <mszeredi@redhat.com>
Thu, 14 May 2020 14:44:24 +0000 (16:44 +0200)
Split out a helper that overrides the credentials in preparation for
actually doing the access check.

This prepares for the next patch that optionally disables the creds
override.

Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/open.c

index 719b320..0ea3cd1 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -345,21 +345,14 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
  * We do this by temporarily clearing all FS-related capabilities and
  * switching the fsuid/fsgid around to the real ones.
  */
-long do_faccessat(int dfd, const char __user *filename, int mode)
+static const struct cred *access_override_creds(void)
 {
        const struct cred *old_cred;
        struct cred *override_cred;
-       struct path path;
-       struct inode *inode;
-       int res;
-       unsigned int lookup_flags = LOOKUP_FOLLOW;
-
-       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
-               return -EINVAL;
 
        override_cred = prepare_creds();
        if (!override_cred)
-               return -ENOMEM;
+               return NULL;
 
        override_cred->fsuid = override_cred->uid;
        override_cred->fsgid = override_cred->gid;
@@ -394,6 +387,28 @@ long do_faccessat(int dfd, const char __user *filename, int mode)
        override_cred->non_rcu = 1;
 
        old_cred = override_creds(override_cred);
+
+       /* override_cred() gets its own ref */
+       put_cred(override_cred);
+
+       return old_cred;
+}
+
+long do_faccessat(int dfd, const char __user *filename, int mode)
+{
+       struct path path;
+       struct inode *inode;
+       int res;
+       unsigned int lookup_flags = LOOKUP_FOLLOW;
+       const struct cred *old_cred;
+
+       if (mode & ~S_IRWXO)    /* where's F_OK, X_OK, W_OK, R_OK? */
+               return -EINVAL;
+
+       old_cred = access_override_creds();
+       if (!old_cred)
+               return -ENOMEM;
+
 retry:
        res = user_path_at(dfd, filename, lookup_flags, &path);
        if (res)
@@ -436,7 +451,6 @@ out_path_release:
        }
 out:
        revert_creds(old_cred);
-       put_cred(override_cred);
        return res;
 }