linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* posix capabilities inheritance
@ 2003-10-21 11:26 Michael Glasgow
  2003-10-23 16:46 ` Theodore Ts'o
  0 siblings, 1 reply; 19+ messages in thread
From: Michael Glasgow @ 2003-10-21 11:26 UTC (permalink / raw)
  To: linux-kernel

I wrote a simple setuid-root wrapper which sets some capabilities, 
gives up all other privs, and and then execs a shell.  I was hoping
to use this wrapper as a login shell so that I could have a user  
log in interactively with a small subset of elevated privileges.

Unfortunately after looking over the capabilities code in the 2.4
kernel, it would appear that this is not currently possible, and
my wrapper cannot work without filesystem support for capabilities.
And even then, I'd have to set each file's inheritable flag for the
capabilities I want on every executable that I am likely to run,
including the shell.  Am I mising something, or is this an accurate
description?

I think I understand the rationale behind this behavior; the draft
posix 1003.1e specification states:

     The purpose of assigning capability states to files is
     to provide the exec() function with information regarding
     the capabilities that any process image created with the
     program in the file is capable of dealing with and have
     been granted by some authority to use.

So, the lack of an inheritable flag on a file can serve to prevent
that file from executing with the corresponding capability enabled.

Fine, but what about my semi-superuser shell situation?  How can
I force the retention of a capability set across exec() for all
executables?  It would seem that neither the spec nor the current
implementation in the 2.4 kernel allow for this, but it strikes
me as a pretty reasonable and useful thing to do in some cases.

As an interim workaround, how about assuming all capabilities are
inheritable in fs/exec.c:prepare_binprm, i.e. instead of
cap_clear(bprm->cap_inheritable), call cap_set_full() ???  I don't
think this would break anything, and it would make capabilities a
lot more useful until we get fs support merged in.

-- 
Michael Glasgow < glasgow at beer dot net >

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
       [not found] <fa.hehull9.10mmngt@ifi.uio.no>
@ 2003-10-21 18:24 ` Andy Lutomirski
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Lutomirski @ 2003-10-21 18:24 UTC (permalink / raw)
  To: Michael Glasgow, linux-kernel

I agree with these problems, but I think the proper fix is complicated.  AFAICT, 
POSIX capability evolution, as specified by whatever draft it was, is broken, so 
the hacks in prepare_binprm (cap_bprm_set_security in 2.6) are needed to avoid 
security problems.  Aside from the fact that non-inheritable-by-default makes 
little sense (and requires root to get capabilities re-added from the file 
_permitted_ set), POSIX cap evolution has some other problems:

1. Can a process have capabilities in its inheritable set and not in its 
permitted set?  POSIX allows such processes to be created (pI = pP = full, then 
execute (fI = 0, fP = 0).  Nevertheless, its pP evolution rule assumes that this 
never happens (pI capabilities can reappear).

2. If a process has pE < pP (i.e. some caps disabled, e.g. uid=0, euid!=0), and 
exec's fE=full, then its capabilities get re-enabled.  This seems like a pretty 
serious breakage of userspace.

I have a possible fix to these issues at 
<http://www.stanford.edu/~luto/linux-fscap/> -- CONFIG_FS_CAPS (in 
cap-1-fscap.patch) changes the capability evolution rules slightly to make them 
(IMHO) both safe and sensible, as well as removing the ugly hackage in 
set_security.  This will allow your capabilities to persist through exec().  The 
second patch (cap-2-ext3.patch) adds file capabilities to ext3.  Both are tested 
on 2.6.0-test6, and they apply with fuzz and compile (but not tested yet) on 
-test8.  (These are different from my last attempt at this -- they are much 
closer to POSIX semantics.)

Unfortunately, I think it's too late to include these in 2.6.0.

Andy


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
       [not found] <fa.f36f4t9.1rg8j3v@ifi.uio.no>
@ 2003-10-22  7:11 ` Michael Glasgow
  2003-10-22 19:40   ` Andy Lutomirski
  0 siblings, 1 reply; 19+ messages in thread
From: Michael Glasgow @ 2003-10-22  7:11 UTC (permalink / raw)
  To: Andy Lutomirski, linux-kernel

Andy Lutomirski wrote:
> 1. Can a process have capabilities in its inheritable set and not
> in its permitted set?  POSIX allows such processes to be created
> (pI = pP = full, then execute (fI = 0, fP = 0).

Sure, this is apparent to me in reading the spec.  I'm not exactly
sure if this is relavent though:  if pP = pE = 0, it does not seem
like it should be possible for pI=full to have any effect on exec,
unless I am missing something.

> Nevertheless, its pP evolution rule assumes that this never happens
> (pI capabilities can reappear).

Certainly with the current rule as implemented in 2.4, it looks as
though you can regain permitted flags: pP' = (fP & X) | (fI & pI)

Is this what you mean when you say they can reappear?  WRT the
spec itself, I don't see this assumption.  The rule could just as
easily be:  pP' = (fP & X) | (pP & fI & pI)  (just an example)
The rule in your patch seems like it should be compliant as well.

I'm not saying there aren't some problems to be worked out with
the spec; I think there are.  But I don't think this is a case of
the spec being broken per se -- just too vague.

> 2. If a process has pE < pP (i.e. some caps disabled, e.g. uid=0,
> euid!=0), and exec's fE=full, then its capabilities get re-enabled.
> This seems like a pretty serious breakage of userspace.

How is this any different from traditional *nix setuid semantics?
I suppose I can see your point somewhat if you are concerned
specifically about the case where pE < pP execs fE=full && fP=0,
but I am unconvinced this constitutes serious breakage.  On the
contrary, I think it seems most reasonable for those caps to be
reenabled, especially for caps where fI=1, but perhaps even when
fI=0.

I'm still looking over your patches to try to figure out how exactly
you think this stuff should work.  I'm glad to see someone out
there is thinking about this.  You're right, it's pretty complex
and still far from useable.

--
Michael Glasgow < glasgow at beer dot net >

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-22  7:11 ` Michael Glasgow
@ 2003-10-22 19:40   ` Andy Lutomirski
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Lutomirski @ 2003-10-22 19:40 UTC (permalink / raw)
  To: Michael Glasgow; +Cc: linux-kernel



Michael Glasgow wrote:

> 
> Certainly with the current rule as implemented in 2.4, it looks as
> though you can regain permitted flags: pP' = (fP & X) | (fI & pI)
> 
> Is this what you mean when you say they can reappear? 

yes.  Intuitively, a process w/o some permitted capability should _never_ 
(unless fP != 0) get that capability back by calling exec.  This happens in 2.4 
and 2.6 in a worse way right now, though.  Any uid=0 process that calls exec (if 
cap_bset is untouched) will regain all capabilities, making it (mostly) 
ineffective to restrict root processes.  At the same time, non-root processes 
with extra caps can't usefully call helpers.  I think this is the problem you 
originally noticed.

> [...] WRT the
> spec itself, I don't see this assumption.  The rule could just as
> easily be:  pP' = (fP & X) | (pP & fI & pI)  (just an example)
> The rule in your patch seems like it should be compliant as well.

Maybe I misread the spec, but I thought it explicitly stated
pP' = (fP & X) | (fI & pI)
(I can't find it right now, though...)

>>2. If a process has pE < pP (i.e. some caps disabled, e.g. uid=0,
>>euid!=0), and exec's fE=full, then its capabilities get re-enabled.
>>This seems like a pretty serious breakage of userspace.
> 
> 
> How is this any different from traditional *nix setuid semantics?
> I suppose I can see your point somewhat if you are concerned
> specifically about the case where pE < pP execs fE=full && fP=0,
> but I am unconvinced this constitutes serious breakage.  On the
> contrary, I think it seems most reasonable for those caps to be
> reenabled, especially for caps where fI=1, but perhaps even when
> fI=0.


I would hope that, on a system that supports file capabilities, a file w/o 
capabilities set and w/o setuid would behave exactly like a file with some 
"default" capabilities.  In my patch, these capabilities are (=ei).  In mainline 
Linux, there is no such capability set (witness the logic in 
cap_binprm_set_security).

As a test, this is IMHO correct: (-test-6 + my patch + both options on)

$ cp `which bash` .
$ chmod 4755 bash
$ su
Password:
# ./bash -p
$ dumpcap [a trivial program I wrote]
         Real        Eff
User    0           500
Group   0           0

Caps: =ip

The bash -p process has uid = 0, euid = 500.  When it execs dumpcap, neither its 
uid nor its euid change, so, in traditional POSIX, it should have no effective 
capabilities (as it acts like uid 500).  (Should it have CAP_SETUID?  My patch 
doesn't change this behavior, but I'm not sure it's correct right now.)

With the (POSIX) rule pE' = pP' & fE, the dumpcap process would have been uid=0, 
euid=500, and all caps effective, which is inconsistant with traditional 
semantics.  Linux currently works correctly because fE and fP are dependent on 
initial uid and euid.


--Andy


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
       [not found] <fa.f9mv0tb.27sf3j@ifi.uio.no>
@ 2003-10-23  1:36 ` Michael Glasgow
  2003-10-23  1:57   ` Andy Lutomirski
  0 siblings, 1 reply; 19+ messages in thread
From: Michael Glasgow @ 2003-10-23  1:36 UTC (permalink / raw)
  To: Andy Lutomirski, linux-kernel

Andy Lutomirski wrote:
> Maybe I misread the spec, but I thought it explicitly stated
> pP' = (fP & X) | (fI & pI)
> (I can't find it right now, though...)

I don't see *any* rules for capabilities evolution explicitly
defined.  There are some limitations and some mandatory characteristics
that any rules of evolution must possess, and these seem to make
sense to me as far as they go.  But there's no explicit "pP' = blah";
perhaps there needs to be.

> I would hope that, on a system that supports file capabilities, a
> file w/o capabilities set and w/o setuid would behave exactly like
> a file with some "default" capabilities.  In my patch, these
> capabilities are (=ei).  In mainline Linux, there is no such
> capability set (witness the logic in cap_binprm_set_security).

I agree for the most part, but why would you choose (=ei) rather
than just (=i)?  Also, what in your opinion should be the meaning
of (fE != 0 && fP=0) versus (fE != 0 && fP = fE)?

> With the (POSIX) rule pE' = pP' & fE, the dumpcap process would
> have been uid=0, euid=500, and all caps effective, which is
> inconsistant with traditional semantics.  Linux currently works
> correctly because fE and fP are dependent on initial uid and euid.

I do not think that rule is specified by the POSIX 1003.1e draft
either, although it is compliant.  Necessary distinction because
I believe we can change the rules in various ways and still be
compliant, if that is important.

Also, it is clear that the inconsistency you point out is due to
your assumption that a file with no capabilities is (=ei) by default.
If it were (=i), then this problem goes away, right?

--
Michael Glasgow < glasgow at beer dot net >

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
@ 2003-10-23  1:41 Albert Cahalan
  0 siblings, 0 replies; 19+ messages in thread
From: Albert Cahalan @ 2003-10-23  1:41 UTC (permalink / raw)
  To: linux-kernel mailing list; +Cc: luto

Andy Lutomirski writes:

> I agree with these problems, but I think the proper
> fix is complicated.  AFAICT, POSIX capability
> evolution, as specified by whatever draft it was,
> is broken, so the hacks in prepare_binprm
> (cap_bprm_set_security in 2.6) are needed to avoid 
> security problems.  Aside from the fact that
> non-inheritable-by-default makes little sense
> (and requires root to get capabilities re-added
> from the file _permitted_ set), POSIX cap
> evolution has some other problems:

You've noticed!  :-)

The people who wrote the code were working from
two different drafts of the spec. I think some
people used draft 16, while others used draft 17.
(or 15 and 16, or 17 and 18 -- a difference of 1)
Between these two drafts there had been BIG changes.
Well, a critical equation changed.

People at SGI, mindlessly cloning the IRIX code,
stuck us with the half-ass set of capability bits
we have today. They ignored the DG-UX implementation
using 256 bits and slightly different equations.
They ignored the fact that the security model will
be terribly inconsistent if you still have apps
making UID-based decisions -- that is, you need to
allocate bits for glibc, XFree86, Linux vendors,
admin tools, various databases, and local site usage.
Yes it's yucky, but it's required. Covering ears
and burying the head won't make this go away.

Nobody thought to have half the bits default
to "on" for stuff currently allowed for regular
users. For example, the right to listen for
incoming network connections could be limited
if this had been given a default-enabled bit.

Then there's the emergency hack done to patch a
security hole that the capability bits introduced.
I think that was back in the early 2.4.x days.

People like to ignore the fact that apps tend
to answer "Do I need setuid-style precautions?"
by examining UID.

People like to ignore the fact that privileged
code, written with setuid in mind, can lead to
all sorts of mayhem if 42% of the privileged
operations are prohibited. Yeah, you'd hope
that a setuid app has great error checking and
can cope... but "hope" shouldn't satisfy you.
We really need a way for app authors to mark a
binary as "always block rights P, Q, and R" and
"block all rights unless given V, W, and X",
with the assumption that an unmarked app requires
an all-or-none situation.

Probably there should be two worlds on the
system. Apps with "funny" rights should be
kept away from UID 0 and setuid apps, while
apps with UID 0 or setuid should be kept
away from "funny" rights. Give the init
process a special ability to cross worlds.

The authors of our code seem to have given up
and moved on. Nobody cleaned up the mess.
Is it any wonder the POSIX draft didn't ever
make it beyond the draft state?

(and damn, WTF is with !capable(...) meaning
that you are capable of performing something?)

One final horror: just imagine trying to write
up some sane documentation for the average admin.
Poorly-understood security mechanisms are a
hazard. BTW, don't forget to imagine documenting
all the interactions with UID, filesystems, etc.

Face it: admins will think in terms of assigning
rights to users, never minding that there are
some weird equations, UID interactions, and
perhaps per-executable bits.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-23  1:36 ` Michael Glasgow
@ 2003-10-23  1:57   ` Andy Lutomirski
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Lutomirski @ 2003-10-23  1:57 UTC (permalink / raw)
  To: Michael Glasgow; +Cc: linux-kernel

Michael Glasgow wrote:
> Andy Lutomirski wrote:
> 
>>Maybe I misread the spec, but I thought it explicitly stated
>>pP' = (fP & X) | (fI & pI)
>>(I can't find it right now, though...)
> 
> 
> I don't see *any* rules for capabilities evolution explicitly
> defined.  There are some limitations and some mandatory characteristics
> that any rules of evolution must possess, and these seem to make
> sense to me as far as they go.  But there's no explicit "pP' = blah";
> perhaps there needs to be.

Section 3, line 36 or so of my copy of POSIX draft 1003.1e gives:

I1 = I0
P1 = (Pf && X) || (If && I0)
E1 = Ef && P1
[where P0 is pP and p1 is pP']

Not sure how relevant this is, though.

>>I would hope that, on a system that supports file capabilities, a
>>file w/o capabilities set and w/o setuid would behave exactly like
>>a file with some "default" capabilities.  In my patch, these
>>capabilities are (=ei).  In mainline Linux, there is no such
>>capability set (witness the logic in cap_binprm_set_security).
> 
> 
> I agree for the most part, but why would you choose (=ei) rather
> than just (=i)?

I don't really see the point of fE in any case, but, since traditional POSIX 
apps have no concept of disables capabilities, I figured that all capabilities 
enabled should be the default.

In any case, it could be useful to use (=i) to mean "this process shouldn't use 
capabilities by default" or (=ip) to mean "this process is privileged, but it 
shouldn't use those privileges without knowing what it's doing".  Neither 
version seems to offer any real security benefit, but if (=i) were the default, 
then I don't see the benefit of (=ei).



> [...] Also, what in your opinion should be the meaning
> of (fE != 0 && fP=0) versus (fE != 0 && fP = fE)?

fP (in my mind) means "this file gets these capabilities always" while fE means 
"if this file has these capabilities after exec evolution rules, then they 
should be enabled _unless they were already disabled."  I could easily be 
convinced that I'm wrong, though.

>>With the (POSIX) rule pE' = pP' & fE, the dumpcap process would
>>have been uid=0, euid=500, and all caps effective, which is
>>inconsistant with traditional semantics.  Linux currently works
>>correctly because fE and fP are dependent on initial uid and euid.
> 
> 
> I do not think that rule is specified by the POSIX 1003.1e draft
> either, although it is compliant.  Necessary distinction because
> I believe we can change the rules in various ways and still be
> compliant, if that is important.

I don't think it really matters, but I changed my patch to be closer to the 
rules quoted above.  Remember that this draft is withdrawn.


> Also, it is clear that the inconsistency you point out is due to
> your assumption that a file with no capabilities is (=ei) by default.
> If it were (=i), then this problem goes away, right?

I think this just changes the problem.  The POSIX rule (assuming my copy isn't 
bogus) gives pE = pP' & fE, which means that (if fE==0) any program that root 
wants to run with caps (most often CAP_DAC_OVERRIDE I presume) needs to either 
have fE explicitly set to full or be rewritten to enable its capabilities.  This 
breaks userspace.


Andy


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-21 11:26 Michael Glasgow
@ 2003-10-23 16:46 ` Theodore Ts'o
  0 siblings, 0 replies; 19+ messages in thread
From: Theodore Ts'o @ 2003-10-23 16:46 UTC (permalink / raw)
  To: Michael Glasgow; +Cc: linux-kernel

On Tue, Oct 21, 2003 at 06:26:45AM -0500, Michael Glasgow wrote:
> I wrote a simple setuid-root wrapper which sets some capabilities, 
> gives up all other privs, and and then execs a shell.  I was hoping
> to use this wrapper as a login shell so that I could have a user  
> log in interactively with a small subset of elevated privileges.
> 
> Unfortunately after looking over the capabilities code in the 2.4
> kernel, it would appear that this is not currently possible, and
> my wrapper cannot work without filesystem support for capabilities.
> And even then, I'd have to set each file's inheritable flag for the
> capabilities I want on every executable that I am likely to run,
> including the shell.  Am I mising something, or is this an accurate
> description?

No, you're not missing anything.

What happened here is that originally there was a security
vulnerability caused by an a badly desgined attempt to take advantage
of capabilities without filesystem support.  In order to fix it, the
patch took a very conservative path, which completely disabled the use
of selective capability inheritance.  (Capabilities are still useful,
but only in setuid root programs that selectively drop unneeded
capabilities --- still in my opinion the best way to use capabilities,
BTW).

> As an interim workaround, how about assuming all capabilities are
> inheritable in fs/exec.c:prepare_binprm, i.e. instead of
> cap_clear(bprm->cap_inheritable), call cap_set_full() ???  I don't
> think this would break anything, and it would make capabilities a
> lot more useful until we get fs support merged in.

I agree this is safe, and allows the use of your setuid wrapper
script.  The one reason why I think it's better to modify programs is
that it's too easy for individual system administrators to screw up
the configuration used by your wrapper script, and accidentally
introduce a security vulnerability into their system.  It's dangerous
to give a program some capability (or reduce the capability given to a
program designed to be setuid) without examining the source code and
being clueful.  So by making the program setuid and editing the source
code to add an explicit capability drop in the program is much, much
safer compared to having a random system administrator to edit a
config file and trust that he or she does so correctly.

						- Ted

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
       [not found] <fa.f4bs2b4.fhub0m@ifi.uio.no>
@ 2003-10-23 22:05 ` Michael Glasgow
  2003-10-23 22:59   ` Theodore Ts'o
  2003-10-24  1:36   ` Ernie Petrides
  0 siblings, 2 replies; 19+ messages in thread
From: Michael Glasgow @ 2003-10-23 22:05 UTC (permalink / raw)
  To: Theodore Ts'o, linux-kernel

Theodore Ts'o wrote:
> I agree this is safe, and allows the use of your setuid wrapper
> script.  The one reason why I think it's better to modify programs is
> that it's too easy for individual system administrators to screw up
> the configuration used by your wrapper script, and accidentally
> introduce a security vulnerability into their system.  It's dangerous
> to give a program some capability (or reduce the capability given to a
> program designed to be setuid) without examining the source code and
> being clueful.  So by making the program setuid and editing the source
> code to add an explicit capability drop in the program is much, much
> safer compared to having a random system administrator to edit a
> config file and trust that he or she does so correctly.

I can see your point, but I guess we'll have to agree to disagree.

Even with selective capability inheritance enabled in this fashion,
it is still possible to avoid using it and modify programs directly,
if you think that's more secure.  Personally, I think that in some
cases it's slightly more secure to have a very small (statically
linked) setuid wrapper program which sets up capabilities properly
than to make a very large program setuid-root (when it was not
designed to run as root), only to add one capability.

Yes, you can do the capability-setup first thing in main()... but
this is occasionally insufficient.  Also, it makes it a pain to
have, for instance, a backup user with CAP_DAC_READ_SEARCH who is
able to run several apps, e.g. dump, tar, cpio, rsync, etc.  from
a restricted shell.

The code to drop privs is not hard, but it's also not trivial.
Those without a clue are just as likely to screw it up as they are
a wrapper; and anyway since when did it become a design goal for
the kernel to cater to the ineptitude of the clueless?  That sounds
more like a Redmond, Washington philosophy than one fit for Linux. :-)

--
Michael Glasgow < glasgow at beer dot net >

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-23 22:05 ` Michael Glasgow
@ 2003-10-23 22:59   ` Theodore Ts'o
  2003-10-24  1:36   ` Ernie Petrides
  1 sibling, 0 replies; 19+ messages in thread
From: Theodore Ts'o @ 2003-10-23 22:59 UTC (permalink / raw)
  To: Michael Glasgow; +Cc: linux-kernel

On Thu, Oct 23, 2003 at 05:05:40PM -0500, Michael Glasgow wrote:
> Even with selective capability inheritance enabled in this fashion,
> it is still possible to avoid using it and modify programs directly,
> if you think that's more secure.  Personally, I think that in some
> cases it's slightly more secure to have a very small (statically
> linked) setuid wrapper program which sets up capabilities properly
> than to make a very large program setuid-root (when it was not
> designed to run as root), only to add one capability.
> 
> Yes, you can do the capability-setup first thing in main()... but
> this is occasionally insufficient.  Also, it makes it a pain to
> have, for instance, a backup user with CAP_DAC_READ_SEARCH who is
> able to run several apps, e.g. dump, tar, cpio, rsync, etc.  from
> a restricted shell.
> 
> The code to drop privs is not hard, but it's also not trivial.
> Those without a clue are just as likely to screw it up as they are
> a wrapper; and anyway since when did it become a design goal for
> the kernel to cater to the ineptitude of the clueless?  That sounds
> more like a Redmond, Washington philosophy than one fit for Linux. :-)

Modifying source code requires programming capabilities, which means
that the most clueless won't do it at all.  It's something that needs
to be done by the upstream authors, or perhaps by the distributions,
at which point the clueless will get it when they upgrade.

It's not matter of catering to the ineptitude of the clueless but
pursueing a design which doesn't leave an open manhole cover where a
clueless system administrator can screw up and put their entire system
at risk.  Consider that even if the distributions ship a package using
your system, there will be a config file which will be an opportunity
for a system administrator to screw up.  In general, for any
particular system program, there is only one acceptable setting in
terms of what capabilities it will need.  So why make it be something
which can be screwed up in a config file?  

Fix it once, by a programmer who knows what he/she is doing, and the
problem is fixed for everyone.  Furthermore, it will be more efficient
since it avoids an exec and requirement for a program to parse a
config file.

						- Ted

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-23 22:05 ` Michael Glasgow
  2003-10-23 22:59   ` Theodore Ts'o
@ 2003-10-24  1:36   ` Ernie Petrides
  2003-10-24  2:19     ` Bernd Eckenfels
  2003-10-25 19:51     ` Pavel Machek
  1 sibling, 2 replies; 19+ messages in thread
From: Ernie Petrides @ 2003-10-24  1:36 UTC (permalink / raw)
  To: Michael Glasgow; +Cc: Theodore Ts'o, linux-kernel

On Thursday, 23-Oct-2003 at 17:5 CDT, "Michael Glasgow" wrote:

> The code to drop privs is not hard, but it's also not trivial.

Here's an example code sequence that demonstrates how a setuid-to-root
application could drop all capabilities except for CAP_IPC_LOCK and
then run with the non-privileged uid:

    #include <sys/prctl.h>
    #include <sys/capability.h>

	...

	cap_t c;

	if (prctl(PR_SET_KEEPCAPS, 1UL, 0UL, 0UL, 0UL) < 0 ||
	    seteuid(getuid()) < 0 ||
	    !(c = cap_from_text("cap_ipc_lock=eip")) ||
	    cap_set_proc(c) < 0)
		/* handle error */;

However, I agree that it's often not viable to require application
changes to achieve the desired result.

Cheers.  -ernie

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-24  1:36   ` Ernie Petrides
@ 2003-10-24  2:19     ` Bernd Eckenfels
  2003-10-24  5:10       ` Ernie Petrides
  2003-10-25 19:51     ` Pavel Machek
  1 sibling, 1 reply; 19+ messages in thread
From: Bernd Eckenfels @ 2003-10-24  2:19 UTC (permalink / raw)
  To: linux-kernel

In article <200310240136.h9O1aaOU002931@pasta.boston.redhat.com> you wrote:
> However, I agree that it's often not viable to require application
> changes to achieve the desired result.

What does often mean? This is the Open Source Linux, and here we can do
changes to the source if it is good for securtiy, architecture, speat,
whatever.

Of course a solution which does the right thing without programming is even
better - Watermarking or something. But I guess wie can combine those. The
typical internet server has already enough cruft for chrooting, priveledge
dropping and FD passing to work around for example port priveledges, a REAL
solution wont make it worse.

Bernd
y

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-24  2:19     ` Bernd Eckenfels
@ 2003-10-24  5:10       ` Ernie Petrides
  0 siblings, 0 replies; 19+ messages in thread
From: Ernie Petrides @ 2003-10-24  5:10 UTC (permalink / raw)
  To: Bernd Eckenfels; +Cc: linux-kernel

On Friday, 24-Oct-2003 at 4:19 +0200, Bernd Eckenfels wrote:

> In article <200310240136.h9O1aaOU002931@pasta.boston.redhat.com> you wrote:
> > However, I agree that it's often not viable to require application
> > changes to achieve the desired result.
>
> What does often mean? This is the Open Source Linux, and here we can do
> changes to the source if it is good for securtiy, architecture, speat,
> whatever.

I agree, but sometimes the source to the *application* is not available
to us.

Cheers.  -ernie

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
       [not found] ` <fa.l1oevhb.1s5k583@ifi.uio.no>
@ 2003-10-24  8:44   ` Andy Lutomirski
  2003-10-24 12:41     ` Theodore Ts'o
  0 siblings, 1 reply; 19+ messages in thread
From: Andy Lutomirski @ 2003-10-24  8:44 UTC (permalink / raw)
  To: linux-kernel, glasgow, albert

Thanks to everyone for making me realize just how complex / screwed up all of 
this is.  I think it's fair to say that something should be fixed/changed, but I 
don't think that a quick patch is a good idea -- currently capabilities are so 
limited that there is little userspace use, and the use that exists is pretty 
much limited to Ernie's example.  Witness the fact that my patch, as well as 
others, appear to break _nothing_.  That means that we have the opportunity (2.7 
timeframe here) to overhaul the system _once_.


At the risk of premature discussion, here are some thoughts:


1. pI is currently almost useless.  If a process really wants a capability to be 
dropped after exec, it can drop it itself.  So redefine pI to mean "these are 
the only capabilities that this process or its children may _ever_ hold."

2. fE is useless.  It doesn't seem to have much of a point, and it just adds 
complexity.  (e.g. look at Windows privileges.  they start unenabled, and 
programs have to jump through hoops to use them.  I see no security benefit.) 
So remove fE entirely.

3. The current use of the capability bits is not as fine-grained as it could be, 
and lacks the ability to restrict normal users.  Redefine it as:
  Capability range             Function
  ----------------             -----------------
  <0                           On by default
  0-31                         Legacy bounds (see below)
  >=32                         Off by default

All of the current capabilities retain their current values.  New capabilities 
above 32 can have a "legacy bound" associated with them, like this:

_u32 legacy_bounds[] = {...};

bool capable(int cap)
{
	if(x<32) return (cap in effective set);
	else return ( (legacy_bounds[cap] & (bits 0-31 of effective set))
	 && (cap in effective set) );
}

This ensures that existing programs that think they have dropped capabilities 
(using the old numbering) really have dropped those capabilities.  New programs 
can do whatever they want, using the new numbering.  Some random thoughts of 
what the "new" capabilities might look like (where CAP_USER_ means <0 and 
CAP_ADM_ means >=32):

Completely new things:
CAP_USER_FSUID /* permission checks can use fsuid */
CAP_USER_FSGID /* permission checks can use fsgid */
CAP_USER_FSWRITE /* can write files */
Saner version of existing features (CAP_SYS_ADMIN, anyone?)
CAP_ADM_MOUNT_BLOCK /* can mount block devices */
CAP_ADM_MOUNT_NONE /* can mount things that are not block devices */

This could be very nice for administrators.  Maybe a large block of capability 
space could be reserved for userspace use.  (Make capabilities 64 bits?  Fun!) 
Albert -- this fixes one of your complaints.


Capability evolution might look like this:
pI' = pI & fI
pP' = ((fP & X) | pP) & pI'
pE' = pP' & (pE|fP) & (only caps <0 if uid==0 and setuid nonroot)

By the way, even if people are scared of programs mishandling fP!=0, this still 
seems very useful just to adjust "per-user" rights.

If there's enough interest, I might try to implement this in the next few weeks 
and get it ready for 2.7.  There's the risk that if any new scheme goes into a 
mainline development kernel, then people will start using it, and it will be 
impossible to change it, which is why I'm floating this around now.  I don't see 
any reason to keep the current system, and, given that there is no de-facto *nix 
capability standard, Linux might as well have the best capability system out there.

Any thoughts/suggestions/flames?

Andy


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-24  8:44   ` posix capabilities inheritance Andy Lutomirski
@ 2003-10-24 12:41     ` Theodore Ts'o
  2003-10-24 16:44       ` Andy Lutomirski
  0 siblings, 1 reply; 19+ messages in thread
From: Theodore Ts'o @ 2003-10-24 12:41 UTC (permalink / raw)
  To: Andy Lutomirski; +Cc: linux-kernel, glasgow, albert

On Fri, Oct 24, 2003 at 01:44:36AM -0700, Andy Lutomirski wrote:
> 
> 1. pI is currently almost useless.  If a process really wants a capability 
> to be dropped after exec, it can drop it itself.  So redefine pI to mean 
> "these are the only capabilities that this process or its children may 
> _ever_ hold."

A lot of the reasons why it looks useless is because we don't have
filesystem support.  The intent behind the POSIX capabilities system
is that system administrator can control which privileges are
conferred upon a program when it is exec'ed, as well as which
privileges it is allowed to inherit.  (The idea behind this is that
even if the exec'ing process wishes to bequeath some super-user
capabilities across an exec, unless that program has been audited and
cleared by the site security officer as being cleared to accept that
additional capability, it shouldn't be given it.)  In addition, of
course, the exec'ing process ought to be allowed to control what
capabilities it is willing to bequeth.  

Hence the capabilities inheritance algorithm of:

	pP' = fP | (fI & pI)

> 2. fE is useless.  It doesn't seem to have much of a point, and it just 
> adds complexity.  (e.g. look at Windows privileges.  they start unenabled, 
> and programs have to jump through hoops to use them.  I see no security 
> benefit.) So remove fE entirely.

It has a lot of point.  It's there for the same reason why just
because you have the root password, you don't want to run as root all
the time.  (At least, sane people don't...)  You might make mistakes.  

A very basic rule of security is that you only use the least amount of
privileges to get the job done.  That way, if you make a mistake, and
get tricked into accessing the wrong file (say, because you failed to
check for .. in pathnames supplied by an untrusted user), you limit
the amount of damage done because of your bone-headed mistake.

Is this more complexity?  Yes.  But security generally means more
complexity.  Deal with it.  If you don't like, it you can just always
run with fE set to fP, just as you just login as root and run with
root privileges all the time.  As long as you're careful, and never
accidentally type the command rm -rf /, why bother with non-root
accounts on a single-user machine?

(And if you really need help answering that question, then let's just
agree to disagree, and remind me to never hire you to be a system
administrator on any of my machines....)

> 3. The current use of the capability bits is not as fine-grained as it 
> could be, and lacks the ability to restrict normal users.  

No.  Bad, bad, bad, bad, bad idea.

A lot of the rules of when capabilities can be dropped and inherited
assume that capabilities enhance privileges, and do not take
privileges away.  A very different calculus emerges when you start
restricting what a normal user can do, especially when this mixes with
setuid (non-root) or setgid programs.  A lot of programs don't do
error checking, and if you can change basic assumptions of what works
and doesn't work, you can actually cause security breaches where none
previously existed.

One of the reasons why fP, fE, and fI are all set to zero was because
in a previous attempt to try to emulate capabilities, the old
"backwards compatibility" algorithm of how to treat setuid root
programs allowed the exec'ing process to control what privileges could
be inherited by a setuid root program.  This was really bad, since it
meant that a setuid root program could have some capabilities (such as
filesystem descretionary access controls override), but not others,
and a failure to check error returns (since after all a setuid root
program would *always* succeed, right?), caused a security hole.

It is for similar reasons that chroot requires root privileges.  One
might think that restricting what part of the filesystem can be seen
by a process shouldn't require root privileges, except that by
changing the environment, it can fool setuid or setgid programs into
doing the wrong thing.

So any scheme that restricts normal user privileges **must** have
different access controls and different semantics than schemes which
allow a process with superuser privileges from dropping some or all of
its capabilities.  It's fundamentally a different thing, and should
not be conflated together.  That way only lies madness.  (And security
holes.)

						- Ted

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-24 12:41     ` Theodore Ts'o
@ 2003-10-24 16:44       ` Andy Lutomirski
  2003-10-24 20:58         ` David Wagner
  0 siblings, 1 reply; 19+ messages in thread
From: Andy Lutomirski @ 2003-10-24 16:44 UTC (permalink / raw)
  To: Theodore Ts'o; +Cc: linux-kernel, glasgow, albert



Theodore Ts'o wrote:

> On Fri, Oct 24, 2003 at 01:44:36AM -0700, Andy Lutomirski wrote:
> 
>>1. pI is currently almost useless.  If a process really wants a capability 
>>to be dropped after exec, it can drop it itself.  So redefine pI to mean 
>>"these are the only capabilities that this process or its children may 
>>_ever_ hold."
> 
> 
> A lot of the reasons why it looks useless is because we don't have
> filesystem support.  The intent behind the POSIX capabilities system
> is that system administrator can control which privileges are
> conferred upon a program when it is exec'ed, as well as which
> privileges it is allowed to inherit.  (The idea behind this is that
> even if the exec'ing process wishes to bequeath some super-user
> capabilities across an exec, unless that program has been audited and
> cleared by the site security officer as being cleared to accept that
> additional capability, it shouldn't be given it.)  In addition, of
> course, the exec'ing process ought to be allowed to control what
> capabilities it is willing to bequeth.  

I agree completely.  I'm just suggesting a different way of doing it. 
If a process is actually not trusted to have some capability, then it is 
presumably not trusted to use helper applications that have that 
capability.  So make it impossible to use or _regain_ caps that are not 
in pI and fI.

On the other hand, if the exec'ing process wants to remove a capability 
without this restriction, then it can just drop it and then call exec. 
Hence:

pP' = (fP | pP) & pI'; (note pI_'_ -- fI restrictions still take effect 
here)

> 
> Hence the capabilities inheritance algorithm of:
> 
> 	pP' = fP | (fI & pI)
> 
> 
>>2. fE is useless.  It doesn't seem to have much of a point, and it just 
>>adds complexity.  (e.g. look at Windows privileges.  they start unenabled, 
>>and programs have to jump through hoops to use them.  I see no security 
>>benefit.) So remove fE entirely.
> 
> 
> It has a lot of point.  It's there for the same reason why just
> because you have the root password, you don't want to run as root all
> the time.  (At least, sane people don't...)  You might make mistakes.
> 
> A very basic rule of security is that you only use the least amount of
> privileges to get the job done.  That way, if you make a mistake, and
> get tricked into accessing the wrong file (say, because you failed to
> check for .. in pathnames supplied by an untrusted user), you limit
> the amount of damage done because of your bone-headed mistake.
> 
> Is this more complexity?  Yes.  But security generally means more
> complexity.  Deal with it.  If you don't like, it you can just always
> run with fE set to fP, just as you just login as root and run with
> root privileges all the time.  As long as you're careful, and never
> accidentally type the command rm -rf /, why bother with non-root
> accounts on a single-user machine?
> 
> (And if you really need help answering that question, then let's just
> agree to disagree, and remind me to never hire you to be a system
> administrator on any of my machines....)

We are both talking about the _file_ effective mask, right?  I 
absolutely agree that pI is needed.

I've been programming Windows for a long time, and windows has a 
capability system.  Essectially, a "privilege" (capability) is either 
present or not present, and, if present, either enabled or disabled. 
This enabled state corresponds to effectiveness in POSIX -- programs can 
freely change it.  All capabilities are disabled by default (almost -- 
there's a pointless exception, of course).  The result is that every 
program that uses a privileged function (e.g. change the time, restart, 
etc.) wraps that call with something that turns enables the capability 
at first, then disables it.  This has no benefit -- a hijacked 
privileged program can still enable them, and the admin never sees this, 
because everything enables them.  I'm not saying that the ability to 
disable capabilities is bad (e.g. single-process file servers absolutely 
require it).

Now let's throw fE into the equation.  Will admins keep a list of which 
programs prefer their capabilities enabled by default?  If I'm an admin, 
and I don't trust a program, I won't give it the capability _at all_. 
Just telling the program "I don't trust you, so please to do 
such-and-such unless you remember to enable the capability first" seems 
useless.  I think a sensible capability system will choose a sane 
default at leave it there.

> 
> 
>>3. The current use of the capability bits is not as fine-grained as it 
>>could be, and lacks the ability to restrict normal users.  
> 
> 
> No.  Bad, bad, bad, bad, bad idea.

I imagined that admins or users would remove almost everything from the 
inheritable mask so that the untrusted program is not given the change 
to screw up.  I'm perfectly willing to drop that part, though.

I think that my proposal for extending super-user capabilities still has 
a lot of value, though.  Things like CAP_SYS_ADMIN are far to wide in 
scope, and I think that can be fixed without breaking old applications.



Andy


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-24 16:44       ` Andy Lutomirski
@ 2003-10-24 20:58         ` David Wagner
  0 siblings, 0 replies; 19+ messages in thread
From: David Wagner @ 2003-10-24 20:58 UTC (permalink / raw)
  To: linux-kernel

Andy Lutomirski  wrote:
>I've been programming Windows for a long time, and windows has a 
>capability system.  [...] All capabilities are disabled by default (almost -- 
>there's a pointless exception, of course).  The result is that every 
>program that uses a privileged function (e.g. change the time, restart, 
>etc.) wraps that call with something that turns enables the capability 
>at first, then disables it.  This has no benefit -- a hijacked 
>privileged program can still enable them, and the admin never sees this, 
>because everything enables them.

Actually, it does have some benefits.  If I do an open() somewhere
else in the code, I know that it is not going to unintentionally use
my elevated privileges.  That's useful.  Least privilege, and all that.

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
       [not found] ` <fa.hq0dft9.9i0obd@ifi.uio.no>
@ 2003-10-24 21:24   ` Andy Lutomirski
  0 siblings, 0 replies; 19+ messages in thread
From: Andy Lutomirski @ 2003-10-24 21:24 UTC (permalink / raw)
  To: David Wagner; +Cc: linux-kernel


David Wagner wrote:

> Andy Lutomirski  wrote:
> 
>>I've been programming Windows for a long time, and windows has a 
>>capability system.  [...] All capabilities are disabled by default (almost -- 
>>there's a pointless exception, of course).  The result is that every 
>>program that uses a privileged function (e.g. change the time, restart, 
>>etc.) wraps that call with something that turns enables the capability 
>>at first, then disables it.  This has no benefit -- a hijacked 
>>privileged program can still enable them, and the admin never sees this, 
>>because everything enables them.
> 
> 
> Actually, it does have some benefits.  If I do an open() somewhere
> else in the code, I know that it is not going to unintentionally use
> my elevated privileges.  That's useful.  Least privilege, and all that.

Agreed, somewhat. The problem IMHO is that, even for caps like 
CAP_DAC_READ_SEARCH, no existing code expects this behavior.  (Windows 
example again: users with SeBackupPrivilege have a _very_ hard time 
using it since few programs actually know what to do with it.)  If I'm a 
user with CAP_DAC_READ_SEARCH, I don't want to have to rewrite all of 
fileutils just to use that privilege.  Users can still have this 
behavior, though, under my proposed evolution rules:
pE' = pP' & (pE|fP)

Pretend that 'cap' is a bash builtin that did the obvious thing:

~backupuser/.bashrc: cap all disable
~backupuser/bin/privrun: cap all enable; exec $*

Now that user can't accidentally use CAP_DAC_READ_SEARCH, but s/he could 
do 'privrun ls', for example, if necessary.  (I'm ignoring funny issues 
with cd here.)  All of this is without the fE mask and without modifying 
or breaking existing user tools.

If you can think of a use for fE, let me know :)


Andy


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: posix capabilities inheritance
  2003-10-24  1:36   ` Ernie Petrides
  2003-10-24  2:19     ` Bernd Eckenfels
@ 2003-10-25 19:51     ` Pavel Machek
  1 sibling, 0 replies; 19+ messages in thread
From: Pavel Machek @ 2003-10-25 19:51 UTC (permalink / raw)
  To: Ernie Petrides; +Cc: Michael Glasgow, Theodore Ts'o, linux-kernel

Hi!

> > The code to drop privs is not hard, but it's also not trivial.
> 
> Here's an example code sequence that demonstrates how a setuid-to-root
> application could drop all capabilities except for CAP_IPC_LOCK and
> then run with the non-privileged uid:
> 
>     #include <sys/prctl.h>
>     #include <sys/capability.h>
> 
> 	...
> 
> 	cap_t c;
> 
> 	if (prctl(PR_SET_KEEPCAPS, 1UL, 0UL, 0UL, 0UL) < 0 ||
> 	    seteuid(getuid()) < 0 ||
> 	    !(c = cap_from_text("cap_ipc_lock=eip")) ||
> 	    cap_set_proc(c) < 0)
> 		/* handle error */;
> 
> However, I agree that it's often not viable to require application
> changes to achieve the desired result.

IIRC, libraries have special startup sections that run before
main(). And c++ constructors do, too; so wrapper still might be safer
option.

								Pavel
-- 
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2003-10-25 19:52 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <fa.n4rmmgg.2423pm@ifi.uio.no>
     [not found] ` <fa.l1oevhb.1s5k583@ifi.uio.no>
2003-10-24  8:44   ` posix capabilities inheritance Andy Lutomirski
2003-10-24 12:41     ` Theodore Ts'o
2003-10-24 16:44       ` Andy Lutomirski
2003-10-24 20:58         ` David Wagner
     [not found] <fa.f26d55g.1qgijbi@ifi.uio.no>
     [not found] ` <fa.hq0dft9.9i0obd@ifi.uio.no>
2003-10-24 21:24   ` Andy Lutomirski
     [not found] <fa.f4bs2b4.fhub0m@ifi.uio.no>
2003-10-23 22:05 ` Michael Glasgow
2003-10-23 22:59   ` Theodore Ts'o
2003-10-24  1:36   ` Ernie Petrides
2003-10-24  2:19     ` Bernd Eckenfels
2003-10-24  5:10       ` Ernie Petrides
2003-10-25 19:51     ` Pavel Machek
2003-10-23  1:41 Albert Cahalan
     [not found] <fa.f9mv0tb.27sf3j@ifi.uio.no>
2003-10-23  1:36 ` Michael Glasgow
2003-10-23  1:57   ` Andy Lutomirski
     [not found] <fa.f36f4t9.1rg8j3v@ifi.uio.no>
2003-10-22  7:11 ` Michael Glasgow
2003-10-22 19:40   ` Andy Lutomirski
     [not found] <fa.hehull9.10mmngt@ifi.uio.no>
2003-10-21 18:24 ` Andy Lutomirski
  -- strict thread matches above, loose matches on Subject: below --
2003-10-21 11:26 Michael Glasgow
2003-10-23 16:46 ` Theodore Ts'o

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).