On 2/11/20 5:58 AM, Paul Moore wrote: > On Mon, Feb 10, 2020 at 6:05 PM Orion Poplawski <[email protected]> wrote: >> On 2/10/20 3:54 PM, Paul Moore wrote: >>> On Fri, Feb 7, 2020 at 4:56 PM Paul Moore <[email protected]> wrote:
>>> >>> Generally speaking the only syscalls which generate a PATH record are >>> those syscalls which take a file pathname as an argument. The reason >>> why is that pathnames are notoriously transient and are only valid for >>> the instant they actually resolve to a file; in fact it is possible >>> that by the time an open(2) syscall returns the fd to the calling >>> application, the file it opened may no longer be accessible at the >>> pathname used to open the file. It really is that crazy. >>> >>> In the case of ftruncate(2) we see that the syscall doesn't take a >>> pathname argument, it takes an open file descriptor, this is why you >>> don't see a PATH record. If we compare it to a syscall which does >>> take a pathname, e.g. chown(2), we will generate a PATH record. Take >>> the example below where we use the example program found in the >>> chown(2) manpage: >>> >>> # touch /tmp/test >>> # auditctl -w /tmp/test -k path_test >>> # gcc -o chown_test -g chown_test.c >>> # ./chown_test >>> ./chown_test <owner> <file> >>> # ./chown_test nobody /tmp/test >>> # ausearch -i -k path_test >>> ---- >>> type=CONFIG_CHANGE msg=audit(02/10/2020 17:50:45.251:255) : auid=root ses=5 >>> subj >>> =unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 op=add_rule >>> key=path_test >>> list=exit res=yes >>> ---- >>> type=PROCTITLE msg=audit(02/10/2020 17:51:29.356:258) : >>> proctitle=./chown_test n >>> obody /tmp/test >>> type=PATH msg=audit(02/10/2020 17:51:29.356:258) : item=0 name=/tmp/test >>> inode=7 >>> 0660 dev=00:21 mode=file,644 ouid=root ogid=root rdev=00:00 >>> obj=unconfined_u:obj >>> ect_r:user_tmp_t:s0 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 >>> cap_fver=0 >>> cap_frootid=0 >>> type=CWD msg=audit(02/10/2020 17:51:29.356:258) : cwd=/root/tmp >>> type=SYSCALL msg=audit(02/10/2020 17:51:29.356:258) : arch=x86_64 >>> syscall=chown >>> success=yes exit=0 a0=0x7ffc820c0603 a1=nobody a2=unset a3=0x40044e items=1 >>> ppid >>> =1678 pid=35451 auid=root uid=root gid=root euid=root suid=root fsuid=root >>> egid= >>> root sgid=root fsgid=root tty=pts1 ses=5 comm=chown_test >>> exe=/root/tmp/chown_tes >>> t subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=path_test >>> >>> ... in the example above we see that we do have a PATH record, as expected. >>> >> >> So, this is all reasonable. But why do I get this with fchown which also >> takes a file descriptor? >> >> type=PROCTITLE msg=audit(02/06/2020 10:59:30.562:59894) : proctitle=kwin >> -session 106f726361000123384967700000029380000_1548775895_794186 >> type=PATH msg=audit(02/06/2020 10:59:30.562:59894) : item=0 name=(null) >> inode=595335 dev=fd:01 mode=file,600 ouid=USER ogid=USER rdev=00:00 >> obj=unconfined_u:object_r:config_home_t:s0 objtype=NORMAL cap_fp=none >> cap_fi=none cap_fe=0 cap_fver=0 >> type=SYSCALL msg=audit(02/06/2020 10:59:30.562:59894) : arch=x86_64 >> syscall=fchown success=yes exit=0 a0=0xd a1=0x584b a2=0x584b a3=0xc items=1 >> ppid=27089 pid=27152 auid=USER uid=USER gid=USER euid=USER suid=USER >> fsuid=USER egid=USER sgid=USER fsgid=USER tty=(none) ses=16 comm=kwin >> exe=/usr/bin/kwin subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 >> key=perm_mod >> >> It's this disparity between fchown and ftruncate that caught my attention. > > First off, it is worth distinguishing between a PATH record with a > valid pathname (the chown(2) case) and a PATH record with an > invalid/NULL pathname (the fchown(2) case). At this point you > hopefully understand why those PATH records are different, and why > they sometimes have a pathname, and why sometimes they do not. > > For syscalls which resolve pathnames the pathname information for the > PATH records are collected as the pathname is resolved (the only time > they are valid). When the syscall is done, the resolved pathname > information is turned into the PATH records you see. > > In the case of fchown(2) there is no pathname resolution, the kernel's > fchown(2) implementation explicitly records the passed file descriptor > for reasons that Casey mentioned: it's security relevant since you are > changing the file's ownership. The ftruncate(2) syscall isn't > security relevant so there is no explicit attempt to record the file > descriptor information. This is why fchown(2) generates a pathless > PATH record, and why ftruncate(2) does not. > > If you are still curious, I would suggest you take a look at the > kernel code, all the answers are there, and we could always use > another set of hands/eyes ;) Thank you again for the detailed response. I was working with RHEL7 stig rules like: https://www.stigviewer.com/stig/red_hat_enterprise_linux_7/2017-12-14/finding/V-72133 which seem to imply some security relevance for ftruncate, and then noticing that the ftruncate record didn't seem to provide any kind of useful information at all. But I can appreciate some cargo-cult like behavior in the security implementation realm :). -- Orion Poplawski Manager of NWRA Technical Systems 720-772-5637 NWRA, Boulder/CoRA Office FAX: 303-415-9702 3380 Mitchell Lane [email protected] Boulder, CO 80301 https://www.nwra.com/
smime.p7s
Description: S/MIME Cryptographic Signature
-- Linux-audit mailing list [email protected] https://www.redhat.com/mailman/listinfo/linux-audit
