l4-hurd
[Top][All Lists]
Advanced

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

Re: ipc security


From: Bas Wijnen
Subject: Re: ipc security
Date: Fri, 22 Oct 2004 01:24:34 +0200
User-agent: Mozilla Thunderbird 0.8 (X11/20040926)

Marcus Brinkmann wrote:
At Thu, 14 Oct 2004 16:13:10 +0200,
Bas Wijnen <address@hidden> wrote:
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.

That's new for me, I expected mere mortal threads to not be allowed to mlock() any page at all. In that case, pagers would have to be paged by some meta-pager (which doesn't do anything else than mapping them back if they were unmapped.) Of course they may also choose to have their own pager, but at some point an unswappable pager must handle things. This still seems preferable to me, as there would be a (probably quite small) upper limit on the pager size otherwise. Am I misunderstanding things?

(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).

I was thinking of the server trying to transfer a large string to the client. The client touched all it's receive buffers beforehand, so they are mapped in when the IPC starts. During the transfer, a server-side page fault occurs, and the server gets some of its string buffers from swap. Because of this, other pages need to be swapped out. Under heavy load, that may be the client's receive buffers. Then the client will page fault, aborting the IPC.

Anyway, it wasn't really important for the argument :-)

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.

Does this mean that every task can refuse to be swapped out? I understood that this is currently the case in the Mach-implementation. However, it seems to me like a bad idea. To prevent denial of service attacks, some kind of quota system will be needed, which likely imposes too strict limits in normal situations.

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.

I would include reply-failure, which is very significant, I think (because the memory can be unmapped.) Returning unbound strings may be rare, but if it is needed it should be possible. I have an idea for this, as you can read below.

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.

In my (previous) proposal, the server would only do non-string IPC to the client and the container manager. It would share a container with the container manager. As far as I understood it, writing in a shared container is not a security issue. Is that incorrect? The string transfer would be done between container manager and server, which would have mutual trust. Anyway, I have a new idea now, which is better than this one :-)

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.

Indeed, I realised that as well by now :-)

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.

I can see that for receiving there is no problem in using strings. I don't see why containers would not be useful for huge objects.

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).

I just finished reading it, and it gave me a new idea. Physmem will act as a string transfer server. So instead of doing a string IPC to some process, you do an RPC to physmem which will transfer the string. So physmem, not the kernel, will take care of the copying operation.

For the transferring party, the operation is just about the same, it just uses untyped words instead of string items. Physmem has of course has access to the memory, so no double copying (as in my previous proposal) is involved. Because physmem is a trusted task, it is not a problem that the string may be in the same page as sensitive data (which should not be exposed), because that will not be copied. Also, if page faults occur on the receiver side, that is not a problem, as they are handled by physmem. The server can set an infinite timeout, as physmem is a trusted task.

Receiving is quite a bit different. My idea is that physmem holds a container for this type of string transfers for every task. If the string is larger than the container, extra pages are added. These pages are not mapped to the task until it asks for them. This is to make sure the transfer succeeds. Once the string is in the container, the server knows the data has arrived, and the client can access it by mapping the page (if it wasn't mapped yet.) There probably should be some sort of access control, to prevent malicious tasks to flood containers with garbage, but that can be done as with strings, by just specifying who may send. Also, a limit can be set to the number of allocated pages. That is mostly useful if physmem implements quota for memory usage, I guess.

Anyway, to make things clear, this is what the client can do:
- Tell physmem who is allowed to do string transfers.
- Set limits on how many pages can be allocated automatically.
- Map allocated pages into its address space.
- Declaring the current partly filled page full, so the next transfer will allocate a new page. This makes it easier to map the page into the task's normal memory, without it being overwritten by physmem.

To do a string transfer, the following operations are needed (server to client reply example):
0 - Client RPC request to server.
1 - RPC executes, and wants to return a string.
2 - Server IPC to physmem: copy string to client.
3 - Physmem copies the string, possibly allocating a page for the client. This does not cost much, as physmem is already executing.
4 - Physmem IPC reply to server: Copying successful.
5 - Server RPC reply to client: Success sending string (address, length).

A normal string IPC would only require an IPC of length similar to 2, and the copying operation, without the possibility for memory allocation. In other words: this proposal supports unbounded strings. The difference is two IPC's, 4 and 5, which are both consisting of only a few words (so they will be passed in registers, and very fast.)

How does that sound?

I just read it again, and think it is only a small improvement over normal physmem containers. You said containers are very slow. Where does the overhead come from? Is it in this scheme as well?

Thanks,
Bas

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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