diff options
author | Miklos Szeredi <mszeredi@redhat.com> | 2020-05-14 16:44:24 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@redhat.com> | 2020-05-14 16:44:24 +0200 |
commit | 9470451505efbcc9eef2d7e74251e6402f5ea385 (patch) | |
tree | c2110afd67d6c38c6066641e034aff82e60ac9ba /fs/open.c | |
parent | 9f6c61f96f2d97cbb5f7fa85607bc398f843ff0f (diff) | |
download | linux-9470451505efbcc9eef2d7e74251e6402f5ea385.tar.bz2 |
vfs: split out access_override_creds()
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>
Diffstat (limited to 'fs/open.c')
-rw-r--r-- | fs/open.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/fs/open.c b/fs/open.c index 719b320ede52..0ea3cd1a1250 100644 --- 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; } |