Bug 1393004 - selinux_validate_context() refpol is required for restorecon() calls
Summary: selinux_validate_context() refpol is required for restorecon() calls
Keywords:
Status: CLOSED CANTFIX
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: selinux-policy
Version: 7.4
Hardware: Unspecified
OS: Linux
low
low
Target Milestone: rc
: ---
Assignee: Lukas Vrabec
QA Contact: BaseOS QE Security Team
URL:
Whiteboard:
Depends On:
Blocks: 1393066
TreeView+ depends on / blocked
 
Reported: 2016-11-08 16:40 UTC by Brian Bouterse
Modified: 2017-08-22 13:05 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2017-08-22 10:06:43 UTC
Target Upstream Version:


Attachments (Terms of Use)

Description Brian Bouterse 2016-11-08 16:40:15 UTC
When using the Python binding for selinux to run restorecon recursively on a directory, the policy restricting the Python process requires the selinux_validate_context permission in addition to the explicit relabel statements, which does not seem right.

The Python code is simple; something like:

import selinux
selinux.restorecon('/path/to/dir', recursive=True)

The selinux label is celery_t and it has these allow statements in its policy:

allow celery_t httpd_sys_rw_content_t:dir relabelto;
allow celery_t httpd_sys_rw_content_t:file relabelto;
allow celery_t httpd_sys_rw_content_t:lnk_file relabelto;
allow celery_t pulp_var_cache_t:dir relabelfrom;
allow celery_t pulp_var_cache_t:file relabelfrom;
allow celery_t pulp_var_cache_t:lnk_file relabelfrom;

The strange thing is that SELinux also requires this statement:

selinux_validate_context(celery_t)

The description on that refpol statement is that statement: "Allows caller to validate security contexts".

Why is that necessary? Is this a bug in the restorecon() call of the selinux python binding?

If I omit the selinux_validate_context() permissions, I receive these AVC denials:

type=AVC msg=audit(1476979237.205:84012): avc:  denied  { read write } for  pid=31476 comm="celery" name="context" dev="selinuxfs" ino=5 scontext=system_u:system_r:celery_t:s0 tcontext=system_u:object_r:security_t:s0 tclass=file permissive=0
type=AVC msg=audit(1476979237.205:84013): avc:  denied  { read write } for  pid=31476 comm="celery" name="context" dev="selinuxfs" ino=5 scontext=system_u:system_r:celery_t:s0 tcontext=system_u:object_r:security_t:s0 tclass=file permissive=0

Comment 3 Brian Bouterse 2017-08-17 16:05:42 UTC
Hi Lukas. Policy is a development technology that can be used to run python applications, so the permissions needed vary application by application depending on the Python code inside. So there isn't a python-celery policy, but for our app, Pulp ( http://pulpproject.org/ ) we have three SELinux policies we maintain and distribute via rpm directly from upstream.

The line of interest is currently committed into our pulp-celery policy here: https://github.com/pulp/pulp/blob/master/server/selinux/server/pulp-celery.te#L149

Please let me know if there is any way I can help.

Comment 4 Lukas Vrabec 2017-08-22 10:06:43 UTC
Thanks Brian, 

If these policy is shipped by upstream, these rules also should be fixed there. Closing this BZ as CANTFIX.

Comment 5 Brian Bouterse 2017-08-22 13:05:40 UTC
Thanks Lukas. At most, this is a very low severity bug, so feel free to respond with a very brief response. My thinking was that refpol or python-selinux may have a bug in it, not the upstream policy. Everything works already in the upstream policy so there isn't a "fix" to apply there at all.

The claim of this bug is that I am required to include a "selinux_validate_context(celery_t)" statement when I run a python-selinux code of "selinux.restorecon('/path/to/dir', recursive=True)". I don't see why that selinux_validate_context() call is required. I may have an incorrect expectation. So the two questions I still have are:

Is it expected that a "selinux_validate_context(celery_t)" statement be included in my policy when running "selinux.restorecon()"? If it isn't then it's a bug in refpol or maybe python-selinux.

How can I learn more to better understand why this specific statement is required? I've read the refpol description, but maybe I should read the python-selinux implementation instead?


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