Print this page
    
7029 want per-process exploit mitigation features (secflags)
7030 want basic address space layout randomization (aslr)
7031 noexec_user_stack should be a secflag
7032 want a means to forbid mappings around NULL.
    
      
        | Split | Close | 
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/os/proc.c
          +++ new/usr/src/uts/common/os/proc.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License, Version 1.0 only
   6    6   * (the "License").  You may not use this file except in compliance
   7    7   * with the License.
   8    8   *
   9    9   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10   10   * or http://www.opensolaris.org/os/licensing.
  11   11   * See the License for the specific language governing permissions
  12   12   * and limitations under the License.
  13   13   *
  14   14   * When distributing Covered Code, include this CDDL HEADER in each
  15   15   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16   16   * If applicable, add the following below this CDDL HEADER, with the
  17   17   * fields enclosed by brackets "[]" replaced with your own identifying
  18   18   * information: Portions Copyright [yyyy] [name of copyright owner]
  19   19   *
  20   20   * CDDL HEADER END
  21   21   */
  22   22  /*
  23   23   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
  26   26   */
  27   27  
  28   28  #include <sys/proc.h>
  29   29  #include <sys/cpuvar.h>
  30   30  #include <sys/disp.h>
  31   31  
  32   32  /*
  33   33   * Install process context ops for the current process.
  34   34   */
  35   35  void
  36   36  installpctx(
  37   37          proc_t *p,
  38   38          void    *arg,
  39   39          void    (*save)(void *),
  40   40          void    (*restore)(void *),
  41   41          void    (*fork)(void *, void *),
  42   42          void    (*exit)(void *),
  43   43          void    (*free)(void *, int))
  44   44  {
  45   45          struct pctxop *pctx;
  46   46  
  47   47          pctx = kmem_alloc(sizeof (struct pctxop), KM_SLEEP);
  48   48          pctx->save_op = save;
  49   49          pctx->restore_op = restore;
  50   50          pctx->fork_op = fork;
  51   51          pctx->exit_op = exit;
  52   52          pctx->free_op = free;
  53   53          pctx->arg = arg;
  54   54          pctx->next = p->p_pctx;
  55   55          p->p_pctx = pctx;
  56   56  }
  57   57  
  58   58  /*
  59   59   * Remove a process context ops from the current process.
  60   60   */
  61   61  int
  62   62  removepctx(
  63   63          proc_t *p,
  64   64          void    *arg,
  65   65          void    (*save)(void *),
  66   66          void    (*restore)(void *),
  67   67          void    (*fork)(void *, void *),
  68   68          void    (*exit)(void *),
  69   69          void    (*free)(void *, int))
  70   70  {
  71   71          struct pctxop *pctx, *prev_pctx;
  72   72  
  73   73          prev_pctx = NULL;
  74   74          kpreempt_disable();
  75   75          for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) {
  76   76                  if (pctx->save_op == save && pctx->restore_op == restore &&
  77   77                      pctx->fork_op == fork &&
  78   78                      pctx->exit_op == exit && pctx->free_op == free &&
  79   79                      pctx->arg == arg) {
  80   80                          if (prev_pctx)
  81   81                                  prev_pctx->next = pctx->next;
  82   82                          else
  83   83                                  p->p_pctx = pctx->next;
  84   84                          if (pctx->free_op != NULL)
  85   85                                  (pctx->free_op)(pctx->arg, 0);
  86   86                          kmem_free(pctx, sizeof (struct pctxop));
  87   87                          kpreempt_enable();
  88   88                          return (1);
  89   89                  }
  90   90                  prev_pctx = pctx;
  91   91          }
  92   92          kpreempt_enable();
  93   93          return (0);
  94   94  }
  95   95  
  96   96  void
  97   97  savepctx(proc_t *p)
  98   98  {
  99   99          struct pctxop *pctx;
 100  100  
 101  101          ASSERT(p == curthread->t_procp);
 102  102          for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
 103  103                  if (pctx->save_op != NULL)
 104  104                          (pctx->save_op)(pctx->arg);
 105  105  }
 106  106  
 107  107  void
 108  108  restorepctx(proc_t *p)
 109  109  {
 110  110          struct pctxop *pctx;
 111  111  
 112  112          ASSERT(p == curthread->t_procp);
 113  113          for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
 114  114                  if (pctx->restore_op != NULL)
 115  115                          (pctx->restore_op)(pctx->arg);
 116  116  }
 117  117  
 118  118  void
 119  119  forkpctx(proc_t *p, proc_t *cp)
 120  120  {
 121  121          struct pctxop *pctx;
 122  122  
 123  123          for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
 124  124                  if (pctx->fork_op != NULL)
 125  125                          (pctx->fork_op)(p, cp);
 126  126  }
 127  127  
 128  128  /*
 129  129   * exitpctx is called during thread/lwp exit to perform any actions
 130  130   * needed when an LWP in the process leaves the processor for the last
 131  131   * time. This routine is not intended to deal with freeing memory; freepctx()
 132  132   * is used for that purpose during proc_exit(). This routine is provided to
 133  133   * allow for clean-up that can't wait until thread_free().
 134  134   */
 135  135  void
 136  136  exitpctx(proc_t *p)
 137  137  {
 138  138          struct pctxop *pctx;
 139  139  
 140  140          for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
 141  141                  if (pctx->exit_op != NULL)
 142  142                          (pctx->exit_op)(p);
 143  143  }
 144  144  
 145  145  /*
 146  146   * freepctx is called from proc_exit() to get rid of the actual context ops.
 147  147   */
 148  148  void
 149  149  freepctx(proc_t *p, int isexec)
 150  150  {
 151  151          struct pctxop *pctx;
  
    | ↓ open down ↓ | 151 lines elided | ↑ open up ↑ | 
 152  152  
 153  153          kpreempt_disable();
 154  154          while ((pctx = p->p_pctx) != NULL) {
 155  155                  p->p_pctx = pctx->next;
 156  156                  if (pctx->free_op != NULL)
 157  157                          (pctx->free_op)(pctx->arg, isexec);
 158  158                  kmem_free(pctx, sizeof (struct pctxop));
 159  159          }
 160  160          kpreempt_enable();
 161  161  }
      162 +
      163 +boolean_t
      164 +secflag_enabled(proc_t *p, secflag_t flag)
      165 +{
      166 +        return (secflag_isset(p->p_secflags.psf_effective, flag));
      167 +}
      168 +
      169 +void
      170 +secflags_promote(proc_t *p)
      171 +{
      172 +        secflags_copy(&p->p_secflags.psf_effective, &p->p_secflags.psf_inherit);
      173 +}
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX