Chapter 7. Compiling SELinux Policy


The commands and steps covered in this chapter may render your system inoperable or unable to be supported.

Nothing in this chapter should be performed on a production system without having been thoroughly tested in a development or sandbox environment first.

If you are going to compile and install a custom policy, be prepared to take the actions you need to safeguard your data and installation. Proper backup procedures, change-reversal plans, and an informed methodology are key to your success.

This chapter covers the considerations and methods for compiling SELinux policy. Following instructions on compiling SELinux policy, this chapter presents some reference information and considerations.

7.1. Policy Compile Procedure

Policy is usually compiled to enable a customization to take effect on your system. You may also compile policy under development, such as when working on writing a new policy or SELinux-aware application.

When you install a new policy, you must eventually reboot to test that it works during system start-up. If the policy change is significant enough, such as installing an entirely new policy, you need to reboot to ensure all applications are running in the right context for the loaded policy. This is similar to any major configuration change under Linux; you want to be sure it works properly from system start-up on at least one production-equivalent machine.


Policy updates from Red Hat should not require a reboot after installation. If a reboot were required, that fact would be clearly noted in the package advisory.

A reboot is required when the policy change is significantly different. For example, switching from the targeted to the strict policy requires a reboot. Ordinary policy updates do not.

To compile SELinux policy:

Compiling the SELinux Policy

  1. cd /etc/selinux/targeted/src/policy/

  2. Policy compiles if there are new or changed files in certain locations in the source tree. Those files must have a later timestamp than policy.conf. If you want to compile the policy but cannot because of the timestamp, you can force a compile.

    • To compile the policy, run make <make_policy_target>.

    • If you need to force a policy build, run make -W <users> <load>. The target can be any from the Makefile.

      The -W option tells make to act as if the command touch had been run on the file users. This virtual update of the timestamp is only from the perspective of make. It triggers the Makefile to build and load the policy because the virtual change to the users file gives it a later timestamp than the policy.conf file.

In order to compile the policy, you need to install the policy source package, selinux-policy-targeted-sources-<version>.

The Significant Policy make Targets list that follows discusses important make targets in the SELinux policy sources. The Makefile itself has more options that you can explore yourself.

Significant Policy make Targets


Compiles, installs, and fully loads the policy into memory.

This runs load_policy and installs $SELINUX_POLICY/policy.<XY> and /etc/selinux/targeted/contexts/files/file_contexts. When the policy gets loaded, the file $SELINUX_SRC/tmp/load is created. The Makefile does not compile the policy as long as nothing has changed in the policy source tree since the creation time on the file policy.conf.


Compiles, installs, and loads or reloads the policy. Reloading lets you load the policy in runtime even if the file $SELINUX_SRC/tmp/load is present and newer than the last changes in policy source.


Only compiles the policy, putting the resulting binary policy file into $SELINUX_SRC/policy.<XY>. It also creates a new policy.conf file, file_contexts/file_contexts, and so forth. This is useful for developing policy that you intend to deploy on another machine.


Relabels the file system using the policy sources, based on the file $SELINUX_SRC/file_contexts/file_contexts. As explained in Section 5.2.2 Relabel a File System, this is not the recommended method for relabeling a file system.


Enables auditing on all of the policy rules that are marked dontaudit. The enableaudit target changes the dontaudit rules in policy.conf, which is then loaded.

make enableaudit 
make load

This is useful for troubleshooting if you are getting SELinux denials that are not generating audit messages. This is usually discovered by testing with setenforce 0 to see if the operation is then allowed.

When enabled, the number of denial messages may be very large. You return to a dontaudit-state by running make clean and then make load in $SELINUX_SRC/.


The Makefile makes some decisions based on the timestamps of the two policy files $SELINUX_SRC/policy.conf, $SELINUX_SRC/policy.<XY>, and the file $SELINUX_SRC/tmp/load/. Because of this you may run into tricky behavior.

The Makefile will only rebuild policy.conf if there are newer policy files in the source tree. Two behaviors arise from this:

  1. If you move a TE file into the source tree that has a timestamp older than the policy.conf, the Makefile does not rebuild policy.conf.

  2. If you move a TE file so that it is no longer in the build path, in particular $SELINUX_SRC/domains/misc/, the Makefile does not necessarily recognize the change.

When this occurs, make load will validate the policy and touch tmp/load, but not compile the policy. You can force the compile with make -W users load.

The make load command compares the timestamp on tmp/load and the binary policy file in $SELINUX_SRC/. This file, policy.<XY>, is created in the policy source directory by the command make policy. If the binary policy file is newer than the file tmp/load, the policy is loaded.

For example, you write a local.te custom policy file, run tests on it, then remove the file from the source tree. With no new files in the policy source tree, the Makefile does not reload the policy. This is because the Makefile is only looking for new files in the source tree. You must run make -W users load, which compiles, installs, and loads the policy. This returns you to an uncustomized state.

Later you decide to use the custom policy again. You retrieve the file from the unused policy source location, moving it back to where it will compile into the policy. However, running make load or make reload has no effect. This is because the file local.te is not a new file, it continues to have the original creation timestamp on it. In order to keep the accurate timestamp on the file, rather than using touch you can again use make -W domains/misc/local.te load.