danwalsh (danwalsh) wrote,

Why doen't SELinux give me the full path in an error message?

Lets examine the SELinux error message; the AVC.
(Not something I like to do in a blog since AVC messages are scary)

node=holycross.devel.redhat.com type=AVC msg=audit(12/13/2006 11:28:14.395:952) : avc: denied { getattr } for pid=7236 comm=vsftpd name=public_html dev=dm-0 ino=9601649 scontext=system_u:system_r:ftpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=dir

node=holycross.devel.redhat.com type=SYSCALL msg=audit(12/13/2006 11:28:14.395:952) : arch=i386 syscall=lstat64 success=no exit=0
a0=8495230 a1=849c830 a2=874ff4 a3=328d28 items=0 ppid=7234 pid=7236 auid=dwalsh uid=dwalsh gid=dwalsh euid=dwalsh suid=dwalsh fsuid=dwalsh egid=dwalsh sgid=dwalsh fsgid=dwalsh tty=(none) comm=vsftpd exe=/usr/sbin/vsftpd subj=system_u:system_r:ftpd_t:s0 key=(null)

This AVC message consists of two records, the actual AVC record and the SYSCALL record. The kernel generates both records when the SELinux system denies an access. This AVC message indicates that SELinux prevented /usr/sbin/vsftpd from the getattr access on a dir named public_html.

Which public_html directory?
Notice, the AVC records do not show the full path to public_html? Performance is the reason the kernel does not provide the full path. The kernel needs to allocate memory for the path before every syscall is called and then free it, when the syscall does not generate an error in order to add the full path to the AVC. Since AVC's should happen infrequently, the kernel reporting the full path is not considered worth the overhead. The AVC records do include the device, dm-0, and the inode, 9601649. You can use the device and inode information to find the correct path if the file/directory still exists.

# find / -inum 9601649

But that is going to take a long time.

The setroubleshoot tools uses the locate program to attempt to reassemble the path.

# locate -r /public_html$

Then setroubleshoot uses stat to get the inode of each file returned and compares it to the ino in the AVC message, if they match it analyzes the full path. Of course you have to have mlocate package installed and running in a cron job to gather the paths.

Sometimes AVC messages refer to mountpoints. In these cases the kernel reports the access against name="/". This is not necessarily the top level "/" that humans understand, but the root of the mounted file system. For example, if an AVC was generated against a file system mounted at /var, the kernel would say the name was "/" and report the device. Setroubleshoot attempts to translate the path "/" into "/var" by searching the mount table for a machine device.

Sometimes AVC messages do not even report the name. For example look at this AVC message.
node=freddi type=AVC msg=audit(1263843455.583:203): avc: denied { dac_override } for pid=6050 comm="plymouthd" capability=1 scontext=system_u:system_r:plymouthd_t:s0 tcontext=system_u:system_r:plymouthd_t:s0 tclass=capability

node=freddi type=SYSCALL msg=audit(1263843455.583:203): arch=c000003e syscall=open success=no exit=-19 a0=d13a60 a1=2 a2=0 a3=7fff3cad2310 items=0 ppid=1 pid=6050 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="plymouthd" exe="/sbin/plymouthd" subj=system_u:system_r:plymouthd_t:s0 key=(null)

These AVC records indicate that the /sbin/plymouthd program was denied the open access, because it required the DAC_OVERRIDE capability. Notice plymouthd is running as root (uid=0 gid=0).

What is the DAC_OVERRIDE capability?

According to SELinux By Example. DAC_OVERRIDE allows a process to ignore Discretionary Access Controls including access lists.

If a process running as root attempts to read a file in my homedir owned by dwalsh with -rw------- permissions, it would have to have DAC_OVERRIDE.

This AVC message indicates that plymouthd tried to open some object (file/direcory/device) that root is not allowed to open, with standard permissions. But with capability checking the kernel does give us any information about the target object. This AVC access denial could simply be a file with the wrong permission bits or wrong ownership, and plymouthd would not need the access if the file permissions was fixed, but there is no way for us to figure it out from the AVC. :^(

In this case we can turn on full auditing. This tells the kernel to save the path before each access check and report the path, if you generate an AVC. I do this on my machine by adding a rule to watch write on /etc/shadow. Add

# echo "-w /etc/shadow -p w" >> /etc/audit/audit.rules
# service auditd restart

These commands will turn on full auditing mode on your system. In this mode the kernel adds the PATH record to the AVC message:

node=holycross.devel.redhat.com type=PATH msg=audit(12/13/2006 11:28:14.395:952) : name=/home/dwalsh/public_html

Making it clear which public_html directory is involved.

When we suggested this to the person who reported the DAC_OVERRIDE problem above, he found that the /dev/fb device had permissions such that root could not open it.

I run with full auditing turned on all the time, since I never notice any performance problems, most desktop users wouldn't.
If you want to turn off auditing you could remove the line and rerun
# service auditd restart.

You can also add and remove rules using auditctl.

Recent Posts from This Journal

  • Container Domains (Types)

    One of the things people have always had a hard time understanding about SELinux is around different types. In this blog, I am going to discuss…

  • Musings on Hybrid Cloud

    I work on the lowest levels of container runtimes and usually around process security. My team and I work on basically everything needed run…

  • Container Labeling

    An issue was recently raised on libpod, the github repo for Podman. "container_t isn't allowed to access container_var_lib_t" Container policy…

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened