CAP_SETPCAP is needed to implement file system support in user
space. There are other ways this could be done, but CAP_SETPCAP is
easy and straight forward.
IMO, CAP_SETPCAP isn't a security hole. It is more powerful than
CAP_SETFCAP, but only somewhat. CAP_SETFCAP is also something you
don't want to give to everybody. We don't currently _have_ CAP_SETFCAP
since we don't have file system support, so we use CAP_SETPCAP
instead. CAP_SETPCAP is what makes it possible to implement
CAP_SETFCAP in user space. POSIX doesn't deal with this issue.
Capabilities should be able to do what we previously used securelevel
for, so a system call which sets capabilities on all processes to
emulate the effect of a securelevel change can be designed. I imagine
something like the following system call interface:
setcap(int version, int pid, cap *inh, cap *perm, cap *eff);
where version gives both the size of the capabilities and possible
mappings needed. User space should do the necessary mapping, but it is
important to be able to catch old programs. pid 0 means current
process, -1 means all processes except current, and >0 means specific
process.
> > As such, we should _allow_ the capability to raise other capabilities. If
> > you don't like that capability, you can just make sure that it is cleared
> > at boot for everybody, and then nobody can inherit it and nobody can ever
> > get it any other way either (as nobody has the capability to raise the
> > capability).
>
> By definition, your opinion is the one that counts.
>
> I guess if I have to concede on this can I suggest that, at the very
> least, this should be a global is_secure(ALLOW_SETPCAP) condition?
> Otherwise, the "nobody can inherit it" part is only good as long as
> there is no executable sitting on a trusted filesystem that has this
> Permitted (Forced) bit raised. (Some protection against the equivalent
> of the current "setuid-root shell" that people like to have lying
> around... :^)
Why do we have to protect ourselves against the file system? I want to
protect my system against a non-trusted filesystem, but not a
_trusted_ filesystem with capabilities support.
How do you get this "setuid-root shell" with the CAP_SETPCAP bit
raised? On a capability-fs system you have to have the CAP_SETFCAP
capability to do this. CAP_SETFCAP is ultimate power and available to
the few selected ones so it shouldn't be trivial. This is an essential
difference between the "suid" system and the capability system. Anyone
can make a binary suid themselves, but you need the CAP_SETFCAP
capability to set forced capabilities. I guess one could say that on a
capability system you protect the file system from the user so you
don't have to do the reverse :-). When you can't protect the file
system from the user (normal file systems) you have to protect the
system from the file system by reading all capabilities as { 0 }.
If we do want to protect ourselves against the file system, I suggest
a global "securelevel" kind of capability set which all
read-file-capability operations are filtered through.
I aggree that having CAP_SETPCAP available to all uid=0 processes _by
default_ is a bad thing. This can be fixed by removing the CAP_SETPCAP
bit from the inheritable (and possibly effective) set of init_task. A
capability-aware init could then raise the bit when needed. This also
applies to the CAP_SETFCAP capability when implemented.
astor
-- Alexander Kjeldaas, Guardian Networks AS, Trondheim, Norway http://www.guardian.no/- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu