Description of problem:
Let have package A and package A-selinux, which define selinux policy for A.
Package A-selinux have in %post section
semodule -i A.module
restorecon /file/of/package/A
When you run
rpm -Uvh A A-selinux
then files from A package has wrong context (sometimes).
If you run
rpm -Uvh A
rpm -Uvh A-selinux
then it is OK. Reverse order is OK to. You just could not run it together.
Version-Release number of selected component (if applicable):
# rpm -qa |grep selinux
libselinux-devel-1.33.4-5.1.el5
libselinux-python-1.33.4-5.1.el5
selinux-policy-2.4.6-203.el5
selinux-policy-devel-2.4.6-203.el5
spacewalk-monitoring-selinux-0.6.10-1.git.29cb6e0f582984620bf455cf4d67627380c20eca
libselinux-1.33.4-5.1.el5
libselinux-utils-1.33.4-5.1.el5
selinux-policy-targeted-2.4.6-203.el5
How reproducible:
sometimes (see steps to reproduce and additional info)
Steps to Reproduce:
Download attached rpm files. It is very minimalized versions of packages from RHN satellite, where we find this behavior. I believe it can be stripped more, but this should be enough for you guys to test without installing all 150 packages we have in our product.
Let first install it without selinux package. That file got var_lib_t:
This is not an SELinux bug but a packaging bug. You need to make sure the selinux policy package is installed first Or run the restorecon on all files covered by the context when the package gets installed.
So the selinux policy module is loaded before perl-NOCpulse-Scheduler is installed. Therefore I assume that file from perl-NOCpulse-Scheduler should have scontext as defined in that module.
Or I understand it wrong?
(In reply to comment #7)
> This is not an SELinux bug but a packaging bug. You need to make sure the
> selinux policy package is installed first
We might consider doing that with Spacewalk/Satellite packages in the future.
> Or run the restorecon on all files
> covered by the context when the package gets installed.
Well, the trouble is, matchpathcon_init() seems to be called at the beginning of the rpm transaction and matchpathcon_fini() at the end, so the newly loaded module (or semanage fcontext, I assume) is not seen by rpm. External restorecon fixes that, yes.
Still, shouldn't rpm detect that the state of SELinux has changed while the package was installed, and rerun that matchpathcon_init() ? Obviously, this bugzilla should probably be aligned to rpm/rpmlib.
I think this is an RPM problem. Maybe call matchpathcon_init after each post install, but the files might be already on disk before any post installs run.
Daniel, is there an libsyslinux API call that rpm could use to track SELinux policy changes? security_policyvers() seems like a potential candidate but does the policy version change if a package loads a module of its own like spacewalk is doing here, or is there a better way to detect policy changes? I'd rather not do matchpathcon_ini() and _fini() after each and every package "just in case", the transaction is slow enough as it is :)
Of course that still leaves a lot uncovered: the policy should optimally be loaded before laying down the files, which gets us to the chicken and egg problem in bug 185434. For "pure" policy packages that contain nothing but a policy, it would help ordering them early in the transaction currently there's no way for rpm to know whether something has selinux policies or not (well, there's %policy files but AFAIK nothing uses them as other pieces are missing to make any use of it)
Yep, a way of detecting either the "incarnation" sequence number of the policy state, or timestamp of the last policy load, could help in rerunning matchpathcon_ini only if the package has actually changed something.
Alternatively, amending rpm behaviour to do the matchpathcon_ini reload if it just installed %policy files (and if the .rpm had some %post script, meaning there is a chance that the .rpm actually did something with those %policy files) could be the way. I admit that my SELinux policy module files are not marked as %policy as of now but I can easily update my .rpms if that would be the preferred way.
Marking policy files with %policy has a side-effect: such files get stuffed into the header too, where policy size might become an issue wrt current header size limits. Hmm... looking at F11 selinux-policy-targeted, /usr/share/selinux/targeted/ is 2.7M which wouldn't be a problem to store in the header, uncompressed that becomes 43MB which *is* a problem.
Another problem with %policy is that it expects plaintext .te files, rpm doesn't support arrays of binary data so the data is stored as array of \0-terminated strings, which would blow up big time if you try to include binary policies there. So rpm would need to base64 encode them (it should probably do it anyway for its own safety), which means a fair increase in data size but maybe not prohibitive, the F11 targeted policy compressed "only" becomes 3.5MB base64-encoded.
So while %policy would provide the necessary hint for rpm to reload selinux contexts, and actually even preload the policies from there, it's not usable as it is now.
Hmm, selinux_set_callback() with SELINUX_CB_POLICYLOAD seems even better than manually polling policy version, especially if that callback occurs on any semodule load.
Yes, selinux_set_callback() with SELINUX_CB_POLICYLOAD should get notification of policy reloads, which will happen upon semodule -i.
With regard to %policy, Tresys is looking into migrating away from binary policy modules to a text representation and into improved rpm-selinux integration.
Actually, you may need to call the avc_netlink* interfaces as well, as rpm doesn't presently use the AVC and that callback only gets called from the AVC (right Eamon?).
Man avc_netlink_open(3). You can set up the POLICYLOAD callback with
selinux_set_callback(), then open-code a loop using the avc_netlink
functions, or use avc_netlink_loop() to enter a blocking loop (in a
thread, for example). The POLICYLOAD callback will be called, and calling avc_open() to set up the AVC is not required.
Moving this to 5.5 although I'm not sure the scope of these proposed changes makes it feasible for the RHEL5 stream at all. But lets keep the discussion going and Panu is looking at this for upstream.
1. rpm being able to reload the policy
2. policy packages being required by the main package (filesystem if in doubt). This means that we'd need to create -nopolicy policy packages that can be chosen if no selinux policy is wanted. I really don't see a more beautiful way of getting the ordering right.
As both together is a too big change for an update release I close this bug as DEFFRRED. For now there is still the possibility of calling restorecon in a %posttrans scriptlet or and %post scriptlet and set a Requires: to the -selinux package.
PS: RHEL 5 still has libselinux-1.33.4
PPS: As the first installation is happening into a install root calling restorecon from within scriptlets could still be required. SElinux and install roots do not mix very well.
Description of problem:
Let have package A and package A-selinux, which define selinux policy for A.
Package A-selinux have in %post section
semodule -i A.module
restorecon /file/of/package/A
When you run
rpm -Uvh A A-selinux
then files from A package has wrong context (sometimes).
If you run
rpm -Uvh A
rpm -Uvh A-selinux
then it is OK. Reverse order is OK to. You just could not run it together.
Version-Release number of selected component (if applicable): devel-1. 33.4-5. 1.el5 python- 1.33.4- 5.1.el5 policy- 2.4.6-203. el5 policy- devel-2. 4.6-203. el5 monitoring- selinux- 0.6.10- 1.git.29cb6e0f5 82984620bf455cf 4d67627380c20ec a 1.33.4- 5.1.el5 utils-1. 33.4-5. 1.el5 policy- targeted- 2.4.6-203. el5
# rpm -qa |grep selinux
libselinux-
libselinux-
selinux-
selinux-
spacewalk-
libselinux-
libselinux-
selinux-
How reproducible:
sometimes (see steps to reproduce and additional info)
Steps to Reproduce:
Download attached rpm files. It is very minimalized versions of packages from RHN satellite, where we find this behavior. I believe it can be stripped more, but this should be enough for you guys to test without installing all 150 packages we have in our product.
Let first install it without selinux package. That file got var_lib_t:
# rpm -Uvh perl-NOCpulse- Scheduler- 1.58.12- 1.git.e8b11458f b42a0ffacd01104 d6a7d3088877199 7.noarch. rpm ####### ####### ####### ####### ####### # [100%] NOCpulse- Scheduler# ####### ####### ####### ####### ####### ####### [100%] nocpulse/ NPkernel. out u:object_ r:var_lib_ t /var/lib/ nocpulse/ NPkernel. out
Preparing... #######
1:perl-
[root@dri//tmp]# ls -ldZ /var/lib/
drwxr-xr-x root root system_
Now install selinux package. That file will get spacewalk_ monitoring_ var_lib_ t:
[root@dri//tmp]# rpm -Uvh spacewalk- monitoring- selinux- 0.6.10- 1.git.29cb6e0f5 82984620bf455cf 4d67627380c20ec a.noarch. rpm ####### ####### ####### ####### ####### # [100%] monitoring- se##### ####### ####### ####### ####### ####### ### [100%] nocpulse/ NPkernel. out u:object_ r:spacewalk_ monitoring_ var_lib_ t /var/lib/ nocpulse/ NPkernel. out
Preparing... #######
1:spacewalk-
....
[root@dri//tmp]# ls -ldZ /var/lib/
drwxr-xr-x root root system_
Now remove it and install both packages in one transaction and that file got var_lib_t: monitoring- selinux perl-NOCpulse- Scheduler u:object_ r:unlabeled_ t:s0->system_ u:object_ r:var_lib_ t:s0 Scheduler- 1.58.12- 1.git.e8b11458f b42a0ffacd01104 d6a7d3088877199 7.noarch. rpm spacewalk- monitoring- selinux- 0.6.10- 1.git.29cb6e0f5 82984620bf455cf 4d67627380c20ec a.noarch. rpm ####### ####### ####### ####### ####### # [100%] monitoring- se##### ####### ####### ####### ####### ####### ### [ 50%] u:object_ r:var_lib_ t:s0->system_ u:object_ r:spacewalk_ monitoring_ var_lib_ t:s0 nocpulse/ NOCpulse. ini context system_ u:object_ r:var_lib_ t:s0->system_ u:object_ r:spacewalk_ monitoring_ var_lib_ t:s0 nocpulse/ ....
[root@dri//tmp]# rpm -e spacewalk-
/sbin/restorecon reset /var/lib/nocpulse context system_
...
[root@dri//tmp]# rpm -Uvh perl-NOCpulse-
Preparing... #######
1:spacewalk-
/sbin/restorecon: error while labeling files under /etc/notification
/sbin/restorecon reset /var/lib/nocpulse context system_
/sbin/restorecon reset /var/lib/
/sbin/restorecon reset /var/lib/