lkml.org 
[lkml]   [1999]   [Apr]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: caps in elf, next itteration (the hack get's bigger)
Hi Pavel,

On Wed, 14 Apr 1999, Pavel Machek wrote:

> > But, as far as I can tell, setuid0 only helps us with binaries that were
> > formerly run full setuid-root, where the stickable solution secures
> > executables that formerly were just _run_ by root. I do _not_ want
> > binaries to inherit everything.
>
> Sorry. Not acceptable. This is too big change in semantic. When I run
> emacs as root, I want it to use all capabilities I have. When I run
> cat /dev/zero > /dev/hda as root, I do not want kernel denying
> operation because cat does not inherit "RAW DISK ACCESS"
> capability. Sorry.

Ok, my solution will _totally_ preserve these semantics. 100%. Or, if
the administrator/distribution developer decides certain binaries should
_not_ inherit all caps, this can be done too; it's a matter of
flexibility.

But let me use the named(8) example again, because I've thought it over
again and find that my original thinking was wrong. (why am I picking on
named(8) you ask? because that's how my box was rooted. that's why I'm
on a holy mission to get capabilities implemented)

If I were designing a secure distribution based on the stickable solution,
here's how named would start:

Calling process: ( I feel certain this can be easily arranged with the
'stickable' solution, and don't want to make this example longer than it
already is)
uid=named
gid=named (only)
permitted bits=0
inheritable bits=0
effective bits=0

Named binary:
-rwsr-x--T 1 named named 432880 Jan 4 01:07 named*
permitted bits=CAP_NET_BIND_SERVICE (only)
inheritable bits=0
effective bits=CAP_NET_BIND_SERVICE
extended file attributes=immutable bit set

named process after exec'ed by calling process: (CAP_NET_BIND_SERVICE
abbrev. to CAP_NET)
uid=named
gid=named (only)
permitted bits: pP' = fP | ( fI & pI ) = CAP_NET | ( 0 & 0 ) = CAP_NET
inheritable bits: pI' = pI = 0
effective bits: pE' = pP' & fE = CAP_NET & CAP_NET = CAP_NET

bash binary:
-r-xr-xr-T 1 root root 426980 Oct 19 22:57 bash*
permitted bits=0
inheritable bits=(all)
effective bits=(all)
extended file attributes=immutable bit set

Now, let's say another remotely-exploitable buffer overflow is found in
named(8). A black hat overflows the buffer, and manages to exec a bash
shell. Now let's compute the state of the bash shell that's been exec'ed:

bash shell process running parameters:
uid=named; rights in fs: read rights only to: /etc/named.conf,
/var/named/*, and /usr/sbin/named; write rights to
/var/named/(secondaries); execute right to /usr/sbin/named
gid=named; rights in fs: read and execute /usr/sbin/named
permitted bits: pP' = fP | ( fI & pI ) = 0 | ( (all) & 0 ) == 0
inheritable bits: pI' = pI = 0
effective bits: pE' = pP' & fE = 0 & (all) = 0

So after the attack, the attacker is left only with a shell that can:
- trash /var/named/(secondaries)
- re-start named(8), but not modify it in any way.

Which, IMHO, is about as secure as you can get. (dunno for sure if it
can't be improved)


Now, I see three situations possible with setuid0:
1) you can mark named(8) setuid root and implement exactly my scenario
above. I hope you reject the idea of setuid root named as fast as I do.
2) you make the named binary have no permitted, and inheritable=CAP_NET,
with the calling process having only CAP_NET in it's inheritable, and
otherwise the same as my example. This is your _best_ scenario IMHO, and
I'll come back to this in a moment.
3) You put whatever you want in the cap elf headers, _don't_ mark the file
'setuid 0', and interpret your cap elf headers in whatever way you wish,
but not compliant with the specification for how capabilities operate.
This would be an abomination IMHO, which I hope you reject.

If you use scenario 2, and black hat overflows your named the resulting
bash process gets: (abbreviated)
uid & gid(s) as above with fs rights as above
permitted = CAP_NET
inheritable = CAP_NET
effective = CAP_NET

So you get a process that can create a binary in /var/named/(secondaries)
that can get CAP_NET in it's permitted set, and listen on any unused
priviledged port; then it can restart named so you never know the
difference. This, IMHO, is unnacceptable; say you've not enabled telnet,
and attacker makes a trojan telnet that just records user names and
passwords and stores them in /var/named/(secondaries). Very ugly.

Now, this example was long enough as it is, and I had to skip quite a bit
of logic to keep it as short as it is. You should be able to fill in the
missing bits, however. If not, please re-read the specification for
capabilities (whose link I've provided _many_ times now) and give this a
lot more thought before you continue coding. Myself, I read this several
days ago, and have been thinking of little else since then. (I got out of
the shower this morning, stopped, and had to ask myself: Did I wash my
hair? I had to assume that it was taken care of by some poor background
process eaking out the remaining 3% CPU time)

[snip MUCH]

> Agreed that storing uid in headers is ugly. I probably do not
> understand capabilities model.

Then please, please re-read the specification and think about it a few
days; hopefully my real-world concrete examples will help, since I've
already derived this behavior. Also, I beg that you re-consider the
stickybit+immutable bit solution; it appears you understand well enough
how it operates. I'm considering trying to modify your patch myself; I
have the C coding skills, but no experience with kernel data structures
and API's. I _would_ give it a shot, however.

> I've seen paper, but I do not see why
> it is good thing.

It took me a long while to understand why it's such a good thing. Not
PERFECT, mind you, but much better than the current root==all powerful
model.

[snip]
>
> Pavel
> --
> I'm really pavel@atrey.karlin.mff.cuni.cz. Pavel
> Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).
>

cheers,
David

- --
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/

\
 
 \ /
  Last update: 2005-03-22 13:51    [W:0.126 / U:0.088 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site