Is there any documentation anywhere on including SELinux Policy Modules in packages (e.g. for Extras) in FC5? For instance, is there a directory where modules can be dropped into so that they get picked up aotomatically? Where should they live?
Consider an example. I have an LDAP-backed addressbook frontend written in PHP that runs on apache. So I install the files in /var/www/someplace in my package and I need to provide an SELinux module that:
* Includes the appropriate file contexts for the application's cache directory, which needs to be writable by httpd * Gives httpd permission to contact LDAP servers over the network (i.e. ports 389 and 636)
Is it possible to turn on the httpd_builtin_scripting boolean from a module (the app is written in PHP and needs this)? Is it even sensible to try to do this, or there just be a README.SELinux telling people they need to do this themselves?
Should the module be loaded in a %post script?
Some guidelines would no doubt be appreciated by many people.
Paul.
On Tue, 2006-03-14 at 10:29 +0000, Paul Howarth wrote:
Is there any documentation anywhere on including SELinux Policy Modules in packages (e.g. for Extras) in FC5? For instance, is there a directory where modules can be dropped into so that they get picked up aotomatically? Where should they live?
Yes, this would be useful to document in the Fedora SELinux wiki. Ideally, policy for a given software package should live in its own package on which the software package depends so that the package manager will install (and thus load) the policy before it tries to unpack the software package (thereby ensuring that any necessary file types are already defined in the kernel policy), e.g. package foo would depend on foo-policy. Not certain where the foo-policy package should drop its policy module, possibly under /usr/share/selinux/foo, and then it can install it by running semodule -i from its %post scriptlet.
Consider an example. I have an LDAP-backed addressbook frontend written in PHP that runs on apache. So I install the files in /var/www/someplace in my package and I need to provide an SELinux module that:
- Includes the appropriate file contexts for the application's cache
directory, which needs to be writable by httpd
- Gives httpd permission to contact LDAP servers over the network (i.e.
ports 389 and 636)
Is it possible to turn on the httpd_builtin_scripting boolean from a module (the app is written in PHP and needs this)? Is it even sensible to try to do this, or there just be a README.SELinux telling people they need to do this themselves?
Not sure if enabling the boolean is the right model there vs. "calling" an interface from your module to enable those rules unconditionally when your module is loaded, because you want the behavior reverted if/when your module is removed but other modules might likewise want the same rules or the admin may have a local customization already. The foo-policy package could certainly call setsebool -P from %post, but I doubt that is the right approach.
Should the module be loaded in a %post script?
Yes, but ideally from a foo-policy package on which foo depends, so that it is loaded before unpacking foo (so that the file contexts can be set down properly).
Some guidelines would no doubt be appreciated by many people.
Stephen Smalley wrote:
On Tue, 2006-03-14 at 10:29 +0000, Paul Howarth wrote:
Is there any documentation anywhere on including SELinux Policy Modules in packages (e.g. for Extras) in FC5? For instance, is there a directory where modules can be dropped into so that they get picked up aotomatically? Where should they live?
Yes, this would be useful to document in the Fedora SELinux wiki. Ideally, policy for a given software package should live in its own package on which the software package depends so that the package manager will install (and thus load) the policy before it tries to unpack the software package (thereby ensuring that any necessary file types are already defined in the kernel policy), e.g. package foo would depend on foo-policy. Not certain where the foo-policy package should drop its policy module, possibly under /usr/share/selinux/foo, and then it can install it by running semodule -i from its %post scriptlet.
I've tried this and it doesn't quite work as I expected.
I have a main package "contagged" and a subpackage "contagged-policy".
The "contagged" packages has:
Requires: contagged-policy = %{version}-%{release} Requires(pre): contagged-policy = %{version}-%{release}
This ensures that the policy package is installed before the main package, and hangs around as long as the main package itself.
The policy package dumps policy in %{_datadir}/selinux/packages/contagged and uses scriptlets to handle module insertion and removal:
%post policy [ -x /usr/sbin/semodule ] && /usr/sbin/semodule -i %{_datadir}/selinux/packages/contagged/contagged.pp || :
%postun policy [ $1 -eq 0 ] && [ -x /usr/sbin/semodule ] && /usr/sbin/semodule -r contagged || :
The only thing the policy module is actually doing is specifying a file context in contagged.fc:
/var/cache/contagged(/.*)? gen_context(system_u:object_r:httpd_cache_t,s0)
If contagged-policy is installed first, and then the contagged package is installed (separate rpm transactions), the file contexts get set up as expected. However, if both are done in the same RPM transaction, the packages get installed in the right order (and there is a noticeable delay after installing the policy subpackage where semodule is being called) but the context for directory /var/cache/contagged is left as system_u:object_r:var_t. I suspect that the reason for this is that rpm installs the files for all packages in the transaction and sets their file contexts before running (presumably in order) the %post scripts for the packages.
This rather defeats the purpose of having the separate -policy package, since I need to use restorecon to fix the file contexts at post-install time in case both packages are installed in the same transaction (a likely scenario). I could do this equally well using a single package, but it's untidy (I have to specify the pathnames that need non-standard contexts in both the .fc policy file and as an argument to restorecon in %post). I really prefer the separate package solution, but I think that would need changes in rpm, which might be hard to get done.
Any thoughts?
Paul.
On Tue, 2006-05-16 at 15:08 +0100, Paul Howarth wrote:
Stephen Smalley wrote:
On Tue, 2006-03-14 at 10:29 +0000, Paul Howarth wrote:
Is there any documentation anywhere on including SELinux Policy Modules in packages (e.g. for Extras) in FC5? For instance, is there a directory where modules can be dropped into so that they get picked up aotomatically? Where should they live?
Yes, this would be useful to document in the Fedora SELinux wiki. Ideally, policy for a given software package should live in its own package on which the software package depends so that the package manager will install (and thus load) the policy before it tries to unpack the software package (thereby ensuring that any necessary file types are already defined in the kernel policy), e.g. package foo would depend on foo-policy. Not certain where the foo-policy package should drop its policy module, possibly under /usr/share/selinux/foo, and then it can install it by running semodule -i from its %post scriptlet.
I've tried this and it doesn't quite work as I expected.
I have a main package "contagged" and a subpackage "contagged-policy".
The "contagged" packages has:
Requires: contagged-policy = %{version}-%{release} Requires(pre): contagged-policy = %{version}-%{release}
This ensures that the policy package is installed before the main package, and hangs around as long as the main package itself.
The policy package dumps policy in %{_datadir}/selinux/packages/contagged and uses scriptlets to handle module insertion and removal:
%post policy [ -x /usr/sbin/semodule ] && /usr/sbin/semodule -i %{_datadir}/selinux/packages/contagged/contagged.pp || :
%postun policy [ $1 -eq 0 ] && [ -x /usr/sbin/semodule ] && /usr/sbin/semodule -r contagged || :
The only thing the policy module is actually doing is specifying a file context in contagged.fc:
/var/cache/contagged(/.*)? gen_context(system_u:object_r:httpd_cache_t,s0)
If contagged-policy is installed first, and then the contagged package is installed (separate rpm transactions), the file contexts get set up as expected. However, if both are done in the same RPM transaction, the packages get installed in the right order (and there is a noticeable delay after installing the policy subpackage where semodule is being called) but the context for directory /var/cache/contagged is left as system_u:object_r:var_t. I suspect that the reason for this is that rpm installs the files for all packages in the transaction and sets their file contexts before running (presumably in order) the %post scripts for the packages.
This rather defeats the purpose of having the separate -policy package, since I need to use restorecon to fix the file contexts at post-install time in case both packages are installed in the same transaction (a likely scenario). I could do this equally well using a single package, but it's untidy (I have to specify the pathnames that need non-standard contexts in both the .fc policy file and as an argument to restorecon in %post). I really prefer the separate package solution, but I think that would need changes in rpm, which might be hard to get done.
Any thoughts?
Yes, it appears that the separate -policy package approach isn't going to work after all (also raised separately on selinux list), so a different approach is under investigation. It requires some changes kernel side (to allow rpm to set down files in their proper contexts first, then load the policy module that defines them - see kernel patch posted to selinux list), as well as some userland changes to allow rpm to determine the file contexts from the .pp file without having to install it first. And I think that they want to have rpm compute the file contexts and store them in the rpm headers again as in FC2 at build time, then only override them at install time if you aren't using the default policy.
On 5/16/06, Paul Howarth paul@city-fan.org wrote:
Stephen Smalley wrote:
On Tue, 2006-03-14 at 10:29 +0000, Paul Howarth wrote:
Is there any documentation anywhere on including SELinux Policy Modules in packages (e.g. for Extras) in FC5? For instance, is there a directory where modules can be dropped into so that they get picked up aotomatically? Where should they live?
This rather defeats the purpose of having the separate -policy package, since I need to use restorecon to fix the file contexts at post-install time in case both packages are installed in the same transaction (a likely scenario). I could do this equally well using a single package, but it's untidy (I have to specify the pathnames that need non-standard contexts in both the .fc policy file and as an argument to restorecon in %post). I really prefer the separate package solution, but I think that would need changes in rpm, which might be hard to get done.
Any thoughts?
An ugly ugly ugly fix might be to have a triggerpost that does a restorecon/setcon on the files when the parent package is installed. That way it ensures the package is reset correctly. Again ugly and might not work.
Paul.
-- fedora-selinux-list mailing list fedora-selinux-list@redhat.com https://www.redhat.com/mailman/listinfo/fedora-selinux-list
Stephen John Smoogen wrote:
On 5/16/06, Paul Howarth paul@city-fan.org wrote:
Stephen Smalley wrote:
On Tue, 2006-03-14 at 10:29 +0000, Paul Howarth wrote:
Is there any documentation anywhere on including SELinux Policy
Modules
in packages (e.g. for Extras) in FC5? For instance, is there a
directory
where modules can be dropped into so that they get picked up aotomatically? Where should they live?
This rather defeats the purpose of having the separate -policy package, since I need to use restorecon to fix the file contexts at post-install time in case both packages are installed in the same transaction (a likely scenario). I could do this equally well using a single package, but it's untidy (I have to specify the pathnames that need non-standard contexts in both the .fc policy file and as an argument to restorecon in %post). I really prefer the separate package solution, but I think that would need changes in rpm, which might be hard to get done.
Any thoughts?
An ugly ugly ugly fix might be to have a triggerpost that does a restorecon/setcon on the files when the parent package is installed. That way it ensures the package is reset correctly. Again ugly and might not work.
For now I've merged the two packages back into one and am using restorecon in %post after semodule to fix up the context.
Next problem:
I built and tested the package on one system, which was fully up to date. Worked fine. Then tried installing the package on other system that was running an older kernel and had older libsepol and selinux-policy-targeted packages. The result was:
# rpm -Uvh contagged-0.3-2.noarch.rpm Preparing... ########################################### [100%] 1:contagged warning: /etc/httpd/conf.d/contagged.conf created as /etc/httpd/conf.d/contagged.conf.rpmnew ########################################### [100%] libsepol.class_copy_callback: contagged: Modules may not yet declare new classes. libsemanage.semanage_link_sandbox: Link packages failed /usr/sbin/semodule: Failed! # rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.34-3.fc5 libsepol-1.12.4-1.fc5 libsemanage-1.6.2-2.fc5
After doing a "yum update" on this system, the package installed cleanly.
Is this a result of the required feature being missing from one of these (or some other) packages, or is a compiled .pp module compatible only with the specific version of something it was built against?
Is there some way of specifying the necessary dependency in the package containing the binary policy module, or is it so volatile (like a kernel module for instance) that the best bet would be to ship policy sources and build them in %post?
Paul.
On Tue, 2006-05-16 at 16:56 +0100, Paul Howarth wrote:
Next problem:
I built and tested the package on one system, which was fully up to date. Worked fine. Then tried installing the package on other system that was running an older kernel and had older libsepol and selinux-policy-targeted packages. The result was:
# rpm -Uvh contagged-0.3-2.noarch.rpm Preparing... ########################################### [100%] 1:contagged warning: /etc/httpd/conf.d/contagged.conf created as /etc/httpd/conf.d/contagged.conf.rpmnew ########################################### [100%] libsepol.class_copy_callback: contagged: Modules may not yet declare new classes. libsemanage.semanage_link_sandbox: Link packages failed /usr/sbin/semodule: Failed! # rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.34-3.fc5 libsepol-1.12.4-1.fc5 libsemanage-1.6.2-2.fc5
After doing a "yum update" on this system, the package installed cleanly.
Is this a result of the required feature being missing from one of these (or some other) packages, or is a compiled .pp module compatible only with the specific version of something it was built against?
I'm confused - I thought you said that the policy package only contained a file contexts section, not a policy module. Was there a policy module? If so, what was the source? The above looks like a bug to me.
The receiving system has to have a libsepol that understands the policy package format and module format, which are versioned, but the above doesn't appear to be a format issue. There is a pending change in the module format, but you will be able to tell checkmodule to generate the older format as well, and libsepol provides backward compatibility for older formats.
Is there some way of specifying the necessary dependency in the package containing the binary policy module, or is it so volatile (like a kernel module for instance) that the best bet would be to ship policy sources and build them in %post?
No, they are intended to allow separate building and distribution.
Stephen Smalley wrote:
On Tue, 2006-05-16 at 16:56 +0100, Paul Howarth wrote:
Next problem:
I built and tested the package on one system, which was fully up to date. Worked fine. Then tried installing the package on other system that was running an older kernel and had older libsepol and selinux-policy-targeted packages. The result was:
# rpm -Uvh contagged-0.3-2.noarch.rpm Preparing... ########################################### [100%] 1:contagged warning: /etc/httpd/conf.d/contagged.conf created as /etc/httpd/conf.d/contagged.conf.rpmnew ########################################### [100%] libsepol.class_copy_callback: contagged: Modules may not yet declare new classes. libsemanage.semanage_link_sandbox: Link packages failed /usr/sbin/semodule: Failed! # rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.34-3.fc5 libsepol-1.12.4-1.fc5 libsemanage-1.6.2-2.fc5
After doing a "yum update" on this system, the package installed cleanly.
Is this a result of the required feature being missing from one of these (or some other) packages, or is a compiled .pp module compatible only with the specific version of something it was built against?
I'm confused - I thought you said that the policy package only contained a file contexts section, not a policy module. Was there a policy module? If so, what was the source? The above looks like a bug to me.
It contains a policy module, but the module only includes file contexts.
The .if file is empty.
The .te file is just: --------------------------------------------------------------------- # It's currently only necessary to set file contexts for the cache directory # in this policy, but doing it in a module is easier from a package maintenance # point of view than using semanage and chcon in scriptlets
policy_module(contagged, 0.1)
######################################## # # Declarations #
# (none needed)
######################################## # # Local policy #
# (none needed) ---------------------------------------------------------------------
The .fc file is: --------------------------------------------------------------------- /var/cache/contagged(/.*)? gen_context(system_u:object_r:httpd_cache_t,s0) ---------------------------------------------------------------------
The module was built on a system with: $ rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.38-1.fc5 libsepol-1.12.6-1.fc5 libsemanage-1.6.2-2.fc5
The error occurred when the package was installed on a system with: $ rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.34-3.fc5 libsepol-1.12.4-1.fc5 libsemanage-1.6.2-2.fc5
Paul.
On Tue, 2006-05-16 at 17:33 +0100, Paul Howarth wrote:
It contains a policy module, but the module only includes file contexts.
Clarification: it is a policy package (.pp), but the policy package only includes file contexts. The module itself is just the .mod file created by checkmodule; it never includes file contexts.
If this is going to be common, then semodule_package and libsemanage need to allow for policy packages that have no policy module.
The .te file is just:
# It's currently only necessary to set file contexts for the cache directory # in this policy, but doing it in a module is easier from a package maintenance # point of view than using semanage and chcon in scriptlets
policy_module(contagged, 0.1)
This pulls in requires statements for the kernel classes and permissions. Which it seems are being confused with an attempt to declare classes/permissions in the module by the older libsepol.
The .fc file is:
/var/cache/contagged(/.*)? gen_context(system_u:object_r:httpd_cache_t,s0)
You can't use gen_context() there, can you? I thought it had to be preprocessed already.
The module was built on a system with: $ rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.38-1.fc5 libsepol-1.12.6-1.fc5 libsemanage-1.6.2-2.fc5
The error occurred when the package was installed on a system with: $ rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.34-3.fc5 libsepol-1.12.4-1.fc5 libsemanage-1.6.2-2.fc5
Hmmm...and what version of checkmodule was used to build it?
Stephen Smalley wrote:
On Tue, 2006-05-16 at 17:33 +0100, Paul Howarth wrote:
It contains a policy module, but the module only includes file contexts.
Clarification: it is a policy package (.pp), but the policy package only includes file contexts. The module itself is just the .mod file created by checkmodule; it never includes file contexts.
Ah, right, thanks for the clarification.
If this is going to be common, then semodule_package and libsemanage need to allow for policy packages that have no policy module.
I think it is, because changes to file contexts are much more easily managed using semodule, since the policy packages are versioned and semodule will always do the right thing when any newer version is installed.
The alternative, using semanage to tweak file contexts, could quickly become unmanageable. For example, suppose package foo went through some major revisions, moving files around the filesystem hierarchy that needed custom contexts. So the first version of the package would contain an semanage call to set contexts for say:
/var/www/foo/cache(/.*)
The next version moved the cache directory to /var/cache/foo, so a package upgrade would need to remove the context object set up in the first version and create a new one for:
/var/cache/foo(/.*)
There might then be an upstream name change from foo to bar, requiring contexts for:
/var/cache/bar(/.*)
The %post script for this package would need to identify the version of the package being upgraded (none, foo-1, foo-2, or bar), remove the appropriate context object (none, /var/www/foo/cache(/.*), /var/cache/foo(/.*)) if necessary and then install the new context object.
Using semanage, if the policy package remained as foo.pp throughout, "semodule -i foo.pp" would always do the right thing. If for the last version, the policy package changed to bar.pp, it could do "semodule -r foo.pp" first and discard any error messages or failure codes before running "semodule -i bar.pp". Much better I think.
The .te file is just:
# It's currently only necessary to set file contexts for the cache directory # in this policy, but doing it in a module is easier from a package maintenance # point of view than using semanage and chcon in scriptlets
policy_module(contagged, 0.1)
This pulls in requires statements for the kernel classes and permissions. Which it seems are being confused with an attempt to declare classes/permissions in the module by the older libsepol.
The .fc file is:
/var/cache/contagged(/.*)? gen_context(system_u:object_r:httpd_cache_t,s0)
You can't use gen_context() there, can you? I thought it had to be preprocessed already.
I just copied from other .fc files I found in the policy sources, and it seems to work (usually). If I'm wrong, what should I be using?
The module was built on a system with: $ rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.38-1.fc5 libsepol-1.12.6-1.fc5 libsemanage-1.6.2-2.fc5
The error occurred when the package was installed on a system with: $ rpm -q selinux-policy-targeted libsepol libsemanage selinux-policy-targeted-2.2.34-3.fc5 libsepol-1.12.4-1.fc5 libsemanage-1.6.2-2.fc5
Hmmm...and what version of checkmodule was used to build it?
$ rpm -q checkpolicy checkpolicy-1.30.3-1.fc5
Paul.
Paul Howarth wrote:
Stephen Smalley wrote:
On Tue, 2006-05-16 at 17:33 +0100, Paul Howarth wrote:
It contains a policy module, but the module only includes file contexts.
Clarification: it is a policy package (.pp), but the policy package only includes file contexts. The module itself is just the .mod file created by checkmodule; it never includes file contexts.
Ah, right, thanks for the clarification.
If this is going to be common, then semodule_package and libsemanage need to allow for policy packages that have no policy module.
Is the absence of a policy module the actual cause of this error? If so, would having a "dummy" policy module that was effectively a no-op (e.g. by including an allow rule that was already in the base policy) be a usable workaround?
Should this be bugzilla-ed?
Paul.
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.
Paul.
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.
On Fri, 2006-05-19 at 09:12 -0400, 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, this leads on to some other issues:
Ideally, I'd like to be able to package up policy modules built for each of the base policies that are shipped in Core. The Makefile currently defaults to targeted policy - how should modules for other base policies be built, particularly in the mock environment used for the Extras build system, where SELinux is disabled.
Following on from that, at package install-time it would be necessary to identify which base policy/policies is/are installed, and install the appropriate modules. Is there a convenient way of finding out which policy/policies are installed without doing an rpm query?
There's also the awkward problem of what to do if a base policy is installed at a later date than a package containing a policy module. For instance, someone might decide to try out the strict policy. Any package containing policy modules for the strict policy would already have skipped its chance to install the strict module during its %post. This could be addressed using triggers but the complexity that would involve for handling all possible policies would make it a struggle to get it past a package review :-) Perhaps an alternative would be for packages to have some way of registering the modules they have available for each base policy, so that they were automatically picked up if that base policy was installed?
Paul.
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 # 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 %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...
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.
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:
- 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.
Daniel J Walsh wrote:
Paul Howarth wrote:
*** 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?
I believe semodule will output "semodule: SELinux policy is not managed or store cannot be accessed.", hence the redirection of all output to /dev/null and the "|| :" to ignore the semodule exit code.
# 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.
Good point. So in this case I'd need:
/sbin/restorecon -Rh %{_localstatedir}/cache/contagged || :
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.
Ah, I saw the clamav.pp in there and assumed it was from an Extras package but it's not. There probably needs to be a separate hierarchy for package modules then, perhaps:
/usr/share/selinux/packages/VARIANT/
and the .pp files go in there. And if it's the same .pp file for all variants, it would go in /usr/share/selinux/packages/share/ instead.
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/
From a package management point of view, it's probably best (and certainly easiest) to just install it as a regular file and then it'll get removed if the package is removed. It's not as if it's saving a huge amount of disk space.
Paul.
On Thu, 2006-05-18 at 13:39 +0100, Paul Howarth wrote:
Paul Howarth wrote:
Stephen Smalley wrote:
On Tue, 2006-05-16 at 17:33 +0100, Paul Howarth wrote:
It contains a policy module, but the module only includes file contexts.
Clarification: it is a policy package (.pp), but the policy package only includes file contexts. The module itself is just the .mod file created by checkmodule; it never includes file contexts.
Ah, right, thanks for the clarification.
If this is going to be common, then semodule_package and libsemanage need to allow for policy packages that have no policy module.
Is the absence of a policy module the actual cause of this error? If so, would having a "dummy" policy module that was effectively a no-op (e.g. by including an allow rule that was already in the base policy) be a usable workaround?
No, per Chad (via private email), the problem you encountered was actually caused by an unintended side effect of the helpful policy_module() macro in refpolicy. Since that macro expands to include require statements for all kernel classes and permissions (so that the policy writer doesn't have to manually specify them for each kernel class and permission he uses), it unfortunately can pick up requires for new classes and permissions in the refpolicy on the build system that are not yet defined in the base policy on the target system (in your case, due to not having fully updated the target system). There are some changes in progress that should help with that problem.
Should this be bugzilla-ed?
I suppose there are two separate issues here: - Avoiding unnecessary dependencies in policy modules on the build system's refpolicy (of which this is only one instance). There is already more general effort in progress to introduce real interfaces into the language and module format so that modules can be truly linked against the interfaces of the base policy on the target system. - Cleanly supporting policy packages that do not include a binary policy module in the tools (e.g. semodule_package) and libraries (e.g. libsemanage, libsepol), so that they can be used to ship just file contexts or other components. I don't know of any work in progress yet on that issue, so it may make sense to bugzilla it, although it is really an upstream issue, and there isn't presently an upstream bugzilla for selinux (just the mailing list).
On Fri, 2006-05-19 at 08:03 -0400, Stephen Smalley wrote:
On Thu, 2006-05-18 at 13:39 +0100, Paul Howarth wrote:
Paul Howarth wrote:
Stephen Smalley wrote:
On Tue, 2006-05-16 at 17:33 +0100, Paul Howarth wrote:
It contains a policy module, but the module only includes file contexts.
Clarification: it is a policy package (.pp), but the policy package only includes file contexts. The module itself is just the .mod file created by checkmodule; it never includes file contexts.
Ah, right, thanks for the clarification.
If this is going to be common, then semodule_package and libsemanage need to allow for policy packages that have no policy module.
Is the absence of a policy module the actual cause of this error? If so, would having a "dummy" policy module that was effectively a no-op (e.g. by including an allow rule that was already in the base policy) be a usable workaround?
No, per Chad (via private email), the problem you encountered was actually caused by an unintended side effect of the helpful policy_module() macro in refpolicy. Since that macro expands to include require statements for all kernel classes and permissions (so that the policy writer doesn't have to manually specify them for each kernel class and permission he uses), it unfortunately can pick up requires for new classes and permissions in the refpolicy on the build system that are not yet defined in the base policy on the target system (in your case, due to not having fully updated the target system). There are some changes in progress that should help with that problem.
A possible workaround for that might be for a package to conflict with selinux-policy versions older than the one it was built against. Is there a convenient way of finding the selinux-policy version short of doing an rpm query?
Should this be bugzilla-ed?
I suppose there are two separate issues here:
- Avoiding unnecessary dependencies in policy modules on the build
system's refpolicy (of which this is only one instance). There is already more general effort in progress to introduce real interfaces into the language and module format so that modules can be truly linked against the interfaces of the base policy on the target system.
- Cleanly supporting policy packages that do not include a binary policy
module in the tools (e.g. semodule_package) and libraries (e.g. libsemanage, libsepol), so that they can be used to ship just file contexts or other components. I don't know of any work in progress yet on that issue, so it may make sense to bugzilla it, although it is really an upstream issue, and there isn't presently an upstream bugzilla for selinux (just the mailing list).
OK I'll bugzilla it, but which component should I use?
Paul.
On Fri, 2006-05-19 at 08:03 -0400, Stephen Smalley wrote:
On Thu, 2006-05-18 at 13:39 +0100, Paul Howarth wrote:
Paul Howarth wrote:
Stephen Smalley wrote:
On Tue, 2006-05-16 at 17:33 +0100, Paul Howarth wrote:
It contains a policy module, but the module only includes file contexts.
If this is going to be common, then semodule_package and libsemanage need to allow for policy packages that have no policy module.
[cut]
- Cleanly supporting policy packages that do not include a binary policy
module in the tools (e.g. semodule_package) and libraries (e.g. libsemanage, libsepol), so that they can be used to ship just file contexts or other components. I don't know of any work in progress yet on that issue, so it may make sense to bugzilla it, although it is really an upstream issue, and there isn't presently an upstream bugzilla for selinux (just the mailing list).
I was looking at what it would take to support a package without a module. Without the binary policy, there is one problem of where the module name and version will come from. We could either add this to the package itself (which would require a policy package format change), or add a section to the package for module name and version (which seems like a hack to me).
More importantly, I believe a package without a module does not make sense because the types and users used in the file contexts should either be declared or required by the module in the package. Otherwise the transaction fails late when the file contexts are validated, rather than early during linking.
On Tue, 2006-06-20 at 16:12 -0400, Christopher J. PeBenito wrote:
On Fri, 2006-05-19 at 08:03 -0400, Stephen Smalley wrote:
On Thu, 2006-05-18 at 13:39 +0100, Paul Howarth wrote:
Paul Howarth wrote:
Stephen Smalley wrote:
On Tue, 2006-05-16 at 17:33 +0100, Paul Howarth wrote:
It contains a policy module, but the module only includes file contexts.
If this is going to be common, then semodule_package and libsemanage need to allow for policy packages that have no policy module.
[cut]
- Cleanly supporting policy packages that do not include a binary policy
module in the tools (e.g. semodule_package) and libraries (e.g. libsemanage, libsepol), so that they can be used to ship just file contexts or other components. I don't know of any work in progress yet on that issue, so it may make sense to bugzilla it, although it is really an upstream issue, and there isn't presently an upstream bugzilla for selinux (just the mailing list).
I was looking at what it would take to support a package without a module. Without the binary policy, there is one problem of where the module name and version will come from. We could either add this to the package itself (which would require a policy package format change), or add a section to the package for module name and version (which seems like a hack to me).
What I'm suggesting isn't a policy package with just file contexts, it's one with no allow/dontaudit rules in the policy, like this:
:::::::::::::: contagged.if :::::::::::::: # contagged.if # # This module has no interfaces :::::::::::::: contagged.fc :::::::::::::: /var/cache/contagged(/.*)? gen_context(system_u:object_r:httpd_cache_t,s0) :::::::::::::: contagged.te :::::::::::::: # It's currently only necessary to set file contexts for the cache directory # in this policy, but doing it in a module is easier from a package maintenance # point of view than using semanage and chcon in scriptlets
policy_module(contagged, 0.3)
######################################## # # Declarations #
require { type httpd_cache_t; };
######################################## # # Local policy #
# (none needed)
More importantly, I believe a package without a module does not make sense because the types and users used in the file contexts should either be declared or required by the module in the package. Otherwise the transaction fails late when the file contexts are validated, rather than early during linking.
I agree. It would make sense for compilation/linking of the module above to fail if the "require" wasn't present. Currently that doesn't happen.
Paul.
selinux@lists.fedoraproject.org