When should I use the “optional_policy” block statement?
I wrote the blog why we use optinal_policy block statements in the policy. But I got the following question.
“How could I know for which interface I should use it or not”.
If we want to add a new policy module there is a place where we need to tell SELinux to know about it and use it. These files are modules-*.conf:
which contain statements like
# Layer: kernel
# Module: domain
# Required in base
# Core policy for domains.
domain = base
# Layer: system
# Module: init
# System initialization programs (init and init scripts).
init = module
What does either “base” or “module” mean? The note says
# For modular policies, modules set to "base" will be
# included in the base module. "module" will be compiled
# as individual loadable modules.
The base.pp policy module contains core policy modules which are needed for the basic confinement of your system focused on the core operating system. The base.pp module can not be removed from your policy.
But what about “module”. This is different. These modules (well almost all of them) are optional. It means that you could be able removed them from the policy. If you want to list them, you can using
$ semodule -l
And this is what we want to know. Basically if you call an interface which is not a part of the base module, you should call it with the optional_policy block. It causes that you will be able to remove a non policy module without issues. There are some exceptions for modules like miscfiles, authlogin, init, systemd, sysnetwork. We define them as “module” in the modules-*.conf file but they can not be removed.
Let's say you write a policy and you need to use a rpm interface because your application execute rpm -qi. First, we need to examine that the rpm module is not a part of the base.pp policy module
$ semodule -l | grep rpm
Ok, I see it is not. So I will call a rpm interface with the optional_policy block.