l4-hurd
[Top][All Lists]
Advanced

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]