Bug 505066 - restorecon do not set selinux context when run in rpm transaction
Summary: restorecon do not set selinux context when run in rpm transaction
Keywords:
Status: CLOSED DEFERRED
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: rpm
Version: 5.3
Hardware: All
OS: Linux
low
high
Target Milestone: rc
: ---
Assignee: Panu Matilainen
QA Contact: BaseOS QE Security Team
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2009-06-10 15:00 UTC by Miroslav Suchý
Modified: 2011-03-15 13:52 UTC (History)
9 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2009-10-02 10:58:48 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
perl-NOCpulse-Scheduler rpm (3.16 KB, application/x-rpm)
2009-06-10 15:01 UTC, Miroslav Suchý
no flags Details
spacewalk-monitoring-selinux (11.91 KB, application/x-rpm)
2009-06-10 15:02 UTC, Miroslav Suchý
no flags Details
spacewalk-monitoring (10.30 KB, application/x-rpm)
2009-06-10 15:02 UTC, Miroslav Suchý
no flags Details
SRPM of perl-NOCpulse-Scheduler (19.39 KB, application/x-rpm)
2009-06-10 15:05 UTC, Miroslav Suchý
no flags Details
SRPM of spacewalk-monitoring-selinux (9.77 KB, application/x-rpm)
2009-06-10 15:06 UTC, Miroslav Suchý
no flags Details
SRPM of spacewalk-monitoring (12.68 KB, application/x-rpm)
2009-06-10 15:08 UTC, Miroslav Suchý
no flags Details

Description Miroslav Suchý 2009-06-10 15:00:52 UTC
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:

# rpm -Uvh perl-NOCpulse-Scheduler-1.58.12-1.git.e8b11458fb42a0ffacd01104d6a7d30888771997.noarch.rpm
Preparing...                ########################################### [100%]
   1:perl-NOCpulse-Scheduler########################################### [100%]
[root@dri//tmp]# ls -ldZ /var/lib/nocpulse/NPkernel.out
drwxr-xr-x  root root system_u:object_r:var_lib_t      /var/lib/nocpulse/NPkernel.out

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.29cb6e0f582984620bf455cf4d67627380c20eca.noarch.rpm
Preparing...                ########################################### [100%]
   1:spacewalk-monitoring-se########################################### [100%]
....
[root@dri//tmp]# ls -ldZ /var/lib/nocpulse/NPkernel.out
drwxr-xr-x  root root system_u:object_r:spacewalk_monitoring_var_lib_t /var/lib/nocpulse/NPkernel.out

Now remove it and install both packages in one transaction and that file got var_lib_t:
[root@dri//tmp]# rpm -e spacewalk-monitoring-selinux perl-NOCpulse-Scheduler
/sbin/restorecon reset /var/lib/nocpulse context system_u:object_r:unlabeled_t:s0->system_u:object_r:var_lib_t:s0
...
[root@dri//tmp]# rpm -Uvh perl-NOCpulse-Scheduler-1.58.12-1.git.e8b11458fb42a0ffacd01104d6a7d30888771997.noarch.rpm spacewalk-monitoring-selinux-0.6.10-1.git.29cb6e0f582984620bf455cf4d67627380c20eca.noarch.rpm
Preparing...                ########################################### [100%]
   1:spacewalk-monitoring-se########################################### [ 50%]
/sbin/restorecon:  error while labeling files under /etc/notification
/sbin/restorecon reset /var/lib/nocpulse context system_u:object_r:var_lib_t:s0->system_u:object_r:spacewalk_monitoring_var_lib_t:s0
/sbin/restorecon reset /var/lib/nocpulse/NOCpulse.ini context system_u:object_r:var_lib_t:s0->system_u:object_r:spacewalk_monitoring_var_lib_t:s0
/sbin/restorecon reset /var/lib/nocpulse/.ssh context system_u:object_r:var_lib_t:s0->system_u:object_r:spacewalk_monitoring_var_lib_t:s0
/sbin/restorecon reset /var/lib/nocpulse/.ssh/nocpulse-identity.pub context system_u:object_r:var_lib_t:s0->system_u:object_r:spacewalk_monitoring_var_lib_t:s0
/sbin/restorecon reset /var/lib/nocpulse/.ssh/authorized_keys context system_u:object_r:var_lib_t:s0->system_u:object_r:spacewalk_monitoring_var_lib_t:s0
/sbin/restorecon reset /var/lib/nocpulse/.ssh/nocpulse-identity context system_u:object_r:var_lib_t:s0->system_u:object_r:spacewalk_monitoring_var_lib_t:s0
/sbin/restorecon:  error while labeling files under /var/lib/notification
   2:perl-NOCpulse-Scheduler########################################### [100%]
[root@dri//tmp]# ls -ldZ /var/lib/nocpulse/NPkernel.out
drwxr-xr-x  root root system_u:object_r:var_lib_t      /var/lib/nocpulse/NPkernel.out

Actual results:
/var/lib/nocpulse/NPkernel.out get var_lib_t. But since selinux module has been loaded in %post prior installation of  perl-NOCpulse-Scheduler, I would expect that any file installed after spacewalk-monitoring-selinux will get selinux context as defined in this politics.

Expected results:
/var/lib/nocpulse should have spacewalk_monitoring_var_lib_t

Additional info:
[root@dri//tmp]# getenforce
Permissive
Note: It seems that it depends on order of package installation. This bug only appear if spacewalk-monitoring-selinux is picked up before perl-NOCpulse-Scheduler. Since the rpm picked up order randomly, you may find that it will install perl-NOCpulse-Scheduler as first. Try to swap name of packages on command line, try to run it more time, try to wait and run it later ... till you get the order the same as I have in steps to reproduce.

Jnovy sugggested to use %posttrans instead of %post which seems to make workaround, so it is not critical for us, but I still suppose this is serious bug, which do something which is not expected.

Comment 1 Miroslav Suchý 2009-06-10 15:01:52 UTC
Created attachment 347235 [details]
perl-NOCpulse-Scheduler rpm

Comment 2 Miroslav Suchý 2009-06-10 15:02:27 UTC
Created attachment 347237 [details]
spacewalk-monitoring-selinux

Comment 3 Miroslav Suchý 2009-06-10 15:02:58 UTC
Created attachment 347238 [details]
spacewalk-monitoring

Comment 4 Miroslav Suchý 2009-06-10 15:05:43 UTC
Created attachment 347239 [details]
SRPM of perl-NOCpulse-Scheduler

Comment 5 Miroslav Suchý 2009-06-10 15:06:24 UTC
Created attachment 347240 [details]
SRPM of spacewalk-monitoring-selinux

Comment 6 Miroslav Suchý 2009-06-10 15:08:13 UTC
Created attachment 347242 [details]
SRPM of spacewalk-monitoring

Comment 7 Daniel Walsh 2009-06-10 17:35:04 UTC
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.

Comment 8 Miroslav Suchý 2009-06-11 07:53:06 UTC
Notice that in %post section of spacewalk-monitoring-selinux is called script spacewalk-monitoring-selinux-enable, which contains:

# Install SELinux policy modules
for selinuxvariant in mls strict targeted
  do
    /usr/sbin/semodule -s ${selinuxvariant} -l > /dev/null 2>&1 \
      && /usr/sbin/semodule -s ${selinuxvariant} -i \
        /usr/share/selinux/${selinuxvariant}/spacewalk-monitoring.pp || :
  done

/sbin/restorecon -rv /etc/rc.d/np.d /etc/notification /var/lib/nocpulse /var/lib/notification /var/log/nocpulse
/sbin/restorecon -rvi /var/log/SysVStep.* /var/run/SysVStep.*

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?

Comment 9 Jan Pazdziora 2009-06-11 14:21:34 UTC
(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.

Comment 10 Daniel Walsh 2009-06-11 15:39:05 UTC
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.

Comment 11 Panu Matilainen 2009-06-26 07:47:42 UTC
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)

Comment 12 Jan Pazdziora 2009-06-26 08:08:22 UTC
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.

Comment 13 Panu Matilainen 2009-06-26 09:04:59 UTC
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.

Comment 14 Daniel Walsh 2009-06-26 20:06:28 UTC
Steven you have any ideas?

Comment 15 Stephen Smalley 2009-06-29 12:42:40 UTC
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.

Comment 16 Stephen Smalley 2009-06-29 16:07:45 UTC
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?).

Comment 17 Eamon Walsh 2009-06-29 18:31:31 UTC
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.

Comment 18 Eamon Walsh 2009-06-29 18:35:14 UTC
...Although you need libselinux 2.0.80 for these functions, not sure what is in RHEL.

Comment 20 Denise Dumas 2009-07-20 12:59:26 UTC
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.

Comment 21 Florian Festi 2009-10-02 10:58:48 UTC
This could possibly be solved by 

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.


Note You need to log in before you can comment on or make changes to this bug.