From: Will Deacon <will@kernel.org>
To: selinux@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, Will Deacon <will@kernel.org>
Subject: [RFC PATCH 2/2] selinux: Propagate RCU walk status from 'security_inode_follow_link()'
Date: Tue, 19 Nov 2019 18:40:57 +0000 [thread overview]
Message-ID: <20191119184057.14961-3-will@kernel.org> (raw)
In-Reply-To: <20191119184057.14961-1-will@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 <will@kernel.org>
---
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,
--
2.24.0.432.g9d3f5f5b63-goog
next prev parent reply other threads:[~2019-11-19 18:41 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-19 18:40 [RFC PATCH 0/2] Avoid blocking in selinux inode callbacks on RCU walk Will Deacon
2019-11-19 18:40 ` [RFC PATCH 1/2] selinux: Don't call avc_compute_av() from RCU path walk Will Deacon
2019-11-19 18:59 ` Stephen Smalley
2019-11-20 13:12 ` Will Deacon
2019-11-20 15:28 ` Stephen Smalley
2019-11-20 19:07 ` Paul E. McKenney
2019-11-20 19:13 ` Will Deacon
2019-11-19 18:40 ` Will Deacon [this message]
2019-11-19 18:46 ` [RFC PATCH 2/2] selinux: Propagate RCU walk status from 'security_inode_follow_link()' Stephen Smalley
2019-11-20 13:13 ` Will Deacon
2019-11-20 13:31 ` Stephen Smalley
2019-11-29 7:36 ` [selinux] 5149a783b9: WARNING:at_security/selinux/avc.c:#avc_has_perm_flags kernel test robot
2019-11-29 7:36 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191119184057.14961-3-will@kernel.org \
--to=will@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=selinux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.