[PATCH ALT4 V2 1/2] audit: show fstype:pathname for entries with anonymous parents

Paul Moore paul at paul-moore.com
Wed Jun 28 19:03:05 UTC 2017


On Tue, Jun 27, 2017 at 5:11 PM, Richard Guy Briggs <rgb at redhat.com> wrote:
> On 2017-05-30 17:21, Paul Moore wrote:
>> On Tue, Apr 4, 2017 at 5:21 AM, Richard Guy Briggs <rgb at redhat.com> wrote:

...

>> > diff --git a/kernel/audit.c b/kernel/audit.c
>> > index 25dd70a..7d83c5a 100644
>> > --- a/kernel/audit.c
>> > +++ b/kernel/audit.c
>> > @@ -66,6 +66,7 @@
>> >  #include <linux/freezer.h>
>> >  #include <linux/pid_namespace.h>
>> >  #include <net/netns/generic.h>
>> > +#include <linux/dcache.h>
>> >
>> >  #include "audit.h"
>> >
>> > @@ -1884,6 +1885,10 @@ void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,
>> >         name->gid   = inode->i_gid;
>> >         name->rdev  = inode->i_rdev;
>> >         security_inode_getsecid(inode, &name->osid);
>> > +       if (name->dentry) {
>> > +               dput(name->dentry);
>> > +               name->dentry = NULL;
>> > +       }
>>
>> Out of curiosity, what terrible things happen if we take a reference
>> to a non-NULL dentry passed to audit_copy_inode() and store it in
>> name->dentry?  Does performance tank?
>
> Interesting idea.  Right now it is optimized to only take a reference to
> the dentry's parent dentry in the case we're handed an anonymous entry.
> Most of the time it will never be used even though we invest in the
> overhead of taking a reference count.  Besides, __audit_inode_child()
> hands in a NULL for the dentry parameter to audit_copy_inode().

[NOTE: audit_copy_inode() hands a NULL dentry only in the anonymous parent case]

I believe I was just thinking of less conditional handling, especially
when reference counts are concerned.  I'm just trying to limit future
headaches, but I suspect the perf cost would be problematic, and as
you point out, there is no *need* for the majority of cases.

Looking at this again today, why would we want to clear name->dentry
in audit_copy_inode() if it is already set?  Does that ever happen?
I'm not sure it does ...

> I'm
> assuming you are hinting at also using that dentry to compare the
> audit_names entry, which I think it a bad idea since there could be
> multiple paths to access a dentry.  I did orignially have another patch
> that would have tried to use that as well, which didn't seem to hurt,
> but I didn't think was worth upstreaming.

No, I wasn't thinking that, the dev/inode numbers should be sufficient
in those cases I believe; I'm not sure the dentry would help us here.

>> Also out of curiosity, why do we want to drop a dentry reference here
>> if one already exists?
>
> I think we want to drop a dentry reference here because this inode child
> could be a subsequent access to the same dentry with a full path,
> removing the need to cache this dentry information in the first place.

Related to my comment above from today ... what code path please?

>> > @@ -1925,6 +1930,17 @@ void audit_log_name(struct audit_context *context, struct audit_names *n,
>> >                         audit_log_n_untrustedstring(ab, n->name->name,
>> >                                                     n->name_len);
>> >                 }
>> > +       } else if (n->dentry) {
>> > +               char *fullpath;
>> > +               const char *fullpathp;
>> > +
>> > +               fullpath = kmalloc(PATH_MAX, GFP_KERNEL);
>> > +               if (!fullpath)
>> > +                       return;
>>
>> I'm wondering if there is some value in still emitting the record if
>> the kmalloc() fails, just with the name field set as the unset "?"
>> value, e.g. "name=?".  Thoughts?
>
> Possibly.  We've got much bigger problems if that happens, but this
> sounds like a good defensive coding approach.  I'm even tempted to call
> audit_panic().

No audit_panic().  We've still got good information that we can
record, e.g. dev/inode numbers; let's just print "name=?" and go on
our way recording the rest of the information.  This is in keeping
with the current audit_log_name() error handling.

At the very least you need to clean up here instead of just returning.
As the patch currently stands I believe this will end up leaking an
audit_buffer.

-- 
paul moore
www.paul-moore.com




More information about the Linux-audit mailing list