Re: [RFC PATCH ghak9 0/3] audit: Record the path of FDs passed to *at(2) syscalls

Ondrej Mosnacek
2018-07-26T09:13:09Z

On Thu, Jul 26, 2018 at 10:12 AM Ondrej Mosnacek <omosnace@redhat.com> wrote:
> I think it should be possible to collect that information by putting
> hooks in the right places of the filesystem code (and fixing the
> current ones).

Hm, after closer look, it seems this won't be doable (at least not
easily). The PATH record always logs the original path string from
userspace (and I think we need to preserve this behavior in case
someone relies on it). In case of PARENT records, it truncates away
the last component (because it wants to log inode information also for
the parent directory). If this truncated string ends up empty (i.e.
the original string had just one component), it just smashes in the
absolute path of the CWD (which is known), because it pretends no
*at() syscalls exist and all relative paths are relative to current
CWD.

So to fix this, we need to do one of the following:
1. Add a new field to the PATH records that would specify the path of
the directory that the value of name=... is relative to. If this is
CWD, we can just use some special value
("(null)"/"(none)"/"(cwd)"/...) or omit the field completely. I prefer
this approach, because it will best solve the case of renameat(),
where different PATH records can have different base directories.
2. If adding fields is considered A Bad Thing, we could alternatively
provide this information in separate records (either PATH with special
nametype or a new record). However in such case we need to somehow
specify to which PATH records each base directory corresponds. For
PATH records this could be guessed from their order, but this is a
fragile thing (changes in filesystem code could change the order).

Let me give an example to illustrate better how it might look like:
=== renameat() with two FD arguments ===
openat(AT_FDCWD, "/tmp/tmp.SIMqhBS0eI/a", O_RDONLY|O_PATH|O_DIRECTORY) = 3
openat(AT_FDCWD, "/tmp/tmp.SIMqhBS0eI/b", O_RDONLY|O_PATH|O_DIRECTORY) = 4
renameat(3, "x/f", 4, "y/g") = 0
close(3) = 0
close(4) = 0

type=SYSCALL msg=audit(1532504483.814:5): [...]
type=CWD msg=audit(1532504483.814:5): cwd="/root/Dokumenty/Kernel"
type=PATH msg=audit(1532504483.814:5): item=0 name="x/" inode=2156
dev=00:1a mode=040755 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=PARENT
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir="/tmp/tmp.SIMqhBS0eI/a"
type=PATH msg=audit(1532504483.814:5): item=1 name="y/" inode=2158
dev=00:1a mode=040755 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=PARENT
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir="/tmp/tmp.SIMqhBS0eI/b"
type=PATH msg=audit(1532504483.814:5): item=2 name="x/f" inode=2159
dev=00:1a mode=0100644 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=DELETE
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir="/tmp/tmp.SIMqhBS0eI/a"
type=PATH msg=audit(1532504483.814:5): item=3 name="y/g" inode=2159
dev=00:1a mode=0100644 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=CREATE
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir="/tmp/tmp.SIMqhBS0eI/b"

=== renameat() with one CWD and one FD argument ===
openat(AT_FDCWD, "/tmp/tmp.SIMqhBS0eI/a", O_RDONLY|O_PATH|O_DIRECTORY) = 3
renameat(3, "x/f", AT_FDCWD, "y/g") = 0
close(3) = 0

type=SYSCALL msg=audit(1532504483.814:5): [...]
type=CWD msg=audit(1532504483.814:5): cwd="/root/Dokumenty/Kernel"
type=PATH msg=audit(1532504483.814:5): item=0 name="x/" inode=2156
dev=00:1a mode=040755 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=PARENT
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir="/tmp/tmp.SIMqhBS0eI/a"
type=PATH msg=audit(1532504483.814:5): item=1 name="y/" inode=2158
dev=00:1a mode=040755 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=PARENT
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir=(cwd)
type=PATH msg=audit(1532504483.814:5): item=2 name="x/f" inode=2159
dev=00:1a mode=0100644 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=DELETE
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir="/tmp/tmp.SIMqhBS0eI/a"
type=PATH msg=audit(1532504483.814:5): item=3 name="y/g" inode=2159
dev=00:1a mode=0100644 ouid=0 ogid=0 rdev=00:00
obj=system_u:object_r:tmpfs_t:s0 nametype=CREATE
cap_fp=0000000000000000 cap_fi=0000000000000000 cap_fe=0 cap_fver=0
basedir=(cwd)

--
Ondrej Mosnacek <omosnace at redhat dot com>
Associate Software Engineer, Security Technologies
Red Hat, Inc.