My thinking on this implementation has been very fluid over the last
several days; many have stimulated new thoughts for me, others have just
made excellent suggestions. So thanks to all of you.
Before I lay this out, let me say now that 'works over nfs' is _not_ a
design issue for me; and not everybody agrees with this. I hope, however,
that you will still read this and give it some consideration. It's really
pretty short. Also, please read it through completely, as you will no
doubt have issues as you read, but I may solve them later on.
I think Ted's idea of using a new extended attribute bit to mark a file as
capability-enabled is the best idea yet. The sticky bit idea was a bit
broken, requiring the kernel to honor a once-useless (and non-priviledged)
bit as now essentially all-powerful. To fix this, we tied in the
immutable bit, but of course that means it can't be used for it's intended
purpose. So now, for the kernel to honor capabilities encoded into the
file being exec'ed, this 'cap-enable' flag must be set. Setting and
unsetting this flag requires CAP_SETFCAP raised in the current process.
This still raised problems with compatibility with current tools; this for
me _is_ a design issue, as I don't want to do the enormous work to patch
all the necessary tools. My thinking here is to have a settable kernel
option (somewhere in /proc) for 'tool compatibility'. Setting this would
cause the kernel to map the 'cap-enable' flag to the sticky bit (no, the
sticky bit didn't completely die, but now it's completely harmless). That
way, when you tar an archive, it would see the sticky bit as set, thus
preserving the fact that the file contains capability encoding. Then, for
unpacking, setting the sticky bit would again map to the cap-enable flag,
and still require CAP_SETFCAP, without that cap, the bit just wouldn't be
set. Note that while 'tool compatibilty' is set, the kernel ignores the
actual value of the sticky bit (for files only; the sticky bit on
directories should act as it always has); you also want this compatibility
flag unset _most_ of the time, except, for instance, when installing new
packages on the system which need the ability to set the cap flag. It may
be possible to eventually remove this feature. I hope, too, that this
solves people's issues with 'smuggling' cap-enabled binaries into the fs.
(i.e., admin unpacks what he thinks is a harmless source archive).
Finally, I also suggest a small change in the capability semantics.
Currently, files have a capability set fE, which are the effective bits
which immediately get raised for the file. Andrej Presern noted, and I
agree, that this does nothing to enhance security, since an exploit can
trivially raise all effective bits; they might as well be raised on
execution for all current tools. Note that for capability-aware
applications, the process effective set pE can still be useful to insure
an operation doesn't have side effects; so I'm leaving the behavior of pE
alone.
I'm suggesting that fE be redefined as fM, an 'inheritable Mask', which
will drop inheritable bits in the process being exec'ed. The effect of
this is to cause certain (or all) inheritance to 'dead-end' during this
exec. When considering design of a secure distribution, I thought this
would be a useful feature.
Ok, that's it. Thoughts?
- --
David L. Parsley
Network Specialist
City of Salem Schools
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/