-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Serge E. Hallyn wrote:
>> 0. fix the implementation of cap_setpcap. It is supposed to mean 'this
>> process can raise capabilities, outside its permitted set, in _its own_
>> inheritable set'.
>
> A few clarification questions:
>
> Process p1 is calling capsetp(3) on p2. p2 may or may not equal p1.
>
> Are you saying p1 may raise capabilities in p2 so long as they are in
> p1's inheritable set, or so long as they are in p2's?
The current meaning of CAP_SETPCAP is that a process, p1, can change
the capabilities of another process, p2. This is not the meaning that
was intended for this capability at all. This implementation came about
purely because, without filesystem capabilities, there was no way to use
capabilities without one process bestowing them on another.
Since we now have a filesystem support for capabilities we can fix the
implementation of CAP_SETPCAP.
The most significant thing about this change is that, with it in effect,
no process can set the capabilities of another process.
The only time one can influence the capabilities on another program
(since the pid does not change its not a different process really) is
via the capability convolution rules:
pI(post-exec) = pI(pre-exec)
pP(post-exec) = (X(aka cap_bset) & fP) | (pI(post-exec) & fI)
pE(post-exec) = fE ? pP(post-exec) : 0
at exec() time.
The correct role for CAP_SETPCAP is that it can be used to add extra pI
capabilities to the current process - to be picked up by subsequent
exec()s when combined with the fI capabilities of the exec()d file.
Let's say we have a process, p. It has capability sets, pE, pP and pI.
Generally (currently), p, can change the value of its own pI to pI' where
(pI' & ~pI) & ~pP = 0.
That is, the only new things in pI' that were not present in pI need to
be present in pP.
The role of CAP_SETPCAP is basically to permit changes beyond this:
if (pE & CAP_SETPCAP) {
pI' = anything; /* ie., even (pI' & ~pI) & ~pP != 0 */
}
This capability is useful for things like login, which (say, via
pam_cap) might want to raise certain inheritable capabilities for use by
the children of the logged-in user's shell, but those capabilities are
not useful to the login program itself.
One such use might be to limit who can run ping. You set the
capabilities of the 'ping' program to be "= cap_net_raw+i", and then
only shells that have (pI & CAP_NET_RAW) will be able to run it. Without
CAP_SETPCAP, login(pam_cap) would have to also have (pP & CAP_NET_RAW)
in order to raise this capability and pass it on through the inheritable
set.
I have a working patch that makes this change. Unfortunately, it makes
it impossible to use CAP_SETPCAP in the old (broken) way, and since I
complained that you should make the filesystem capabilities optional
(and contained within the security/ code, I feel I need to rethink it. :*( )
>> 1. [..cap_bset a per-process thing..]
> 2. replace the global secure-bits with a per-process set. The idea here
>> is that different process trees can operate with root as the super-user,
>> or with capabilities, or both. As with 1, this is a better fit for un*x
>> than a (hard to use) global flag.
>
> Good, I like this. How do you intend to authorize setting the
> secure-bit?
Not exactly sure yet. I tend to agree with Casey, that this is less
urgent, so I'm happy to let the idea brew a bit first.
>> 3. Get rid of all the 'emulate root with capabilities' support. I've
>> come to believe that this emulation was basically a mistake born of the
>> fact that there was no file-system capability support.
>>
>> I'm not sure how controversial these changes will be.
>
> Most of them shouldn't affect anyone who doesn't opt to make use of
> them, so I would expect the main challenge to be showing that current
> subtle but expected behaviors are not adversely affected.
>
>> I have started to look at 3, but can look at 1 first if you consider it
>> more urgent.
>
> I don't know what you mean by 'getting rid of emulate root with
> capabilities'. You mean you want to re-introduce the special-casing of
> uid 0 all over the place, alongside capability checks, depending on the
> per-process secure-bits? (I assume that's not what you mean)
Basically, the implementation looks something like:
capable(cap)
{
if (pE & cap) return true;
else if (root-allowed && (relevant_uid == 0)) return true;
else return false;
}
and all of the setuid support loses all of its capability manipulating
side-effects.
My current working preference is: 0, 3, 1, 2. I don't consider any of
them as urgent as getting the inode modification protection fixed.
Cheers
Andrew
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGtPCjmwytjiwfWMwRAmr8AJkBU3+cNTMwjbMaFJu83Swf3uPb7QCfetXA
++jTr/UeGk7ijdVfT5zNnd4=
=9/CY
-----END PGP SIGNATURE-----
-
To unsubscribe from this list: send the line "unsubscribe
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html