3.3. Understanding the File Contexts Files

The files in $SELINUX_SRC/file_contexts/ declare the security contexts that are applied to files when the policy is installed. You can read more about what a file context is at Section 2.4 File System Security Contexts.

The file context descriptions use regular expression pattern matching (regexp) to match a file, set of files, directory, or directory and associated files. A specific SELinux label is then applied to that:

# Syntax of file context description

regexp <-type> ( <file_label> | <<none>> )

The regexp is anchored on both ends, meaning the expression search only considers matches that start with the first character and end with the last character. This means that it ignores an expression that appears in the middle of a sentence, the way /var/run appears in this sentence, and only declares a match if the pattern is on a line by itself:

/var/run

This is the way a directory is displayed by the output of ls, and is how setfiles sees files and directories when it traverses the directory tree. In regexp notation, this kind of match is denoted by prepending a ^ (caret) symbol and appending a $ (dollar sign or ding) to the expression. This is done automatically by SELinux, and can be overridden using the match-anything pattern .* on either or both sides of the regexp pattern.

The field -type is optional and can be left blank. When it is filled, it is similar to the mode field for the ls command. For example, the -d means to match only directories, the -- means to match only files.

The value field is the last field on the right, and is set to either a single security label such as system_u:object_r:home_root_t or is set to <<none>>. The <<none>> value tells the relabeling application to not relabel the matching file. In the case where there is more than one match, the last matching value is used. Hard linked files that have different contexts generate a labeling error, and the file is labeled based on the last matching specification other than <<none>>.

There are files listed in types.fc that are not persistent, but get created each time during boot. Those files gain their labels through type transition rules, but they are listed here to prevent their label being overwritten by a relabeling operation during runtime. One example of this is /var/run/utmp.

Here are some examples from $SELINUX_SRC/file_contexts/types.fc, the main file describing file contexts:

/bin(/.*)?			system_u:object_r:bin_t
/bin/bash		--	system_u:object_r:shell_exec_t

/u?dev(/.*)?			system_u:object_r:device_t
/u?dev/pts(/.*)?		<<none>>
ifdef(`distro_redhat', `
/dev/root		-b	system_u:object_r:fixed_disk_device_t
')

/proc(/.*)?			<<none>>
/sys(/.*)?			<<none>>
/selinux(/.*)?			<<none>>
/etc(/.*)?			system_u:object_r:etc_t
/etc/passwd\.lock	--	system_u:object_r:shadow_t
/etc/group\.lock	--	system_u:object_r:shadow_t
/etc/shadow.*		--	system_u:object_r:shadow_t

/usr(/.*)?/lib(64)?/.*\.so(\.[^/]*)*	--	system_u:object_r:shlib_t
/usr(/.*)?/java/.*\.so(\.[^/]*)*	--	system_u:object_r:shlib_t

Similarly, there are specific file contexts files for all domains, depending on their special needs. The *.fc files are present in the policy source, but are only used if there is an associated *.te file in $SELINUX_SRC/domains/program/. Here is an example from mta.fc:

# types for general mail servers
/usr/sbin/sendmail(.sendmail)? -- system_u:object_r:sendmail_exec_t
/usr/lib(64)?/sendmail         -- system_u:object_r:sendmail_exec_t
/etc/aliases            --      system_u:object_r:etc_aliases_t
/etc/aliases\.db        --      system_u:object_r:etc_aliases_t
/var/spool/mail(/.*)?           system_u:object_r:mail_spool_t
/var/mail(/.*)?                 system_u:object_r:mail_spool_t

ifdef(`dhcp_defined', `', `
/var/lib/dhcp(3)?	-d	system_u:object_r:dhcp_state_t
define(`dhcp_defined')
')

Example 3-1. ifdef statement in a context file

Another interesting example is Example 3-1. The file context dhcp_state_t must be set for the DHCP-based daemons to work properly, so the pattern and value are in both dhcpd.fc and dhcpc.fc (the DHCP client daemon contexts). This is to ensure the label value is present in case one file is not included in a policy build. In fact, this is the case for the targeted policy, where the DHCP client is not confined by SELinux policy. In this case, the file dhcpd.fc declares the file context for /var/lib/dhcp for the pattern matching ^/var/lib/dhcp(3)?$.

If you include policy to cover the DHCP client programs, you want to ensure that it also can declare the context for /var/lib/dhcp/. However, if you include both programs and they both declare the context, setfiles reports an error during policy build. This happens when a file context is specified multiple times, even if the specification is identical.

To handle this, a conditional ifdef statement is used. When concatenating the file context files into the single file $SELINUX_SRC/file_contexts/file_contexts, the first time the ifdef statement is reached, the definition dhcp_defined is checked for. If it is defined, the value true is returned, and the additional file context is skipped. If dhcp_defined has not been defined, the value returns as false, the file context is read from inside the statement, and dhcp_defined is defined.