[Top][All Lists]
[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
signature.asc
Description: OpenPGP digital signature
- RE: ipc security, Volkmar Uhlig, 2004/10/08
- Re: ipc security, Bas Wijnen, 2004/10/14
- Re: ipc security, Marcus Brinkmann, 2004/10/19
- Re: ipc security,
Bas Wijnen <=
- Re: ipc security, Marcus Brinkmann, 2004/10/21
- Re: ipc security, Bas Wijnen, 2004/10/22
- Re: ipc security, Marcus Brinkmann, 2004/10/22
- Re: ipc security, Bas Wijnen, 2004/10/22
- Re: ipc security, Marcus Brinkmann, 2004/10/22