validity test in cap_set_proc(), POSIX.1e 25.4.15.2

Robert Watson rwatson at FreeBSD.org
Wed Dec 5 18:01:26 GMT 2001


On Wed, 5 Dec 2001, Casey Schaufler wrote:

> Robert Watson wrote:
> > 
> > POSIX.1e D17 25.4.15.2 reads:
> > 
> >   The function cap_set_proc() shall set the values for all capability
> >   flags for all capabilities defined in the implementation with the
> >   capability state identified by cap_p.  The new capability state of the
> >   process shall be completely determined by the contents of cap_p upon
> >   successful return from this function.  If any flag in cap_p is set for
> >   any capability not currently permitted for the calling process, the
> >   function shall fail, and the capability state of the process shall
> >   remain unchanged.
> > 
> > In our currently implementation, we impose an additional check on cap_p
> > provided to cap_set_proc(): we require that the resulting capability set
> > be "valid" in the sense that the new effective capabilities be a subset of
> > the new permitted capabilities.  Does anyone else take this reading, and
> > if not, is there a good reason not to?
> 
> You may wish to have a case where you need an effective capability to do
> an exec(), perhaps CAP_DAC_OVERRIDE, but explicitly don't want it in the
> permitted set of the resulting program. In this case you would raise
> CAP_DAC_OVERRIDE to effective, and clear it from permitted. You can't
> clear the permitted set while leaving any effective in your scheme. 
> 
> I haven't spent the time required to follow through the capability
> recalculation calculus to verify this as an important case, but it could
> be. 

Hmm.  How is this not addressed through use of the inheritable set?
Imagine for a moment we try to reproduce the scenario you have in mind
(only using CAP_DAC_EXECUTE, since that's the spec version):

Process starts out with:

pI: CAP_DAC_EXECUTE
pP: CAP_DAC_EXECUTE
pE: CAP_DAC_EXECUTE

If it just exec'd the binary, which likely has fI of CAP_ALL if it's a
base system binary, you get: 

pI': CAP_DAC_EXECUTE
pP': CAP_DAC_EXECUTE
pE': CAP_DAC_EXECUTE

However, if it removes inheritable, making it:

pP: CAP_DAC_EXECUTE
pE: CAP_DAC_EXECUTE

It then excutes the binary, which has fI of CAP_ALL, resulting in:

pI': CAP_NONE
pP': CAP_NONE
pE': CAP_NONE

This seems to be the desirable outcome based on rules:

 *   pI` = pI
 *   pP` = (fP & X) | (fI & pI)
 *   pE` = (fE & pP`)

Robert N M Watson             FreeBSD Core Team, TrustedBSD Project
robert at fledge.watson.org      NAI Labs, Safeport Network Services



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