l4-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: On trusting its parent process


From: Jonathan S. Shapiro
Subject: Re: On trusting its parent process
Date: Mon, 10 Oct 2005 22:01:27 -0400

[Somehow, my copy of Ludovic's note here was lost or deleted.
Thankfully, it was forwarded to me! This reply will not preserve the
mail server's discussion threading. Also, another long note. Please
accept my apologies.]


Ludovic wrote:

> LSM talks by Shapiro (on EROS and Coyotos) and Forsyth (on Plan 9) were
> quite insightful.  I just found this followup:
> http://www.coyotos.org/pipermail/coyotos-dev/2005-July/000138.html .
> 
> What strikes me in this message is this:
> 
>   1. The *only* way that a process in plan-9 can obtain a capability is
>   from its parent. This is a problem if the capability refers to
> important
>   state and the parent is untrusted. Consider, for example, that the
>   "passwd" program can no longer trust the content of /etc/passwd,
> because
>   it has no way to know if it is receiving an authentic copy of the
> file.
[...]
> Now, what does "authentic" mean in a system designed in such a way that
> most system services can be replaced by the user?  Should programs be
> allowed to rely on a specific implementation of a given service?

In the case of the EROS space bank, the program *must* rely on an
implementation. More generally, any time that your program must make a
guarantee of behavior of any kind, it necessarily relies on the behavior
guarantees of its subprograms and servers. This is an implementation
dependency, not an interface dependency.

The idea that implementation dependencies do not or should not exist is
simply silly. I think that a more useful question is:

  Given that implementation dependencies exist but are
  inconvenient, how can we architect a system that minimizes
  the need for them.

In EROS, I can at least say that in practice these dependencies are very
low level, and they mostly happen on things that are intrinsically
system-wide. I will try to give a complete list in a moment, but here is
an example: ignoring imaginary paper designs, it is hard to imagine a
successful system in which there are competing allocators for
bottom-level disk storage. If nothing else, they would need to
coordinate to avoid stepping on each other.



The problem in original Plan 9 (I am speaking of Plan 9 *before*
factotum, which is really very elegant) is as follows:

  Following UNIX tradition, the 'su' program runs with magic
  privilege. In particular, it has the ability to switch user
  identities.

  The su program relies on being able to open the "official"
  password file in order to verify a password. This is done
  by opening "/etc/passwd".

  However, the user can mount over or replace /etc/passwd.
  In particular, they can replace it with a variant whose UIDs
  are correct but whose password has been altered to something
  the user knows.

  The user can therefore su to anyone at any time.

This is almost as secure as NFS. :-)

>From the perspective of the 'su' program, the difficult is that 'su'
utterly relies on the fact that the password file is authentic. It can
check that the format of the file is good, but it has no way to know if
the file has been replaced entirely. In Plan 9, this is a case where the
*identity* rather than the *interface* matters.

To see how this problem of identity would generalize to code, imagine
replacing the /etc/passwd file with a Hurd server that implements the
file server but internally uses a database. Changing the implementation
from file to code does not alter the fact that there is an "official"
version, that substitution is possible, and that security relies on the
ability to detect forgery here.


In EROS [actually, I am now describing what was implemented in KeyKOS,
but we planned to re-implement it in EROS], we are able to rely on
global persistence and also on the fact that the instantiating (parent)
process is not the only source of capabilities. This allows us to use a
completely different design, and it lets us close the vulnerability by
altering the protocol. The description that I am about to give has been
simplified to remove some complications introduced by the possibility of
multiple sessions.

Since we do not have user ids, there is no program that is comparable to
'su'. I will instead describe what happens for login. Because window
system sessions can be instantiated inside other windows recursively,
there is a vulnerability that is parallel to the Plan 9 vulnerability if
the password file is replaceable. Here is how we eliminate it.

The KeyKOS password database consists of tuples of the form:

  (user-name, encrypted-password, session-restart-capability)

Notice the session-restart-capability. That is the key to the solution.

When the login protocol wishes to authenticate a new user, it already
holds a capability to the password validation subsystem (which contains
the database). The protocol is:

  authenticator->checkPass(user-name, alleged-password) => 
        session-restart-capability | void-capability

If a session restart capability is returned, this is re-attached to the
window system and the windows reappear. The session restart capability
is ONLY returned if the password checks.

The system-level login program holds a capability to the password
authenticator by prior introduction, so there is no way to replace the
authenticator. However, an attacker could basically build a new system
image using a newly created window system (think X-nest), instantiate
and attach a new copy of the login program, but set it up with a
*different* password agent.

This is harmless, however, because if the attacker does not already have
my session restart capability they cannot install it in the new password
agent. And of course, if they *already* have it then there is no need to
attack me.


shap





reply via email to

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