From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751177AbcFATdF (ORCPT ); Wed, 1 Jun 2016 15:33:05 -0400 Received: from nm18-vm0.bullet.mail.bf1.yahoo.com ([98.139.213.138]:48193 "EHLO nm18-vm0.bullet.mail.bf1.yahoo.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750727AbcFATdD (ORCPT ); Wed, 1 Jun 2016 15:33:03 -0400 X-Greylist: delayed 351 seconds by postgrey-1.27 at vger.kernel.org; Wed, 01 Jun 2016 15:33:03 EDT X-Yahoo-Newman-Id: 844733.33939.bm@smtp218.mail.bf1.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: dpGL0.QVM1kHFc_rp1bqK67uGQbDrzZkXcOvYuqHsnfIv8p AtmXiWe58Wv8TJsQRmkedNwcr9peQ6PBDejObTG2M5YsGTM4oAjQ95IIxTG0 HqHdDO7fbDYMcjQOLFGNls8tDi4emFY9y.yB4XNxAtrJgWfdurKQ.ozusf.X TwoA1tros8yyp8yBuGL3zB5WqKOlhnpRkrBnyZx0Inks9BmicD5XXIQyMszU 5PWxNOiQK7vzs5gJaNZ_Ebd.26tzaZ1M0tPubIZzzBveZpdRYfqGhOYQDMwk kP1IS5hYXY93fQn_mqgCFhtS9y8H2jL99s4gljY5I7FShA_Y9gJHrnP7kwXl butM8Czhg30bXfq._a_9FCBWuQlk1CJ3nsOZ1lWBFuD7.2wLE3YCnLDnnmsX aN0fL7uYT8.PtMA.y1csL201bFLDXCy5lObdgopcz1vf.qcIdOQDiqfDBxV1 wyWYRi.x1TpUfqIIIh.vt_zdKS9EdJNzePdckGd40A7B6QdUahxLd.IyJrK4 LrpEiCD4OBXp0Gg0QyHwriF7Q3gy9rJYhA_3HujaX2I0mv_J3UV3MKsdtF44 - X-Yahoo-SMTP: OIJXglSswBDfgLtXluJ6wiAYv6_cnw-- From: Casey Schaufler Subject: [PATCH] LSM: Reorder security_capset to do access checks properly To: LSM , James Morris Cc: LKLM , SE Linux Message-ID: <0243a591-a6e1-8827-3f03-884c3ad331d0@schaufler-ca.com> Date: Wed, 1 Jun 2016 12:27:02 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Subject: [PATCH] LSM: Reorder security_capset to do access checks properly The security module hooks that check whether a process should be able to set a new capset are currently called after the new values are set in cap_capset(). This change reverses the order. The capability module no longer adds cap_capset to the module list. Instead, it is invoked directly by the LSM infrastructure. This isn't an approach that generalizes well. Signed-off-by: Casey Schaufler --- security/commoncap.c | 2 +- security/security.c | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/security/commoncap.c b/security/commoncap.c index 48071ed..f5bce18 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1073,7 +1073,7 @@ struct security_hook_list capability_hooks[] = { LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme), LSM_HOOK_INIT(capget, cap_capget), - LSM_HOOK_INIT(capset, cap_capset), + /* Carefull! Do not include cap_capset! */ LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds), LSM_HOOK_INIT(bprm_secureexec, cap_bprm_secureexec), LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv), diff --git a/security/security.c b/security/security.c index 92cd1d8..1610be8 100644 --- a/security/security.c +++ b/security/security.c @@ -177,8 +177,28 @@ int security_capset(struct cred *new, const struct cred *old, const kernel_cap_t *inheritable, const kernel_cap_t *permitted) { - return call_int_hook(capset, 0, new, old, - effective, inheritable, permitted); + struct security_hook_list *hp; + int rc; + + /* + * Special case handling because the "new" capabilities + * should not be set until it has been determined that + * all modules approve of the change. Passing NULL pointers + * to all modules except the capabilty module as it is + * expected that only the capability modules needs the + * result pointers. + * + * cap_capset() must not be in the capability module hook list! + */ + list_for_each_entry(hp, &security_hook_heads.capset, list) { + rc = hp->hook.capset(new, old, NULL, NULL, NULL); + if (rc != 0) + return rc; + } + /* + * Call cap_capset now to update the new capset. + */ + return cap_capset(new, old, effective, inheritable, permitted); } int security_capable(const struct cred *cred, struct user_namespace *ns,