From 8068866c4af124345e2a129be921278aada7830f Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Wed, 10 Apr 2019 09:55:41 -0700 Subject: 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 Signed-off-by: Micah Morton --- security/safesetid/lsm.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'security') 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; } /* -- cgit v1.2.3-55-g7522