/[hurd]/hurd-l4/doc/hurd-on-l4.tex
ViewVC logotype

Diff of /hurd-l4/doc/hurd-on-l4.tex

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by marcus, Thu Aug 28 14:19:43 2003 UTC revision 1.2 by marcus, Sat Aug 30 01:32:52 2003 UTC
# Line 10  Line 10 
10    
11  \begin{document}  \begin{document}
12  \maketitle  \maketitle
13    \newpage
14    \tableofcontents
15    \newpage
16    
17  \section{Introduction}  \section{Introduction}
18    
# Line 125  image and modifies it in the following w Line 127  image and modifies it in the following w
127      architecture of course.  We might want to have a more architecture      architecture of course.  We might want to have a more architecture
128      independent way to pass the information about further modules to      independent way to pass the information about further modules to
129      the rootserver.  We also might want to gather the information      the rootserver.  We also might want to gather the information
130      provided by GRUB in a single page (if it isn't).      provided by GRUB in a single page (if it is not).
131    \end{comment}    \end{comment}
132  \end{itemize}  \end{itemize}
133    
# Line 222  information about other initial tasks an Line 224  information about other initial tasks an
224  initial task in a generalized manner.  initial task in a generalized manner.
225    
226  \begin{comment}  \begin{comment}
227    The exact number and type of initial tasks necessary    The exact number and type of initial tasks necessary to boot the
228    to boot the Hurd are not yet known.  Chances are that this list    Hurd are not yet known.  Chances are that this list includes the
229    includes the task server, the physical memory server, the device    task server, the physical memory server, the device servers, and the
230    servers, and the boot filesystem.    boot filesystem.  The boot filesystem might be a small simple
231      filesystem, which also includes the device drivers needed to access
232      the real root filesystem.
233  \end{comment}  \end{comment}
234    
235    
236  \section{IPC}  \section{Inter-process communication (IPC)}
237    
238  The Hurd requires a capability system.  The current L4 specification  The Hurd requires a capability system.  Capabilities are used to proof
239  supports the notion of a redirector, that can be set for a task by the  your identity to other servers (authentication), and access
240  privileged threads and forces all IPC through a different thread that  server-side implemented objects like devices, files, directories,
241  can then define the policy for IPC.  terminals, and other things.  The server can use a capability for
242    whatever it wants.  Capabilities provide interfaces.  Interfaces can
243    be invoked by sending messages to the capability.  In L4, this means
244    that a message is sent to a thread in the server providing the
245    capability, with the identifier for the capability in the message.
246    
247    Capabilities are protected objects.  Access to a capability needs to
248    be granted by the server.  Once you have a capability, you can copy it
249    to other tasks (if the server permits it, which is usually the case).
250    In the Hurd, access to capabilities is always granted to a whole task,
251    not to individual threads.
252    
253  This adds one addition IPC to each RPC.  Furthermore, it makes  \begin{comment}
254  accounting the cost for managing capabilities difficult.  It also    There is no reason for the server not to permit it, because the
255  keeps the IPC policy in system code which is imposed on the user.    holder of the capability could also just act as a proxy for the
256      intended receiver instead copying the capability to it.  The
257      operation might fail anyway, for example because of resource
258      shortage, in particular if the server puts a quota on the number of
259      capabilities a user can hold.
260    \end{comment}
261    
262  The goal is to define and implement a capability system locally in  Capabilities provide two essential services to the Hurd.  They are
263  each task, and without requiring mutual trust.    used to restrict access to a server function, and they are the
264    standard interface the components in the Hurd use to communicate with
265    each others.  Thus, it is important that their implementation is fast
266    and secure.
267    
268  One difficulty is that in L4, IPC is always from thread to thread.  \begin{comment}
269  Thread identifiers are global and can be reused.  So programs must be    There are several ways to implement such a capability system.  A
270  careful not to send any sensitive data to the wrong thread.    more traditional design would be a global, trusted capability server
271      that provides capabilities to all its users.  The L4 redirector
272      could be used to reroute all client traffic automatically through
273      this server.  This approach has several disadvantages:
274    
275      \begin{itemize}
276      \item It adds a lot of overhead to every single RPC, because all
277        traffic has to be routed through the capability server, which must
278        then perform the authentication on the server's behalf.
279      \item It would be difficult to copy a capability to another task.
280        Either the cap server would have to provide interfaces for clients
281        to do it, or it would be have to know the message format for every
282        interface and do it automatically.
283      \item It would be a single point of failure.  If it had a bug and
284        crashed, the whole system would be affected.
285      \item Users could not avoid it, it would be enforced system code.
286      \item It is inflexible.  It would be hard to replace or extend at
287        run-time.
288      \end{itemize}
289      
290      Another approach is taken by CORBA with IORs.  IORs contain long
291      random numbers which allow the server to identify a user of an
292      object.  This approach is not feasible for the following reasons:
293    
294      \begin{itemize}
295      \item Even good random numbers can be guessed.  Long enough random
296        numbers can reduce the likelihood to arbitrary small numbers,
297        though (below the probability of a hardware failure).
298      \item Good random numbers are in short supply, and is slow to
299        generate.  Good pseudo random is faster, but it is still difficult
300        to generate.  The random number generator would become a critical
301        part of the operating system.
302      \item The random number had to be transfered in every single
303        message.  Because it would have to be long, it would have a
304        significant negative impact on IPC performance.
305      \end{itemize}
306    \end{comment}
307    
308  \subsection{IPC Implementation Roadmap}  The Hurd implements the capability system locally in each task.  A
309    common default implementation will be shared by all programs.
310    However, a malicious untrusted program could do nothing to disturb the
311    communication of other tasks.  A capability will be identified in the
312    client task by a the server thread and a local identifier (which can
313    be different from client to client).  The server thread will receive
314    messages for the capabilities.  The first argument in the message is
315    the capability identifier.  Although every task can get different IDs
316    for the same capability, a well-behaving server will give the same ID
317    to a client which already has a capability and gets the same
318    capability from another client.  So clients can compare capability IDs
319    from the server numerically to check if two capabilities are the same,
320    but only if one of the two IDs is received while the client already
321    had the other one.
322    
323    Because access to a capability must be restricted, the server needs to
324    be careful in only allowing registered and known users to access the
325    capability.  For this, the server must be sure that it can determine
326    the sender of a message.  In L4, this is easy on the surface: The
327    kernel provides the receiving thread with the sender's thread ID,
328    which also contains the task ID in the version field.  However, the
329    server must also know for sure if this task is the same task that it
330    gave access to the capability.  Comparing the task IDs numerically is
331    not good enough, the server must also somehow have knowledge or
332    influence on how task IDs are reused when tasks die and are created.
333    
334    The same is true for the client, of course, which trusts the server
335    and thus must be sure that it is not tricked into trusting on
336    unreliable data from an imposter, or sends sensitive data to it.
337    
338  \subsection{Threads and Tasks}  \begin{comment}
339      The task server wants to reuse thread numbers because that makes
340      best use of kernel memory.  Reusing task IDs, the version field of a
341      thread ID, is not so important, but there are only 14 bits for the
342      version field (and the lower six bits must not be all zero).  So a
343      thread ID is bound to be reused eventually.
344        
345  The Hurd will encode the task ID in the version part of the L4 thread    Using the version field in a thread ID as a generation number is not
346  ID.  The version part can only be changed by the privileged system    good enough, because it is so small.  Even on 64-bit architectures,
347  code, so it is protected by the kernel.  This allows recipients of a    where it is 32 bit long, it can eventually overflow.
348  message to quickly determine the task from the sender's thread ID.  \end{comment}
349    
350  Task IDs will not be reused as long as there are still tasks that  The best way to prevent that a task can be tricked into talking to an
351  might actively communicate with the (now destroyed) task.  Task info  imposter is to have the task server notify the task if the
352  capabilities provided by the task server can be used for that.  The  communication partner dies.  The task server must guarantee that the
353  task info capability will also receive the task death notification (as  task ID is not reused until all tasks that got such a notification
354  a normap capability death notification).  The task server will reuse a  acknowledge that it is processed, and thus no danger of confusion
355  task ID only when all task info capabilities for the task with that ID  exists anymore.
356  have been released.  
357    The task server will provide references to task IDs in form of
358    \emph{task info capabilities}.  If a task has a task info capability
359    for another task, it will prevent that this other task's task ID is
360    reused even if that task dies, and it will also make sure that task
361    death notifications are delivered in that case.
362    
363  This of course can open a DoS attack.  Programs can attempt to acquire  \begin{comment}
364  task info capabilities and never release them.  Several strategies can    Because only the task server can create and destroy tasks, and
365  be applied to compensate that: The task server can automatically time    assign task IDs, there is no need to hold such task info
366  out task info capability references to dead tasks.  The proc server    capabilities for the task server, nor does the task server need to
367  can show dead task IDs with task info capability references as some    hold task info capabilities for its clients.  This avoids the
368  variant of zombie tasks, and provide a way to list all tasks    obvious bootstrap problem in providing capabilities in the task
369  preventing the task ID from being reused, allowing the system    server.  This will even work if the task server is not the real task
370  administrator to identify malicious or faulty users.  Task ID    server, but a proxy task server (see section \ref{proxytaskserver}
371  references can be taken into account in quota restrictions, to    on page \pageref{proxytaskserver}).
372  encourage a user to release them when they are not needed anymore (in  \end{comment}
373  particular, a user holding a task ID reference to a dead task could be  
374  punished with the same costs as for an additional normal task owned by  As task IDs are a global resource, care has to be taken that this
375  the user).  Another idea is to not allow any task to allocate more  approach does not allow for a DoS-attack by exhausting the task ID
376  task info capabilities than there are live tasks in the system, plus  number space.
377  some slack.  This provides a high incentive for tasks to release their  
378  info caps (and if they get an error, they could block until their  \begin{comment}
379  notification system has processed the task death notification and    Several strategies can be taken:
380  released the reference, and try again).  
381      \begin{itemize}
382      \item Task death notifications can be monitored.  If there is no
383        acknowdgement within a certain time period, the task server could
384        be allowed to reuse the task ID anyway.  This is not a good
385        strategy because it can considerably weaken the security of the
386        system (capabilities might be leaked to tasks which reuse such a
387        task ID reclaimed by force).
388      \item The proc server can show dead task IDs which are not released
389        yet, in analogy to the zombie processes in Unix.  It can also make
390        available the list of tasks which prevent reusing the task ID, to
391        allow users or the system administrator to clean up manually.
392      \item Quotas can be used to punish users which do not acknowledge
393        task death timely.  For example, if the number of tasks the user
394        is allowed to create is restricted, the task info caps that the
395        user holds for dead tasks could be counted toward that limit.
396      \item Any task could be restricted to as many task ID references as
397        there are live tasks in the system, plus some slack.  That would
398        prevent the task from creating new task info caps if it does not
399        release old ones from death tasks.  The slack would be provided to
400        not unnecessarily slow down a task that processes task death
401        notifications asynchronously to making connections with new tasks.
402      \end{itemize}
403      
404      In particular the last two approaches should proof to be effective
405      in providing an incentive for tasks to release task info caps they
406      do not need anymore.
407    \end{comment}
408    
409    
410    \subsection{Capabilities}
411    
412    This subsection contains implementation details about capabilities.
413    
414    A server will usually operate on objects, and not capabilities.  In
415    the case of a filesystem, this could be file objects, for example.
416    
417    \begin{comment}
418      In the Hurd, filesystem servers have to keep different objects for
419      each time a file is looked up (or ``opened''), because some state,
420      for example authentication, open flags and record locks, are
421      associated not with the file directly, but with this instance of
422      opening the file.  Such a state structure (``credential'') will also
423      contain a pointer and reference to the actual file node.  For
424      simplicity, we will assume that the capability is associated with a
425      file node directly.
426    \end{comment}
427    
428    To provide access to the object to another task, the server creates a
429    capability, and associates it with the object (by setting a hook
430    variable in the capability).  From this capability, the server can
431    either create send references to itself, or to other tasks.  If the
432    server creates send references for itself, it can use the capability
433    just as it can use capabilities implemented by other servers.  This
434    makes access to locally and remotely implemented capabilities
435    identical.  If you write code to work on capabilities, it can be used
436    for remote objects as well as for local objects.
437    
438    If the server creates a send reference for another task (a client), a
439    new capability ID will be created for this task.  This ID will only be
440    valid for this task, and should be returned to the client.
441    
442    The client itself will create a capability object from this capability
443    ID.  The capability will also contain information about the server,
444    for example the server thread which should be used for sending
445    messages to the capability.
446    
447    If the client wants to send a message, it will send it to the provided
448    server thread, and use the capability ID it got from the server as the
449    first argument in the RPC.  The server receives the message, and now
450    has to look up the capability ID in the list of capabilties for this
451    task.
452    
453    \begin{comment}
454      The server knows the task ID from the version field of the sender's
455      thread ID.  It can look up the list of capabilities for this task in
456      a hash table.  The capability ID can be an index into an array, so
457      the server only needs to perform a range check.  This allows to
458      verify quickly that the user is allowed to access the object.
459      
460      This is not enough if several systems run in parallel on the same
461      host.  Then the version ID for the threads in the other systems will
462      not be under the control of the Hurd's task server, and can thus not
463      be trusted.  The server can still use the version field to find out
464      the task ID, which will be correct \emph{if the thread is part of
465        the same subsystem}.  It also has to verify that the thread
466      belongs to this subsystem.  Hopefully the subsystem will be encoded
467      in the thread ID.  Otherwise, the task server has to be consulted
468      (and, assuming that thread numbers are not shared by the different
469      systems, the result can be cached).
470    \end{comment}
471    
472    The server reads out the capability associated with the capability ID,
473    and invokes the server stub according to the message ID field in the
474    message.
475    
476    After the message is processed, the server sends it reply to the
477    sender thread with a zero timeout.
478    
479    \begin{comment}
480      Servers must never block on sending messages to clients.  Even a
481      small timeout can be used for DoS-attacks.  The client can always
482      make sure that it receives the reply by using a combined send and
483      receive operation together with an infinite timeout.
484    \end{comment}
485    
486    The above scheme assumes that the server and the client already have
487    task info caps for the respective other task.  This is the normal
488    case, because acquiring these task info caps is part of the protocol
489    that is used when a capability is copied from one task to another.
490    
491    
492    \subsubsection{Bootstrapping a client-server connection}
493    
494    If the client and the server do not know about each other yet, then
495    they can bootstrap a connection without support from any other task
496    except the task server.  The purpose of the initial handshake is to
497    give both participants a chance to acquire a task info cap for the
498    other participants task ID, so they can be sure that from there on
499    they will always talk to the same task as they talked to before.
500    
501    \paragraph{Preconditions}
502    The client knows the thread ID of the server thread that receives and
503    processes the bootstrap messages.  Some other task might hold a task
504    info capability to the server the client wants to connect to.
505    
506    \begin{comment}
507      If no such other tasks exists, the protocol will still work.
508      However, the client might not get a connection to the server that
509      run at the time the client started the protocol, but rather to the
510      server that run at the time the client acquired the task info cap
511      for the server's task ID (after step 1 below).
512    
513      This is similar to how sending signals works in Unix: Technically,
514      at the time you write \texttt{kill 203}, and press enter, you do not
515      know if the process with the PID 203 you thought of will receive the
516      signal, or some other process that got the PID in the time between
517      you getting the information about the PID and writing the
518      \texttt{kill}-command.
519    \end{comment}
520    
521    FIXME: Here should be the pseudo code for the protocol.  For now, you
522    have to take it out of the long version.
523    
524    \begin{enumerate}
525      
526    \item The client acquires a task info capability for the server's task
527      ID, either directly from the task server, or from another task in a
528      capability copy.  From that point on, the client can be sure to
529      always talk to the same task when talking to the server.
530      
531      Of course, if the client already has a task info cap for the server
532      it does not need to do anything in this step.
533    
534    \begin{comment}
535      As explained above, if the client does not have any other task
536      holding the task info cap already, it has no secure information
537      about what this task is for which it got a task info cap.
538    \end{comment}
539    
540    \item The client sends a message to the server, requesting the initial
541      handshake.
542      
543    \item The server receives the message, and acquires a task info cap
544      for the client task (directly from the task server).
545      
546      Of course, if the server already has a task info cap for the client
547      it does not need to do anything in this step.
548    
549    \begin{comment}
550      At this point, the server knows that future messages from this task
551      will come from the same task as it got the task info cap for.
552      However, it does not know that this is the same task that sent the
553      initial handshake request in step 2 above.  This shows that there is
554      no sense in verifying the task ID or perform any other
555      authentication before acquiring the task info cap.
556    \end{comment}
557    
558    \item The server replies to the initial handshake request with an
559      empty reply message.
560    
561    \begin{comment}
562      Because the reply now can go to a different task than the request
563      came from, sending the reply might fail.  It might also succeed and
564      be accepted by the task that replaced the requestor.  Or it might
565      succeed normally.  The important thing is that it does not matter to
566      the server at all.  It would have provided the same ``service'' to
567      the ``imposter'' of the client, if he had bothered to do the
568      request.  As no authentication is done yet, there is no point for
569      the server to bother.
570      
571      This means however, that the server needs to be careful in not
572      consuming too many resources for this service.  However, this is
573      easy to achieve.  Only one task info cap per client task will ever
574      be held in the server.  The server can either keep it around until
575      the task dies (and a task death notification is received), or it can
576      clean it up after some timeout if the client does not follow up and
577      do some real authentication.
578    \end{comment}
579    
580    \item The client receives the reply message to its initial handshake
581      request.
582      
583    \item The client sends a request to create its initial capability.
584      How this request looks depends on the type of the server and the
585      initial capabilities it provides.  Here are some examples:
586    
587      \begin{itemize}
588      \item A filesystem might provide an unauthenticated root directory
589        object in return of the underlying node capability, which is
590        provided by the parent filesystem and proves to the filesystem
591        that the user was allowed to look up the root node of this
592        filesystem (see section \ref{xfslookup} on page
593        \pageref{xfslookup}).
594    
595        \begin{comment}
596          In this example, the parent filesystem will either provide the
597          task info cap for the child filesystem to the user, or it will
598          hold the task info cap while the user is creating their own
599          (which the user has to verify by repeating the lookup, though).
600          Again, see section \ref{xfslookup} on page \pageref{xfslookup}.
601          
602          The unauthenticated root directory object will then have the be
603          authenticated using the normal reauthentication mechanism (see
604          section \ref{auth} on pageref{auth}).  This can also be combined
605          in a single RPC.
606        \end{comment}
607        
608      \item Every process acts as a server that implements the signal
609        capability for this process.  Tasks who want to send a signal to
610        another task can perform the above handshake, and then provide
611        some type of authentication capability that indicates that they
612        are allowed to send a signal.  Different authentication
613        capabilities can be accepted by the signalled task for different
614        types of signals.
615    
616        \begin{comment}
617          The Hurd used to store the signal capability in the proc server,
618          where authorized tasks could look it up.  This is no longer
619          possible because a server can not accept capabilities
620          implemented by untrusted tasks, see below.
621        \end{comment}
622      \end{itemize}
623      
624    \item The server replies with whatever capability the client
625      requested, provided that the client could provide the necessary
626      authentication capabilities, if any.
627    
628      \begin{comment}
629        It is not required that the server performs any authentication at
630        all, but it is recommended, and all Hurd servers will do so.
631        
632        In particular, the server should normally only allow access from
633        tasks running in the same system, if running multiple systems on
634        the same host is possible.
635      \end{comment}
636    \end{enumerate}
637    
638    \paragraph{Result}
639    The client has a task info capability for the server and an
640    authenticated capability.  The server has a task info capability for
641    the client and seen some sort of authentication for the capability it
642    gave to the client.
643    
644    \begin{comment}
645      If you think that the above protocol is complex, you have seen
646      nothing yet!  Read on.
647    \end{comment}
648    
649    
650    \subsubsection{Returning a capability from a server to a client}
651    
652    Before we go on to the more complex case of copying a capability from
653    one client to another, let us point out that once a client has a
654    capability from a server, it is easy for the server to return more
655    capabilities it implements to the client.
656    
657    The server just needs to create the capability, acquire a capability
658    ID in the client's cap ID space, and return the information in the
659    reply RPC.
660    
661    FIXME: Here should be the pseudo code for the protocol.  For now, you
662    have to take it out of the long version.
663    
664    \begin{comment}
665      The main point of this section is to point out that only one task
666      info capability is required to protect all capabilities provided to
667      a single task.  The protocols described here always assume that no
668      task info caps are held by anyone (except those mentioned in the
669      preconditions).  In reality, sometimes the required task info caps
670      will already be held.
671    \end{comment}
672    
673    
674    \subsubsection{Copying a capability from one client to another task}
675    
676    The most complex operation in managing capabilities is to copy or move
677    a capability from the client to another task, which subsequently
678    becomes a client of the server providing the capability.  The
679    difficulty here lies in the fact that the protocol should be fast, but
680    also robust and secure.  If any of the participants dies unexpectedly,
681    or any of the untrusted participants is malicious, the others should
682    not be harmed.
683    
684    \paragraph{Preconditions}
685    The client $C$ has a capability from server $S$ (this implies that $C$
686    has a task info cap for $S$ and $S$ has a task info cap for $C$).  It
687    wants to copy the capability to the destination task $D$.  For this,
688    it will have to make RPCs to $D$, so $C$ has also a capability from
689    $D$ (this implies that $C$ has a task info cap for $D$ and $D$ has a
690    task info cap for $C$).  Of course, the client $C$ trusts its servers
691    $S$ and $D$.  $D$ might trust $S$ or not, and thus accept or reject
692    the capability that $C$ wants to give to $D$.  $S$ does not trust
693    either $C$ or $D$.
694      
695    The task server is also involved, because it provides the task info
696    capabilities.  Everyone trusts the task server they use.  This does
697    not need to be the same one for every participant.
698    
699    FIXME: Here should be the pseudo code for the protocol.  For now, you
700    have to take it out of the long version.
701    
702    \begin{enumerate}
703    \item The client invokes the \verb/cap_ref_cont_create/ RPC on the
704      capability, providing the task ID of the intended receiver $D$ of
705      the capability.
706      
707    \item The server receives the \verb/cap_ref_cont_create/ RPC from the
708      client.  It requests a task info cap for $D$ from its trusted task
709      server, under the constraint that $C$ is still living.
710    
711      \begin{comment}
712        A task can provide a constraint when creating a task info cap in
713        the task server.  The constraint is a task ID.  The task server
714        will only create the task info cap and return it if the task with
715        the constraint task ID is not destroyed.  This allows for a task
716        requesting a task info capability to make sure that another task,
717        which also holds this task info cap, is not destroyed.  This is
718        important, because if a task is destroyed, all the task info caps
719        it held are released.
720    
721        In this case, the server relies on the client to hold a task info
722        cap for $D$ until it established its own.  See below for what can
723        go wrong if the server would not provide a constraint and both,
724        the client and the destination task would die unexpectedly.
725      \end{comment}
726      
727      Now that the server established its own task info cap for $D$, it
728      creates a reference container for $D$, that has the following
729      properties:
730    
731      \begin{itemize}
732      \item The reference container has a single new reference for the
733        capability.
734        
735      \item The reference container has an ID that is unique among all
736        reference container IDs for the client $C$.
737        
738      \item The reference container is associated with the client $C$.  If
739        $C$ dies, and the server processes the task death notification for
740        it, the server will destroy the reference container and release
741        the capability reference it has (if any).  All resources
742        associated with the reference container will be released.  If this
743        reference container was the only reason for $S$ to hold the task
744        info cap for $D$, the server will also release the task info cap
745        for $D$.
746        
747      \item The reference container is also associated with the
748        destination task $D$.  If $D$ dies, and the server processes the
749        task death notification for it, the server will release the
750        capability reference that is in the reference container (if any).
751        It will not destroy the part of the container that is associated
752        with $C$.
753      \end{itemize}
754    
755      The server returns the reference container ID $R$ to the client.
756    
757    \item The client receives the reference container ID $R$.
758    
759      \begin{comment}
760        If several capabilities have to be copied in one message, the
761        above steps need to be repeated for each capability.  With
762        appropriate interfaces, capabilities could be collected so that
763        only one call per server has to be made.  We are assuming here
764        that only one capability is copied.
765      \end{comment}
766    
767    \item The client sends the server thread ID $T$ and the reference
768      container ID $R$ to the destination task $D$.
769      
770    \item The destination task $D$ receives the server thread ID $T$ and
771      the reference container ID $R$ from $C$.
772      
773      It now inspects the server thread ID $T$, and in particular the task
774      ID component of it.  $D$ has to make the decision if it trusts this
775      task to be a server for it, or if it does not trust this task.
776      
777      If $D$ trusts $C$, it might decide to always trust $T$, too,
778      irregardless of what task contains $T$.
779      
780      If $D$ does not trust $C$, it might be more picky about the task
781      that contains $T$.  This is because $D$ will have to become a client
782      of $T$, so it will trust it.  For example, it will block on messages
783      it sends to $T$.
784    
785      \begin{comment}
786        If $D$ is a server, it will usually only accept capabilities from
787        its client that are provided by specific other servers it trusts.
788        This can be the authentication server, for example (see section
789        \ref{auth} on page \pageref{auth}).
790        
791        Usually, the type of capability that $D$ wants to accept from $C$
792        is then further restricted, and only one possible trusted server
793        implements that type of capabilities.  Thus, $D$ can simply
794        compare the task ID of $T$ with the task ID of its trusted server
795        (authentication server, ...) to make the decision if it wants to
796        accept the capability or not.
797      \end{comment}
798      
799      If $D$ does not trust $T$, it replies to $C$ (probably with an error
800      value indicating why the capability was not accepted).  In that
801      case, jump to step 8.
802      
803      Otherwise, it requests a task info cap for $S$ from its trusted task
804      server, under the constraint that $C$ is still living.
805      
806      Then $D$ sends a \verb/cap_ref_cont_accept/ RPC to the server $S$,
807      providing the task ID of the client $C$ and the reference container
808      ID $R$.
809    
810    \begin{comment}
811      \verb/cap_ref_cont_accept/ is one of the few interfaces that is not
812      sent to a (real) capability, of course.  Nevertheless, it is part of
813      the capability object interface, hence the name.  You can think of
814      it as a static member in the capability class, that does not require
815      an instance of the class.
816    \end{comment}
817      
818    \item The server receives the \verb/cap_ref_cont_accept/ RPC from the
819      destination task $D$.  It verifies that a reference container exists
820      with the ID $R$, that is associated with $D$ and $C$.
821      
822      \begin{comment}
823        The server will store the reference container in data structures
824        associated with $C$, under an ID that is unique but local to $C$.
825        So $D$ needs to provide both information, the task ID and the
826        reference container ID of $C$.
827      \end{comment}
828    
829      If that is the case, it takes the reference from the reference
830      container, and creates a capability ID for $D$ from it.  The
831      capability ID for $D$ is returned in the reply message.
832      
833      From that moment on, the reference container is deassociated from
834      $D$.  It is still associated with $C$, but it does not contain any
835      reference for the capability.
836    
837      \begin{comment}
838        It is not deassociated from $C$ and removed completely, so that
839        its ID $R$ (or at least the part of it that is used for $C$) is
840        not reused.  $C$ must explicitely destroy the reference container
841        anyway because $D$ might die unexpectedly or return an error that
842        gives no indication if it accepted the reference or not.
843      \end{comment}
844      
845    \item The destination task $D$ receives the capability ID and enters
846      it into its capability system.  It sends a reply message to $C$.
847    
848      \begin{comment}
849        If the only purpose of the RPC was to copy the capability, the
850        reply message can be empty.  Usually, capabilities will be
851        transfered as part of a larger operation, though, and more work
852        will be done by $D$ before returning to $C$.
853      \end{comment}
854      
855    \item The client $C$ receives the reply from $D$.  Irregardless if it
856      indicated failure or success, it will now send the
857      \verb/cap_ref_cont_destroy/ message to the server $S$, providing the
858      reference container $R$.
859    
860      \begin{comment}
861        This message can be a simple message.  It does not require a reply
862        from the server.
863      \end{comment}
864      
865    \item The server receives the \verb/cap_ref_cont_destroy/ message and
866      removes the reference container $R$.  The reference container is
867      deassociated from $C$ and $D$.  If this was the only reason that $S$
868      held a task info cap for $D$, this task info cap is also released.
869    
870      \begin{comment}
871        Because the reference container can not be deassociated from $C$
872        by any other means than this interface, the client does not need
873        to provide $D$.  $R$ can not be reused without the client $C$
874        having it destroyed first.  This is different from the
875        \verb/cap_ref_cont_accept/ call made by $D$, see above.
876      \end{comment}
877    
878    \end{enumerate}
879    
880    \paragraph{Result}
881    For the client $C$, nothing has changed.  The destination task $D$
882    either did not accept the capability, and nothing has changed for it,
883    and also not for the server $S$.  Or $D$ accepted the capability, and
884    it now has a task info cap for $S$ and a reference to the capability
885    provided by $S$.  In this case, the server $S$ has a task info cap for
886    $D$ and provides a capability ID for this task.
887    
888    The above protocol is for copying a capability from $C$ to $D$.  If
889    the goal was to move the capability, then $C$ can now release its
890    reference to it.
891    
892    \begin{comment}
893      Originally we considered to move capabilities by default, and
894      require the client to acquire an additional reference if it wanted
895      to copy it instead.  However, it turned out that for the
896      implementation, copying is easier to handle.  One reason is that the
897      client usually will use local reference counting for the
898      capabilities it holds, and with local reference counting, one
899      server-side reference is shared by many local references.  In that
900      case, you would need to acquire a new server-side reference even if
901      you want to move the capability.  The other reason is cancellation.
902      If an RPC is cancelled, and you want to back out of it, you need to
903      restore the original situation.  And that is easier if you do not
904      change the original situation in the first place until the natural
905      ``point of no return''.
906    \end{comment}
907    
908    The above protocol quite obviously achieves the result as described in
909    the above concluding paragraph.  However, many other, and often
910    simpler, protocols would also do that.  The other protocols we looked
911    at are not secure or robust though, or require more operations.  To
912    date we think that the above is the shortest (in particular in number
913    of IPC operations) protocol that is also secure and robust (and if it
914    is not we think it can be fixed to be secure and robust with minimal
915    changes).  We have no proof for its correctness.  Our confidence comes
916    from the scrutiny we applied to it.  If you find a problem with the
917    above protocol, or if you can prove various aspects of it, we would
918    like to hear about it.
919    
920    To understand why the protocol is laid out as it is, and why it is a
921    secure and robust protocol, one has to understand what could possibly
922    go wrong and why it does not cause any problems for any participant if
923    it follows its part of the protocol (independent on what the other
924    participants do).  In the following paragraphs, various scenarios are
925    suggested where things do not go as expected in the above protocol.
926    This is probably not a complete list, but it should come close to it.
927    If you find any other problematic scenario, again, let us know.
928    
929    \begin{comment}
930      Although some comments like this appear in the protocol description
931      above, many comments have been spared for the following analysis of
932      potential problems.  Read the analysis carefully, as it provides
933      important information about how, and more importantly, why it works.
934    \end{comment}
935    
936    \paragraph{The server $S$ dies}
937    What happens if the server S dies unexpectedly sometime throughout the
938    protocol?
939    
940    \begin{comment}
941      At any time a task dies, the task info caps it held are released.
942      Also, task death notifications are sent to any task that holds task
943      info caps to the now dead task.  The task death notifications will
944      be processed asynchrnouly, so they might be processed immediately,
945      or at any later time, even much later after the task died!  So one
946      important thing to keep in mind is that the release of task info
947      caps a task held, and other tasks noticing the task death, are
948      always some time apart.
949    \end{comment}
950    
951    Because the client $C$ holds a task info cap for $S$ no imposter can
952    get the task ID of $S$.  $C$ and $D$ will get errors when trying to
953    send messages to $S$.
954    
955    \begin{comment}
956      You might now wonder what happens if $C$ also dies, or if $C$ is
957      malicious and does not hold the task info cap.  You can use this as
958      an exercise, and try to find the answer on your own.  The answers
959      are below.
960    \end{comment}
961    
962    Eventually, $C$ (and $D$ if it already got the task info cap for $S$)
963    will process the task death notification and clean up their state.
964    
965    \paragraph{The client $C$ dies}
966    The server $S$ and the destination task $D$ hold a task info cap for
967    $C$, so no imposter can get its task ID.  $S$ and $D$ will get errors
968    when trying to send messages to $C$.  Depending on when $C$ dies, the
969    capability might be copied successfully or not at all.
970    
971    Eventually, $S$ and $D$ will process the task death notification and
972    release all resources associated with $C$.  If the reference was not
973    yet copied, this will include the reference container associated with
974    $C$, if any.  If the reference was already copied, this will only
975    include the empty reference container, if any.
976    
977    \begin{comment}
978      Of course, the participants need to use internal locking to protect
979      the integrity of their internal data structures.  The above protocol
980      does not show where locks are required.  In the few cases where some
981      actions must be performed atomically, a wording is used that
982      suggests that.
983    \end{comment}
984    
985    \paragraph{The destination task $D$ dies}
986    
987    The client $C$ holds a task info cap for $D$ over the whole operation,
988    so no imposter can get its task ID.  Depending on when $D$ dies, it
989    has either not yet accepted the capability, then $C$ will clean up by
990    destroying the reference container, or it has, and then $S$ will clean
991    up its state when it processes the task death notification for $D$.
992    
993    \paragraph{The client $C$ and the destination task $D$ die}
994    
995    This scenario is the reason why the server acquires its own task info
996    cap for $D$ so early, and why it must do that under the constraint
997    that $C$ still lives.  If $C$ and $D$ die before the server created
998    the reference container, then either no request was made, or creating
999    the task info cap for $D$ fails because of the constraint.  If $C$ and
1000    $D$ die afterwards, then no imposter can get the task ID of $D$ and
1001    try to get at the reference in the container, because the server has
1002    its own task info cap for $D$.
1003    
1004    \begin{comment}
1005      This problem was identified very late in the development of this
1006      protocol.  We just did not think of both clients dieing at the same
1007      time!  In an earlier version of the protocol, the server would
1008      acquire its task info cap when $D$ accepts its reference.  This is
1009      too late: If $C$ and $D$ die just before that, an imposter with
1010      $D$'s task ID can try to get the reference in the container before
1011      the server processes the task death notification for $C$ and
1012      destroys it.
1013    \end{comment}
1014    
1015    Eventually, the server will receive and process the task death
1016    notifications.  If it processes the task death notification for $C$
1017    first, it will destroy the whole container immediately, including the
1018    reference, if any.  If it processes the task death notification for
1019    $D$ first, it will destroy the reference, and leave behind the empty
1020    container associated with $C$, until the other task death notification
1021    is processed.  Either way no imposter can get at the capability.
1022    
1023    Of course, if the capability was already copied at the time $C$ and
1024    $D$ die, the server will just do the normal cleanup.
1025    
1026    \paragraph{The client $C$ and the server $S$ die}
1027    
1028    This scenario does not cause any problems, because on the one hand,
1029    the destination task $D$ holds a task info cap for $C$, and it
1030    acquires its own task info cap for $S$.  Although it does this quite
1031    late in the protocol, it does so under the constraint that $C$ still
1032    lives, which has a task info cap for $S$ for the whole time (until it
1033    dies).  It also gets the task info cap for $S$ before sending any
1034    message to it.  An imposter with the task ID of $S$, which it was
1035    possible to get because $C$ died early, would not receive any message
1036    from $D$ because $D$ uses $C$ as its constraint in acquireing the task
1037    info cap for $S$.
1038    
1039    \paragraph{The destination task $D$ and the server $S$ die}
1040    
1041    As $C$ holds task info caps for $S$ and $D$, there is nothing that can
1042    go wrong here.  Eventually, the task death notifications are
1043    processed, but the task info caps are not released until the protocol
1044    is completed or aborted because of errors.
1045    
1046    \paragraph{The client $C$, the destination task $D$ and the server $S$ die}
1047    
1048    Before the last one of these dies, you are in one of the scenarios
1049    which already have been covered.  After the last one dies, there is
1050    nothing to take care of anymore.
1051    
1052    \begin{comment}
1053      In this case your problem is probably not the capability copy
1054      protocol, but the stability of your software!  Go fix some bugs.
1055    \end{comment}
1056    
1057    So far the scenarios where one or more of the participating tasks die
1058    unexpectedly.  They could also die purposefully.  Other things that
1059    tasks can try to do purposefully to break the protocol are presented
1060    in the following paragraphs.
1061    
1062    \begin{comment}
1063      A task that tries to harm other tasks by not following a protocol
1064      and behaving as other tasks might expect it is malicious.  Beside
1065      security concerns, this is also an issue of robustness, because
1066      malicious behaviour can also be triggered by bugs rather than bad
1067      intentions.
1068      
1069      It is difficult to protect against malicious behaviour by trusted
1070      components, like the server $S$, which is trusted by both $C$ and
1071      $D$.  If a trusted component is compromised or buggy, ill
1072      consequences for software that trusts it must be expected.  Thus, no
1073      analysis is provided for scenarious involving a malicious or buggy
1074      server $S$.
1075    \end{comment}
1076    
1077    \paragraph{The client $C$ is malicious}
1078    
1079    If the client $C$ wants to break the protocol, it has numerous
1080    possibilities to do so.  The first thing it can do is to provide a
1081    wrong destination task ID when creating the container.  But in this
1082    case, the server will return an error to $D$ when it tries to accept
1083    it, and this will give $D$ a chance to notice the problem and clean
1084    up.  This also would allow for some other task to receive the
1085    container, but the client can give the capability to any other task it
1086    wants to anyway, so this is not a problem.
1087    
1088    \begin{comment}
1089      If a malicious behaviour results in an outcome that can also be
1090      achieved following the normal protocol with different parameters,
1091      then this not a problem at all.
1092    \end{comment}
1093    
1094    The client could also try to create a reference container for $D$ and
1095    then not tell $D$ about it.  However, a reference container should not
1096    consume a lot of resources in the server, and all such resources
1097    should be attributed to $C$.  When $C$ dies eventually, the server
1098    will clean up any such pending containers when the task death
1099    notification is processed.
1100    
1101    The same argument holds when $C$ leaves out the call to
1102    \verb/cap_ref_cont_destroy/.
1103    
1104    The client $C$ could also provide wrong information to $D$.  It could
1105    supply a wrong server thread ID $T$.  It could supply a wrong
1106    reference container ID $R$.  If $D$ does not trust $C$ and expects a
1107    capability implemented by some specific trusted server, it will verify
1108    the thread ID numerically and reject it if it does not match.  The
1109    reference container ID will be verified by the server, and it will
1110    only be accepted if the reference container was created by the client
1111    task $C$.  Thus, the only wrong reference container IDs that the
1112    client $C$ could use to not provoke an error message from the server
1113    (which then lead $D$ to abort the operation) would be a reference
1114    container that it created itself in the first place.  However, $C$
1115    already is frree to send $D$ any reference container it created.
1116    
1117    \begin{comment}
1118      Again $C$ can not achieve anything it could not achieve by just
1119      following the protocol as well.  If $C$ tries to use the same
1120      reference container with several RPCs in $D$, one of them would
1121      succeed and the others would fail, hurting only $C$.
1122      
1123      If $D$ does trust $C$, then it can not protect against malicious
1124      behaviour by $C$.
1125    \end{comment}
1126    
1127    To summarize the result so far: $C$ can provide wrong data in the
1128    operations it does, but it can not achieve anything this way that it
1129    could not achieve by just following the protocol.  In most cases the
1130    operation would just fail.  If it leaves out some operations, trying
1131    to provoke resource leaks in the server, it will only hurt itself (as
1132    the reference container is strictly associated with $C$ until the
1133    reference is accepted by $D$).
1134    
1135    \begin{comment}
1136      For optimum performance, the server should be able to keep the
1137      information about the capabilities and reference containers a client
1138      holds on memory that is allocated on the clients behalf.
1139      
1140      It might also use some type of quota system.
1141    \end{comment}
1142    
1143    Another attack that $C$ can attempt is to deny a service that $S$ and
1144    $D$ are expecting of it.  Beside not doing one or more of the RPCs,
1145    this is in particular holding the task info caps for the time span as
1146    described in the protocol.  Of course, this can only be potentially
1147    dangerous in combination with a task death.  If $C$ does not hold the
1148    server task info capability, then an imposter of $S$ could trick $D$
1149    into using the imposter as the server.  However, this is only possible
1150    if $D$ already trusts $C$.  Otherwise it would only allow servers that
1151    it already trusts, and it would always hold task info caps to such
1152    trusted servers when making the decision that it trusts them.
1153    However, if $D$ trusts $C$, it can not protect against $C$ being
1154    malicious.
1155    
1156    \begin{comment}
1157      If $D$ does not trust $C$, it should only ever compare the task ID
1158      of the server thread against trusted servers it has a task info cap
1159      for.  It must not rely on $C$ doing that for $D$.
1160      
1161      However, if $D$ does trust $C$, it can rely on $C$ holding the
1162      server task info cap until it got its own.  Thus, the task ID of $C$
1163      can be used as the constraint when acquiring the task info cap in
1164      the protocol.
1165    \end{comment}
1166    
1167    If $C$ does not hold the task info cap of $D$, and $D$ dies before the
1168    server acquires its task info cap for $D$, it might get a task info
1169    cap for an imposter of $D$.  But if the client wants to achieve that,
1170    it could just follow the protocol with the imposter as the destination
1171    task.
1172    
1173    \paragraph{The destination task $D$ is malicious}
1174    
1175    The destination task has not as many possibilities as $C$ to attack
1176    the protocol.  This is because it is trusted by $C$.  So the only
1177    participant that $D$ can try to attack is the server $S$.  But the
1178    server $S$ does not rely on any action by $D$.  $D$ does not hold any
1179    task info caps for $S$.  The only operation it does is an RPC to $S$
1180    accepting the capability, and if it omits that it will just not get
1181    the capability (the reference will be cleaned up by $C$ or by the
1182    server when $C$ dies).
1183    
1184    The only thing that $D$ could try is to provide false information in
1185    the \verb/cap_ref_cont_accept/ RPC.  The information in that RPC is
1186    the task ID of the client $C$ and the reference container ID $R$.  The
1187    server will verify that the client $C$ has previously created a
1188    reference container with the ID $R$ that is destined for $D$.  So $D$
1189    will only be able to accept references that it is granted access to.
1190    So it can not achieve anything that it could not achieve by following
1191    the protocol (possibly the protocol with another client).  If $D$
1192    accepts capabilities from other transactions outside of the protocol,
1193    it can only cause other transactions in its own task to fail.
1194    
1195    \begin{comment}
1196      If you can do something wrong and harm yourself that way, then this
1197      is called ``shooting yourself in your foot''.
1198      
1199      The destination task $D$ is welcome to shoot itself in its foot.
1200    \end{comment}
1201    
1202    \paragraph{The client $C$ and the destination task $D$ are malicious}
1203    
1204    The final question we want to raise is what can happen if the client
1205    $C$ and the destination task $D$ are malicious.  Can $C$ and $D$
1206    cooperate and attacking $S$ in a way that $C$ or $D$ alone could not?
1207    
1208    In the above analysis, there is no place where we assume any specific
1209    behaviour of $D$ to help $S$ in preventing an attack on $S$.  There is
1210    only one place where we make an assumption for $C$ in the analysis of
1211    a malicious $D$.  If $D$ does not accept a reference container, we
1212    said that $C$ would clean it up by calling
1213    \verb/cap_ref_cont_destroy/.  So we have to look at what would happen
1214    if $C$ were not to do that.
1215    
1216    Luckily, we covered this case already.  It is identical to the case
1217    where $C$ does not even tell $D$ about the reference container and
1218    just do nothing.  In this case, as said before, the server will
1219    eventually release the reference container when $C$ dies.  Before
1220    that, it only occupies resources in the server that are associated
1221    with $C$.
1222    
1223    This analysis is sketchy in parts, but it covers a broad range of
1224    possible attacks.  For example, all possible and relevant combinations
1225    of task deaths and malicious tasks are covered.  Although by no means
1226    complete, it can give us some confidence about the rightness of the
1227    protocol.  It also provides a good set of test cases that you can test
1228    your own protocols, and improvements to the above protocol against.
1229    
 Access to task info capabilities can be open to everyone.  The above  
 strategies to prevent tasks from allocating too many of them for too  
 long work even if access to task info capabilities is given out  
 without any preconditions, and there is no real incentive other than  
 those above for a task to not pass on a task info capability to any  
 interested task anyway.  Allowing every task to create task info  
 capabilities for other tasks simplifies the protocols involved and  
 allows for some optimizations.  
1230    
1231    
1232  \subsection{Synchronous IPC}  \subsection{Synchronous IPC}
# Line 302  There are possibly some places in the Hu Line 1238  There are possibly some places in the Hu
1238  asynchronous IPC is assumed.  These must be replaced with different  asynchronous IPC is assumed.  These must be replaced with different
1239  strategies.  One example is the implementation of select() in the GNU  strategies.  One example is the implementation of select() in the GNU
1240  C library.  C library.
1241    
1242    \begin{comment}
1243      A naive implementation would use one thread per capability to select
1244      on.  A better one would combine all capabilities implemented by the
1245      same server in one array and use one thread per server.
1246        
1247      A more complex scheme might let the server process select() calls
1248      asynchronously and report the result back via notifications.
1249    \end{comment}
1250    
1251  In other cases the Hurd receives the reply asynchronously from sending  In other cases the Hurd receives the reply asynchronously from sending
1252  the message.  This works fine in Mach, because send-once rights are  the message.  This works fine in Mach, because send-once rights are
1253  used as reply ports and Mach guarantees to deliver the reply message,  used as reply ports and Mach guarantees to deliver the reply message,
# Line 310  ignoring the kernel queue limit.  In L4, Line 1255  ignoring the kernel queue limit.  In L4,
1255  such places need to be rewritten in a different way (for example using  such places need to be rewritten in a different way (for example using
1256  extra threads).  extra threads).
1257    
1258    
1259  \subsection{Notifications}  \subsection{Notifications}
1260        
1261  Notifications to untrusted tasks happens frequently.  One case is  Notifications to untrusted tasks happen frequently.  One case is
1262  object death notifications, in particular task death notifications.  object death notifications, in particular task death notifications.
1263  Other cases might be select() or notifications of changes to the  Other cases might be select() or notifications of changes to the
1264  filesystem.  filesystem.
1265      
1266  The console uses notifications to broadcast change events to the  The console uses notifications to broadcast change events to the
1267  console content, but it also uses shared memory to broadcast the  console content, but it also uses shared memory to broadcast the
1268  actual data, so not all notifications need to be received for  actual data, so not all notifications need to be received for
# Line 352  notifications for which clients, and tha Line 1298  notifications for which clients, and tha
1298  notified of pending notifications.  Then the clients can poll the  notified of pending notifications.  Then the clients can poll the
1299  notifications from the servers.  notifications from the servers.
1300    
 The whole issue of notifications requires more thoughtful analysis.  
1301    
1302  \subsection{Capabilities}  \section{Threads and Tasks}
1303        
1304  Capabilities will be the building stones of the Hurd system.  Servers  The Hurd will encode the task ID in the version part of the L4 thread
1305  will provide capabilities to clients.  Clients can invoke messages on  ID.  The version part can only be changed by the privileged system
1306  the capabilities, which are then processed by the server providing the  code, so it is protected by the kernel.  This allows recipients of a
1307  capability.  A capability will be normally associated with an object  message to quickly determine the task from the sender's thread ID.
 at the server side (for example an opened file).  
   
 The low level interface will use client capability IDs that are local  
 to each client.  If a client gets the same capability through two  
 different ways at the same time, well-behaving servers will provide  
 the same local ID both times.  This allows a client to compare local  
 IDs numerically to establish identity within capabilities provided by  
 a single server..  
   
 Clients will be able to copy capabilities to other tasks.  This will  
 be possible without requiring mutual trust between the clients and the  
 server (the only trust requirements are that the clients trust the  
 server and that the sender of a capability trusts the receiver).  
     
 The straightforward protocol to move a capability from one client C1  
 to another client C2 is that the client C1 sends a request to the  
 server S to create a transitional object, a reference container  
 destined for client C2.  After receiving the identifier for this  
 object, client C1 sends the information about it to C2.  C2 can then  
 send a request to the server S to complete the transition, and reply  
 to C1 to allow it to synchronize with the completion of the operation  
 and destroy the transitional object.  
     
 There are some obvious and not-so-obvious properties of this basic  
 protocol.  For example, C1 can not hide references to objects in other  
 tasks, because the receiver has to explicitely accept the reference.  
 If C1 were to die before C2 can accept the reference (or if C2 does  
 reject to accept the handle), the server S would destroy the  
 transitional object.  On the other hand, C1 does not need to rely on  
 C2 to accept the reference, as it will always destroy it afterwards.  
     
 This basic protocol is not enough to provide secure capability  
 transfer on L4, though, as at any time a participant could die, and  
 there is the danger of another task reusing that participants task and  
 thread IDs.  Such an imposter can then gain access to capabilities it  
 would normally not allowed to get.  To prevent this, task info  
 capabilities have to be acquired by all participants to ensure that  
 the task IDs of the others are not reused in the whole process.  This  
 greatly increases the complexity of the protocol.  
     
 The exact syntax of such a protocol depend on the actual interfaces.  
 But here is a rough overview.  The starting condition is that C1 has a  
 capability implemented in S, and a capability implemented in C2.  C1  
 will send the capability implemented in S as part of a message invoked  
 on the capability implemented in C2.  Because C1 and S, as well as C1  
 and C2, are already communicating, C1 has task info capabilities for S  
 and C2, S has a task info capability for C1, and C2 has a task info  
 capability for S.  
1308    
1309  \begin{enumerate}  Task IDs will not be reused as long as there are still tasks that
1310  \item C1 sends a request to S to create a transitional object  might actively communicate with the (now destroyed) task.  Task info
1311    (reference container) destined for C2.  capabilities provided by the task server can be used for that.  The
1312  \item Before replying, S acquires a task info capability for C2 if it  task info capability will also receive the task death notification (as
1313    doesn't have any already.  It also must check if C1 is still alive  a normap capability death notification).  The task server will reuse a
1314    after that (this can be done by the task server along with creating  task ID only when all task info capabilities for the task with that ID
1315    the task info capability), before entering the container into its  have been released.
1316    data structures.  This prevents that an imposter (of C2) can acquire  
1317    the capability by guessing the reference container ID before the  This of course can open a DoS attack.  Programs can attempt to acquire
1318    server can receive and process the task death notifications for C1.  task info capabilities and never release them.  Several strategies can
1319  \item Then the server replies to C1 with the reference container ID.  be applied to compensate that: The task server can automatically time
1320    The task info capability will stay with the reference container, and  out task info capability references to dead tasks.  The proc server
1321    both will be associated with C1.  If C1 dies now before C2 accepts  can show dead task IDs with task info capability references as some
1322    the capability, both the reference and the task info capability will  variant of zombie tasks, and provide a way to list all tasks
1323    be destroyed.  preventing the task ID from being reused, allowing the system
1324  \item C1 sends a request to C2 with the reference container ID and  administrator to identify malicious or faulty users.  Task ID
1325    other necessary information (like the server thread ID).  references can be taken into account in quota restrictions, to
1326  \item C2 looks at the server thread ID, and if it wants to accept a  encourage a user to release them when they are not needed anymore (in
1327    capability implemented by this server (in other words: if it trusts  particular, a user holding a task ID reference to a dead task could be
1328    that server), it acquires a task info capability for the server task  punished with the same costs as for an additional normal task owned by
1329    if it doesn't have any already.  It then must check if C1 is still  the user).  Another idea is to not allow any task to allocate more
1330    alive (this can be done by the task server along with creating the  task info capabilities than there are live tasks in the system, plus
1331    task info capability), because otherwise there might already be an  some slack.  This provides a high incentive for tasks to release their
1332    imposter (of S).  info caps (and if they get an error, they could block until their
1333  \item Now C2 can send a request to S to accept the capability from C1.  notification system has processed the task death notification and
1334  \item The server will check that there is a reference container for C2  released the reference, and try again).
1335    provided by C1.  It will then install the reference as a proper  
1336    reference for the capability owned by C2.  For this, it will also  Access to task info capabilities can be open to everyone.  The above
1337    install the task info capability.  If now C1 dies, the reference  strategies to prevent tasks from allocating too many of them for too
1338    container will be empty and C2 will keep its capability reference.  long work even if access to task info capabilities is given out
1339  \item The server replies to C2, returning the capability ID for C2.  without any preconditions, and there is no real incentive other than
1340  \item C2 can now return to C1, indicating success.  those above for a task to not pass on a task info capability to any
1341  \item C1 can now destroy the transitional objectq, and optionally  interested task anyway.  Allowing every task to create task info
1342    deallocate its own reference to the capability.  capabilities for other tasks simplifies the protocols involved and
1343  \end{enumerate}  allows for some optimizations.
1344      
1345  Each step is necessary, and the order is peculiar.  If various things  
1346  go wrong, all behaving participants in this protocol can properly  \subsection{Proxy Task Server}
1347  clean up their state and resources without being harmed or tricked  \label{proxytaskserver}
1348  into trusting a task they don't want to trust.  
1349    The task server can be safely proxied, and the users of such a proxy
1350  There will be other protocols, for example to return new capabilities  task server can use it like the real task server, even though
1351  to the same server in a server reply (which is easy to do), and to  capabilities work a bit different for the task server than for other
1352  receive capabilities implemented by other servers from a server (which  servers.
1353  can be done by creating empty reference containers in the client  
1354  before sending the request).  The problem exists because the proxy task server would hold the real
1355    task info capabilities for the task info capabilities that it provides
1356    to the proxied task.  So if the proxy task server dies, all such task
1357    info capabilities would be released, and the tasks using the proxy
1358    task server would become insecure and open to attacks by imposters.
1359    
1360    However, this is not really a problem, because the proxy task server
1361    will also provide proxy objects for all task control capabilities.  So
1362    it will be the only task which holds task control capabilities for the
1363    tasks that use it.  When the proxy task server dies, all tasks that
1364    were created with it will be destroyed when these tak control
1365    capabilities are released.  The proxy task server is a vital system
1366    component for the tasks that use it, just as the real task server is a
1367    vital system component for the whole system.
1368    
1369    
1370  \section{Virtual Memory Management}  \section{Virtual Memory Management}
# Line 531  actually kernel state associated with a Line 1441  actually kernel state associated with a
1441  to be destroyed by exec() anyway.  There is a lot of Hurd specific  to be destroyed by exec() anyway.  There is a lot of Hurd specific
1442  state associated with a task (capabilities, for example), but it is  state associated with a task (capabilities, for example), but it is
1443  difficult to preserve that.  There are security concerns, because  difficult to preserve that.  There are security concerns, because
1444  POSIX programs don't know about Hurd features like capabilities, so  POSIX programs do not know about Hurd features like capabilities, so
1445  inheriting all capabilities across exec() seems dangerous.  There are  inheriting all capabilities across exec() seems dangerous.  There are
1446  also implementation obstacles, because only local threads can  also implementation obstacles, because only local threads can
1447  manipulate the virtual memory mappings, and there is a lot of local  manipulate the virtual memory mappings, and there is a lot of local
# Line 606  idea.  The details will depend a lot on Line 1516  idea.  The details will depend a lot on
1516    
1517    
1518  \section{Authentication}  \section{Authentication}
1519    \label{auth}
1520    
1521  The auth server gives out auth objects that contain zero or more of  The auth server gives out auth objects that contain zero or more of
1522  effective user IDs, available user IDs, effective group IDs and  effective user IDs, available user IDs, effective group IDs and
# Line 626  that a task having the passport capabili Line 1537  that a task having the passport capabili
1537  unless they were given the passport object by that task.  unless they were given the passport object by that task.
1538    
1539    
   
1540  \section{Unix Domain Sockets and Pipes}  \section{Unix Domain Sockets and Pipes}
1541    
1542  In the Hurd on Mach, there was a global pflocal server that provided  In the Hurd on Mach, there was a global pflocal server that provided
# Line 651  accessing it will create a pipe in his p Line 1561  accessing it will create a pipe in his p
1561  an active translator must be installed in the node that redirects any  an active translator must be installed in the node that redirects any
1562  other users to the right pflocal server implementing this fifo.  This  other users to the right pflocal server implementing this fifo.  This
1563  is asymmetrical in that the first user to access a fifo will implement  is asymmetrical in that the first user to access a fifo will implement
1564  it, and thus pay the costs for it.  But it doesn't seem to cause any  it, and thus pay the costs for it.  But it does not seem to cause any
1565  particular problems in implementing the POSIX semantics.  particular problems in implementing the POSIX semantics.
1566    
1567  The GNU C library can contact ~/servers/socket/pflocal to implement  The GNU C library can contact ~/servers/socket/pflocal to implement
1568  socketpair, or start a pflocal server for this task's exclusive use if  socketpair, or start a pflocal server for this task's exclusive use if
1569  that node doesn't exist.  that node does not exist.
1570    
1571  All this are optimizations: It should work to have one pflocal process  All this are optimizations: It should work to have one pflocal process
1572  for each socketpair.  However, performance should be better with a  for each socketpair.  However, performance should be better with a
# Line 665  shared pflocal server, one per user. Line 1575  shared pflocal server, one per user.
1575    
1576  \section{Filesystem Translators}  \section{Filesystem Translators}
1577    
1578    \label{xfslookup}
1579    
1580  The Hurd has the ability to let users mount filesystems and other  The Hurd has the ability to let users mount filesystems and other
1581  servers providing a filesystem-like interface.  Such filesystem  servers providing a filesystem-like interface.  Such filesystem
1582  servers are called translators.  In the Hurd on GNU Mach, the parent  servers are called translators.  In the Hurd on GNU Mach, the parent
# Line 694  filesystem (by first building up a conne Line 1606  filesystem (by first building up a conne
1606  authentication capability from the parent filesystem, and receiving a  authentication capability from the parent filesystem, and receiving a
1607  root directory capability in exchange).  root directory capability in exchange).
1608    
1609    \begin{comment}
1610      There is a race here.  If the child filesystem dies and the parent
1611      filesystem processes the task death notification and releases the
1612      task info cap for the child before the user acquires its own task
1613      info cap for the child, then an imposter might be able to pretend to
1614      be the child filesystem for the client.
1615      
1616      This race can only be avoided by a more complex protocol:
1617      
1618      Variant 1: The user has to acquire the task info cap for the child
1619      fs, and then it has to perform the lookup again.  If then the thread
1620      ID is for the task it got the task ID for in advance, it can go on.
1621      If not, it has to retry.  This is not so good because a directory
1622      lookup is usually an expensive operation.  However, it has the
1623      advantage of only slowing down the rare case.
1624      
1625      Variant 2: The client creates an empty reference container in the
1626      task server, which can then be used by the server to fill in a
1627      reference to the child's task ID.  However, the client has to create
1628      and destroy such a container for every filesystem where it excepts
1629      it could be redirected to another (that means: for all filesystems
1630      for which it does not use \verb/O_NOTRANS/).  This is quite an
1631      overhead to the common case.
1632    \end{comment}
1633    
1634  The actual creation of the child filesystem can be performed much like  The actual creation of the child filesystem can be performed much like
1635  a suid exec, just without any client to follow up with further  a suid exec, just without any client to follow up with further
1636  capabilities and startup info.  The only problem that remains is how  capabilities and startup info.  The only problem that remains is how

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26