[lxc-devel] Building without libcap2?

Michael Tokarev mjt at tls.msk.ru
Sat Dec 18 11:23:36 UTC 2010


18.12.2010 03:07, Rob Landley wrote:
>> It's easy to blame something if you don't understand what
>> you're blaming.
> 
> Yes, that's why I'm asking.  To understand.

This wasn't obvious at all.  Maybe it's just me but.. n/m.

>> Capabilities (libcap2) is a tiny library (on my i386
>> userspace it's just a 13Kb shared object), it has _no_
>> external dependencies whatsoever - neither at build nor
>> at run time (it does not use perl for one), 
> 
> make[1]: Entering directory `/home/libcap-2.19/libcap'
> => making cap_names.list.h from /home/libcap-2.19/libcap/../libcap/include/linux/capability.h
> perl -e ...
> make: *** [all] Error 2
> 
> Care to guess again?

Yes, I already commented on this in another email.
It was wrong statement on my side, please excuse
me for this.  During _build_ time, libcap tries to
construct a list of capability names as defined in
current kernel headers, and this is done using
perl, a trivial in-line perl script (two of them).

It looks your build environment does not have perl
for some reason - and having in mind you're talking
about some embedded/small system, I can guess you're
trying to build something on that system directly.
Usually in such cases the build environment is set
up on a more powerful machine using a cross-compiler,
so that you can enjoy fast compilation speeds and
all the tools awailable.

>> and it is _required_ for lxc internally.
> 
> Currently, yes.  But the way configure ends with this even afer you install
> debian's libcap2:
> 
>   Warning:
>   --------
> 
>   The setcap binary was not found. This means the tools to set the
>   privilege for the lxc commands are not available, that's ok, but you
>   will need to run these commands as root or install libcap-2.

In debian the tools (setpcap in particular) are in
lipcap2-bin package.

Again, this is not a requiriment for _you_ to use
capabilities in any way.  The install system of
lxc tries to set up permissions for the lxc tools
so that it is possible to run them as non-root user.
I'm not sure this actually works, but the idea was
like that, to be able to use lxc as non-root.

You can argue that a setuid binary should work better
in this context.  Probably, but setuid concept is
flawed since the beginning - way too many holes were
created already.  The principle is like this -- only
give a process the _really_ _necessary_ privileges
and nothing more.  For example, you don't need to
run apache as root _just_ for it to be able to bind
to port 80 (privileged port).  But this is a bit
beyond the topic, I don't want to go into general
"what capabilities are good for" discussion just
yet, esp. here in lxc-devel at .

> And the existence of HAVE_SYS_CAPABILITY_H in Config.h.in
> implied to me that maybe it wasn't intentional, which is why I asked.

Many things in lxc package are leftovers or
something that hasn't been completed.  It
needs quite a lot of polishing.  For this
particular feature, I'd say libcap is
essential, at least until the kernel does
not have special meaning for syscalls like
sys_reboot() when called from within a
container.

>> No one forces _you_ to use capabilities.
> 
> Unless I want to use containers, you mean?

No.  You referred to complexity of something
and said that a complex feature is less likely
to be used due to difficulties understanding it
and difficulties writing right configurations.
You're not _required_ to write any configuration
here or set up capability system for anything on
your machine.  Lxc uses capabilities internally,
it does not ask _you_ to maintain or worry about
capability sets.  It only asks you to provide the
library to access the mechanism (which is built-in
to the kernel).

>>  It's a very
>> simple construct unlike can be told from your description
>> (you understanding is wrong, but this is not the point),
> 
> I agree it's not the point.  I'd like to understand how I'm wrong, though.

The complexity - you told it's complex.  It's not, at least
not in my understanding.  Maybe it's just me again, dunno.
I once tried to understand selinux - and gave up pretty fast
(but I had no time available to that either).

> The suid bit is pretty darn simple too.  Securing a system with suid
> executables isn't.  Adding capabilities so that binaries try to drop
> priviledges via setuid() and don't notice they can't (or any of the other
> fun failures that can never happen until you retroactively change the
> security model out from under the programmer in non-posix ways) is
> one of those little perennial bits of fun that keeps on giving.

Um.  I don't understand really what you're saying.  Yes, securing system
with setuid executables isn't simple, and we've too rich proof of that
already, in all these years with all these holes.  But it's not "adding
capabilities" to "unsuspected binaries", or not even "adding capabilities"
per se, -- inside the kernel capabilties _replace_ the root/non-root
separation entirely, and suid-root is keept to mean "all possible capabilities"
for compatibility.

> There's a theory among security types that a secure system is one that's
> fully understood, and an insecure system is one that isn't.  Thus "put all your
> eggs in one basket and WATCH THAT BASKET" is sometimes a preferable
> approach to painting over dry rot to create a multi-layered system no human
> can quite understand the full ramifications of, in hopes the additional layers will
> contain the underlying misunderstandings.  I've never quite understood why
> if we can't get one security context right (where you're either on fire or not on
> fire, and you realize you're PLAYING WITH FIRE and do not let fire spread),
> creating 2^32 different combinations is supposed to improve matters.

It's not about 2^32 combinations (actually much more than 32, the capability
set were increased, or _meant_ to be increased beyond 32 bits).  It's about
the only privileges (in addition to regular user rights) which are actually
needed for a given executable or user.  _Any_ additional privilege is "playing
with fire", be it full-blown setuid-root or a simple CAP_NET_RAW for example.
But it does not give you 2^32 combinations to watch, it's just not useful to
watch all possible combinations.  It's not addition layers either, it's a
system which is used _instead_ of full-blown suid-root _already_ inside the
kernel.  Suid-root just turns on them all, nothing more.

> Is my reasoning defective because I don't agree with you?  There is one true
> opinion on this topic?

We're, again, resorted to arguing about whenever capability system is good
or not.  This is not a discussion for this list to start with.  The real
life is that lxc currently _requires_ ability to manipulate capability
sets for the containers it creates, or else there's no way to protect
host system from container actions, at least for certain operations already
mentioned.

>> but it is used by lxc tools internally.  For example,
>> you don't want a container to be able to shut down your
>> host machine by executing sys_reboot syscall - this is
>> ensured by dropping CAP_SYS_BOOT when entering container.
> 
> Right, so the UID namespace thing where PID 1 isn't necessarily
> using the host's UID 0 is useless then?  My mistake.

UID namespaces has nothing to do with things such sys_reboot().
These are entirely different.

>> Note that every permission check in linux kernel is built
>> based on capabilities, so at least every linux kernel
>> programmer thinks capabilities are a good thing...
> 
> If you think every linux kernel programmer agrees on the color of the
> sky I'm not sure we're talking abou the same group of people.
> 
> Does the fact the kernel uses RCU and spinlocks internally mean
> userspace apps must use them, even if they want to be single-threaded?
> I'm not following the logic here.

Ugh.  You said capability system is somehow bad or flawed.
Kernel is built around it.  This is a fact.  That's what
I tried to say, nothing more.  And I mentioned numerous times,
you're not forced to _use_ capabilities yourself.

Consider lxc is a userspace component of a very specific kernel
subsystem, which _has_ to understand and use kernel-side view
of things.  And capabilities is just one such thing.

You're arguing about a tiny piece of code used internally by
lxc tools.  Is it maybe better for lxc to reimplement that
piece of code instead of reusing already existing library?

>> I can only guess you're confusing capability system with
>> something else which _is_ actually complex, but I can't
>> guess what it is.
> 
> Translation: "We've hard-wired in the assumption you're using capabilities
> from userspace into the design of lxc, and some of us might be a bit
> defensive about it."

No comment.

/mjt




More information about the lxc-devel mailing list