From patchwork Tue Nov 19 18:40:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 11252567 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E23B138C for ; Tue, 19 Nov 2019 18:41:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 2737122409 for ; Tue, 19 Nov 2019 18:41:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574188874; bh=ID5i6LVxAXJWLxbt0faGOihxGx2WttitYMxA2sPDKsg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=1s41y0pFAqi4Bnk9XSd5W6hIhliBpv0EUeZoTgp5qi7jVkO6D1EsYzy6jArtgKLRI NfPSHEk093lybJknmz3vNNC68beJyzd4aWa4kzdiVbGexiyBn3M14kwqJCpcvQwj3H 2Z2esu2wolhKIkRDsM+3Zj2wul6ARzQBgWK+D06A= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727415AbfKSSlG (ORCPT ); Tue, 19 Nov 2019 13:41:06 -0500 Received: from mail.kernel.org ([198.145.29.99]:52788 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726792AbfKSSlF (ORCPT ); Tue, 19 Nov 2019 13:41:05 -0500 Received: from localhost.localdomain (236.31.169.217.in-addr.arpa [217.169.31.236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1FCEF2240B; Tue, 19 Nov 2019 18:41:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574188864; bh=ID5i6LVxAXJWLxbt0faGOihxGx2WttitYMxA2sPDKsg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qQeCmPx7uvR5TXjLvO7hl3dDLVDJuANdiapoBJXvEorZvmmemwQ1gwz7fDtcYWOFE LguQTyU5XUPAOyclY6HGobwDxqVnAgqEwpEH7X539g6d2bxf16aacY1YSLQwNaaRY6 SnmG7fnRc750oLaOnarXXwH/xG4CXev6Q8uU5VtM= From: Will Deacon To: selinux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Will Deacon Subject: [RFC PATCH 1/2] selinux: Don't call avc_compute_av() from RCU path walk Date: Tue, 19 Nov 2019 18:40:56 +0000 Message-Id: <20191119184057.14961-2-will@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191119184057.14961-1-will@kernel.org> References: <20191119184057.14961-1-will@kernel.org> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 'avc_compute_av()' can block, so we carefully exit the RCU read-side critical section before calling it in 'avc_has_perm_noaudit()'. Unfortunately, if we're calling from the VFS layer on the RCU path walk via 'selinux_inode_permission()' then we're still actually in an RCU read-side critical section and must not block. 'avc_denied()' already handles this by simply returning success and postponing the auditing until we're called again on the slowpath, so follow the same approach here and return early if the node lookup fails on the RCU walk path. Signed-off-by: Will Deacon --- security/selinux/avc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index ecd3829996aa..9c183c899e92 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -1159,16 +1159,19 @@ inline int avc_has_perm_noaudit(struct selinux_state *state, rcu_read_lock(); node = avc_lookup(state->avc, ssid, tsid, tclass); - if (unlikely(!node)) + if (unlikely(!node)) { + if (flags & AVC_NONBLOCKING) + goto out; node = avc_compute_av(state, ssid, tsid, tclass, avd, &xp_node); - else + } else { memcpy(avd, &node->ae.avd, sizeof(*avd)); + } denied = requested & ~(avd->allowed); if (unlikely(denied)) rc = avc_denied(state, ssid, tsid, tclass, requested, 0, 0, flags, avd); - +out: rcu_read_unlock(); return rc; } From patchwork Tue Nov 19 18:40:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Will Deacon X-Patchwork-Id: 11252565 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A7ED5138C for ; Tue, 19 Nov 2019 18:41:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 8901C223E4 for ; Tue, 19 Nov 2019 18:41:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574188871; bh=3m7sna6+G+TQL2w+vr9AGbmik1zbuRAz/wJpe/P3i6Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=fV2g2syMgyp5phOcTdLNFIF8g/QReCLLWOUulqzALAdxBirfZA99Ot/TNSTPyXIiW PCF3e3NaB9hqvVQ8ESb8ysWPpphS1nvSDCDDvIX6yl4rrvdro/tJfc+HvOKxNxrjoI Y7/DrNqdKPB8oiPhdPQotqiehMvwR0dVw5dWkcYY= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727450AbfKSSlH (ORCPT ); Tue, 19 Nov 2019 13:41:07 -0500 Received: from mail.kernel.org ([198.145.29.99]:52826 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727205AbfKSSlG (ORCPT ); Tue, 19 Nov 2019 13:41:06 -0500 Received: from localhost.localdomain (236.31.169.217.in-addr.arpa [217.169.31.236]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 40E6422409; Tue, 19 Nov 2019 18:41:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1574188866; bh=3m7sna6+G+TQL2w+vr9AGbmik1zbuRAz/wJpe/P3i6Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oAGrncSLLMav3KH009Hn91MYEcG3QZYlOy9gCkO4ViFtZqwknzcxVMH9HxMmYruN/ ljeSnoc6en8McivZisV03omqYhbqL1Vl5IljpFmCWETsqtOdyAdV8bBlnPxvQdgFTV u7c/poT6uNg7/5ubDDfOsEf1lRvIUA5ytm8UVzyk= From: Will Deacon To: selinux@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Will Deacon Subject: [RFC PATCH 2/2] selinux: Propagate RCU walk status from 'security_inode_follow_link()' Date: Tue, 19 Nov 2019 18:40:57 +0000 Message-Id: <20191119184057.14961-3-will@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191119184057.14961-1-will@kernel.org> References: <20191119184057.14961-1-will@kernel.org> MIME-Version: 1.0 Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org 'selinux_inode_follow_link()' can be called as part of an RCU path walk, and is passed a 'bool rcu' parameter to indicate whether or not it is being called from within an RCU read-side critical section. Unfortunately, this knowledge is not propagated further and, instead, 'avc_has_perm()' unconditionally passes a flags argument of '0' to both 'avc_has_perm_noaudit()' and 'avc_audit()' which may block. Introduce 'avc_has_perm_flags()' which can be used safely from within an RCU read-side critical section. Signed-off-by: Will Deacon --- security/selinux/avc.c | 12 +++++++----- security/selinux/hooks.c | 5 +++-- security/selinux/include/avc.h | 12 ++++++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 9c183c899e92..7d99dadd24d0 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -1177,11 +1177,12 @@ inline int avc_has_perm_noaudit(struct selinux_state *state, } /** - * avc_has_perm - Check permissions and perform any appropriate auditing. + * avc_has_perm_flags - Check permissions and perform any appropriate auditing. * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @requested: requested permissions, interpreted based on @tclass + * @flags: AVC_STRICT, AVC_NONBLOCKING, or 0 * @auditdata: auxiliary audit data * * Check the AVC to determine whether the @requested permissions are granted @@ -1192,17 +1193,18 @@ inline int avc_has_perm_noaudit(struct selinux_state *state, * permissions are granted, -%EACCES if any permissions are denied, or * another -errno upon other errors. */ -int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, - u32 requested, struct common_audit_data *auditdata) +int avc_has_perm_flags(struct selinux_state *state, u32 ssid, u32 tsid, + u16 tclass, u32 requested, unsigned int flags, + struct common_audit_data *auditdata) { struct av_decision avd; int rc, rc2; - rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, 0, + rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested, flags, &avd); rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc, - auditdata, 0); + auditdata, flags); if (rc2) return rc2; return rc; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9625b99e677f..0c09f59a2740 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3008,8 +3008,9 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, if (IS_ERR(isec)) return PTR_ERR(isec); - return avc_has_perm(&selinux_state, - sid, isec->sid, isec->sclass, FILE__READ, &ad); + return avc_has_perm_flags(&selinux_state, sid, isec->sid, isec->sclass, + rcu ? AVC_NONBLOCKING : 0, + 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 7be0e1e90e8b..0450e1b88182 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -149,10 +149,14 @@ int avc_has_perm_noaudit(struct selinux_state *state, unsigned flags, struct av_decision *avd); -int avc_has_perm(struct selinux_state *state, - u32 ssid, u32 tsid, - u16 tclass, u32 requested, - struct common_audit_data *auditdata); +int avc_has_perm_flags(struct selinux_state *state, + u32 ssid, u32 tsid, + u16 tclass, u32 requested, + unsigned flags, + struct common_audit_data *auditdata); + +#define avc_has_perm(state, ssid, tsid, tclass, requested, auditdata) \ + avc_has_perm_flags(state, ssid, tsid, tclass, requested, 0, auditdata) int avc_has_extended_perms(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested,