lkml.org 
[lkml]   [1998]   [Apr]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [patch 2.1.97] more capabilities support
Theodore Y. Ts'o wrote:
>
> Date: Sun, 26 Apr 1998 01:27:11 +0200
> From: Andrej Presern <andrejp@luz.fe.uni-lj.si>
>
> > How about the fact that in order to do pure capability systems, you'd
> > have to rev the interface of every single system call to take a
> > capability argument (just as file I/O syscalls now take a file
> > descriptor)?
>
> An example use of such a basic and primitive extension would be that a
> suid program can throw away its authority to execve() system call, if it
> doesn't need it.
>
> Huh? That's hardly a pure-capability system. In a pure capaibility
> system, you have something that is effectively like a "key", which can
> get passed around between processes, and a privileged program is merely
> a program that has several keys that confer more abilities than the
> standard default capability.

Don't you think that the two syscall capabilities are essentially two
'keys' that 'open different syscalls'? I designed the syscall capability
the way I did exactly to demonstrate that you don't neccessarily have to
pass the capability like a fd when you invoke it, keeping existing
syscall interfaces unchanged.

I stated in the mail that for starters I don't want a process to be able
to pass the syscall capability around to other processes (which it could
nonetheless if we don't tie the memory containing the copy of the
sys_call_table to the process that requested it).

You don't need a special authority granting daemon to have pure
capabilities because every object can have its own set that it can give
away. In the case of a syscall capability that I described, the kernel
gives a single syscall capability to all processes by default, and if
the process wants it can create its own subset of the system calls that
it received. As I already stated, if we don't tie this syscall
capability to the process (that is if we don't free the memory that it
occupies when the process exits), a process could as well communicate it
to other processes (the reference is just 4 bytes) if, of course, it
includes the authority to call system calls that can be used to
communicate with other processes.

> Using the lock/key anaology, though, having a key doesn't mean that when
> I walk towards a locked door (with a bad guy following behind) that the door
> will automatically open. I have to explicitly take out the key
> (capability) insert it into the lock (pass the capaibility to the
> Trusted Code Base) and use the key before it does any good.

The 'install sys_call_table' capability is such a key. The process
installs a syscall table that doesn't include execve() by default, and
only installs the other one (that includes execve()) before it actually
calls execve(). This means that the process must explicitly open the
lock that it created by itself before a portion of its code can get
authority to use it. If an invader wanted to abuse this authority, it
should take over the code where the lock is open, which is not very
easy:

...
/* program init */
install_sys_call_table( without_execve );

/* this is the dangerous part of the code where the attacker can get in
*/
parse_input_from_user();
...
/* this is the part of the program that needs authority to call execve()
*/
install_sys_call_table( with_execve );
execve( ... );
install_sys_call_table( without_execve );
...

The other way to abuse the program is that the attacker installs the
syscall capability that contains execve() by itself before calling
execve(). But this means that the attacker must have such a capability.
And because it can't just produce one by itself, and because it can't
get one from the system (it can only get a copy of the currently
installed one) the only way to get it is by stealing it from the
attacked process (and to do that it must know exactly where the attacked
process holds it), which complicates things even more.

> This is the argument for why pure capability systems are better, because
> it means that it's much harder to trick a privileged program into doing
> something it shouldn't during its course of routine operations, since
> (for example) it would pass a highly privileged capability to the
> creat() system call when creating a temporary file in /tmp. This
> instantly eliminates entire classes of security holes. It also makes
> the system completely unlike Unix. (And of course, capabilities still
> don't help you you against stack overrun attacks.)
>
> Your scheme of simply throwing away authority is something that you can
> do using the POSIX capaibility system, and in fact you can do it today
> with the current 2.1.x system.
>
> In any case, Alexandar Kjeldaas pointed out (and I completely agree with
> him), system calls are completely the wrong level of granularity for
> capabilities. Execve() is perhaps the only system call where it might
> be interesting, and even there, you might want the ability to exec a
> non-privileged process, but not a privileged one. Throwing away the
> ability to open any file is almost certainly not going to be useful, but
> restricting the ability to bypass the normal permissions checks while
> opening files would be useful.

I wanted to reply to that mail but I decided to wait a bit more because
I didn't think a lot of people would pick at exactly the same thing. It
seems that you both had the impression that I'm trying to solve all
security problems by proposing some 20 lines of code. What I proposed
with the syscall capability was only a tiny little step toward using a
slightly different way of thinking when designing system code. While
it's wrong to think that a single piece of code will solve all of our
security problems, it is true that we can change our lives quite
radically if we change the way we think (that's by William James, Nobel
prize winner for psychology). So, no, I didn't even want to control
which individual files can be accessed because that's not the job for
syscall capabilities but rather for file capabilities.

The reason why I picked system calls as the first target to chew is
because everything that a process does in Linux is through the system
calls. So if you want to strip a process of virtually all authority, you
take away its ability to do system calls. And even though system calls
are the number one doer, a process (and the attacker) can currently
assume that all system calls are available at all time whether the
process needs them or not (if the process doesn't need them, the
attacker can still find some use for them), which is simply too much
authority that can't even be reduced by the process if neccessary,
making things even worse.

As I said, the proposed change is only a beginning and while it's very
small it can give quite a headache to those trying to invade a running
process.

Andrej

--
Andrej Presern, andrejp@luz.fe.uni-lj.si


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

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