diff options
author | Jann Horn <jannh@google.com> | 2019-04-10 09:55:41 -0700 |
---|---|---|
committer | Micah Morton <mortonm@chromium.org> | 2019-07-15 08:06:58 -0700 |
commit | 8068866c4af124345e2a129be921278aada7830f (patch) | |
tree | 90c2257973f71d811392404a2d506002d8f4012e | |
parent | 1cd02a27a9473fed0294561137cfb7dcc9b3aaa0 (diff) |
LSM: SafeSetID: refactor safesetid_security_capable()
At the moment, safesetid_security_capable() has two nested conditional
blocks, and one big comment for all the logic. Chop it up and reduce the
amount of indentation.
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Micah Morton <mortonm@chromium.org>
-rw-r--r-- | security/safesetid/lsm.c | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c index 56e1b285a4ae..9db1c7a51d3d 100644 --- a/security/safesetid/lsm.c +++ b/security/safesetid/lsm.c @@ -55,21 +55,32 @@ static int safesetid_security_capable(const struct cred *cred, int cap, unsigned int opts) { - if (cap == CAP_SETUID && - setuid_policy_lookup(cred->uid, INVALID_UID) != SIDPOL_DEFAULT) { - if (!(opts & CAP_OPT_INSETID)) { - /* - * Deny if we're not in a set*uid() syscall to avoid - * giving powers gated by CAP_SETUID that are related - * to functionality other than calling set*uid() (e.g. - * allowing user to set up userns uid mappings). - */ - pr_warn("Operation requires CAP_SETUID, which is not available to UID %u for operations besides approved set*uid transitions\n", - __kuid_val(cred->uid)); - return -1; - } - } - return 0; + /* We're only interested in CAP_SETUID. */ + if (cap != CAP_SETUID) + return 0; + + /* + * If CAP_SETUID is currently used for a set*uid() syscall, we want to + * let it go through here; the real security check happens later, in the + * task_fix_setuid hook. + */ + if ((opts & CAP_OPT_INSETID) != 0) + return 0; + + /* + * If no policy applies to this task, allow the use of CAP_SETUID for + * other purposes. + */ + if (setuid_policy_lookup(cred->uid, INVALID_UID) == SIDPOL_DEFAULT) + return 0; + + /* + * Reject use of CAP_SETUID for functionality other than calling + * set*uid() (e.g. setting up userns uid mappings). + */ + pr_warn("Operation requires CAP_SETUID, which is not available to UID %u for operations besides approved set*uid transitions\n", + __kuid_val(cred->uid)); + return -1; } /* |