Messages in this thread | | | Date | Wed, 14 Apr 1999 22:40:56 -0400 (EDT) | From | "David L. Parsley (lkml account)" <> | Subject | Re: 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/
| |