l4-hurd
[Top][All Lists]
Advanced

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

Re: Part 2: System Structure


From: Bas Wijnen
Subject: Re: Part 2: System Structure
Date: Wed, 17 May 2006 11:32:31 +0200
User-agent: Mutt/1.5.11+cvs20060403

On Tue, May 16, 2006 at 01:14:00PM -0400, Jonathan S. Shapiro wrote:
> My apologies. The last few days have been stressful for reasons that
> have absolutely nothing to do with Hurd or the current discussion.

Although I am often curious what your reply will be, I would advise you in
such situations to delay the reply until you have some more rest, or else only
write a very short note that your reply will be delayed.

> > > EROS does this because 40 years of experience says that the default has
> > > to be opaque or security fails.
> > 
> > That sounds reasonable.  It also sounds incorrect. :-)
> 
> Then I don't think you understand security yet. :-)
> 
> Seriously: it is a long-standing principle of secure and robust design
> that things should default closed and programmers should have to make
> conscious, intentional decisions to open them; never the other way
> around.

Ah, this was higher level than I expected.  I thought this was specifically
about the space bank.

I agree with this principle.  However, I don't think the "transparent space
bank" approach is in conflict with it.

Any important is started directly by the user.  That means that only the
session (TCB) is a parent of it.  The session allows access to programs only
to the user's shell (TCB).  So the "danger" in that case is that if the
session or shell is compromised, the attacker can debug the program.  You know
what?  If the TCB is compromised, you have bigger problems.  So I don't think
it's relevant in that case.

Analogously, when a "real" program (started from the session) starts a
subprogram (a plugin, for example), and the parent gets compromised, the
subprogram is lost anyway.  If the subprogram can reasonably run without the
parent, then it is probably a good idea to not make it a subprogram, but let
the parent ask the session to spawn it, so it gets its own powerbox.  Then it
also is protected from the "parent", because the parent isn't actually a
parent, but a sibling.

In short: a subprogram spawned from a program is under complete control of the
program.  It has nothing to hide.  It is _defined_ by the parent, so the
parent simply defines that it has nothing to hide.  (This is very different
from the government/citizen problem of privacy, because the government doesn't
define the citizen.)  If the parent thinks it's a good idea that the child can
hide things, then it arranges for this by asking its parent (usually the
session) to create a sibling.

There are situations where programs want to hide even from the user's shell.
This can of course be arranged in the session, by giving out sub-space banks
to which the shell is not allowed.  This can for example be used to store
encryption keys.  Yes, the session (and the primary space bank, and the
kernel) can still access that memory.  But we trust that they don't.  That's
why it's called TCB.  If we have a bug in the TCB, and in particular in one of
those parts, which allows an attacker to take control of them, then we're
completely lost.  With an opaque space bank, this part gets limited to only
the kernel, I think.  However, the price is too high.  Consider the following
use case:

Jack is happily running Hurd on his computer.  I gave him a server S for doing
foo, and he has been using it for 3 years already.  Now his computer is doing
strange things.  He doesn't know a lot about computers, so he asks me.  I find
out that S is doing weird things, and I want to debug it.  I specifically
don't want to restart it in "debug mode", because I've tested it many times
and never found any problems.  It might have to do with the fact that it has
been running for 3 years.  So if I restart it, I might need to wait 3 years.
That's not acceptable.  Luckily the Hurd allows the user access to his
resources, so I can directly debug S and (hopefully) find the problem.

Note that in this example, Jack is not a programmer.  So "programmers should
set the default to debuggable" isn't a solution.

> > Ok, this is a technical thing.  I'm assuming that the space bank can
> > provide me a page of memory which I can use.  If it's hard, I'll use a
> > library for it.  No problem.
> 
> It can. The difficulty is that the space bank has no idea how you glue
> together the pieces that it hands you. The situation is similar to
> having a disk driver that will give you back any block that you want.
> You still need to know how the file system is structured to make this
> useful.
> 
> Except that the process relationships are more complicated than the
> relationships of data structures in the file system.

If the constructor can do it, then a library can as well.  I don't see how
complexity can be an argument here.

> > You are assuming that there is a constructor, and you add something to it to
> > make it "simpler".  I am removing the constructor (moving part of its
> > functionality, creating a new process, into a library) and claim that that
> > really makes things simpler.  It removes a step of indirection.  Instead of
> > asking a server (the constructor) to create a process, I can just do it
> > myself.
> 
> This is a VERY bad idea, for reasons that have nothing to do with
> encapsulation or transparency.
> 
... some stuff why shared libraries are bad ...
>
> This has nothing to do with the open/closed/transparent issue. It's a
> simple matter of fault isolation. This is why I have stated my opinion
> that Hurd should use the Constructor pattern for process creation even
> if it does not impose the encapsulation and opaqueness properties.

While I think the problems you described may be solvable, I wasn't actually
thinking about shared libraries.  I was thinking about static libraries.  The
point is that if something requires complex code, that is no reason to move it
into a separate process.  It's a reason to prepare the code in advance and use
it when needed.  One way of "preparing" is to put it in a process of its own.
A library (which can be static) is another way, and it's less complex IMO.

> > > Opaqueness is like virginity. Once you give it up, you can never get it
> > > back. In consequence, if *any* process *ever* requires opaqueness, the
> > > default must be to make storage opaque.
> > 
> > Nonsense.  If a process requires opaqueness, there must be a way to
> > allocate opaque storage.  There's no reason at all that it must be the
> > default.
> 
> The problem with your approach is that it only takes one omission by a
> single programmer to expose a whole lot of stuff.

Not at all.  Consider the constructor-approach: every spawned process will be
a sibling of every other one.  It's a flat structure, really.  Therefore,
using a transparent space bank in that case doesn't change anything, because
the parents (that's the constructors) aren't going to look at the memory
anyway.

The approach I was thinking of is quite close to this.  Except that the
session is the parent of most processes of a user, not the constructor.  And
so the user _can_ look at all his programs.  And that's a very good thing.
There is a very limited class of programs which is not started by the session,
but by programs themselves.  These are all helpers, which do something for
their parent.  For them, it is no problem if the parent can look at them.  If
the parent gets compromised, they become useless (because the type of help
they provide no longer fits with what the parent wants).  If they themselves
get compromised, there is no problem for the parent: the transparency doesn't
work the other way.

> If opaqueness is the default, and you leave out the "make it visible"
> option, your program tends to break very quickly and you notice it.

Not at all.  In my use case above, it took 3 years (which obviously was an
arbitrary "long time").

> If opaqueness is an option and you leave it out, it is very easy to ship the
> program to the field without ever noticing.

There is a big difference between "spawning a program" and "spawning a
helper".  Both have different defaults.  For a helper, transparency is the
default.  For a program, opaqueness (to the instantiator) is.  If you spawn a
program, but accidentily make it a helper, you will very soon find out that
this helper requires a power box.  At which point you will notice your
mistake.  Of course, you can also give it a power box, but in that case you
probably know what you're doing, and it's good as well.  (You're probably
running in a sub-hurd, and your parent is the sub-session.)

> > > This is fundamental. There really *are* programs that need to manage
> > > sensitive state, and you really *don't* want those programs (in most
> > > cases) to have to run off of system-supplied storage.
> > 
> > Actually, I think in most cases we very much do want this.  Maybe even in
> > all cases (but we're still discussing that).
> 
> In order for such a program to be correct, it must be designed in such a
> way that all request messages to this services have payload sizes that
> can be statically sized at IPC compile time.

Not at all.  We can let the user provide any storage we need, except for parts
which must not be disclosed to them.  Obviously a buffer for an IPC transfer
may be disclosed to the user.

> > > The system design that Marcus proposes relies on a process hierarchy
> > > with trusted system processes close to the top. A problem with this
> > > design, which will become apparent to developers after 2-3 years of
> > > coding,
> > 
> > If you see it coming already, then it should be easy for you to find an
> > actual use-case where this problem shows up.  Please share this with us.
> 
> Bas: Marcus has made it clear that he wishes me to diminish my
> participation, and I have a product to deliver. I simply do not have time to
> devote to this activity when it is unlikely that my input will produce any
> value.

I know, and I'm not happy at all with it.  But you sounded like you already
had several examples ready.  If that is the case, I would like you to tell us.
If it costs more time, then I can understand that you don't want to spend that
on it.  But as I said, I'm not happy with that.

> > > is that this design only works in a transparent storage design IF those
> > > servers supply the storage for all of the operations that they perform
> > > (i.e.  they never rely on user-supplied storage).
> > 
> > They shouldn't rely on user-supplied storage for things that they don't
> > want to share with the user.  They can rely on user-supplied storage for
> > all other things, which is a lot.  Actually, the non-sharable part would
> > usually be constant size, I think, so in that case there is no problem.
> 
> It turns out to be surprisingly easy to have an IPC that has a
> dynamically sized element. Anything that passes a string as an argument
> is an example...

But those don't fall in the category "that they don't want to share with the
user".

> > > The problem with this is that there is a "free rider" problem that leads
> > > directly to denial of resource.
> > 
> > It would if the size is not O(0).  Please give an example of a case where
> > it isn't.
> 
> POSIX open(2).

You mean the pathname argument?  I thought you wanted that to have a real
PATH_MAX. :-)  Anyway, it's not something that the user can't know.

> POSIX read(2).

This too, is not something that the user may not see.  Except of course if the
server needs to read on request of the user from a protected file.  But in
that case the server defines the buffer size, so it is O(0).

> > > I am very very concerned about the extremist ideology of transparency
> > > here. This goes ORDERS OF MAGNITUDE beyond what is required by GPL or
> > > FSF.
> > 
> > Does it?  The only new part is that --x permission cannot be given.  That
> > is, x implies r (and r implies x).  I don't think I've ever seen a
> > situation where users were not given read-permission to a binary that they
> > could execute, that was actually useful.  The only reason I know for its
> > use is to make it harder for crackers to find bugs in it.  That is
> > security through obscurity.  It doesn't work.
> 
> This is such complete nonsense that I don't quite know where to begin to
> explain how wrong it is. I will try to respond to this tomorrow, when I
> am not up against a critical deadline.

That's the sort of "note" I meant at the start of this e-mail.  Good boy. ;-)

> > That's not what Marcus' proposal says either.  The only "new" thing
> > (compared to EROS) is that it says "if you want me to run your code, you
> > need to give it to me".
> 
> This also goes FAR beyond GPL.

The GPL is about other things, not about what users within one system do.  The
GPL says things like "If you give me a CD with your program, you must provide
the source code".  This is about users within one system, running each other's
programs.  As I said, if I want you to run my program, I have to give you a CD
with the program on it in normal life.  In this case, it is technically
possible that I don't.  This is not something the GPL talks about.

> > But for us, "I want to run your code, but you don't need to give it to
> > me" is something new.  And we don't see the usefulness of it as
> > automatically as you do.
> 
> Obviously it is not new to the GPL community, because this question
> precisely was a long part of the discussions of GPL3, and the outcome
> was MUCH less strict than the outcome that you are contemplating.

I didn't follow these discussions very closely.  But this question is about
"who pays".  I can't imagine that the GPL discussion was about this, because
it is simply irrelevant on current systems (that is, GNU/Linux).

All you want is totally possible with a transparent space bank.  The only
thing is that the one who wants to keep his program secret has to pay for the
storage.  Ok, and encapsulation isn't guaranteed to the instantiator.

> > The storage is transparent to the user himself, not to the rest of the
> > world.  It is based on the assumption that only users have rights, and
> > programs don't.
> 
> Actually, I think that this statement is a very good summary of the
> essential assumption. I think that this essential assumption is going to
> be a problem, and I will try to explain why tomorrow or the next day.

I look forward to it.

Thanks,
Bas

-- 
I encourage people to send encrypted e-mail (see http://www.gnupg.org).
If you have problems reading my e-mail, use a better reader.
Please send the central message of e-mails as plain text
   in the message body, not as HTML and definitely not as MS Word.
Please do not use the MS Word format for attachments either.
For more information, see http://129.125.47.90/e-mail.html

Attachment: signature.asc
Description: Digital signature


reply via email to

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