SELinux/Tutorials/Where to find SELinux permission denial details

Where to find SELinux permission denial details
Now that you are aware that SELinux governs file access by verifying the security context of the process (the domain) and the context of the file, it is time to find out how, if SELinux denies a certain access, you can troubleshoot this in more detail.

SELinux logging
The most important feature of SELinux, and one you should start learning by heart, is that it is able to log everything. And with everything, I mean everything. If you want, we can have SELinux log all granted accesses (although I can imagine that becomes dull to look at, and might slow down the performance of the system), but more importantly it logs access denials.

The default location where you can find this logging depends a bit on the distribution, but generally it is either in if you are not running the Linux audit daemon, and in  or  if you are. This logging is very verbose, mainly because you need many details in order to troubleshoot problems.

But before we take a look at the denials, we also want to give you a heads up. Mar 12 17:46:42 hpl kernel: [  14.453644] audit_printk_skb: 84 callbacks suppressed
 * 1) Not every denial you find in the logs is a problem by itself. Some denials are cosmetic, meaning that they do occur but do not influence the behavior of an application. This is often because of an application development malpractice (like not properly closing file descriptors) or because of high-level library functions where only a small fraction of the features are used by an application.
 * 2) Denials are logged as they come along. That means that you will see a lot of denials, and although many will be related to each other (one denial leads to the other) many will also have nothing to do with the problem you are investigating.
 * 3) If there are too many denials succeeding each other, they might be suppressed by the Linux kernel; if that happens, you will get a message like the following, so if you find this message in your logs you have to understand that you are not seeing everything that SELinux might be reporting:

So let's take a look at one denial. This one comes from the audit log (which you can tell from the start of the log, type=AVC, which you will not see in the as it is implied there).

type=AVC msg=audit(1363289005.532:184): avc: denied  { read } for  pid=29199 comm="Trace" name="online" dev="sysfs" ino=30 scontext=staff_u:staff_r:googletalk_plugin_t tcontext=system_u:object_r:sysfs_t tclass=file

We warned you that it was verbose ;-)

Disecting the AVC denial
AVC stands for Access Vector Cache. Not that that is worth much right now, but the word cache does already give you feedback as to why the logs might not show everything if SELinux had too many things to report. Just thought it might interest you (since the term avc denial might show up in documentation). But let's get back to the denial we had.

type=AVC msg=audit(1363289005.532:184): avc: denied  { read } for  pid=29199 comm="Trace" name="online" dev="sysfs" ino=30 scontext=staff_u:staff_r:googletalk_plugin_t tcontext=system_u:object_r:sysfs_t tclass=file

Once you get to know this denial structure, you can translate this into the following:

The Trace process with PID 29199 tried to read a file called on a file system hosted on the sysfs device. This file has inode number 30, and has the security context system_u:object_r:sysfs_t assigned to it. The Trace process itself is running with the staff_u:staff_r:googletalk_plugin_t context (domain).

You probably find the details from the translated sentence back in the denial easily, but I'm going to disect the denial part by part anyway. The following table gives a part by part explanation. We do want to tell you though that the logs can be a bit different based on what is denied - for instance, a file read access shows a few different parts than a socket connect denial. The majority of fields however will be present in all cases.

This is a lot to digest, but it is very important that you understand this log. When you have a permission denied error, you should look into the SELinux logs for avc denials to see if SELinux is the culprit or not.

Hidden denials
We've told you already that denial logs can be cosmetic. Since they do not reflect real problems, SELinux policy writers can hide those denials from regular logging so that users are not baffled by the various denials they get. This is done through dontaudit statements. A default SELinux policy in most distributions will already have a lot of such statements active, which you can verify through seinfo.

In some cases, the SELinux policy writers can be wrong (of course, they are still human) so it might make sense to disable these dontaudit statements for a short while (while you are reproducing the permission problem you are facing). This can be done using the semodule command:

The shorter version of this command is semodule -DB, btw. What happens here is that the SELinux management utility semodule rebuilds the SELinux policy, but ignores the dontaudit statements. The policy is then loaded in memory. Once you disable the dontaudit statements, effectively all denials are logged.

When you are tired of seeing all those denials, you can re-enable the dontaudit statements, by rebuilding the policy:

If you want to see all the dontaudit statements, run sesearch --dontaudit. You will notice that they follow the same structure as the allow statements we have seen earlier on.

Later, when we learn how to create our own policy modules, we will show you how you can add your own dontaudit statements.

Other ways to read denial information
The friendly developers that work with SELinux on a daily basis have made a few tools that help you identify SELinux-related issues.

ausearch
The ausearch utility is not an SELinux-specific utility. It is a Linux audit related utility, which parses the audit logs and allows you to query the entries in the logs. One of the advantages that it shows is that it already converts the time stamp into a human readable one.

The recent start gives the denials from the last 10 minutes. You can also use today for, well, today's denials.

sealert
The sealert command is not provided on a SELinux-enabled Gentoo system by default, but it is available on RedHat Enterprise Linux and related distributions. It integrates together with a specific daemon called setroubleshootd, which gives a translation of an AVC denial similar to the human translation given earlier in this tutorial. For instance, the following message can be displayed in the system logs:

setroubleshoot: SELinux is preventing httpd (httpd_t) "getattr" to /var/www/html/file1 (samba_share_t). For complete SELinux messages. run sealert -l 84e0b04d-d0ad-4347-8317-22e74f6cd020

The sealert tool then gives a more detailed explanation of the denial:

What you need to remember
From this tutorial, you should remember that
 * denials are logged in the (no audit daemon running) or  (audit daemon running) log files
 * denials might be obscured through dontaudit statements, which you can disable using semodule -DB and re-enable through semodule -B
 * the denial logging gives you great detail about who (process information, including security context) is trying to do what (permission) against something (target information, including security context)