RE: how to implement permissive domains + an old bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2008-02-15 at 15:17 -0500, Joshua Brindle wrote:
> Stephen Smalley wrote:
> > On Fri, 2008-02-15 at 14:43 -0500, Eric Paris wrote:
> >> On Fri, 2008-02-15 at 13:57 -0500, Stephen Smalley wrote:
> >>> On Fri, 2008-02-15 at 13:35 -0500, Joshua Brindle wrote:
> >>>> Stephen Smalley wrote:
> >>>>> On Fri, 2008-02-15 at 12:50 -0500, Eric Paris wrote:
> >>>>>> So after many months of trying to avoid it Dan finally beat me
> >>>>>> into looking at permissive domains.  I'm coming to the list to
> >>>>>> ask how people feel the transfer of knowledge that a domain is
> >>>>>> permissive between the policy and the kernel should be
> >>>>>> implemented.  (And to point out what I think is a bug I found
> >>>>>> while trolling around the code today)
> >>>>>> 
> >>>>>> Old discussion of permissive domains.
> >>>>>> http://marc.info/?l=selinux&m=118953810913436&w=2
> >>>>>> 
> >>>>>> The basic idea is that we want a domain in which a process can
> >>>>>> run without any permission enforcement and without flooding the
> >>>>>> audit logs. After much discussion I think everyone agreed with
> >>>>>> (or at least stopped arguing against) a couple of things.
> >>>>>> 
> >>>>>> 1) do this in policy (not selinuxfs)
> >>>>>> 2) have it act just like 'setenforce 0'
> >>>>>> 
> >>>>>> My question today is about #1.  How to implement?  Karl
> >>>>>> suggested stealing a bit from the type_datum->primary field to
> >>>>>> indicate to the kernel that a certain type was a
> > permissive domain.  Can I do this?
> >>>>>> I guess this is a question for the setools group. Do you make
> >>>>>> use of the actual value stored in 'primary'?  The kernel does
> >>>>>> not.  Does anything make use of the actual value outside of the
> >>>>>> tool chain? Please say 'no' and make this easier for me.
> >>>>>> 
> >>>>>> I want to throw away the 'primary' field all together in the
> >>>>>> final binary policy and create a 'new' field called 'flags' in
> >>>>>> its place. After my change flags would make use of 2 bits.
> >>>>>> 
> >>>>>> #define F_PRIMARY		0x00000001
> >>>>>> #define F_PERMISSIVE		0x80000000
> >>>>>> if (type_datum->old_primary)
> >>>>>> 	type_datum->flags = F_PRIMARY; if (permissive domain)
> >>>>>>     type_datum->flags |= F_PERMISSIVE
> >>>>>> 
> >>>>>> This only works if noone makes actual use of the value in
> >>>>>> ->primary. If someone makes use of the value in primary I can't
> >>>>>> really reuse that area on disk and I think I'm going to have to
> >>>>>> bump the policy version and add a whole new ->flags field on
> >>>>>> disk (I don't think pmoore's capability stuff really helps).
> >  Maybe the
> >>>>>> tools could just agree to ignore the last bit?  To be honest
> >>>>>> I'm not personally terribly concerned about setools backwards
> >>>>>> compatibility.  I'm really only thinking about function
> >>>>>> backwards compatibility, so maybe the tools people would be ok
> >>>>>> with me just userping a bit (but I'd much rather have a more
> >>>>>> clear 'flags' than 'primary + one bit stolen for some other
> >>>>>> random crap).  For backwards compatibility I might have to bump
> >>>>>> the policy number even if noone has a problem with me
> >>>>>> redefining the meaning of the ->primary field, not sure yet
> >>>>>> haven't really wrapped my brain around it.  I think there is a
> >>>>>> kernel bug which actually makes it possible to reuse the field
> >>>>>> in my new way and maintain
> >>>>> backwards kernel compatibility.
> >>>>>> 
> >>>>>> **The Bug**
> >>>>>> In the binary policy on disk ->primary is a uint32_t but in the
> >>>>>> kernel ->primary is an unsigned char.  When we load policy we
> >>>>>> just have 
> >>>>>> 
> >>>>>> typdatum->primary = le32_to_cpu(buf[2]);
> >>>>>> 
> >>>>>> So we are truncating to 8 bits.  I think that means that if the
> >>>>>> on disk ->primary value is greater than 0xFF but the lower 8
> >>>>>> bits are all 0 we are going to screw this up (maybe this is
> >>>>>> impossible, but I don't see why looking at libsepol quickly).
> >>>>>> Thanks to this bug though I think I could use the 32nd bit of
> >>>>>> the on disk representation on old kernels and they wouldn't even
> >>>>>> realize it. New kernels could be made to pay attention to that
> >>>>>> bit. Backwards compatibility through bugs, I love it. It also
> >>>>>> means I don't really want to fix this bug right now *smile* **End
> >>>>>> bug**
> >>>>> 
> >>>>> Kernel policy representation only uses ->primary as a boolean
> >>>>> flag (is it a primary name or an alias, with the type index
> >>>>> value in ->value regardless).  Modular policy introduced the
> >>>>> notion of using it to store the primary type index for aliases
> >>>>> (when ->flavor == TYPE_ALIAS).  By the time we reach kernel
> >>>>> policy (after expansion), it should only be a boolean again.
> >> 
> >> I guess this being done in src/expand.c::type_copy_callback().
> >> 
> >> All my thought is for nothing though.  Somehow in the language we
> >> have to represent permissive domains.  That in and of itself
> >> requires a version bump doesn't it?  Drat.
> >> 
> >> So what format do we want to go with?
> >> 
> >> permissive httpd_t;
> >> 
> >> anyone got anything better?
> >> 
> >> So with the policy version bump should I add a new field, ->flags to
> >> the on disk type_datum represenation?  Should I instead just rename
> >> ->primary to ->flags and teach libsepol to mask off the flag?  I
> >> don't know the toolchain well enough to know if we ever write more
> >> than a boolean to disk in ->primary.  Guess that's what I'll look
> >> for now but first glance tells me I might as well use another 32
> >> bits on disk since it seems as though we have such disperate usage
> >> of primary for POLICY_KERNEL vs everything else.
> > 
> > Crazy idea:  Make "permissive" a special type attribute name,
> > and mark types that should be permissive with that attribute
> > via typeattribute.
> > Then let the usual type attribute handling propagate it throughout.
> > 
> 
> Aaahhh! Here we got rid of those magic mls attributes and you want to
> add more :)
> 
> I'd much prefer a proper feature instead of special cased attribute
> names, just me though.

I'm not as convinced, so possibly others should chime in too.

Type attributes are intended to indicate "properties" of types.  It just
happens that at present, the names and semantics of those properties are
entirely defined within the policy configuration.  But reserving some
attribute names to have well-defined semantics encoded in the policy
engine itself seems a natural extension, and we did do that in the
original MLS implementation for trusted subjects (and I didn't view that
as necessarily a bad thing).

Introducing a new language primitive each time we want to mark a set of
types for special handling by the policy engine logic seems less clean
to me, even aside from implementation aspects.

It also makes Eric's life a lot simpler ;)  No need to modify
checkpolicy or the policy module logic at all.  A new kernel policy
version would still be required, but we would get a side benefit from it
in addition to permissive domains - preservation of type attribute names
in the kernel policy.

> The last time we got rid of magic attributes with new contraints, maybe
> we need an 'unconstrain' :)

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux