l4-hurd
[Top][All Lists]
Advanced

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

Process hierarchies


From: Jonathan S. Shapiro
Subject: Process hierarchies
Date: Tue, 11 Oct 2005 15:51:51 -0400

In many of the past messages, there has been discussion of process
hierarchies and trust hierarchies, and how these two things are closely
related tied in Hurd. This is often a good design, but it is not a
required design, and it is very unfortunate if this type of hierarchy is
the *only* kind of trust that is sustainable. In this note, I want to
talk about process hierarchy. In the next one, I will describe the EROS
constructor mechanism and describe how it creates an opportunity for
other kinds of useful trust relationships. Finally, I will tie these
together by discussing a hypothetical EROS version of an XMMS plugin.

We are accustomed to process hierarchies that result from parent/child
relationships. Most of us learned this idea from UNIX, where it is
strongly embedded. The embedding takes several forms:

        fork+exec forms a child relationship
        wait+exit forms an exist status relationship
        ptrace forms a control relationship
        descriptor inheritance facilitates communication within
          a parent/child hierarchy
        process id return (in fork()) and authority to send
          signals

and so forth. Aside from the implicit descriptor inheritance, which
(from a security perspective) is a bug, process hierarchies are good and
useful things to have. [The issue is that the descriptor inheritance
should require explicit statement of what *is* to be inherited, rather
than explicit statement of what is *not* to be inherited.]

However: there is nothing magical or sacred about process hierarchies,
and many reasons why some or all of the elements of the parent/child
process relationship should not exist in some cases. Let me try to
describe which relationships are essential and which are an artifact of
UNIX policy.

>From the perspective of the child process, it has a *necessary*
dependency on the following things:

        1. It's storage allocator
        2. It's schedule
        3. It's initial program image
        4. The capabilities in its initial operating environment

Any dependency on its creating process results entirely from the fact
that its creating process may have ability to exercise control over one
or more of these. The most obvious example is that the instantiating
process provides the schedule and storage from which the new program is
created.

In EROS, the most common arrangement when a new process is created is
that the instantiating process supplies the schedule, the storage
allocator, and some set of initial argument capabilities. The address
space, and possibly other "initial" capabilities, are supplied by the
constructor. An important property of the design is that the new process
knows which capabilities originated from the constructor and which from
the instantiating process.

In EROS, the mere fact of parenthood does not convey any special rights
regarding communication. There is no requirement that the newly created
process should return *any* capability to the parent that would permit
communication -- this is the overwhelmingly common pattern, but it is
not required.

In EROS, the mere fact of parenthood does not convey the right to
*inspect* the child. The child may allocate pages from a parent-supplied
storage allocator, but this does NOT allow the parent to inspect the
content of those pages. The most the parent can do is to destroy the
space bank (which revokes all of the storage that it has allocated).

In EROS, there is no intrinsic relationship between parent and child
concerning process death. If the child sends a message to the parent,
that is fine. There is no kernel-enforced requirement here. If the
parent exits, but does not destroy the child's storage, then the child
survives.

The new child receives its initial capabilities from two sources: the
parent and the constructor (I still need to explain the constructor).
Either set, of course, can be ignored. It is very common for the
capabilities supplied by the constructor to include verification
capabilities (e.g. the ability to verify that a space bank capability
names an official space bank).

Before creating the new process, the client can ask the constructor
whether the new process will receive any capability from the constructor
that would permit communication to a third process. If the answer is
"yes", the parent is free *not* to create the child. If the answer is
"no", then the parent knows that the initial communication relationships
of the child are fully determined by the initial capabilities that the
parent provides. However, if the parent creates the child, the parent
cannot prevent the child from receiving the capabilities supplied by the
constructor.

In general, the child can tell if it's space bank is an "official" space
bank, but it is NOT able to determine whether the parent has enough
authority to destroy this bank. This allows the child to elect NOT to
disclose information to the parent. On the other hand, the parent can
prevent leakage of information to any third party (by controlling the
initial capabilities).

In EROS, a parent has no intrinsic debugging right on its child. If
debugging is desired, the parent must request authority to debug from
the child. Applications that choose to permit this generally provide
this as part of their protocol.

One consequence of the differences between the EROS model and the POSIX
model is this: the POSIX model can be implemented on the EROS model, but
the native EROS model does not intrinsically carry the same sense of
parent/child hierarchy relationship. The child is much closer to
co-equal with the parent. The hierarchy relationship is attached to the
storage allocators rather than to the parent/child relationship. For
this reason, we do not tend to refer to these processes in EROS as
parent and child. We instead tend to refer to them as "creator" and
"yield".

Because the child has access to verification capabilities, it generally
does NOT need to trust the parent when the parent says "this is an X
capability". It is very common that it *does* trust the parent. When the
child is only going to serve one parent, and the parent lies, the parent
can only hurt itself, so why check? But the *ability* to check is
occasionally very useful. [I need to explain where these verification
capabilities come from.]

If you have the impression that the relationship between parent and
child is pretty minimal, that is exactly correct. The EROS design
applies the "principle of least privilege" rigorously!


shap





reply via email to

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