Re: Frustrated with capabilities..

Previous thread: r8169 regression in 2.6.26.3 vs 2.6.26.2 by Pascal Terjan on Wednesday, August 27, 2008 - 2:20 am. (6 messages)

Next thread: [PATCH 0/4] Blackfin supports for ALSA/ASOC by Bryan Wu on Wednesday, August 27, 2008 - 2:39 am. (25 messages)
From: Markku Savela
Date: Wednesday, August 27, 2008 - 2:31 am

I just want to run an exectable with limited capabilities and assumed
the following approach would work fine:

 1) fork process
 2) in child

    2.1 set current capabilities (eip) using cap_set_proc
    2.2 execve the executable.

But it frigging does not work! Just before the execve, the result of
cap_to_text is

    = cap_net_bind_service+eip

but, in the execve executable, the result is suddenly

    = cap_net_bind_service+i

Why does the execve clear the effective and permitted capabities,
against my clear instructions? (I also have the prctl KEEP_CAPS set,
though in this case it should be irrelevant).

- The kernel is from ubuntu distro, 2.6.24.

- the executable *does* *not* have any setuid/setgid bits

- the upcoming file capabities will not be any help, because I will
  need to start the same executable with different capabilities
  depending on context.

If this is not a bug in kernel, it is a misdesign, which makes the
obvious use of cap_set_proc rather useless...

-- 
Markku Savela
--

From: Pavel Machek
Date: Thursday, August 28, 2008 - 7:18 am

Yes, you need upcoming filesystem capabilities.  Binary may not
inherit capabilities unless filesystem flags permit that.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
--

From: Markku Savela
Date: Thursday, August 28, 2008 - 7:45 am

I think this is wrong. Normal executables inherit uid/gid and
supplementary groups by default. Why should capabilities be any
different?

IMHO, even with file system capabilities, the default should be
inherit, if nothing else is specified.


--

From: Theodore Tso
Date: Thursday, August 28, 2008 - 10:48 am

Well, because that's not the what the POSIX draft specification (and
the rest of the Unix industry who were striving to meet the US
Department of Defense's "B2 by '92" initiative) ended up implementing.

The reason for that was to avoid bugs where a program that wasn't
expecting to be setuid (or just written by a stupid progammer) exec's
some program which wasn't expecting to have root privileges then bad
things happen.  The classic example of this was running the mail
program, which was setuid or setgid to the mail user/group, and then
typing "!/bin/sh" which would exec a shell running with those
privileges (because the mail program didn't know to drop its
privileges).

So in the capabilities model, the capabilities do *not* inherit unless
the a particular file explicitly states that it should inherit the
capabilities.  It's the principle of least privilege taken to its
logical conclusion.

						- Ted
--

From: David P. Quigley
Date: Thursday, August 28, 2008 - 2:03 pm

Minor nit. It was actually C2(Controlled Access Protection) by '92 which
is mainly just DAC protections as opposed to B2(Structured Protection)
which also included MAC policies and Sensitivity labels in addition to
DAC protections.

Dave

--

From: Casey Schaufler
Date: Thursday, August 28, 2008 - 9:47 pm

But the fun part was that the evaluation requirements for B1,
which fell in between C2 and B2 (the order from least secure to
most was D, C1, C2, B1, B2, B3, A1, and "Beyond A1") where so
close to those for C2 that everyone implemented B1, which did
include MAC policy in the form of Bell and LaPadula sensitivity.
The privilege model (now called capabilities, and you have to buy
me a beer to get the whole story) does not actually come in the
requirements until B3, although some people will argue that it
was intended they be included at B2. Even though no one even tried
a B3 and no one succeeded at B2 everyone did capabilities based
on one of the drafts or another.

Anyone who thinks that the capability scheme is wrong headed is
encouraged to read the P1003.1e/2c (withdrawn) DRAFT. It's on
the web in several places. You may end up still thinking it's
wrong, but at least you will have seen how the arguments got
hashed out.

And we're still not talking about the Jackson Hole meeting.


--

From: David P. Quigley
Date: Friday, August 29, 2008 - 7:20 am

And one wonders why these certs aren't in use anymore ;)

Dave

--

From: Markku Savela
Date: Friday, August 29, 2008 - 3:18 am

Considering the current case, without the file capabilites, I note

- if the caller of /bin/sh is ROOT, the capabities are inherited. Thus
  my request has no relevance in that case.

- if the caller does first setuid to non-root, the capabilities are
  cleared, unless KEEP_CAPS is explicitly set. Thus, my requested
  change would not cause problems with your buggy mail program.

- if the caller goes through all the trouble of setting KEEP_CAPS and
  changing to non-root, I would expect it to be sensible that the
  caller also intends the execve code to inherit capabilities.

As an experiment and example, I made a small patch to Ubuntu 2.6.24
kernel, to make it work like I think it should: if KEEP_CAPS is set,
they are inherited (see at end).

I'm ok with the current kernel code, which seems to clear the
KEEP_CAPS on execve. Thus, each executable must again re-enable it, if

I'm looking at network oriented devices, where executables or
interpreted content from network sources is executed by helper
applications or directly as executables. Depending on the source of
the "code", the helper application or the downloaded exectuable may be
allowed to run with different permissions (capabilities, uid/gid
etc). [For example, look at android security model with manifests of
requested and declared permissions, but applied to everything
downloaded or installed].

File capabilities (nor selinux) won't work, because the "helper
applications" need to be executed with different capabilities and
permissions, depending on the "manifests" of the downloaded
"code". Obviously, serious permissions are granted only to properly
verified "code" (signed).

  [Any ideas how selinux would help to enforce a permission which is
  dynamically defined by installing application?]

I'm using "code" in quotes, because in my mind, it can include HTML,
word documents, spreadsheets, images. Data formats are getting so
complex, that they start to look more like interpreted code, than
plain passive ...
From: James Morris
Date: Friday, August 29, 2008 - 3:47 am

You could implement a specialized userpsace application launcher, which 
parses the manifest, determines a security context for the application, 
performs any requiste object labeling, then launches the application it in 
that context.  The kernel policy could enforce which particular contexts 
the launcher was authorized to use, and which applications could be 

There is a project underway to extend SELinux (and MAC labeling in 
general) over NFS: http://selinuxproject.org/page/Labeled_NFS


- James
-- 
James Morris
<jmorris@namei.org>
--

From: Theodore Tso
Date: Friday, August 29, 2008 - 7:07 am

In the full capabilities model (which we can't have until file
capabilities get added), having a user id of 0 has no meaning.  The
whole concept of "root" goes away.  Like SELinux, turning it on
without making sure programs are ready for it will break a lot of

What you are suggesting is not insane.  But then again, the setuid
root (and allow a process to inherit all privileges) model wasn't
insane either.  The full capabilities model, however, is striving to
far more stringent than either the traditional root-oriented model or
your concept of allowing the program to decide (on its own) whether it
a downstream exec should inherit its privileges.  And what it is
trying to do is this:

It is very reasonable to suggest that a system administrator, or a
site security officer, be able to audit a system and know what
programs can run with any kind of elevated privileges (and I still
prefer the term "privileges" to "capabilities"; one of these days I
will need to buy Casey a beer).  But if you allow unbridled
inheritance, you Just Don't Know who could run as root.  If you make
it based on whether KEEP_CAPS is set, it still becomes impossible for
a system administrator to audit all of the binaries on the system ---
for the simple reason that the system administrator may not have
access to the sources, and even if she did, how would she know whether
the sources precisely matched up to the binaries, in every single
case?  And even if she did know how would she know what program or
programs a particular privileged program could exec?  It's just not
possible.

The solution in the capabilities model is that each executable has a
capability bitmask which indicates which privileges it is allowed to
inherit --- and the default is no privileges whatsoever.  This means
that just as today, a system administrator or site security officer
can scan for setuid root programs, in the capabilities world, it is
possible to determine exactly which binaries could ever run with
elevated privileges, ...
From: Serge E. Hallyn
Date: Friday, August 29, 2008 - 10:11 am

You're misinterpreting the empirical evidence.

If the caller is root, then capabilities are not "inherited."  Rather,
if you are running in !issecure(SECURE_NOROOT) (which everyone is right
now), then we fake an all-powerful root by filling the file capability
sets at exec.  So it's not that the task's capabliities are inherited.
Rather, it's that as the capabilities are recalculated, we pretend that
the file had full capability sets.

That's very different, but leads to the same results in your example

Both capabilities and selinux will allow:

	1. the same binaries to be executed with different
	   privileges/permissions depending on the context of
	   the caller.

	2. different binaries to be executed by the same caller
	   resulting in different privileges/permissions.


-serge
--

From: Serge E. Hallyn
Date: Friday, August 29, 2008 - 9:58 am

They will help.  The context is pI.  When a file is executed, the task's
new permitted set is calculated as:

	pP' = (fI&pI) | (fP & X)

So you can give /bin/foo the file capabilities:
	fI=cap1,cap2,cap3
Then task 1 runs with pI=cap1, so when it executes /bin/foo it will get
	pP' = cap1
Task 2 runs with pI=cap2,cap3,cap4 so when it executes /bin/foo it will
get
--

Previous thread: r8169 regression in 2.6.26.3 vs 2.6.26.2 by Pascal Terjan on Wednesday, August 27, 2008 - 2:20 am. (6 messages)

Next thread: [PATCH 0/4] Blackfin supports for ALSA/ASOC by Bryan Wu on Wednesday, August 27, 2008 - 2:39 am. (25 messages)