Hi Alex,
Sorry, I didn't make it clear.
I need to protect all files under a directory, e.g /secure/
So if there's any newly created symlinks that points to files under
that directory, e.g /secure/some_file, I will need to know.
(/secure is not a symlink, but an existing directory)
However "-a exit,always -F arch=b64 -S symlink -F success=1 -F
dir=/secure" doesn't do the job.
If I do "ln -s /secure/some_file /tmp/aa", no auditing log is generated
So I suspect auditing on symlink isn't for the source file/directory,
but the target "string".
If I do "ln -s /bin/ls /secure/new_file", an auditing log is generated.
That's what I mean by "bug".
On Tue, Dec 31, 2013 at 6:19 PM, Alexander Viro <aviro(a)redhat.com> wrote:
On Fri, Dec 27, 2013 at 01:13:32PM +0800, Aaron Lewis wrote:
> Hi,
>
> Looks like on 2.6.32 kernel there was a bug with sys_symlink,
>
> I'm trying to monitor all symlinks that points to a specific dir, so I added:
>
> -a exit,always -F arch=b64 -S symlink -F success=1 -F dir=/secure
>
> But "ln -s /secure/file /tmp/file" doesn't trigger alert
> And "cd /secure; ln -s /bin/ls" does.
>
> So I guess the auditing implementation is somehow incomplete?
No, but your understanding of the symlinks does not match the reality.
Symlink target is a _string_, not a location. It is resolved every
time you traverse that symlink and result of such resolution depends
upon the state of filesystem(s) at that moment.
In other words, "symlink that points to a specific dir" is not well-defined.
Moreover, consider the following example:
ln -s foo/secure /tmp/bar
Does the resulting symlink satisfy your condition? No? It doesn't resolve
to anything, unless /tmp/foo existed already. Now
ln -s / /tmp/foo
and suddenly /tmp/bar resolves to /tmp/foo/secure, which resolves to /secure.
At which point did an interesting symlink appear in that scenario? Note also
that mv /tmp/a/b/c/ /tmp/x might very well have turned a symlink somewhere
under /tmp/a/b/c/something/else into one that resolves to /secure - all it
takes is something like "../../../../../../secure" as target. Would you
have rename(2) scan the entire directory tree in search of such beasts?
Worse, a symlink to /proc/self/cwd/secure will resolve to different things
for different processes and simple cd / will suffice to turn it into something
that will (for that process) resolve to /secure.
And all of the above can be combined, of course.
So if you need to prevent/catch the appearance of symlinks that will
resolve to something in given directory, you are SOL. Symlinks simply do
not work that way - the location some symlink resolves to is not a function
of that symlink alone and unless you are seriously proposing to rescan
the entire filesystem upon each rename(2) (and, worse yet, each chdir(2)),
you can not catch the moment when such symlinks appear.
Watching for creation of symlinks with bodies matching .*/secure(/.*|$)
would theoretically be feasible, but it'll yield tons of false positives.
And I seriously doubt that we want to open that can of worms, anyway -
regex matching isn't something you want in the kernel *and* restricting
to e.g. some subtree won't work - offending symlink could've been created
anywhere. Logging all symlink(2) and filtering out non-interesting target
names in userland is feasible right now, but you'll
a) get your logs spammed to hell and back (symlink(2) isn't
that rare a syscall) and
b) even after filtering the rate of false positives (i.e. symlinks
that might eventually resolve to something in /secure, but never will)
will be quite high.
Kernel-side filtering on substrings of symlink(2) target might deal with
(a), but (b) can't be helped at all.
--
Best Regards,
Aaron Lewis - PGP: 0x13714D33 -
http://pgp.mit.edu/
Finger Print: 9F67 391B B770 8FF6 99DC D92D 87F6 2602 1371 4D33