Hello,
On Tuesday, July 23, 2024 5:24:53 PM EDT Michael McKinley wrote:
Based on the performance enhancements it would be preferable to use
syscall
monitors to monitor the directory.
But the limitation of having the rule not load, as well as any following
rules not load when the directory is not present is effectively a
non-start.
Here's what you are seeing as a difference. With the -w notation, it doesn't
know if you are pointing to a file or a directory. So, it does a stat to find
out. If the object doesn't exist, you get an -ENOENT return. So, it assumes
it's a file. It places the watch on the parent which does exist.
With the -F dir= no checking is done because you specified a directory. The
kernel checks and it does not exist so it cannot place a watch on the
directory. If you change 'dir' to 'path' it is successful but not what you
want. The -w notation gives the appearance that its working but not really if
you test it out.
By placing a watch on the directory itself, you can see objects created/
deleted in the directory but not the access of the objects.
What can be done is create a plugin to auditd and have it watch for events of
some kind and then insert a rule into the kernel when it sees the trigger
event. Use the key field to trigger insertion of the rule. The rule might
watch for a mount in /tmp or mkdirat. The plugin just filters all events
looking for the key and if it finds it, react.
-Steve
The downside is -w style rules are deprecated and while they appear
to
support -F style options they aren’t explicitly supported.
So we are left with a situation where we either try and pursue -s style,
which can lead to rules breaking, or -w style, which is legacy, and we are
using -w style in a way that it was not intended to be used, per the docs.
I haven’t had time to read the code on this specific implementation.
Ideally, -s style does a dir check instead of failing to load the rule+
rules following.
- Michael
On Tue, July 23 2024 at 4:15 PM Steve Grubb <sgrubb(a)redhat.com>
wrote:
Hello,
On Tuesday, July 23, 2024 9:57:39 AM EDT Michael McKinley wrote:
> Auditctl version 3.0.7
> Kernel 6.5.0-44-generic.
ok
> That extra check on if the directory exists may be the core difference.
> What is interesting is the -w version seems to honor the rule filter
> given
> (-F exe!=/usr/bin/example).
I looked at the watch code. It appears to go back to at least 2008. You can
use whichever notation works for your problem. But the -w rule syntax is
deprecated. All watches in the sample rules have been switched over quite
some time ago.
That said, a watch is set for all syscalls. Starting in 3.1.3, the -F style
rules target specific syscalls based on the perm option. The impact of an
'all' rule is small but measurable across the whole system and this is why
perms are now used to select the syscalls. It makes the whole system run
faster.
For example, with a -w rule, if any program makes a call to read, the
kernel rule matching engine will have to check this rule to see if it
matches. Whereas with the -F style of rule, read is not chosen so this
rule is skipped.
-Steve
> On Mon, July 22 2024 at 6:06 PM Steve Grubb
> <sgrubb(a)redhat.com>
>
> wrote:
> Hello,
>
> On Monday, July 22, 2024 4:00:37 PM EDT Michael McKinley via Linux-audit
>
> wrote:
> > I believe I’ve come across a bug in Linux audit when writing syscall
> > monitors for a directory.
> >
> > File watchers are suggested to be syscall rules under the hood. I don’t
> > believe this is true, based on the different behavior of syscall rules
> > and
> > file watcher rules when monitoring directories that don’t exist.
> > Suggested
> > to be equivalent per auditctl(8):-w /tmp/fakedir -p warx -k test1 -s
> > always, exit -F dir=/tmp/fakedir -F perm=warx -k test2
>
> It might be good to know what version of the audit package (auditctl -v)
> you are using and the version of the kernel (uname -r). They were
> different once upon a time.
>
> > What will happen if the dir doesn’t exist in case 1 is the rule loads
> > and
> > continues. In case 2, the rule will fail to load, thus failing to load
> > all
> > rules below it.
>
> In the current code, when it find a 'w' option, it calls stat on the
> directory to ensure it is there. If it is, it converts the call to
> syscall
> auditing on all syscalls. This gets refined when it finds the -perm
> field.
>
> When it finds a 'S', it adds the syscall without any checks. When it
> finds
> '-F dir=' it verifies the filter that it's being placed on but no other
> path checks are done.
>
> That means the -w version is more strict and needs a directory to exist
> when the rule loads. The code in this area is probably at least 15 years
> old without much reworking.
>
> > The auditctl(8)
> > Per the auditctl(8) man page -F (rule fields) are not supported by
> > watchers. This doesn’t appear to be true any longer, as watchers do
> > seem
> > to honor -F (extensive testing not performed).
>
> My man page differs. It says:
>
> The -w form of writing watches is for backwards compatibility and is
> deprecated due to poor system performance. Convert watches of this
> form to the syscall based form.
>
> > Any insight or suggestions? I am considering using a watcher with rule
> > fields despite it not being officially supported due to the loading
> > error
> > with syscalls.
>
> I'd be curious what versions you are using.
>
> -Steve