Multics Technical Bulletin                                MTB-693
Improved Security IPC

To:       Distribution

From:     Eric J. Swenson

Date:     11/11/84

Subject:  Improving the Security of Multics IPC


     This  MTB  describes  some  of  the  problems  with the
     current   implementation   of  Multics   Inter  Process
     Communications (IPC) and suggests several changes which
     will improve its reliability and security.  The changes
     proposed  will  be  completely  invisible  to  users of

     Comments should be sent to the author:

     via Multics Mail:
        Swenson at either System-M, MIT, or CISL-SERVICE.

     via Forum:
        >udd>m>mtgs>B2 on System-M

     via telephone:
        (HVN) 492-9365, or
        (617) 492-9365


Multics  project  internal  working  documentation.   Not  to  be
reproduced or distributed outside the Multics project without the
consent of the author or the author's management.

MTB-693                                Multics Technical Bulletin
                                            Improved Security IPC


     In the  current implementation of IPC,  the hardcore is
     unable to validate completely  a user's request to send
     an IPC wakeup to another  process.  To send a wakeup, a
     sending  process  needs  to  know the  process-id  of a
     target process,  and the name of  an event channel over
     which  to  send  the  wakeup.  While  the  hardcore can
     easily  determine the  validity of the  process-id of a
     target process, it has no mechanism to verify the event
     channel  name other  than a few  very primitive checks.
     It is  not difficult for a  malicious user to construct
     event channel names which pass these incomplete checks.
     Since the hardcore is unable to perform the validation,
     it  relies  on  the  target  process  to  do  so.  This
     necessarily  means that  a malicious  user can  send an
     arbitrary  number of  wakeups to a  target process, and
     the target process must  spend arbitrary amounts of CPU
     time  (for  which  it  is charged)  verifying  that the
     wakeups   are   indeed  for   event  channels   it  has
     established.  Even then, the target process has no sure
     way  to  validate the  wakeup and  can be  tricked into
     performing actions not expected or desired on behalf of
     the sending process.

          Further,  due  to  various  bugs  in  the hardcore
     handling  of wakeups,  it is  possible for  a malicious
     user to construct mal-formed  event channel names which
     will  result  in  the  target process'  taking  a fatal
     process error when attempting to process the wakeup.

          The  security of  the current  IPC depends  on the
     fact  that  the  process-ids  of  other  processes  are
     difficult to determine unless explicitly made available
     by a  process.  Although not  within the scope  of this
     MTB, it  can be demonstrated  that guessing process-ids
     is a trivial programming  effort.  In all fairness, IPC
     security  is also  based on the  fact that  in order to
     send a wakeup over a  particular event channel, one has
     to  know  its  name,  or  handle.   However,  as stated
     previously, enough  mischief can be caused  on the part
     of a malicious process, by carefully constructing event
     channel names, which, when  processed, will bring about
     the desired effect.

          A  side  effect  of  the  hardcore's  inability to
     validate IPC wakeups is  its inability to audit invalid
     wakeups.   Due  to  the   lack  of  a  secure  auditing
     mechanism  in   the  user-ring  IPC   software,  it  is

Multics Technical Bulletin                                MTB-693
Improved Security IPC

     currently  impossible  to perform  the auditing  in the
     target process either.


     The effect of the changes  proposed in this MTB will be
     to  provide  wakeup-time  validation  of  IPC  wakeups,
     auditing  of invalid  wakeups, an  event channel naming
     scheme  which will  greatly increase  the difficulty of
     fabricating event  channel names, and  fixes to various
     IPC bugs  currently known to exist.   The validation of
     wakeups  and  the  auditing  of  invalid  ones  will be
     performed by the sending process in ring-0, eliminating
     much of  the need for  the target process  to spend its
     own resources rejecting invalid wakeups.


     The  security  problems surrounding  IPC stem  from the
     format  of  event channel  names  and the  inability of
     Ring-0  IPC  and user-ring  IPC to  completely validate
     them.   There  are two  types  of event  channels, fast
     channels and regular event channels.  The format of the
     event channel names for  each is different and detailed
     below by way of a PL/I structure declaration:

       dcl 1 fast_event_channel_name structure aligned,
             2 ecte_ptr pointer unaligned,
             2 ring fixed bin (3) unsigned unaligned,
             2 mbz bit (15) unaligned,
             2 channel_index fixed bin (17) unaligned;

       dcl 1 regular_event_channel_name structure aligned,
             2 ecte_ptr pointer unaligned,
             2 ring fixed bin (3) unsigned unaligned,
             2 unique_id fixed bin (33) unsigned unaligned;

     Both  event channel  name formats  include an ecte_ptr.
     For regular  channels, this is a  packed pointer to the
     Event Channel Table Entry  (ECTE) in the ring specified
     by the  "ring" in the  event channel name.   It is very
     difficult  for either  Ring-0 IPC  or user-ring  IPC to
     validate that the ecte_ptr  does indeed address an ECTE
     created  by IPC.   For fast  channels, the  ecte_ptr is
     null  and  the  channel_index  is used  to  locate data
     associated with the fast channel.

MTB-693                                Multics Technical Bulletin
                                            Improved Security IPC

          The new  IPC will remove  the ECTE pointer  in the
     event channel  name.  Instead will be  an encoded index
     into  the new  Event Channel Index  Table (ECIT).  This
     table, whose entries contain  solely packed pointers to
     the  actual ECTEs,  will be created  and initialized at
     ECT initialization.  The index  will be encoded using a
     special algorithm,  described below, so that  it can be
     validated both at wakeup time and at handling time.  In
     addition to encoding the index,  a new 3-bit flag field
     will be  encoded as well.  While  the flag field serves
     no  purpose  and  is  ignored  in  this implementation,
     future  changes  to  IPC  will  utilize  this  field to
     specify channels  which require special  handling.  The
     following PL/I declaration specifies  the format of the
     new event channel names:

       dcl 1 event_channel_name structure aligned,
             2 encoded_index_and_flags bit (18) unaligned,
             2 verifier bit (18) unaligned,
             2 ring fixed bin (3) unsigned unaligned,
             2 type bit (1) unaligned,
             2 mbz bit (14) unaligned,
             2 unique_id fixed bin (18) unsigned unaligned;

     The "encoded_index_and_flags" field  will contain in an
     encoded fashion, the index into  the ECIT and the 3-bit
     flag field.  The encoding algorithm is described later.
     The "verifier"  field will be used  in conjunction with
     the  "encoded_index_and_flags"  field  to  validate the
     event  channel name.   "ring" contains,  as before, the
     ring number where the event channel originated.  "type"
     specifies  whether  the event  channel  is a  "fast" or
     "regular"  event  channel.  The  unique_id is  used, as
     before,  to make  regular event channels  unique and to
     index into the arrays of fast event channel data.

          Because  the  proposed change  could result  in an
     encoded  index and  verifier with  the value  of a null
     packed   pointer,   it   is  no   longer   possible  to
     distinguish, for certain, a fast channel from a regular
     channel simply  by examining the  former ecte_ptr field
     for  equivalence with  a null packed  pointer.  The new
     "type" field within the  event channel name will become
     the method of distinguishing fast channels from regular
     channels.  Ring-0 will be  modified appropriately to do

Multics Technical Bulletin                                MTB-693
Improved Security IPC

4.1 R-Offset and R-Factor

     The  encoding algorithm,  whose description  follows in
     the  next  section, makes  use  of the  operands termed
     "R-Offset"   and   "R-factor".    These   operands  are
     initialized  at  process  creation time  by  the ring-0
     programs  act_proc  and  init_proc  and  stored  in the
     process' Active  Process Table Entry  (APTE).  They are
     in the  APTE so that  ring-0 will be  able to reference
     these values  for a specified target  process at wakeup
     time  (call  to  hcs_$wakeup).  These  values  are also
     retrieved   from  ring-0   by  user-ring   IPC  at  ECT
     initialization time  and stored in  the ECT for  use in
     event  channel  name decoding.   R-Offset is  an 18-bit
     unsigned  integer,  and R-Factor  is a  36-bit unsigned
     integer.  All arithmetic algorithms  to be described is
     unsigned  and  modular   arithmetic  --  overflows  are

          For best  results, these values  should be random.
     However, adequate effects can be achieved by generating
     both numbers by keying off  bit substrings of the clock
     value.  In order to minize the ability for a process to
     guess the value of R-Factor for a process given that it
     has knowlege of R-Offset, a delay is introduced between
     generating  R-Offset  and   R-Factor.   This  delay  is
     accomplished  by  having act_proc  create  R-Offset and
     init_proc  create  R-Factor.   init_proc  is  the first
     ring-0 program  to run in  a process after  it receeves
     the   initial  wakeup   from  the   answering  service.
     Act_proc is run in the  answering service to set up the
     process.   There is  an unpredictable  time lag between
     these program's running.

4.2 Encoding ECIT Indices and Flags

     When an event channel is created, a free ECIT slot will
     be located  by the user-ring  IPC.  The index  into the
     ECIT  (a  15-bit value)  and  the 3-bit  flags  will be
     combined  to produce  an 18-bit  unencoded index.  This
     index is added to the value of R-Offset for the process
     to  produce  the  encoded  index  stored  in  the event
     channel  name.  The  "verifier" is  generated by taking
     the  middle  18-bits  from  the 54-bit  product  of the
     unencoded  index  and  R-Factor.   The  verifier,  too,
     becomes  part  of the  event  channel name.   Note that
     R-Offset and R-Factor will be  stored in the ECT header
     for easy access by the  process and will be unavailable
     to any process other than the owner of the ECT.

MTB-693                                Multics Technical Bulletin
                                            Improved Security IPC

4.3 Validating Event Channel Names

     When a process calls hcs_$wakeup  to send a wakeup to a
     target process,  Ring-0 will extract  the encoded_index
     and verifier from the event channel name supplied.  The
     target  process  will  be  located, and  the  values of
     R-Offset and R-Factor found in the target process' APTE
     will be used in the validation algorithm which follows:
     The unencoded index is derived by subtracting the value
     of R-Offset from the encoded index in the event channel
     name.   A verifier  is generated by  the same algorithm
     described in the proceeding section and compared to the
     verifier supplied  in the event channel  name.  If they
     match,  then ring-0  will perform  the same  actions as
     currently  done.   If  the  computed  verifier  and the
     verifier in  the event channel name  do not match, then
     the wakeup is rejected and an audit message logged.

4.4 Guessing Event Channel Names

     The new event channel  naming scheme will make guessing
     event  channel  names   more  difficult.   Without  the
     knowledge  of any  event channel  names for  a process,
     guessing  an  event  channel  name  will  be  difficult
     because R-Offset and R-Factor are not known.  Given one
     event  channel name,  it is  not terribly  difficult to
     guess event  channel names by making  assumptions as to
     what  the value  of R-Offset  is and  then, from there,
     determining  an  appropriate  R-factor.   However,  for
     processes  with  many event  channels, the  guessing is
     much more  difficult than for processes  with few event
     channels.   All  in all,  while guessing  event channel
     names is not impossible,  the proposed scheme is better
     than the current scheme.


     All  the programs  which comprise  user-ring and ring-0
     IPC must  be recompiled with the  new include files and
     modified slightly  to accommodate the  changes in event
     channel names  and the datatypes of  the various fields
     in  the  include  files.   In  addition,  ipc_real_ and
     ipc_util_  must be  changed to  generate the new-format
     event channel  names and to  allow location of  an ECTE
     given an event channel  name.  This includes setting up
     the  new  ECIT.  Ring-0  IPC (hc_ipc,  fast_hc_ipc, and
     pxss) must be changed to recognize the new format event
     channel names.  They must include calls to validate the

Multics Technical Bulletin                                MTB-693
Improved Security IPC

     event channel name (by extracting R-Offset and R-Factor
     from the target APTE  and performing the computations).
     The   Ring-0  module   act_proc  must   be  changed  to
     initialize  R-Offset.   init_proc  must  be  changed to
     initialize  R-Factor.   tc_util  will  be  modified  to
     extract  the values  of R-Offset  and R-Factor  from an
     APTE  and  an  hcs_  entrypoint, hcs_$get_ipc_operands,
     will be created to return  these values for the calling


     The TCP/IP  networking software has its  own version of
     IPC which implements the changes needed for the tasking
     software.  Making the proposed changes to the installed
     IPC  will cause  the network  software (tasking)  to no
     longer  function.    Therefore,  it  is   necessary  to
     integrate the  new IPC validation  functionality in the
     version  of  IPC used  by  the tasking  software.  This
     involves  modifying several  programs in  the a similar
     manner as for the installed version of IPC.


     Currently, when the ECT is  created, an area is created
     which  is  large  enough  for  approximately  30  event
     channels.  The area  software automatically expands the
     area if an attempt is made to allocate channels into it
     which  would  exceed  the  current  size.   In  the new
     implementation, the  ECIT is created with  a size of 30
     and  expanded if  it is  overflowed.  Because  it is an
     allocated  structure  in the  ECT area,  a new  ECIT is
     created  and  all  the  entries  copied  into  the new,
     larger,  ECIT,  and  the  old one  freed.   Because the
     Initializer process uses so  many event channels, a new
     entrypoint  will  be  provided,  ipc_$create_ect, which
     will allow create  an ECT and ECIT with  enough room to
     accommodate  the  expected  number  of  event channels.
     This  will  improve  the  efficiency  of  event channel
     creation in the Initializer process.  This entry may be
     used by  other applications (before  any event channels
     are created) to  set the size of the  ECT and ECIT.  If
     the entry is called  after ECT initialization, the size
     specified in the call will  be stored in the ECT header
     for  use  the  next  time  the  ECIT  is  expanded,  if