Capabilities/privileges and bounding sets
Andrew Morgan
morgan at transmeta.com
Mon Aug 28 16:53:34 GMT 2000
Robert Watson wrote:
>
> On Sun, 27 Aug 2000, Andrew Morgan wrote:
>
> > Robert Watson wrote:
> > > Addition of new flag: CAP_BOUND
> > >
> > > Inheritence rules:
> > > pI' = pI & ~(pB')
> > > pP' = (fP` | (fI & pI)) & ~(pB')
> pE' = (fE & pP) & ~(pB')
> > > pB' = pB | fB
> >
> > Your rules do not appear to be based on those of DS17. DS17 has:
> >
> > pI' = pI
> > pP' = (fP & X) | (fI & pI)
> > pE' = (fE & pP)
>
And I typoed too:
pE' = (fE & pP')
(namely, added a ' to pP).
> > X = fB & (~pB)
> >
> > fB is a per-filesystem-mount bound, ~pB is a per process bound: pB' =
> > pB. [I'm trying to use your notation for pB - namely the '~' of the
> > mask. Although elsewhere I'm likely to use another notation.]
> >
> > The decision about whether to leak (pI & pB) bits through process
> > execution is entirely up to the program that restricts ~pB and then does
> > an exec(). Namely, one would expect such a program to force (pI & pB) =
> > 0, but if there is a reason this isn't appropriate in individual cases,
> > then said program wouldn't be required to do it.
[..excellent jailing description..]
> Hence the desire to place a strict bound on pP', rather than have it only
> affect those capabilities gained through fP -- the bit set on the file
> system should not result in the bit being set in the process. However,
Well, logically the above supports this limit too. Where you have (~pB)
as the single bound. What I described can implement that as well, but
(~pB | pI) becomes the effective bound. So, for a jail to fully bound
the capabilities of an exec()d child, you have to modify two capability
sets as opposed to your one.
> > The fI value seems to need a mask associated with it too. I'd probably
> > prefer to map fI on the disc to (fI & fB) in system. [This is arguably
> > the only extension beyond DS17.]
>
> I think this is to some extent what I describe above, but if not, I'm not
> sure I follow. Could you go into a bit more detail or provide more
> context?
Yes. But note, this fB set is a per mountpoint thing and not a per file
thing. I got the impression that your fB was a per file thing. All I was
saying here was that if the mountpoint has been denied CAP_SETUID, then
it should not be possible for it to leak such a capability in conjuction
with (fI&pI). I believe we agree on this issue.
> > For Linux, I'm pursuing this restriction on pP':
> >
> > (pP' & fP) == fP
> >
> > Namely, I interpret fP to be the minimum capabities that the program
> > requires to function correctly, so if any of those capabilities are not
> > available, then the file cannot be executed.
> Sounds good, although this allows a binary to have unhappy capabilities
> set on it, but only to discover that at execution time. However, it has
How so? The file is expecting fP to be forced. If it doesn't get that,
then is it really safe to execute the program? The fI bits are optional
(and available only when pI is set appropriately) so the application
isn't expecting to always get them.
> > Linux will probably be closer to SGI here, namely CAP_SETPCAP will
> > remove the pP bound on raising new capabilities in pI. [We've had some
> > debate about whether to make CAP_SETPCAP wholely equivalent to eip=~0
> > (which I understand would make us completely compatible with SGI), but
> > especially for chroot jail type things this looks insufficiently
> > restrictive.]
>
> Hmm. My only concern here would be: my reading of POSIX.1e didn't
> distinguish CAP_SETPCAP from any other capability in terms of properties,
> so I assumed that revoking CAP_SETPCAP would not impact the presence of
> other capabilities. If CAP_SETPCAP = ~0, wouldn't revoking CAP_SETPCAP
> result in revoking all capabilities? Perhaps I'm reading this wrong.
Sorry, I was very sloppy with that paragraph. What I meant (by eip=~0)
was this: we've debated making pP=CAP_SETPCAP mean the current process
is able to raise/lower any capability in its p{EIP} sets. I personally
think, since this interpretation is equivalent to pP=~0, that such a
single capability seems redundant. I'm arguing instead for
pP=CAP_SETPCAP to mean that the process can raise anything in pI only
(independent of the value of pP). In writing this again, I see that
there does still needs to be a (~pB) bound on new additions to pI even
with CAP_SETPCAP available. (This is required for the strict monotonic
inheritance of bounded capabilities in the scheme I'm describing.)
> > > Open question: when an application calls cap_set_proc() with a
> > > capability set with B set all zeros, and E,I, and P don't violate the pB
> > > of the process, should it EPERM, or succeed, but not set the bound?
> >
> > I'm not sure what this means.
>
> Suppose the application calls cap_new(), and copies over the EIP fields
> from its old capability set, subject to certain limitations (or more
> likely, it creates the capability set precisely as it thinks it needs),
> [...]
Thanks, I think I see now. Could I phrase it this way: are these
bounding sets part of a 'posix' quartet (ne triplet) cap_t, or not? If
they are, then when you create capabability sets, you need to understand
the implications of setting or not setting the B member...?
I personally view these pB and fB objects (part of 'X') as
system-specific bounds. Something that would be manipulated by non-posix
applications (a jail gakekeeper for example). Consequently, they will be
manipulated with a different API from the preserved 'posix' triplet.
That is, the cap_t object will not contain a reference to said bounds.
We've not settled on said API, but I believe we'll end up leveraging a
number of the functions in the 'posix' API to raise and lower bits in
these sets, but not use cap_t to store them.
This approach means that from an application programmer's perspective we
look just like the DS17 implementation, but the system as a whole will
support jail like environments.
> > We'll probably extend the 'posix' API to read and write the two flavors
> > of bound. That is, make them visible. How has not been decided.
>
> Sorry -- two flavors? I saw fB from the file, and potentionally an fB
> from the file system. What was the other flavor of bound you had in mind?
By two flavors of bound I am referring to fB (filesystem specific,
perhaps fB should also be per root-directory specific?) and pB (process
specific) bounds.
> The most consistent way would seem to be to introduce a CAP_BOUND as an
> addition to CAP_EFFECTIVE, et al. I hadn't originally planned to allow a
> CAP_BOUND entry on a binary, but that probably would make a good way to
> handle the jail entry point.
Not quite sure I follow this.
One thing I have toyed with is the idea of making fB 'directory
specific', but the performance characteristics and its complexity has
not quite sunk in yet. (Should you apply such masks recursively as you
go down through the directory tree...? I actually can't decide if this
sort of thing would be useful.)
Cheers
Andrew
To Unsubscribe: send mail to majordomo at cyrus.watson.org
with "unsubscribe posix1e" in the body of the message
More information about the posix1e
mailing list