On Fri, Nov 22, 2019 at 11:27:37AM -0500, Stephen Smalley wrote: > On 11/22/19 11:11 AM, Al Viro wrote: > > On Thu, Nov 21, 2019 at 09:52:45AM -0500, Stephen Smalley 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. > > > Return -ECHILD on either LSM_AUDIT_DATA_INODE or LSM_AUDIT_DATA_DENTRY. > > > LSM_AUDIT_DATA_INODE only requires this handling due to the fact > > > that dump_common_audit_data() calls d_find_alias() and collects the > > > dname from the result if any. > > > Other cases that might require similar treatment in the future are > > > LSM_AUDIT_DATA_PATH and LSM_AUDIT_DATA_FILE if any hook that takes > > > a path or file is called under RCU-walk. > > > > > > Fixes: bda0be7ad994 ("security: make inode_follow_link RCU-walk aware") > > > Signed-off-by: Stephen Smalley <sds@xxxxxxxxxxxxx> > > > --- > > > security/selinux/avc.c | 3 ++- > > > 1 file changed, 2 insertions(+), 1 deletion(-) > > > > > > diff --git a/security/selinux/avc.c b/security/selinux/avc.c > > > index 74c43ebe34bb..f1fa1072230c 100644 > > > --- a/security/selinux/avc.c > > > +++ b/security/selinux/avc.c > > > @@ -779,7 +779,8 @@ noinline int slow_avc_audit(struct selinux_state *state, > > > * during retry. However this is logically just as if the operation > > > * happened a little later. > > > */ > > > - if ((a->type == LSM_AUDIT_DATA_INODE) && > > > + if ((a->type == LSM_AUDIT_DATA_INODE || > > > + a->type == LSM_AUDIT_DATA_DENTRY) && > > > (flags & MAY_NOT_BLOCK)) > > > > IDGI, to be honest. Why do we bother with slow path if MAY_NOT_BLOCK has > > been given? If we'd run into "there's something to report" case, we > > are not on the fastpath anymore. IOW, why not have > > audited = avc_audit_required(requested, avd, result, 0, &denied); > > if (likely(!audited)) > > return 0; > > if (flags & MAY_NOT_BLOCK) > > return -ECHILD; > > return slow_avc_audit(state, ssid, tsid, tclass, > > requested, audited, denied, result, > > a, flags); > > in avc_audit() and be done with that? > > That works for me; we would also need to do the same in > selinux_inode_permission(). We can then stop passing flags down to > slow_avc_audit() entirely. I'm new to looking at this code, but that would certainly have helped me to understand it when I was reading it a couple of weeks back! So, for what it's worth, you can count me in favour. Cheers, Will