aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-07-18 18:25:27 -0400
committerKees Cook <keescook@chromium.org>2017-08-01 15:03:08 -0400
commit46d98eb4e1d2bc225f661879e0e157a952107598 (patch)
tree39248131210a85f157d4414f3b99790c24454cab /security
parentccbb6e1065fa9cd27f2bf406e8c5d5cf0273f554 (diff)
commoncap: Refactor to remove bprm_secureexec hook
The commoncap implementation of the bprm_secureexec hook is the only LSM that depends on the final call to its bprm_set_creds hook (since it may be called for multiple files, it ignores bprm->called_set_creds). As a result, it cannot safely _clear_ bprm->secureexec since other LSMs may have set it. Instead, remove the bprm_secureexec hook by introducing a new flag to bprm specific to commoncap: cap_elevated. This is similar to cap_effective, but that is used for a specific subset of elevated privileges, and exists solely to track state from bprm_set_creds to bprm_secureexec. As such, it will be removed in the next patch. Here, set the new bprm->cap_elevated flag when setuid/setgid has happened from bprm_fill_uid() or fscapabilities have been prepared. This temporarily moves the bprm_secureexec hook to a static inline. The helper will be removed in the next patch; this makes the step easier to review and bisect, since this does not introduce any changes to inputs nor outputs to the "elevated privileges" calculation. The new flag is merged with the bprm->secureexec flag in setup_new_exec() since this marks the end of any further prepare_binprm() calls. Cc: Andy Lutomirski <luto@kernel.org> Signed-off-by: Kees Cook <keescook@chromium.org> Reviewed-by: Andy Lutomirski <luto@kernel.org> Acked-by: James Morris <james.l.morris@oracle.com> Acked-by: Serge Hallyn <serge@hallyn.com>
Diffstat (limited to 'security')
-rw-r--r--security/commoncap.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index 7abebd782d5e..abb6050c8083 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -481,6 +481,8 @@ out:
481 return rc; 481 return rc;
482} 482}
483 483
484static int is_secureexec(struct linux_binprm *bprm);
485
484/** 486/**
485 * cap_bprm_set_creds - Set up the proposed credentials for execve(). 487 * cap_bprm_set_creds - Set up the proposed credentials for execve().
486 * @bprm: The execution parameters, including the proposed creds 488 * @bprm: The execution parameters, including the proposed creds
@@ -614,11 +616,14 @@ skip:
614 if (WARN_ON(!cap_ambient_invariant_ok(new))) 616 if (WARN_ON(!cap_ambient_invariant_ok(new)))
615 return -EPERM; 617 return -EPERM;
616 618
619 /* Check for privilege-elevated exec. */
620 bprm->cap_elevated = is_secureexec(bprm);
621
617 return 0; 622 return 0;
618} 623}
619 624
620/** 625/**
621 * cap_bprm_secureexec - Determine whether a secure execution is required 626 * is_secureexec - Determine whether a secure execution is required
622 * @bprm: The execution parameters 627 * @bprm: The execution parameters
623 * 628 *
624 * Determine whether a secure execution is required, return 1 if it is, and 0 629 * Determine whether a secure execution is required, return 1 if it is, and 0
@@ -627,9 +632,9 @@ skip:
627 * The credentials have been committed by this point, and so are no longer 632 * The credentials have been committed by this point, and so are no longer
628 * available through @bprm->cred. 633 * available through @bprm->cred.
629 */ 634 */
630int cap_bprm_secureexec(struct linux_binprm *bprm) 635static int is_secureexec(struct linux_binprm *bprm)
631{ 636{
632 const struct cred *cred = current_cred(); 637 const struct cred *cred = bprm->cred;
633 kuid_t root_uid = make_kuid(cred->user_ns, 0); 638 kuid_t root_uid = make_kuid(cred->user_ns, 0);
634 639
635 if (!uid_eq(cred->uid, root_uid)) { 640 if (!uid_eq(cred->uid, root_uid)) {
@@ -1079,7 +1084,6 @@ struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
1079 LSM_HOOK_INIT(capget, cap_capget), 1084 LSM_HOOK_INIT(capget, cap_capget),
1080 LSM_HOOK_INIT(capset, cap_capset), 1085 LSM_HOOK_INIT(capset, cap_capset),
1081 LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), 1086 LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
1082 LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec),
1083 LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), 1087 LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
1084 LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv), 1088 LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
1085 LSM_HOOK_INIT(mmap_addr, cap_mmap_addr), 1089 LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),