Red Hat Bugzilla – Bug 1001231
RFE: Merge gcl policy into system policy
Last modified: 2014-02-24 11:08:02 EST
Created attachment 790655 [details]
Description of problem:
The gcl package has had its own SELinux policy since 2006, with major updates in 2009 and 2011. The SELinux policy affects more than just gcl, however, as binaries produced by gcl have to have the gcl_exec_t type. Since maxima compiles a gcl backend, the maxima package depends on the gcl package's SELinux policy. It would be cleaner to import the gcl policy into the system policy, so that the labeling of maxima (and any future users of gcl) can be right without needing tricks with semodule, etc.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
I will attach the source files for the gcl SELinux policy. If there is some existing type that already confers the appropriate permissions, I am not adverse to using such a type.
Created attachment 790664 [details]
Created attachment 790667 [details]
could you merge it and try to test.
This policy modules raises some questions with me:
1. what was the reason to implement this policy?
2. there are also questions with regard to how this policy should work
take for example these two entries from the enclosed gcl.fc file:
/usr/lib/maxima/[^/]+/binary-gcl/maxima -- gen_context(system_u:object_r:gcl_exec_t,s0)
/usr/lib64/maxima/[^/]+/binary-gcl/maxima -- gen_context(system_u:object_r:gcl_exec_t,s0)
These files seem to not be part of the maxima package:
# repoquery -ql maxima | grep "/usr/lib"
So they seem to not be installed by the maxima package, instead they are maybe created? If so then they are not created with the gcl_exec_t type sid because there is no such type transition rule. So my question is: what is going on there?
I have more questions but these two questions are most pressing to me
(In reply to Dominick Grift from comment #5)
> This policy modules raises some questions with me:
> 1. what was the reason to implement this policy?
GCL has a complex memory manager. It repurposes chunks of memory during program execution. It uses mprotect() to change the permission bits on a given chunk of memory according to its current purpose. All efforts to convert this code to use mmap() have, so far, failed. If somebody smarter than me can figure out how to make that work, I would be delighted.
> 2. there are also questions with regard to how this policy should work
> take for example these two entries from the enclosed gcl.fc file:
> /usr/lib/maxima/[^/]+/binary-gcl/maxima --
> /usr/lib64/maxima/[^/]+/binary-gcl/maxima --
> These files seem to not be part of the maxima package:
They aren't. They are part of the maxima-runtime-gcl package.
(In reply to Jerry James from comment #6)
> (In reply to Dominick Grift from comment #5)
> > This policy modules raises some questions with me:
> > 1. what was the reason to implement this policy?
> GCL has a complex memory manager. It repurposes chunks of memory during
> program execution. It uses mprotect() to change the permission bits on a
> given chunk of memory according to its current purpose. All efforts to
> convert this code to use mmap() have, so far, failed. If somebody smarter
> than me can figure out how to make that work, I would be delighted.
Sure, that is the impression the policy module gave me. So the only reason for this policy is to make the application work without having to toggle the memory protection SELinux booleans.
I think that is a bit of a stretch, aren't these booleans set to true by default these days any ways. I think Gnome shell relies on execmem as well.
Not to mention that confining the unconfined is a oxymoron in the first place.
But yes, that does not solve the issue for confined users... so i guess from that perspective a SELinux policy for this app may be in order. Just not the one that was enclosed with this bug report.
> > 2. there are also questions with regard to how this policy should work
> > take for example these two entries from the enclosed gcl.fc file:
> > /usr/lib/maxima/[^/]+/binary-gcl/maxima --
> > gen_context(system_u:object_r:gcl_exec_t,s0)
> > /usr/lib64/maxima/[^/]+/binary-gcl/maxima --
> > gen_context(system_u:object_r:gcl_exec_t,s0)
> > These files seem to not be part of the maxima package:
> They aren't. They are part of the maxima-runtime-gcl package.
I see, thanks
(In reply to Dominick Grift from comment #7)
> Sure, that is the impression the policy module gave me. So the only reason
> for this policy is to make the application work without having to toggle the
> memory protection SELinux booleans.
> I think that is a bit of a stretch, aren't these booleans set to true by
> default these days any ways. I think Gnome shell relies on execmem as well.
Are they? On my x86_64 Fedora 19 box, semanage boolean reports that selinuxuser_execheap is off and defaults to off. I believe that is the one that gcl triggers with its use of mprotect().
> Not to mention that confining the unconfined is a oxymoron in the first
I don't know much about confined vs. unconfined, but part of that, at least, was a response to bug 529757. If you are talking about something else, please forgive me for being an SELinux ignoramus.
> But yes, that does not solve the issue for confined users... so i guess from
> that perspective a SELinux policy for this app may be in order. Just not the
> one that was enclosed with this bug report.
I am open to suggestions.
(In reply to Jerry James from comment #8)
> (In reply to Dominick Grift from comment #7)
> > Sure, that is the impression the policy module gave me. So the only reason
> > for this policy is to make the application work without having to toggle the
> > memory protection SELinux booleans.
> > I think that is a bit of a stretch, aren't these booleans set to true by
> > default these days any ways. I think Gnome shell relies on execmem as well.
> Are they? On my x86_64 Fedora 19 box, semanage boolean reports that
> selinuxuser_execheap is off and defaults to off. I believe that is the one
> that gcl triggers with its use of mprotect().
execmem and execmod are true by default in f19 i can confirm that but as for execheap it seems you are right, although for some reason it is set to true currently on my main system.
So yes in that case you are right. Still, question is then does this justify that policy module. My position is, no not really as users can just toggle the execheap boolean instead, and we can debate whether unconfined users should be restricted (not be allowed execheap by default) in the first place.
But again that does not count for confined users afaik, and if we want to support this app for confined users then we should probably write policy for that.
BTW That is just my opinion though
In my view this bug should be reassigned to the selinux-policy component, and they discussion should be between the selinux-policy maintainers about whether these (well intentioned) inconsistencies actually help the cause.
first inconsistency is:
"unconfined, except" either its unconfined, or it isn't
second inconsistency is:
why allow execmem, execmod, execstack by default, but not execheap?
They're all equally bad, Why favour the former three over the latter? Because their more commonly encountered?
I think i also figured out why execheap was set to true on my workstation: i think "steam" needs execheap as well
Well the person who developed these checks (Uli Drepper) believed execheap was the worst. We have gradually moved towards turning them off for unconfined_t since there is so much code that is gradually requiring these access.
The POSIX specification does not permit it, but the Linux implementation of mprotect allows changing the access protection of memory on the heap (e.g., allocated using malloc). This error indicates that heap memory was supposed to be made executable. Doing this is really a bad idea. If anonymous, executable memory is needed it should be allocated using mmap which is the only portable mechanism.
It is also more of a pragmatic problem. We see almost no apps that ever need execheap, so we don't have a problem leaving it locked down. Where as execmod happens constantly because of badly written libraries and execstack/execmem happen for tools that do JIT compiles. Python, Java, Mono all tend to need it, nd these leak into most desktop apps.
Sure i understand all that but now we have developers writing and deploying policy modules on their own just because this permission is disallowed by default. I do not think that is very efficient either.
Why cant we just make unconfined: unconfined, get it over with, and focus on making the confined users more appealing, then we can protect sessions, and make it sensible at the same time.
Now we are getting confronted with the same few issues over and over again, and the confined user domains are pretty much neglected.
I am not against that, but I am not sure how you get most people to change from unconfined_t to staff_t. Also staff_t/user_t/xguest_t has the same problems with the exec* checks.
Well that's probably going to be a process, and before we even consider that we might want to carefully think about a plan for a sustainable future.
I think we should rethink the confined domains a bit (just my opinion)
But anyways as for this bugzilla, i think the maintainer should probably just mention in his README, that the program requires that the selinux_execheap boolean be set to true
I would not implement the policy module that is enclosed with this bugzilla as is, because its pretty useless in my view
But thats up to you all to decide
I think you probably already know my opinion. We have various issues that i think will need to be addressed sooner or later.
The first issue i see is the ever growing policy: I think we should probably at least to some extent embrace the fact that there is no one-size-fits-all policy. I think Fedora recently also had a thread on the devel maillist about creating "spins" that target specific purposes. I think that is a great idea because similarly it could be argued that there is no one-size-fits-all Fedora
One way to hit two bird with one stone, as i see it, is to think of a different was to deploy modules rather than forcing everyone to install the same collection of modules. Because, although just installing all modules by default is easy, it also inefficient. I have policy modules install that i would probably never need due to my use profile.
Its basically the same with Fedora, rather than just installing the whole software collection, we are able to install groups of packages that have things in common, and ofcourse you can install indiviual packages.
If we are able to install policy that applies only then that is much more efficient i believe, and although its still in essence a one-size-fits-all policy it is now at least tailored some what tailor to the systems profile
The result: For machines with specific purposes we end up with a very small, fast and efficient policy.
On Desktop systems we now actually can really confine the desktop without have to worry about explosion of policy due to the nature of desktop layers.
So its 2020: everyone has a systems that have installed exactly what they need with policy that covers just that, we have this unconfined domain thats really unconfined, and we have confined sessions that are really confined. Life is good , things are consistent and makes sense.
Users have changed to confined domains without us using force. We made it compelling. The revolution started with people that has a need for integrity (our former sandbox users) these people helped improve the experience and help spread the word.
Our policy footprint is reasonably small because its tailored to the requirement of the system. There is no unneeded overhead. Its efficient.
Meanwhile on another front a campaign was started to really demystify the technology. Previously SELinux was one of the industries best kept secret. This because instead of just explaining the basics concepts and principles people were fed with pre-digested recipes that really only applied to specific predefined configurations.
Rather than spending time on just explaining what each configurable identifier means, people were taught how to figure that out themselves so that the knowledge would apply to any configuration not just one.
People were also taught how SELinux is in essence transparent to the user space and that the components of the user space could optionally be made aware of SELinux or even an extension to it. Similarly it was explained that identifiers are configurable. The result was that application developers started to understand SELinux, and use the SELinux library functions is sensible ways
Sure SELinux was still seen as annoying (like for example network firewalls are still seen as annoying to some today) but now at least people could explain why annoying to them. and why it is used.
In conclusion: The Common Intermediary Language (CIL), can i think, be a great opportunity for us to work towards our (realligned) goals. We have learned a lot, CIL is designed with all that we learned in the past in mind. SELinux 2.0: Lets look at CIL more closely and see how she can help us make the vision a reality. Please lets also work in consensus with the community as a whole because united be stand, and devided we fall
(In reply to Daniel Walsh from comment #13)
> Also staff_t/user_t/xguest_t has the same problems with the exec* checks.
That's not how i see it. unconfined_t is unconfined and thus has no need to ever transition out of the unconfined_t domain
Confined domains however have every reason to transition out of their domain into confined application domains. This property enables us to specify on a domain type level who can execheap and who not.
But yes i can already hear the next question coming: What if the app is not yet covered in policy? Well there are i guess various ways to temporarily deal with that scenario, but the goal should probably be to somehow contain the app eventually.
The current confined domains are, excuse my french, half-baked. They do not provide users with much integrity. Theyre just semi-unconfined domains. A pretty permissive domain in which most apps run with the same privileges as the user shell process.
This is what i mean with consistency:
unconfined == unconfined
confined == confined
unconfined == unconfined,except
confined == confined,except
I have let this sit for a few months, because I was unsure where to go with it. The conversation spun wildly off-topic. Can we get back to the real problem here now? This is the problem:
Without the policy currently shipped with gcl, people who "yum install mamxima maxima-runtime-gcl" find that maxima doesn't work, because SELinux prevented gcl from running. On the other hand, the policy for gcl includes policy for maxima, and will have to include policy for any future gcl-compiled code, which is the wrong place for such policy. Can we please come up with some way of fixing *that* problem?
JIT compilers were mentioned above. That's exactly what GCL is doing. It is a Common Lisp system, and part of Common Lisp is supporting (eval), which means compiling code on the fly.
Miroslav, can we move the gcl code into the main package?