Re: [RFC] Capabilities still can't be inherited by normal programs
From: Andy Lutomirski
Date: Sun Dec 02 2012 - 18:04:33 EST
On Sun, Dec 2, 2012 at 2:26 PM, Andrew G. Morgan <morgan@xxxxxxxxxx> wrote:
> On Sun, Dec 2, 2012 at 10:35 AM, Andy Lutomirski <luto@xxxxxxxxxxxxxx> wrote:
>> On Sun, Dec 2, 2012 at 9:21 AM, Andrew G. Morgan <morgan@xxxxxxxxxx> wrote:
>>> There is a fairly well written paper ;-) explaining how things are
>>> supposed to work:
>>>
>>> http://ols.fedoraproject.org/OLS/Reprints-2008/hallyn-reprint.pdf
>>>
>>> The inheritable set is not intended to work the way you seem to want.
>>> Naive inheritance like that is quite explicitly the opposite of what
>>> was designed.
>>
>> I'm aware that the system was designed, or perhaps evolved, to prevent
>> users with uid != 0 from inheriting capabilities unless vfs
>> inheritable caps are granted on a per-file basis. I want a way around
>> that -- I want to mix non-root, capabilities, and exec. This is damn
>> near impossible right now if I don't have CAP_SETFCAP or root's
>> explicit, per-program cooperation. CAP_SETFCAP is essentially
>> equivalent to "let me do anything".
>>
>> As it stands, using something like pam_cap to grant a user cap_net_raw
>> is useless -- that user can't use the privilege because (unless uid ==
>> 0) the privilege will never end up in the permitted set.
>
> Have you tried adding fI of cap_net_raw to the file to be executed?
Yes, and it works. I don't like this solution because:
a) It doesn't scale in terms of sysadmin resources required.
b) It adds no real security over real inheritable capabilities. I'd
be rather surprised if tcpdump does not have any bugs that would allow
me to subvert it to recover its inherited capabilities. For example,
it drops privileges like this:
if (setgid(getgid()) != 0 || setuid(getuid()) != 0 )
fprintf(stderr, "Warning: setgid/setuid failed !\n");
This is buggy for at least two reasons: it doesn't abort on error and
setuid doesn't actually drop capabilities when uid 0 isn't involved.
c) tcpdump isn't really special. I trust this user account with
cap_net_raw, and that should be all the configuration I need.
d) If I really wanted, I could emulate execve without actually doing
execve, and capabilities would be inherited.
The issue with allowing real capability inheritance is that,
currently, it's safe for a program with fP != 0 to add an inheritable
capability and then execve something caller-controlled. I don't know
whether anything actually does this, but it's hard to prove that
nothing does. Hence my idea of requiring no_new_privs to make
capabilities inheritable.
An alternative, and considerably more intrusive, change would be to
add a fourth mask of genuinely inheritable capabilities.
--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/