So what does an administrator do when he wants to make some small modifications to policy?
We have introduced the concept of modular policy. This allows vendors to ship SELinux policy separate from the OS Policy. It also allows administrators to make local changes to policy and not have to worry about the next policy install. Modular policy was introduced in Fedora Core 5 and more features were added in Fedora Core 6. The major command that was added was semodule.
>man semodule
SEMODULE(8) NSA SEMODULE(8)
NAME
semodule - Manage SELinux policy modules.
SYNOPSIS
semodule [options]... MODE [MODES]...
DESCRIPTION
semodule is the tool used to manage SELinux policy modules, including installing, upgrading, listing and remov-
ing modules. semodule may also be used to force a rebuild of policy from the module store and/or to force a
reload of policy without performing any other transaction. semodule acts on module packages created by semod-
ule_package. Conventionally, these files have a .pp suffix (policy package), although this is not mandated in
any way.
OPTIONS
...
If you want to view the policy modules on a system you can use the semodule -l command
# semodule -l
amavis 1.1.0
ccs 1.0.0
clamav 1.1.0
dcc 1.1.0
evolution 1.1.0
iscsid 1.0.0
mozilla 1.1.0
nagios 1.1.0
oddjob 1.0.1
pyzor 1.1.0
razor 1.1.0
ricci 1.0.0
smartmon 1.1.0
This command does not show you the base policy module which is also installed. You can read all about loadable policy modules at tresys. Also the excellent book,
SELinux by Example, has some great information on SELinux and modules. And no I do not recieve commisions. :^)
If you look in /usr/share/selinux/targeted/ you will see a lot of policy package (*.pp) files there. These files are included in the selinux-policy rpm and are used to build the policy file.
So lets get back to builind a local policy module. Lets look at an example. Currenly there is a bug in policy. The ypbind init script executes the setsebool command which in turn tries to use the terminal. This is generating a denial
type=AVC msg=audit(1164222416.269:22): avc: denied { use } for pid=1940 comm="setsebool" name="0" dev=devpts ino=2 scontext=system_u:system_r:semanage_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=fd
While this is not a big deal, since everything works correctly, it can be an aggravation. To eliminate this AVC, you could use audit2allow to generate a rule that looks like this.
# grep setsebool /var/log/audit/audit.log | audit2allow
allow semanage_t init_t:fd use;
But since we do not have policy sources what do you do? Well audit2allow now has the ability to build policy modules.
# grep setsebool /var/log/audit/audit.log | audit2allow -M mysemanage
Generating type enforcment file: mysemanage.te
Compiling policy
checkmodule -M -m -o mysemanage.mod mysemanage.te
semodule_package -o mysemanage.pp -m mysemanage.mod
******************** IMPORTANT ***********************
In order to load this newly created policy package into the kernel,
you are required to execute
semodule -i mysemanage.pp
The audit2allow rule has actually gone out and built a type enforcement file (mysemanage.te). audit2allow then executed the checkmodule command to compile a module file (mysemanage.mod). Finally it uses the semodule_package package up a policy package (mysemanage.pp). If you look at the te file:
cat mysemanag.te
module mysemanage 1.0;
require {
class fd use;
type init_t;
type semanage_t;
role system_r;
};
allow semanage_t init_t:fd use;
You will see three sections in the te file. The first section is the module command which identifies the name of the module and its version. This must be unigue, which is why I prefix "my" on my module names. If I created a semanage module and one already existed the system would try to replace the existing module package with mine. The last part of the module line is the version. semodule has the ability to update module packages and will check the version versus the currently installed version.
The next block of the te file is the require block. This is used to tell the policy loader semodule, which type, classes and roles are required to be already in the system policy before this module can be installed. If any of these fields are undefined, the semodule command will fail.
Finally are the allow rules. Now we could modify this line to dontaudit, since semodule does not need to access the file descriptor.
Why do we have to run the semodule_package command?
This command basically wraps up different policy files together in a policy package. Usually just the module and potentially a file context file. The final step for the administrator is to load the policy package with the semodule command.
# semodule -i mysemanage.pp
This command will recompile the policy file and regenerate the file context file. The changes are permanent and will survive a reboot. Also the policy package file mysemanage.pp can be copied to other machines and installed using semodule.
Audit2allow shows you the commands it executed to create the policy package so you can edit the te file to add new rules if you want or change the allow to dontaudit. You could then recompile and repackage the policy package to be installed again.
There is no limit to the number of policy packages so you could create one for each local modification you want to make, or you could continue to edit one, but make sure your "require" statements match all of the allow rules.