From patchwork Thu Jun 10 15:51:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 12313423 X-Patchwork-Delegate: paul@paul-moore.com 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 85600C48BDF for ; Thu, 10 Jun 2021 15:51:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6EDF4613D8 for ; Thu, 10 Jun 2021 15:51:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231770AbhFJPxL (ORCPT ); Thu, 10 Jun 2021 11:53:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35786 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231769AbhFJPxL (ORCPT ); Thu, 10 Jun 2021 11:53:11 -0400 Received: from zeniv-ca.linux.org.uk (zeniv-ca.linux.org.uk [IPv6:2607:5300:60:148a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E129BC061574 for ; Thu, 10 Jun 2021 08:51:14 -0700 (PDT) Received: from viro by zeniv-ca.linux.org.uk with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1lrMxd-006dDH-TU for selinux@vger.kernel.org; Thu, 10 Jun 2021 15:51:14 +0000 Date: Thu, 10 Jun 2021 15:51:13 +0000 From: Al Viro To: selinux@vger.kernel.org Subject: [PATCH 1/2] selinux: slow_avc_audit has become non-blocking Message-ID: MIME-Version: 1.0 Content-Disposition: inline Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org [followup to dump_common_audit_data() changes from this winter; in vfs.git#work.audit] Does anybody have objections to the below? From 663a40ab49308b5acaba8a335190fce66e17d969 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 16 Jan 2021 15:40:54 -0500 Subject: [PATCH 1/2] selinux: slow_avc_audit has become non-blocking dump_common_audit_data() is safe to use under rcu_read_lock() now; no need for AVC_NONBLOCKING and games around it Signed-off-by: Al Viro --- security/selinux/avc.c | 28 ++++++++-------------------- security/selinux/hooks.c | 13 ++----------- security/selinux/include/avc.h | 4 ---- 3 files changed, 10 insertions(+), 35 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ad451cf9375e..9c3d2a29616a 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -758,7 +758,11 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) } } -/* This is the slow part of avc audit with big stack footprint */ +/* + * This is the slow part of avc audit with big stack footprint. + * Note that it is non-blocking and can be called from under + * rcu_read_lock(). + */ noinline int slow_avc_audit(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, int result, @@ -825,7 +829,7 @@ int __init avc_add_callback(int (*callback)(u32 event), u32 events) * @ssid,@tsid,@tclass : identifier of an AVC entry * @seqno : sequence number when decision was made * @xpd: extended_perms_decision to be added to the node - * @flags: the AVC_* flags, e.g. AVC_NONBLOCKING, AVC_EXTENDED_PERMS, or 0. + * @flags: the AVC_* flags, e.g. AVC_EXTENDED_PERMS, or 0. * * if a valid AVC entry doesn't exist,this function returns -ENOENT. * if kmalloc() called internal returns NULL, this function returns -ENOMEM. @@ -844,21 +848,6 @@ static int avc_update_node(struct selinux_avc *avc, struct hlist_head *head; spinlock_t *lock; - /* - * If we are in a non-blocking code path, e.g. VFS RCU walk, - * then we must not add permissions to a cache entry - * because we will not audit the denial. Otherwise, - * during the subsequent blocking retry (e.g. VFS ref walk), we - * will find the permissions already granted in the cache entry - * and won't audit anything at all, leading to silent denials in - * permissive mode that only appear when in enforcing mode. - * - * See the corresponding handling of MAY_NOT_BLOCK in avc_audit() - * and selinux_inode_permission(). - */ - if (flags & AVC_NONBLOCKING) - return 0; - node = avc_alloc_node(avc); if (!node) { rc = -ENOMEM; @@ -1119,7 +1108,7 @@ int avc_has_extended_perms(struct selinux_state *state, * @tsid: target security identifier * @tclass: target security class * @requested: requested permissions, interpreted based on @tclass - * @flags: AVC_STRICT, AVC_NONBLOCKING, or 0 + * @flags: AVC_STRICT or 0 * @avd: access vector decisions * * Check the AVC to determine whether the @requested permissions are granted @@ -1204,8 +1193,7 @@ int avc_has_perm_flags(struct selinux_state *state, struct av_decision avd; int rc, rc2; - rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, - (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0, + rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0, &avd); rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index eaea837d89d1..f22ad1229471 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3164,17 +3164,13 @@ static noinline int audit_inode_permission(struct inode *inode, { struct common_audit_data ad; struct inode_security_struct *isec = selinux_inode(inode); - int rc; ad.type = LSM_AUDIT_DATA_INODE; ad.u.inode = inode; - rc = slow_avc_audit(&selinux_state, + return slow_avc_audit(&selinux_state, current_sid(), isec->sid, isec->sclass, perms, audited, denied, result, &ad); - if (rc) - return rc; - return 0; } static int selinux_inode_permission(struct inode *inode, int mask) @@ -3209,8 +3205,7 @@ static int selinux_inode_permission(struct inode *inode, int mask) return PTR_ERR(isec); rc = avc_has_perm_noaudit(&selinux_state, - sid, isec->sid, isec->sclass, perms, - no_block ? AVC_NONBLOCKING : 0, + sid, isec->sid, isec->sclass, perms, 0, &avd); audited = avc_audit_required(perms, &avd, rc, from_access ? FILE__AUDIT_ACCESS : 0, @@ -3218,10 +3213,6 @@ static int selinux_inode_permission(struct inode *inode, int mask) if (likely(!audited)) return rc; - /* fall back to ref-walk if we have to generate audit */ - if (no_block) - return -ECHILD; - rc2 = audit_inode_permission(inode, perms, audited, denied, rc); if (rc2) return rc2; diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index cf4cc3ef959b..c3bbfc8e8b46 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -134,9 +134,6 @@ static inline int avc_audit(struct selinux_state *state, audited = avc_audit_required(requested, avd, result, 0, &denied); if (likely(!audited)) return 0; - /* fall back to ref-walk if we have to generate audit */ - if (flags & MAY_NOT_BLOCK) - return -ECHILD; return slow_avc_audit(state, ssid, tsid, tclass, requested, audited, denied, result, a); @@ -144,7 +141,6 @@ static inline int avc_audit(struct selinux_state *state, #define AVC_STRICT 1 /* Ignore permissive mode. */ #define AVC_EXTENDED_PERMS 2 /* update extended permissions */ -#define AVC_NONBLOCKING 4 /* non blocking */ int avc_has_perm_noaudit(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, From patchwork Thu Jun 10 15:52:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Viro X-Patchwork-Id: 12313425 X-Patchwork-Delegate: paul@paul-moore.com 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=-13.8 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,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 912DFC47094 for ; Thu, 10 Jun 2021 15:52:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 75A1F613CB for ; Thu, 10 Jun 2021 15:52:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230366AbhFJPyD (ORCPT ); Thu, 10 Jun 2021 11:54:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35980 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231665AbhFJPyA (ORCPT ); Thu, 10 Jun 2021 11:54:00 -0400 Received: from zeniv-ca.linux.org.uk (zeniv-ca.linux.org.uk [IPv6:2607:5300:60:148a::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4EA3EC061574 for ; Thu, 10 Jun 2021 08:52:04 -0700 (PDT) Received: from viro by zeniv-ca.linux.org.uk with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1lrMyQ-006dED-5Z for selinux@vger.kernel.org; Thu, 10 Jun 2021 15:52:02 +0000 Date: Thu, 10 Jun 2021 15:52:02 +0000 From: Al Viro To: selinux@vger.kernel.org Subject: [PATCH 2/2] kill unused 'flags' argument in avc_has_perm_flags() and avc_audit() Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Sender: Al Viro Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org From 565799de3ee0a295842a07a5f9a459db5e793beb Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 16 Jan 2021 15:57:49 -0500 Subject: [PATCH 2/2] kill unused 'flags' argument in avc_has_perm_flags() and avc_audit() Signed-off-by: Al Viro --- security/selinux/avc.c | 7 +++---- security/selinux/hooks.c | 5 ++--- security/selinux/include/avc.h | 7 ++----- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 9c3d2a29616a..10b71a0efc50 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -1179,7 +1179,7 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, &avd); rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, - auditdata, 0); + auditdata); if (rc2) return rc2; return rc; @@ -1187,8 +1187,7 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, int avc_has_perm_flags(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, - struct common_audit_data *auditdata, - int flags) + struct common_audit_data *auditdata) { struct av_decision avd; int rc, rc2; @@ -1197,7 +1196,7 @@ int avc_has_perm_flags(struct selinux_state *state, &avd); rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, - auditdata, flags); + auditdata); if (rc2) return rc2; return rc; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f22ad1229471..2ae55348bd1c 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1676,7 +1676,7 @@ static int cred_has_capability(const struct cred *cred, sid, sid, sclass, av, 0, &avd); if (!(opts & CAP_OPT_NOAUDIT)) { int rc2 = avc_audit(&selinux_state, - sid, sid, sclass, av, &avd, rc, &ad, 0); + sid, sid, sclass, av, &avd, rc, &ad); if (rc2) return rc2; } @@ -3154,8 +3154,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, return PTR_ERR(isec); return avc_has_perm_flags(&selinux_state, - sid, isec->sid, isec->sclass, FILE__READ, &ad, - rcu ? MAY_NOT_BLOCK : 0); + sid, isec->sid, isec->sclass, FILE__READ, &ad); } static noinline int audit_inode_permission(struct inode *inode, diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index c3bbfc8e8b46..098f31c415e2 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -111,7 +111,6 @@ int slow_avc_audit(struct selinux_state *state, * @avd: access vector decisions * @result: result from avc_has_perm_noaudit * @a: auxiliary audit data - * @flags: VFS walk flags * * Audit the granting or denial of permissions in accordance * with the policy. This function is typically called by @@ -127,8 +126,7 @@ static inline int avc_audit(struct selinux_state *state, u16 tclass, u32 requested, struct av_decision *avd, int result, - struct common_audit_data *a, - int flags) + struct common_audit_data *a) { u32 audited, denied; audited = avc_audit_required(requested, avd, result, 0, &denied); @@ -154,8 +152,7 @@ int avc_has_perm(struct selinux_state *state, int avc_has_perm_flags(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, - struct common_audit_data *auditdata, - int flags); + struct common_audit_data *auditdata); int avc_has_extended_perms(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested,