l4-hurd
[Top][All Lists]
Advanced

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

Re: ipc security


From: Marcus Brinkmann
Subject: Re: ipc security
Date: Tue, 19 Oct 2004 21:38:33 +0200
User-agent: Wanderlust/2.10.1 (Watching The Wheels) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/21.3 (i386-pc-linux-gnu) MULE/5.0 (SAKAKI)

At Thu, 14 Oct 2004 16:13:10 +0200,
Bas Wijnen <address@hidden> wrote:
> > Pistachio may slightly vary, though.)  Overall, string IPC can be bound
> > and is specifically there to have a trusted memory transfer.
> 
> That sounds useful (although I agree with Marcus that a local/remote 
> distinction seems more logical than send/receive.)  However, I don't 
> understand the paragraph in the reference manual at all anymore.  I'll 
> quote it:
> 
> <quote>
> Xfer pagefaults happen while the message is being transferred and both 
> sender and receiver are involved.  Therefore, xfer pagefaults are 
> critical from a security perspective: If such a pagefault occurs in the 
> receiver's space, the sender may be starved by a malicious pager.  An 
> xfer pagefault in the sender's space and a malicious sender pager may 
> starve the receiver.  As such, xfer pagefaults are controlled by the 
> minimum of sender's and receiver's xfer timeouts.
> 
> However, xfer pagefaults can only happen when transferring strings. 
> Send messages without strings or receive buffers without receive string 
> buffers are guaranteed not to raise xfer pagefaults.
> </quote>
> 
> So, I now think that the "starving" part can only happen when using 
> infinite xfer timeouts, is that correct?

Right.
 
> Assuming I have now understood how it works, some more thoughts on the 
> Hurd servers:
> 
> Even if xfer timeouts could be set for local and remote, that still 
> doesn't really solve the problem.  As the server will never use a remote 
> timeout other than 0, the client must always have the memory to receive 
> the string in available.  This means it somehow has to make sure it 
> cannot be swapped out.  Touching it just before the IPC does not 
> guarantee that it isn't swapped out before the string is transferred 

Under the premise that you want the IPC to succeed, this is a correct
analysis.  Of course, in the Hurd, tasks will be self-paged and thus
are in total control over their memory.  So they can mlock() the page.
However, this is not strictly true: Except for a small contingent of
pages which you can wire completely, the physical memory server will
be free to unmap arbitrary pages.  So, either we must use the small
protected contingent (which is also used by the pager itself for
example), or accept that page faults may happen.
 
> (especially if pagefaults may happen in the server's space, because it 
> may need to swap some pages in, which of course means others are swapped 
> out.)

I don't understand that.  Above you seem to talk about client's space
page faults only (under the premise we had local vs remote xfer
timeouts as I proposed them).

> So either every server which allows string transfers must always allow 
> "could you repeat that?"-requests, or there must be a way to tell 
> physmem certain pages should not be swapped out.  While having such an 
> option may be useful, extensively using it doesn't sound like a good 
> idea to me (if only because we may want to make it a restricted request.)

Well, first and foremost, we already are self-paged, so usually
mlock() can have a local implementation that doesn't involve physmem.

The only exception is, as I said above, that physmem might temporarily
unmap memory to reorganize the physical memory (for example, to make
space for DMA operations, etc).  In this case, page faults could still
happen, even if we disabled swapping the pages out in our local pager.
(The pager could quickly map the pages again, as they are guaranteed.
But, the IPC would still be aborted).  Again, I want to stress the
distinction between page faults and swapping (page faults can arise
even if no swapping occurs because of this special physmem behaviour).

Still, we need in every task a contingent of pages that must not be
unmapped by physmem, in particular the memory the pager uses to run
on!  This contingent is naturally restricted in some ways (may not be
useful for DMA, may be fragmented, and is limited to a small amount).
But I don't see a problem in going for this solution if you know the
maximum size of the data in advance.

Now about retrying IPCs: Note that this is no problem when the page
fault happens in the send phase.  In the send phase, you can just try
in the client to repeat the IPC as often as necessary to make it
succeed.  The server does not need to keep any state between attempts
(the client can always restart the whole operation, instead just
continuing the data transfer - of course, likelihood of success is
increased by such a continuation, as is the time required to complete
the operation, as we always make progress and never duplicate effort.
But, state in a server with an open receive does not look very
useful to me).

So, the only case that actually is problematic is when returning
_unbound_ string items from the server to the client (you may also
consider non-recoverability from a reply failure a condition, if you
want).  I am not even sure that this is a significant number of cases.
It certainly depends on how we go about defining the interfaces.
Should the number of IDs returned auth be bound to a couple of
thousand, or unbound?  L4 already provides a clear limit for string
items, but it is quite large (4 MB).  Still, we can usually define
much smaller limits for the server and also for the client (in the
receive buffers for the reply).

> I think the best solution is still to use a container from a container 
> manager.  I'll explain again how that would work, because I have the 
> feeling I wasn't clear the previous time.

We do have that, of course, in physmem.  Physmem is trusted by both
parties, and acts as the mediator

Your description has the analog problems of IPC security between the
container manager and the server.  You don't seem to address that.
Physmem on the other hand is trusted by both, the client and the
server, this is why it provides a way out of the problem.

I don't really see a reason to use containers _and_ string items in a
single interface.  If your data has small bounds, using string items
and locked receive buffers (on the client side) is good enough.  If
your data is large or unbound, using containers seems to be the
correct strategy to me.  But then you have some overhead, so you
better make sure that it is worthwhile in the common case.

For sending data, we could also have two interfaces if needed (one
using string items and one using containers).  For receiving data,
this is less useful.

Have you read the paper IPC-Assurance.ps from Shapiro by now?  You
really should.  It includes an analysis of the problems and a solution
for EROS, the trusted buffer objects (TBO).  Physmem containers
provide a comparable feature in our design, although there are some
differences in how we envision the typical use (and of course, we
don't have kernel support for it).

Thanks,
Marcus





reply via email to

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