From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.7 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B298CC43387 for ; Mon, 7 Jan 2019 19:02:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 63953206B7 for ; Mon, 7 Jan 2019 19:02:35 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="l/5t02A0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727214AbfAGTCe (ORCPT ); Mon, 7 Jan 2019 14:02:34 -0500 Received: from mail-yw1-f67.google.com ([209.85.161.67]:35884 "EHLO mail-yw1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727064AbfAGTCe (ORCPT ); Mon, 7 Jan 2019 14:02:34 -0500 Received: by mail-yw1-f67.google.com with SMTP id i73so570514ywg.3 for ; Mon, 07 Jan 2019 11:02:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=tfgms6KBzZ/9e5VO01ehOPRxAlp2GWJouCBDNLhfcS8=; b=l/5t02A0XCw9a9mKXKQpmLrKEA7ZjweDBBH2JmiwudtX1bwjMD4vbe3/RN8V8sp6eD UU8aw4i85NFS/jllmKaqGbeO8KiDMamkud6wjl0IwDB2gOINAGxUBJMO5lEWOlHOcmXJ oZ5p6AACrLWzKY+mdDzSTwSFaxs45kVKJqQHE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=tfgms6KBzZ/9e5VO01ehOPRxAlp2GWJouCBDNLhfcS8=; b=iZzPxZ2pM0Aw4hWBdqmXFnVkc1IjwibW/JygVVP3JEBL/Fy0vol+6fcOE35/AxRyAE LBPylxMQX6V6+ojkawjDiMiTZitLQh5G8p7hZ6Zi5qfeGkaDiHNVf07GrWOXKRPWjkdy s5mFKgXOpn4KrKqimQRckoqUZ9Fp+kcP81ASBTd/wx9Xz1GoXBSslWIE0h7sV5tjgTwT 54LGKXbleNm8q+fTqacLSk/AH4wOzy+scVClNxAEOpFlBrzOSwNrYXZbuWLCw4qQoZt2 ORiI6t8JjJmG2E1FNHNb6ETS8+Shyg/Te0bQ/9PyvZvs/SJLocspoHy+TBCDmRGrNFXj srZg== X-Gm-Message-State: AA+aEWZ/vp+xuKC2RStWGJGtADpDL6CxDeUBmwwOOy/eoZ5H9uHsymUA nVu/Vi6ZlyVKTDzgmCqeOVACWczUhIH8iDlrofUHvuBHRKQLRg== X-Google-Smtp-Source: AFSGD/WvW5LEBfyZfLeLwuMKHPHQ/c3iqkrOwyFSkPLogHyIir62hHgwD5b/WanXgy3cCupiYiBYJim1IqpZe4PTmgY= X-Received: by 2002:a81:4788:: with SMTP id u130mr62697776ywa.172.1546887752782; Mon, 07 Jan 2019 11:02:32 -0800 (PST) MIME-Version: 1.0 References: <52258331-8aba-c67e-bea0-b5fe0dfcd020@schaufler-ca.com> <20181218223718.96738-1-mortonm@chromium.org> In-Reply-To: From: Micah Morton Date: Mon, 7 Jan 2019 11:02:21 -0800 Message-ID: Subject: Re: [PATCH v2] LSM: generalize flag passing to security_capable To: Casey Schaufler Cc: jmorris@namei.org, serge@hallyn.com, Kees Cook , sds@tycho.nsa.gov, linux-security-module@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Looks like kernel/seccomp.c is the only file that would escape modification if we kept security_capable_noaudit, since the other files where we modify security_capable_noaudit require changes to security_capable as well to pass the flag -- so we'll be changing them anyway. On Mon, Jan 7, 2019 at 10:46 AM Casey Schaufler wrote: > > On 1/7/2019 10:36 AM, Micah Morton wrote: > > It seems a bit weird to me to keep security_capable_noaudit and not > > add the analogous "security_capable_insetid" function (or other > > one-off functions if/when people want to pass new flags to > > security_capable). Taking away the function doesn't complicate the > > callers in any way I can see, and somewhat cleans up the logic in at > > lease one case (ns_capable_common in kernel/capability.c) since > > callers can just modify the last param in security_capable rather than > > calling different functions for audit vs. noaudit. I guess my take is > > why keep "security_capable_noaudit" when it is easy to just call > > "security_capable" with the SECURITY_CAP_NOAUDIT flag? I have no > > strong preference here so I'll do whatever seems best. > > My only reason to suggest keeping the function is to reduce > code churn. I would think that whoever introduced the noaudit > version had a reason to do that. It probably isn't a big deal. > I don't have a lot of energy on the issue, but it would make > your patch a bit smaller, and impact a lot fewer files. > > > > > On Mon, Jan 7, 2019 at 10:16 AM Casey Schaufler wrote: > >> On 1/7/2019 9:55 AM, Micah Morton wrote: > >>> Checking in to see if there are any further comments on this patch now > >>> that the holidays are passed? It seems like a straightforward change > >>> to me, but let me know if there is anything I can clarify that isn't > >>> explained by the commit message. > >>> > >>> On Tue, Dec 18, 2018 at 2:37 PM wrote: > >>>> From: Micah Morton > >>>> > >>>> This patch provides a general mechanism for passing flags to the > >>>> security_capable LSM hook. It replaces the specific 'audit' flag that is > >>>> used to tell security_capable whether it should log an audit message for > >>>> the given capability check. The reason for generalizing this flag > >>>> passing is so we can add an additional flag that signifies whether > >>>> security_capable is being called by a setid syscall (which is needed by > >>>> the proposed SafeSetID LSM). > >>>> > >>>> Signed-off-by: Micah Morton > >>>> --- > >>>> Changes since the last patch: Changed the code to use a bitmask instead > >>>> of a struct to represent the options passed to security_capable. > >>>> > >>>> include/linux/lsm_hooks.h | 8 +++++--- > >>>> include/linux/security.h | 28 +++++++++++++------------- > >>>> kernel/capability.c | 22 +++++++++++--------- > >>>> kernel/seccomp.c | 4 ++-- > >>>> security/apparmor/capability.c | 14 ++++++------- > >>>> security/apparmor/include/capability.h | 2 +- > >>>> security/apparmor/ipc.c | 3 ++- > >>>> security/apparmor/lsm.c | 4 ++-- > >>>> security/commoncap.c | 17 ++++++++-------- > >>>> security/security.c | 14 +++++-------- > >>>> security/selinux/hooks.c | 16 +++++++-------- > >>>> security/smack/smack_access.c | 2 +- > >>>> 12 files changed, 69 insertions(+), 65 deletions(-) > >>>> > >>>> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h > >>>> index aaeb7fa24dc4..ef955a44a782 100644 > >>>> --- a/include/linux/lsm_hooks.h > >>>> +++ b/include/linux/lsm_hooks.h > >>>> @@ -1270,7 +1270,7 @@ > >>>> * @cred contains the credentials to use. > >>>> * @ns contains the user namespace we want the capability in > >>>> * @cap contains the capability . > >>>> - * @audit contains whether to write an audit message or not > >>>> + * @opts contains options for the capable check > >>>> * Return 0 if the capability is granted for @tsk. > >>>> * @syslog: > >>>> * Check permission before accessing the kernel message ring or changing > >>>> @@ -1446,8 +1446,10 @@ union security_list_options { > >>>> const kernel_cap_t *effective, > >>>> const kernel_cap_t *inheritable, > >>>> const kernel_cap_t *permitted); > >>>> - int (*capable)(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap, int audit); > >>>> + int (*capable)(const struct cred *cred, > >>>> + struct user_namespace *ns, > >>>> + int cap, > >>>> + unsigned int opts); > >>>> int (*quotactl)(int cmds, int type, int id, struct super_block *sb); > >>>> int (*quota_on)(struct dentry *dentry); > >>>> int (*syslog)(int type); > >>>> diff --git a/include/linux/security.h b/include/linux/security.h > >>>> index d170a5b031f3..038e6779948c 100644 > >>>> --- a/include/linux/security.h > >>>> +++ b/include/linux/security.h > >>>> @@ -54,9 +54,12 @@ struct xattr; > >>>> struct xfrm_sec_ctx; > >>>> struct mm_struct; > >>>> > >>>> +/* Default (no) options for the capable function */ > >>>> +#define SECURITY_CAP_DEFAULT 0x0 > >>>> /* If capable should audit the security request */ > >>>> -#define SECURITY_CAP_NOAUDIT 0 > >>>> -#define SECURITY_CAP_AUDIT 1 > >>>> +#define SECURITY_CAP_NOAUDIT 0x01 > >>>> +/* If capable is being called by a setid function */ > >>>> +#define SECURITY_CAP_INSETID 0x02 > >>>> > >>>> /* LSM Agnostic defines for sb_set_mnt_opts */ > >>>> #define SECURITY_LSM_NATIVE_LABELS 1 > >>>> @@ -72,7 +75,7 @@ enum lsm_event { > >>>> > >>>> /* These functions are in security/commoncap.c */ > >>>> extern int cap_capable(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap, int audit); > >>>> + int cap, unsigned int opts); > >>>> extern int cap_settime(const struct timespec64 *ts, const struct timezone *tz); > >>>> extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); > >>>> extern int cap_ptrace_traceme(struct task_struct *parent); > >>>> @@ -233,10 +236,10 @@ int security_capset(struct cred *new, const struct cred *old, > >>>> const kernel_cap_t *effective, > >>>> const kernel_cap_t *inheritable, > >>>> const kernel_cap_t *permitted); > >>>> -int security_capable(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap); > >>>> -int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap); > >>>> +int security_capable(const struct cred *cred, > >>>> + struct user_namespace *ns, > >>>> + int cap, > >>>> + unsigned int opts); > >>>> int security_quotactl(int cmds, int type, int id, struct super_block *sb); > >>>> int security_quota_on(struct dentry *dentry); > >>>> int security_syslog(int type); > >>>> @@ -492,14 +495,11 @@ static inline int security_capset(struct cred *new, > >>>> } > >>>> > >>>> static inline int security_capable(const struct cred *cred, > >>>> - struct user_namespace *ns, int cap) > >>>> + struct user_namespace *ns, > >>>> + int cap, > >>>> + unsigned int opts) > >>>> { > >>>> - return cap_capable(cred, ns, cap, SECURITY_CAP_AUDIT); > >>>> -} > >>>> - > >>>> -static inline int security_capable_noaudit(const struct cred *cred, > >>>> - struct user_namespace *ns, int cap) { > >>>> - return cap_capable(cred, ns, cap, SECURITY_CAP_NOAUDIT); > >>>> + return cap_capable(cred, ns, cap, opts); > >>>> } > >> Why get rid of security_capable_noaudit()? > >> > >>>> static inline int security_quotactl(int cmds, int type, int id, > >>>> diff --git a/kernel/capability.c b/kernel/capability.c > >>>> index 1e1c0236f55b..454576743b1b 100644 > >>>> --- a/kernel/capability.c > >>>> +++ b/kernel/capability.c > >>>> @@ -299,7 +299,7 @@ bool has_ns_capability(struct task_struct *t, > >>>> int ret; > >>>> > >>>> rcu_read_lock(); > >>>> - ret = security_capable(__task_cred(t), ns, cap); > >>>> + ret = security_capable(__task_cred(t), ns, cap, SECURITY_CAP_DEFAULT); > >>>> rcu_read_unlock(); > >>>> > >>>> return (ret == 0); > >>>> @@ -340,7 +340,7 @@ bool has_ns_capability_noaudit(struct task_struct *t, > >>>> int ret; > >>>> > >>>> rcu_read_lock(); > >>>> - ret = security_capable_noaudit(__task_cred(t), ns, cap); > >>>> + ret = security_capable(__task_cred(t), ns, cap, SECURITY_CAP_NOAUDIT); > >>>> rcu_read_unlock(); > >>>> > >>>> return (ret == 0); > >>>> @@ -363,7 +363,9 @@ bool has_capability_noaudit(struct task_struct *t, int cap) > >>>> return has_ns_capability_noaudit(t, &init_user_ns, cap); > >>>> } > >>>> > >>>> -static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit) > >>>> +static bool ns_capable_common(struct user_namespace *ns, > >>>> + int cap, > >>>> + unsigned int opts) > >>>> { > >>>> int capable; > >>>> > >>>> @@ -372,8 +374,7 @@ static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit) > >>>> BUG(); > >>>> } > >>>> > >>>> - capable = audit ? security_capable(current_cred(), ns, cap) : > >>>> - security_capable_noaudit(current_cred(), ns, cap); > >>>> + capable = security_capable(current_cred(), ns, cap, opts); > >>>> if (capable == 0) { > >>>> current->flags |= PF_SUPERPRIV; > >>>> return true; > >>>> @@ -394,7 +395,7 @@ static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit) > >>>> */ > >>>> bool ns_capable(struct user_namespace *ns, int cap) > >>>> { > >>>> - return ns_capable_common(ns, cap, true); > >>>> + return ns_capable_common(ns, cap, SECURITY_CAP_DEFAULT); > >>>> } > >>>> EXPORT_SYMBOL(ns_capable); > >>>> > >>>> @@ -412,7 +413,7 @@ EXPORT_SYMBOL(ns_capable); > >>>> */ > >>>> bool ns_capable_noaudit(struct user_namespace *ns, int cap) > >>>> { > >>>> - return ns_capable_common(ns, cap, false); > >>>> + return ns_capable_common(ns, cap, SECURITY_CAP_NOAUDIT); > >>>> } > >>>> EXPORT_SYMBOL(ns_capable_noaudit); > >>>> > >>>> @@ -448,10 +449,11 @@ EXPORT_SYMBOL(capable); > >>>> bool file_ns_capable(const struct file *file, struct user_namespace *ns, > >>>> int cap) > >>>> { > >>>> + > >>>> if (WARN_ON_ONCE(!cap_valid(cap))) > >>>> return false; > >>>> > >>>> - if (security_capable(file->f_cred, ns, cap) == 0) > >>>> + if (security_capable(file->f_cred, ns, cap, SECURITY_CAP_DEFAULT) == 0) > >>>> return true; > >>>> > >>>> return false; > >>>> @@ -500,10 +502,12 @@ bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns) > >>>> { > >>>> int ret = 0; /* An absent tracer adds no restrictions */ > >>>> const struct cred *cred; > >>>> + > >>>> rcu_read_lock(); > >>>> cred = rcu_dereference(tsk->ptracer_cred); > >>>> if (cred) > >>>> - ret = security_capable_noaudit(cred, ns, CAP_SYS_PTRACE); > >>>> + ret = security_capable(cred, ns, CAP_SYS_PTRACE, > >>>> + SECURITY_CAP_NOAUDIT); > >>>> rcu_read_unlock(); > >>>> return (ret == 0); > >>>> } > >>>> diff --git a/kernel/seccomp.c b/kernel/seccomp.c > >>>> index f2ae2324c232..ddf615eb1bf7 100644 > >>>> --- a/kernel/seccomp.c > >>>> +++ b/kernel/seccomp.c > >>>> @@ -383,8 +383,8 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog) > >>>> * behavior of privileged children. > >>>> */ > >>>> if (!task_no_new_privs(current) && > >>>> - security_capable_noaudit(current_cred(), current_user_ns(), > >>>> - CAP_SYS_ADMIN) != 0) > >>>> + security_capable(current_cred(), current_user_ns(), > >>>> + CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT) != 0) > >>>> return ERR_PTR(-EACCES); > >>>> > >>>> /* Allocate a new seccomp_filter */ > >>>> diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c > >>>> index 253ef6e9d445..0f6dca54b66e 100644 > >>>> --- a/security/apparmor/capability.c > >>>> +++ b/security/apparmor/capability.c > >>>> @@ -110,13 +110,13 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile, > >>>> * profile_capable - test if profile allows use of capability @cap > >>>> * @profile: profile being enforced (NOT NULL, NOT unconfined) > >>>> * @cap: capability to test if allowed > >>>> - * @audit: whether an audit record should be generated > >>>> + * @opts: SECURITY_CAP_NOAUDIT bit determines whether audit record is generated > >>>> * @sa: audit data (MAY BE NULL indicating no auditing) > >>>> * > >>>> * Returns: 0 if allowed else -EPERM > >>>> */ > >>>> -static int profile_capable(struct aa_profile *profile, int cap, int audit, > >>>> - struct common_audit_data *sa) > >>>> +static int profile_capable(struct aa_profile *profile, int cap, > >>>> + unsigned int opts, struct common_audit_data *sa) > >>>> { > >>>> int error; > >>>> > >>>> @@ -126,7 +126,7 @@ static int profile_capable(struct aa_profile *profile, int cap, int audit, > >>>> else > >>>> error = -EPERM; > >>>> > >>>> - if (audit == SECURITY_CAP_NOAUDIT) { > >>>> + if (opts & SECURITY_CAP_NOAUDIT) { > >>>> if (!COMPLAIN_MODE(profile)) > >>>> return error; > >>>> /* audit the cap request in complain mode but note that it > >>>> @@ -142,13 +142,13 @@ static int profile_capable(struct aa_profile *profile, int cap, int audit, > >>>> * aa_capable - test permission to use capability > >>>> * @label: label being tested for capability (NOT NULL) > >>>> * @cap: capability to be tested > >>>> - * @audit: whether an audit record should be generated > >>>> + * @opts: SECURITY_CAP_NOAUDIT bit determines whether audit record is generated > >>>> * > >>>> * Look up capability in profile capability set. > >>>> * > >>>> * Returns: 0 on success, or else an error code. > >>>> */ > >>>> -int aa_capable(struct aa_label *label, int cap, int audit) > >>>> +int aa_capable(struct aa_label *label, int cap, unsigned int opts) > >>>> { > >>>> struct aa_profile *profile; > >>>> int error = 0; > >>>> @@ -156,7 +156,7 @@ int aa_capable(struct aa_label *label, int cap, int audit) > >>>> > >>>> sa.u.cap = cap; > >>>> error = fn_for_each_confined(label, profile, > >>>> - profile_capable(profile, cap, audit, &sa)); > >>>> + profile_capable(profile, cap, opts, &sa)); > >>>> > >>>> return error; > >>>> } > >>>> diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h > >>>> index e0304e2aeb7f..1b3663b6ab12 100644 > >>>> --- a/security/apparmor/include/capability.h > >>>> +++ b/security/apparmor/include/capability.h > >>>> @@ -40,7 +40,7 @@ struct aa_caps { > >>>> > >>>> extern struct aa_sfs_entry aa_sfs_entry_caps[]; > >>>> > >>>> -int aa_capable(struct aa_label *label, int cap, int audit); > >>>> +int aa_capable(struct aa_label *label, int cap, unsigned int opts); > >>>> > >>>> static inline void aa_free_cap_rules(struct aa_caps *caps) > >>>> { > >>>> diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c > >>>> index 527ea1557120..4a1da2313162 100644 > >>>> --- a/security/apparmor/ipc.c > >>>> +++ b/security/apparmor/ipc.c > >>>> @@ -107,7 +107,8 @@ static int profile_tracer_perm(struct aa_profile *tracer, > >>>> aad(sa)->label = &tracer->label; > >>>> aad(sa)->peer = tracee; > >>>> aad(sa)->request = 0; > >>>> - aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1); > >>>> + aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, > >>>> + SECURITY_CAP_DEFAULT); > >>>> > >>>> return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb); > >>>> } > >>>> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c > >>>> index 42446a216f3b..0bd817084fc1 100644 > >>>> --- a/security/apparmor/lsm.c > >>>> +++ b/security/apparmor/lsm.c > >>>> @@ -176,14 +176,14 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective, > >>>> } > >>>> > >>>> static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap, int audit) > >>>> + int cap, unsigned int opts) > >>>> { > >>>> struct aa_label *label; > >>>> int error = 0; > >>>> > >>>> label = aa_get_newest_cred_label(cred); > >>>> if (!unconfined(label)) > >>>> - error = aa_capable(label, cap, audit); > >>>> + error = aa_capable(label, cap, opts); > >>>> aa_put_label(label); > >>>> > >>>> return error; > >>>> diff --git a/security/commoncap.c b/security/commoncap.c > >>>> index 232db019f051..3d8609192e17 100644 > >>>> --- a/security/commoncap.c > >>>> +++ b/security/commoncap.c > >>>> @@ -68,7 +68,7 @@ static void warn_setuid_and_fcaps_mixed(const char *fname) > >>>> * kernel's capable() and has_capability() returns 1 for this case. > >>>> */ > >>>> int cap_capable(const struct cred *cred, struct user_namespace *targ_ns, > >>>> - int cap, int audit) > >>>> + int cap, unsigned int opts) > >>>> { > >>>> struct user_namespace *ns = targ_ns; > >>>> > >>>> @@ -222,12 +222,11 @@ int cap_capget(struct task_struct *target, kernel_cap_t *effective, > >>>> */ > >>>> static inline int cap_inh_is_capped(void) > >>>> { > >>>> - > >>>> /* they are so limited unless the current task has the CAP_SETPCAP > >>>> * capability > >>>> */ > >>>> if (cap_capable(current_cred(), current_cred()->user_ns, > >>>> - CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0) > >>>> + CAP_SETPCAP, SECURITY_CAP_DEFAULT) == 0) > >>>> return 0; > >>>> return 1; > >>>> } > >>>> @@ -1208,8 +1207,9 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3, > >>>> || ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ > >>>> || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ > >>>> || (cap_capable(current_cred(), > >>>> - current_cred()->user_ns, CAP_SETPCAP, > >>>> - SECURITY_CAP_AUDIT) != 0) /*[4]*/ > >>>> + current_cred()->user_ns, > >>>> + CAP_SETPCAP, > >>>> + SECURITY_CAP_DEFAULT) != 0) /*[4]*/ > >>>> /* > >>>> * [1] no changing of bits that are locked > >>>> * [2] no unlocking of locks > >>>> @@ -1304,9 +1304,10 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages) > >>>> { > >>>> int cap_sys_admin = 0; > >>>> > >>>> - if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN, > >>>> - SECURITY_CAP_NOAUDIT) == 0) > >>>> + if (cap_capable(current_cred(), &init_user_ns, > >>>> + CAP_SYS_ADMIN, SECURITY_CAP_NOAUDIT) == 0) > >>>> cap_sys_admin = 1; > >>>> + > >>>> return cap_sys_admin; > >>>> } > >>>> > >>>> @@ -1325,7 +1326,7 @@ int cap_mmap_addr(unsigned long addr) > >>>> > >>>> if (addr < dac_mmap_min_addr) { > >>>> ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO, > >>>> - SECURITY_CAP_AUDIT); > >>>> + SECURITY_CAP_DEFAULT); > >>>> /* set PF_SUPERPRIV if it turns out we allow the low mmap */ > >>>> if (ret == 0) > >>>> current->flags |= PF_SUPERPRIV; > >>>> diff --git a/security/security.c b/security/security.c > >>>> index d670136dda2c..d2334697797a 100644 > >>>> --- a/security/security.c > >>>> +++ b/security/security.c > >>>> @@ -294,16 +294,12 @@ int security_capset(struct cred *new, const struct cred *old, > >>>> effective, inheritable, permitted); > >>>> } > >>>> > >>>> -int security_capable(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap) > >>>> +int security_capable(const struct cred *cred, > >>>> + struct user_namespace *ns, > >>>> + int cap, > >>>> + unsigned int opts) > >>>> { > >>>> - return call_int_hook(capable, 0, cred, ns, cap, SECURITY_CAP_AUDIT); > >>>> -} > >>>> - > >>>> -int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap) > >>>> -{ > >>>> - return call_int_hook(capable, 0, cred, ns, cap, SECURITY_CAP_NOAUDIT); > >>>> + return call_int_hook(capable, 0, cred, ns, cap, opts); > >>>> } > >>>> > >>>> int security_quotactl(int cmds, int type, int id, struct super_block *sb) > >>>> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > >>>> index a67459eb62d5..a4b2e49213de 100644 > >>>> --- a/security/selinux/hooks.c > >>>> +++ b/security/selinux/hooks.c > >>>> @@ -1769,7 +1769,7 @@ static inline u32 signal_to_av(int sig) > >>>> > >>>> /* Check whether a task is allowed to use a capability. */ > >>>> static int cred_has_capability(const struct cred *cred, > >>>> - int cap, int audit, bool initns) > >>>> + int cap, unsigned int opts, bool initns) > >>>> { > >>>> struct common_audit_data ad; > >>>> struct av_decision avd; > >>>> @@ -1796,7 +1796,7 @@ static int cred_has_capability(const struct cred *cred, > >>>> > >>>> rc = avc_has_perm_noaudit(&selinux_state, > >>>> sid, sid, sclass, av, 0, &avd); > >>>> - if (audit == SECURITY_CAP_AUDIT) { > >>>> + if (!(opts & SECURITY_CAP_NOAUDIT)) { > >>>> int rc2 = avc_audit(&selinux_state, > >>>> sid, sid, sclass, av, &avd, rc, &ad, 0); > >>>> if (rc2) > >>>> @@ -2316,9 +2316,9 @@ static int selinux_capset(struct cred *new, const struct cred *old, > >>>> */ > >>>> > >>>> static int selinux_capable(const struct cred *cred, struct user_namespace *ns, > >>>> - int cap, int audit) > >>>> + int cap, unsigned int opts) > >>>> { > >>>> - return cred_has_capability(cred, cap, audit, ns == &init_user_ns); > >>>> + return cred_has_capability(cred, cap, opts, ns == &init_user_ns); > >>>> } > >>>> > >>>> static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) > >>>> @@ -3245,11 +3245,11 @@ static int selinux_inode_getattr(const struct path *path) > >>>> static bool has_cap_mac_admin(bool audit) > >>>> { > >>>> const struct cred *cred = current_cred(); > >>>> - int cap_audit = audit ? SECURITY_CAP_AUDIT : SECURITY_CAP_NOAUDIT; > >>>> + unsigned int opts = audit ? SECURITY_CAP_DEFAULT : SECURITY_CAP_NOAUDIT; > >>>> > >>>> - if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, cap_audit)) > >>>> + if (cap_capable(cred, &init_user_ns, CAP_MAC_ADMIN, opts)) > >>>> return false; > >>>> - if (cred_has_capability(cred, CAP_MAC_ADMIN, cap_audit, true)) > >>>> + if (cred_has_capability(cred, CAP_MAC_ADMIN, opts, true)) > >>>> return false; > >>>> return true; > >>>> } > >>>> @@ -3649,7 +3649,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, > >>>> case KDSKBENT: > >>>> case KDSKBSENT: > >>>> error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, > >>>> - SECURITY_CAP_AUDIT, true); > >>>> + SECURITY_CAP_DEFAULT, true); > >>>> break; > >>>> > >>>> /* default case assumes that the command will go > >>>> diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c > >>>> index 9a4c0ad46518..fac2a21aa7d4 100644 > >>>> --- a/security/smack/smack_access.c > >>>> +++ b/security/smack/smack_access.c > >>>> @@ -640,7 +640,7 @@ bool smack_privileged_cred(int cap, const struct cred *cred) > >>>> struct smack_known_list_elem *sklep; > >>>> int rc; > >>>> > >>>> - rc = cap_capable(cred, &init_user_ns, cap, SECURITY_CAP_AUDIT); > >>>> + rc = cap_capable(cred, &init_user_ns, cap, SECURITY_CAP_DEFAULT); > >>>> if (rc) > >>>> return false; > >>>> > >>>> -- > >>>> 2.20.0.405.gbc1bbc6f85-goog > >>>> >