SELinux Module Packaging in FC5

Daniel J Walsh dwalsh at redhat.com
Fri May 26 13:17:39 UTC 2006


Paul Howarth wrote:
> Stephen Smalley wrote:
>> On Thu, 2006-05-18 at 14:18 +0100, Paul Howarth wrote:
>>> Another query regarding policy module packages in RPMs:
>>>
>>> Supposing a package is installed when the system has SELinux disabled.
>>>
>>> What would happen if semodule was called to install a policy module?
>>>
>>> If the result is that nothing happens (or semodule bombs out with an 
>>> error of some sort), what would then happen if the system 
>>> subsequently had SELinux enabled and the system was relabelled? 
>>> Would the package containing the policy module have to be reinstalled?
>>>
>>> I'd try it myself but I can't bring myself to disable SELinux on any 
>>> of my boxes and go through the whole relabelling process.
>>
>> If policy is installed on the system, then semodule (actually
>> libsemanage) will install the module and rebuild the generated files,
>> but will not try to load policy into the kernel since SELinux is
>> disabled.  Then, if you enable SELinux, the module will already be
>> included in the policy.
>>
>> If policy is not installed on the system, then semodule will abort with
>> an error like this:
>> semodule:  SELinux policy is not managed or store cannot be accessed.
>>
>> Note also that one should generally use semodule -s <policytype> as in
>> the selinux-policy .spec file to indicate which kind of policy your
>> module is built for (targeted, strict, mls).  Then, if the system is
>> running a different kind of policy, semodule will know to install the
>> module to the proper location (not the active policy) and to not try to
>> load it.
>
> OK, just to recap where I think we're up to. Here are the relevant 
> parts  of my current spec file for the application "contagged", which 
> will have a policy module package included:
>
> *** Top of spec, so that FC4/FC5 packages can build from same SRPM:
>
> # FC5 and later include SELinux policy module packages
> %if 0%{?fedora} < 5
> %define selinux_module 0
> %define selinux_variants %{nil}
> %else
> %define selinux_module 1
> %define selinux_variants mls strict targeted
> %endif
>
> *** Buildreq needed for building .pp files:
>
> %if %{selinux_module}
> # selinux-policy >= 2.2.40 needed because of #190561
> BuildRequires:  checkpolicy, selinux-policy >= 2.2.40
> %endif
>
> *** Build .pp file for each base policy (SELinux directory contains 
> te/fc/if files):
>
> %build
> %if %{selinux_module}
> cd SELinux
> for selinuxvariant in %{selinux_variants}
> do
>   %{__make} NAME=${selinuxvariant} verbose=@ \
>     -f /usr/share/selinux/devel/Makefile
>   %{__mv} SELinux/contagged.pp contagged.pp.${selinuxvariant}
>   %{__make} NAME=${selinuxvariant} \
>     -f /usr/share/selinux/devel/Makefile clean
> done
> cd -
> %endif
>
> *** Install .pp files
>
> %install
> ... usual stuff ...
> # Install SELinux policy modules
> %if %{selinux_module}
> for selinuxvariant in %{selinux_variants}
> do
>   %{__install} -d %{buildroot}%{_datadir}/selinux/${selinuxvariant}
>   %{__install} -p -m 644 contagged.pp.${selinuxvariant} \
>     %{buildroot}%{_datadir}/selinux/${selinuxvariant}/contagged.pp
> done
> %endif
>
> *** post-install scriptlet installs policy modules and fixes contexts:
>
> %if %{selinux_module}
> %post
> # Install SELinux policy modules
> if [ -x /usr/sbin/semodule ]; then
>   for selinuxvariant in %{selinux_variants}
>   do
>     /usr/sbin/semodule -s ${selinuxvariant} -i \
>       %{_datadir}/selinux/${selinuxvariant}/contagged.pp \
>         &> /dev/null || :
>   done
> fi
Does this fail silently if the policy package is not installed?
> # Fix up non-standard directory context
> [ -x /sbin/restorecon ] && /sbin/restorecon \
>   %{_localstatedir}/cache/contagged || :
> %endif
>
>
> *** pre-uninstall script removes policy modules (and removes app's 
> cache, not SELinux-related)):
>
> %postun
> # Clean up after package removal
> if [ $1 -eq 0 ]; then
>   # Clean out the cache
>   %{__rm} -f %{_localstatedir}/cache/contagged/*.tpl.php
>   /bin/rmdir %{_localstatedir}/cache/contagged &> /dev/null || :
> %if %{selinux_module}
>   # Remove SELinux policy modules
>   if [ -x /usr/sbin/semodule ]; then
>     for selinuxvariant in %{selinux_variants}
>     do
>       /usr/sbin/semodule -s ${selinuxvariant} -r contagged || :
>     done
>   fi
You might need to fixup contexts here also, if you leave anything behind.
>
> %endif
> fi
>
> *** %files section includes policy module packages:
>
> %files
> ... usual stuff ...
> %if %{selinux_module}
> %dir %{_datadir}/selinux/*
> %{_datadir}/selinux/*/contagged.pp
> %endif
>
>
>
>
> Now Dan tells me in #190561 that one .pp file should be OK for all 
> base policies if there is no MLS-specific stuff in the policy. So:
>
> * If there was MLS-specific stuff in the policy module, would the 
> approach above be correct?
>
> * As there is no MLS-specific stuff in my package, I'd be inclined to 
> make a single .pp file, put it in 
> %{_datadir}/selinux/share/contagged.pp and just load that one .pp file 
> for each base policy in %post
>
> Dan also comments in #190561 that "ou only need to install it with 
> semodule, you do not need to intall the pp file"; I don't get this, as 
> how will semodule be able to access the .pp file if it isn't installed 
> with the package...
Sorry you are right.  The only thing is you should not put the pp file 
in /usr/share/selinux/VARIANT, as the current policy package does a 
semodule -i of all pp files in that directory.  (Which I should really 
change)  So if someone does a semodule -r later, the policy upgrade will 
reinstall.  

My point about the pp file, is that you do not need to leave it on disk 
or even use it again after it has been installed.  As a matter of fact 
semodule copies the pp file to
/etc/selinux/VARIANT/modules/active/modules/


>
> I'm also considering adding some horrible hack like this:
>
> %if %{selinux_module}
> %define selinux_policyver %(sed -e 
> 's,.*selinux-policy-\\([^/]*\\)/.*,\\1,' 
> /usr/share/selinux/devel/policyhelp)
> Conflicts: selinux-policy < %{selinux_policyver}
> %endif
>
> to avoid problems like this:
> http://www.redhat.com/archives/fedora-selinux-list/2006-May/msg00102.html
>
>
> My overall plan for this package is:
> 1. In conjuction with fedora-selinux-list, make this as clean a 
> package as possible SELinux-wise, such that it can form a good example 
> for others wishing to include policy module packages in their RPM 
> packages.
> 2. In conjuction with fedora-extras-list, do the same from the point 
> of view of a PHP web application (the usual difficulty with these is 
> that upstream writes them in such a way that they're designed to be 
> untarred somewhere under /var/www and then just work, but that's not 
> FHS-compliant and not a good example).
> 3. Get the package accepted into Fedora Extras.
> 4. Include documentation on the wiki at 
> http://fedoraproject.org/wiki/Packaging/SELinux explaining why things 
> in the package are done the way they are, as a guide for other packagers.
>
> Paul.
>




More information about the fedora-selinux-list mailing list