[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
new exec server protocol
From: |
Marcus Brinkmann |
Subject: |
new exec server protocol |
Date: |
Tue, 20 May 2003 20:16:16 +0200 |
User-agent: |
Mutt/1.5.3i |
Hi,
I had a look at the exec server protocol, and it has two main issues:
* The exec server has to deallocate object handles on behalf of the user
Those are handles that are still needed when exec fails, so they can not
be deallocated before calling exec. In Mach this is a kernel operation,
but in L4 it is sending messages to untrusted servers, which is a no-no.
* The exec server keeps some state that it returns to the new task as a
reply in an exec_startup operation. The state includes object handles.
I don't like that at all, as the exec server has to potentially sit on
resources for a long time if the user doesn't make this call.
* The exec server does a couple of other things on behalf of the client.
For example, it looks for an interpreter in the client filesystem ports.
It also uses the clients proc server. All this only if secure mode is
disabled (ie not for suid programs).
So, I was thinking about an alternative interface. I came up with the
following, but I am not sure it is fully secure considering suid apps etc.
This has to be thought over a bit. In particular, I have no satisfying
solution for the third point above. IMO, all calls from exec to untrusted
ports must be prevented. This means for non-secure exec, the client has to
look for the interpreter itself. This means that exec has to return to the
client with a temporary error and the name of the interpreter required.
Then the client has to look up the interpreter and call exec on that. This
is absolutely essential for a robust exec server, but it requires more
cooperation from the user than now.
The exec call accepts the file and task object, the flags and an array of
words. It doesn't interpret the words. Instead, it does approximately
this:
* if the executable is a script, return to the caller and let it know about
the interpreter name [and arguments?], if we are not secure. In secure mode,
look up the interpreter from our root filesystem. [Currently, we would look
up the interpreter on the user's root dir port, which is bad]
* suspend target task
* If secure, deallocate all send rights except this one from the target task
object (this might need to be done later, after trashing the target task)
This will prevent the old task or its buddies from accessing and
controlling the secure application.
* Trash target task (revoke all mappings, kill all threads)
* Load executable image
* Set up the stack for the executable. [Currently, we would just set up the
bootstrap port and let the user send us a exec_startup message and provide
the information that way]
The stack will contain the array of words, and some information only the
exec server can provide (entry point, stack base and size, program header).
Also the flags, so the application knows when it is supposed to be secure.
And the new auth server port for secure apps.
It then registers what needs to be registered with proc (if anything,
didn't figure that out yet) and starts up the task.
Note that the exec server is now out of business and not needed anymore.
This makes the exec call nonblocking for the exec server in all aspects.
* The new task does now read the information on the stack.
The untyped area has of course a standard format, and includes the object
handles the new task should deallocate for the old task (as the PID is the
same, and the servers don't receive any task death notification for an exec,
this will work - and for secure tasks I don't think there is anything bad
that can happen except that the tasks hangs because of unresponsive
servers - and hanging is not a problem as it is only the user denialing
the suid app service himself). The area will also have information about
file descriptors, initial ports, etc. Of course none of this must be
trusted if the app is in secure mode, but that is easy to accomplish (at
least as easy as it is now).
So, instead of the exec server, the new task has to do all the fd and
object handlee frobbing, and port reauthentication, that the exec server
does today. This is much better, because this way the exec server can not
be attacked, and as long as the glibc code to handle this is carefully
written, the worst thing that can happen is that the secure app won't be
able to run at all (as is already the case, because the exec server can hang
doing the user's job). The important thing is to get the exec server out
of the chain.
Furthermore, the old task is responsible for looking up the interpreter.
I think that something like this (there are some steps I left out because
they are the same in the current and the new protocol) is necessary to make
exec robust and will be in line with the Hurd philosophy, as it pushes back
the responsibility of work to the user but also enables higher flexibility
(ie, what data is exchanged over an exec).
There are some issues with suid scripts and the like which require careful
examination how to do it securely. But my intuition tells me that this can
be worked out.
Thanks,
Marcus
--
`Rhubarb is no Egyptian god.' GNU http://www.gnu.org address@hidden
Marcus Brinkmann The Hurd http://www.gnu.org/software/hurd/
address@hidden
http://www.marcus-brinkmann.de/
- new exec server protocol,
Marcus Brinkmann <=
- Re: new exec server protocol, Niels Möller, 2003/05/20
- Re: new exec server protocol, Marcus Brinkmann, 2003/05/20
- Re: new exec server protocol, Niels Möller, 2003/05/20
- Re: new exec server protocol, Marcus Brinkmann, 2003/05/20
- Re: new exec server protocol, Niels Möller, 2003/05/21
- Re: new exec server protocol, Niels Möller, 2003/05/21
- Re: new exec server protocol, Marcus Brinkmann, 2003/05/21
- Re: new exec server protocol, Marcus Brinkmann, 2003/05/21
- Re: new exec server protocol, Niels Möller, 2003/05/21
- Re: new exec server protocol, Marcus Brinkmann, 2003/05/21