Some time ago, I published a post about shipping custom SELinux modules together with product as rpm subpackage. One of the steps in shipping custom SELinux module is creating a spec file for SELinux package, which can be messy, especially %post and %postun phases.
In order to simplify writing spec files, we have created several macros.
Loading custom SELinux modules
First improvement concerns loading and removing custom SELinux modules. You can see the difference in the following example:
Without macros:
%post
#
# Install all modules in a single transaction
#
%_format MODULES %{_datadir}/selinux/packages/$x.pp.bz2
%{_sbindir}/semodule -n -s %{selinuxtype} -i $MODULES
if %{_sbindir}/selinuxenabled ; then
%{_sbindir}/load_policy
%relabel_files
fi
%postun
if [ $1 -eq 0 ]; then
%{_sbindir}/semodule -n -r %{modulenames} &> /dev/null || :
if %{_sbindir}/selinuxenabled ; then
%{_sbindir}/load_policy
%relabel_files
fi
fi
With macros:
%post
#
# Install all modules in a single transaction
#
%_format MODULES %{_datadir}/selinux/packages/$x.pp.bz2
%selinux_modules_install -s %{selinuxtype} $MODULES
%postun
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} $MODULES
fi
As you can see, module loading is done by one macro instead of 5 lines of code.
Labeling objects from custom policy
Next improvement in spec file is a pair of macros connected to labeling files coming from the custom policy. There is no need to specify all objects in spec file as we did in previously.
# Relabel files
%global relabel_files() \ # ADD files in *.fc file
Instead of specifying objects labeled by custom policy, following macros can be used:
%pre
%selinux_relabel_pre -s %{selinuxtype}
%posttrans
%selinux_relabel_post -s %{selinuxtype}
These macros will handle labeling objects coming from the custom SELinux module and after successfull package installation, all new objects should have correct SELinux label.
Handling SELinux booleans
Last improvement is setting booleans by macros. These macros provide solution for handling booleans in spec files and behave as follows:
- If a boolean mentioned in the product .spec file was not set by user previously, it will be changed in the %post install phase and reverted during the %post uninstall phase will.
- If a boolean mentioned in the product .spec file was set by user previously, it will be changed to a value from this file. However, it will not be reverted during the uninstallation of a product SELinux subpackage.
Usage of booleans macros:
# In preamble define booleans and values which should be used
%global selinuxbooleans booleanname=1 booleanname2=0
# Also some new packages will be needed:
%if 0%{?fedora}
Requires(post): policycoreutils-python-utils
%else
Requires(post): policycoreutils-python
%endif
# use selinux_set_booleans after custom SELinux module is loaded.
%post
%selinux_modules_install -s %{selinuxtype} $MODULES
%selinux_set_booleans -s %{selinuxtype} %{selinuxbooleans}
%postun
%selinux_modules_uninstall -s %{selinuxtype} $MODULES
%selinux_unset_booleans -s %{selinuxtype} %{selinuxbooleans}
All these improvements can be used in Fedora Rawhide and Fedora 26. Repository with sources can be found here.