* [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link"
@ 2019-11-22 17:22 Stephen Smalley
2019-11-22 17:22 ` [PATCH 2/2] selinux: fall back to ref-walk if audit is required Stephen Smalley
2019-12-09 23:42 ` [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" Paul Moore
0 siblings, 2 replies; 4+ messages in thread
From: Stephen Smalley @ 2019-11-22 17:22 UTC (permalink / raw)
To: selinux
Cc: paul, will, viro, neilb, linux-fsdevel, linux-security-module,
Stephen Smalley
This reverts commit e46e01eebbbc ("selinux: stop passing MAY_NOT_BLOCK
to the AVC upon follow_link"). The correct fix is to instead fall
back to ref-walk if audit is required irrespective of the specific
audit data type. This is done in the next commit.
Fixes: e46e01eebbbc ("selinux: stop passing MAY_NOT_BLOCK to the AVC upon follow_link")
Reported-by: Will Deacon <will@kernel.org>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
---
security/selinux/avc.c | 24 ++++++++++++++++++++++--
security/selinux/hooks.c | 5 +++--
security/selinux/include/avc.h | 5 +++++
3 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index ecd3829996aa..74c43ebe34bb 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -862,8 +862,9 @@ static int avc_update_node(struct selinux_avc *avc,
* permissive mode that only appear when in enforcing mode.
*
* See the corresponding handling in slow_avc_audit(), and the
- * logic in selinux_inode_permission for the MAY_NOT_BLOCK flag,
- * which is transliterated into AVC_NONBLOCKING.
+ * logic in selinux_inode_follow_link and selinux_inode_permission
+ * for the VFS MAY_NOT_BLOCK flag, which is transliterated into
+ * AVC_NONBLOCKING for avc_has_perm_noaudit().
*/
if (flags & AVC_NONBLOCKING)
return 0;
@@ -1205,6 +1206,25 @@ int avc_has_perm(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass,
return rc;
}
+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 av_decision avd;
+ int rc, rc2;
+
+ rc = avc_has_perm_noaudit(state, ssid, tsid, tclass, requested,
+ (flags & MAY_NOT_BLOCK) ? AVC_NONBLOCKING : 0,
+ &avd);
+
+ rc2 = avc_audit(state, ssid, tsid, tclass, requested, &avd, rc,
+ auditdata, flags);
+ if (rc2)
+ return rc2;
+ return rc;
+}
+
u32 avc_policy_seqno(struct selinux_state *state)
{
return state->avc->avc_cache.latest_notif;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 36e531b91df2..3eaa3b419463 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, FILE__READ, &ad,
+ rcu ? MAY_NOT_BLOCK : 0);
}
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..74ea50977c20 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -153,6 +153,11 @@ 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,
+ struct common_audit_data *auditdata,
+ int flags);
int avc_has_extended_perms(struct selinux_state *state,
u32 ssid, u32 tsid, u16 tclass, u32 requested,
--
2.23.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH 2/2] selinux: fall back to ref-walk if audit is required 2019-11-22 17:22 [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" Stephen Smalley @ 2019-11-22 17:22 ` Stephen Smalley 2019-12-09 23:42 ` Paul Moore 2019-12-09 23:42 ` [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" Paul Moore 1 sibling, 1 reply; 4+ messages in thread From: Stephen Smalley @ 2019-11-22 17:22 UTC (permalink / raw) To: selinux Cc: paul, will, viro, neilb, linux-fsdevel, linux-security-module, Stephen Smalley commit bda0be7ad994 ("security: make inode_follow_link RCU-walk aware") passed down the rcu flag to the SELinux AVC, but failed to adjust the test in slow_avc_audit() to also return -ECHILD on LSM_AUDIT_DATA_DENTRY. Previously, we only returned -ECHILD if generating an audit record with LSM_AUDIT_DATA_INODE since this was only relevant from inode_permission. Move the handling of MAY_NOT_BLOCK to avc_audit() and its inlined equivalent in selinux_inode_permission() immediately after we determine that audit is required, and always fall back to ref-walk in this case. Fixes: bda0be7ad994 ("security: make inode_follow_link RCU-walk aware") Reported-by: Will Deacon <will@kernel.org> Suggested-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> --- security/selinux/avc.c | 24 +++++------------------- security/selinux/hooks.c | 11 +++++++---- security/selinux/include/avc.h | 8 +++++--- 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 74c43ebe34bb..23dc888ae305 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -424,7 +424,7 @@ static inline int avc_xperms_audit(struct selinux_state *state, if (likely(!audited)) return 0; return slow_avc_audit(state, ssid, tsid, tclass, requested, - audited, denied, result, ad, 0); + audited, denied, result, ad); } static void avc_node_free(struct rcu_head *rhead) @@ -758,8 +758,7 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) noinline int slow_avc_audit(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, int result, - struct common_audit_data *a, - unsigned int flags) + struct common_audit_data *a) { struct common_audit_data stack_data; struct selinux_audit_data sad; @@ -772,17 +771,6 @@ noinline int slow_avc_audit(struct selinux_state *state, a->type = LSM_AUDIT_DATA_NONE; } - /* - * When in a RCU walk do the audit on the RCU retry. This is because - * the collection of the dname in an inode audit message is not RCU - * safe. Note this may drop some audits when the situation changes - * during retry. However this is logically just as if the operation - * happened a little later. - */ - if ((a->type == LSM_AUDIT_DATA_INODE) && - (flags & MAY_NOT_BLOCK)) - return -ECHILD; - sad.tclass = tclass; sad.requested = requested; sad.ssid = ssid; @@ -855,16 +843,14 @@ static int avc_update_node(struct selinux_avc *avc, /* * 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 cannot safely audit the denial. Otherwise, + * 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 in slow_avc_audit(), and the - * logic in selinux_inode_follow_link and selinux_inode_permission - * for the VFS MAY_NOT_BLOCK flag, which is transliterated into - * AVC_NONBLOCKING for avc_has_perm_noaudit(). + * See the corresponding handling of MAY_NOT_BLOCK in avc_audit() + * and selinux_inode_permission(). */ if (flags & AVC_NONBLOCKING) return 0; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 3eaa3b419463..fd34e25c016f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3015,8 +3015,7 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct inode *inode, static noinline int audit_inode_permission(struct inode *inode, u32 perms, u32 audited, u32 denied, - int result, - unsigned flags) + int result) { struct common_audit_data ad; struct inode_security_struct *isec = selinux_inode(inode); @@ -3027,7 +3026,7 @@ static noinline int audit_inode_permission(struct inode *inode, rc = slow_avc_audit(&selinux_state, current_sid(), isec->sid, isec->sclass, perms, - audited, denied, result, &ad, flags); + audited, denied, result, &ad); if (rc) return rc; return 0; @@ -3074,7 +3073,11 @@ static int selinux_inode_permission(struct inode *inode, int mask) if (likely(!audited)) return rc; - rc2 = audit_inode_permission(inode, perms, audited, denied, rc, flags); + /* fall back to ref-walk if we have to generate audit */ + if (flags & MAY_NOT_BLOCK) + return -ECHILD; + + rc2 = audit_inode_permission(inode, perms, audited, denied, rc); if (rc2) return rc2; return rc; diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index 74ea50977c20..cf4cc3ef959b 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h @@ -100,8 +100,7 @@ static inline u32 avc_audit_required(u32 requested, int slow_avc_audit(struct selinux_state *state, u32 ssid, u32 tsid, u16 tclass, u32 requested, u32 audited, u32 denied, int result, - struct common_audit_data *a, - unsigned flags); + struct common_audit_data *a); /** * avc_audit - Audit the granting or denial of permissions. @@ -135,9 +134,12 @@ 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, flags); + a); } #define AVC_STRICT 1 /* Ignore permissive mode. */ -- 2.23.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] selinux: fall back to ref-walk if audit is required 2019-11-22 17:22 ` [PATCH 2/2] selinux: fall back to ref-walk if audit is required Stephen Smalley @ 2019-12-09 23:42 ` Paul Moore 0 siblings, 0 replies; 4+ messages in thread From: Paul Moore @ 2019-12-09 23:42 UTC (permalink / raw) To: Stephen Smalley Cc: selinux, will, viro, neilb, linux-fsdevel, linux-security-module On Fri, Nov 22, 2019 at 12:23 PM Stephen Smalley <sds@tycho.nsa.gov> wrote: > commit bda0be7ad994 ("security: make inode_follow_link RCU-walk aware") > passed down the rcu flag to the SELinux AVC, but failed to adjust the > test in slow_avc_audit() to also return -ECHILD on LSM_AUDIT_DATA_DENTRY. > Previously, we only returned -ECHILD if generating an audit record with > LSM_AUDIT_DATA_INODE since this was only relevant from inode_permission. > Move the handling of MAY_NOT_BLOCK to avc_audit() and its inlined > equivalent in selinux_inode_permission() immediately after we determine > that audit is required, and always fall back to ref-walk in this case. > > Fixes: bda0be7ad994 ("security: make inode_follow_link RCU-walk aware") > Reported-by: Will Deacon <will@kernel.org> > Suggested-by: Al Viro <viro@zeniv.linux.org.uk> > Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> > --- > security/selinux/avc.c | 24 +++++------------------- > security/selinux/hooks.c | 11 +++++++---- > security/selinux/include/avc.h | 8 +++++--- > 3 files changed, 17 insertions(+), 26 deletions(-) Also merged into selinux/next, thanks. -- paul moore www.paul-moore.com ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" 2019-11-22 17:22 [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" Stephen Smalley 2019-11-22 17:22 ` [PATCH 2/2] selinux: fall back to ref-walk if audit is required Stephen Smalley @ 2019-12-09 23:42 ` Paul Moore 1 sibling, 0 replies; 4+ messages in thread From: Paul Moore @ 2019-12-09 23:42 UTC (permalink / raw) To: Stephen Smalley Cc: selinux, will, viro, neilb, linux-fsdevel, linux-security-module On Fri, Nov 22, 2019 at 12:23 PM Stephen Smalley <sds@tycho.nsa.gov> wrote: > This reverts commit e46e01eebbbc ("selinux: stop passing MAY_NOT_BLOCK > to the AVC upon follow_link"). The correct fix is to instead fall > back to ref-walk if audit is required irrespective of the specific > audit data type. This is done in the next commit. > > Fixes: e46e01eebbbc ("selinux: stop passing MAY_NOT_BLOCK to the AVC upon follow_link") > Reported-by: Will Deacon <will@kernel.org> > Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> > --- > security/selinux/avc.c | 24 ++++++++++++++++++++++-- > security/selinux/hooks.c | 5 +++-- > security/selinux/include/avc.h | 5 +++++ > 3 files changed, 30 insertions(+), 4 deletions(-) Merged into selinux/next, thanks. -- paul moore www.paul-moore.com ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-12-09 23:43 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-11-22 17:22 [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" Stephen Smalley 2019-11-22 17:22 ` [PATCH 2/2] selinux: fall back to ref-walk if audit is required Stephen Smalley 2019-12-09 23:42 ` Paul Moore 2019-12-09 23:42 ` [PATCH 1/2] selinux: revert "stop passing MAY_NOT_BLOCK to the AVC upon follow_link" Paul Moore
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox