Print this page
Code review comments from jeffpc
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/lib/libc/port/sys/sbrk.c
          +++ new/usr/src/lib/libc/port/sys/sbrk.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  28      -
  29   27  #pragma weak _sbrk = sbrk
  30   28  #pragma weak _brk = brk
  31   29  
  32   30  #include "lint.h"
  33   31  #include <synch.h>
  34   32  #include <errno.h>
  35   33  #include <sys/isa_defs.h>
  36   34  #include <sys/types.h>
  37   35  #include <sys/sysmacros.h>
  38   36  #include <inttypes.h>
  39   37  #include <unistd.h>
  40   38  #include "mtlib.h"
  41   39  #include "libc.h"
  42   40  
  43      -extern int _end;
  44      -void *_nd = &_end;
       41 +void *_nd = NULL;
  45   42  mutex_t __sbrk_lock = DEFAULTMUTEX;
  46   43  
  47      -extern int _brk_unlocked(void *);
  48      -extern void *_sbrk_unlocked(intptr_t);
       44 +extern intptr_t _brk_unlocked(void *);
       45 +void *_sbrk_unlocked(intptr_t);
  49   46  
  50   47  /*
  51   48   * The break must always be at least 8-byte aligned
  52   49   */
  53   50  #if (_MAX_ALIGNMENT < 8)
  54   51  #define ALIGNSZ         8
  55   52  #else
  56   53  #define ALIGNSZ         _MAX_ALIGNMENT
  57   54  #endif
  58   55  
↓ open down ↓ 21 lines elided ↑ open up ↑
  80   77   * We must align the old break because _nd may begin life misaligned.
  81   78   * The addend can be either positive or negative, so there are two
  82   79   * overflow/underflow edge conditions to reject:
  83   80   *
  84   81   *   - the addend is negative and brk + addend < 0.
  85   82   *   - the addend is positive and brk + addend > ULONG_MAX
  86   83   */
  87   84  void *
  88   85  _sbrk_unlocked(intptr_t addend)
  89   86  {
  90      -        char *old_brk = BRKALIGN(_nd);
  91      -        char *new_brk = BRKALIGN(old_brk + addend);
       87 +        char *old_brk;
       88 +        char *new_brk;
       89 +
       90 +        if (_nd == NULL) {
       91 +                _nd = (void *)_brk_unlocked(0);
       92 +        }
       93 +
       94 +        old_brk = BRKALIGN(_nd);
       95 +        new_brk = BRKALIGN(old_brk + addend);
  92   96  
  93   97          if ((addend > 0 && new_brk < old_brk) ||
  94   98              (addend < 0 && new_brk > old_brk)) {
  95   99                  errno = ENOMEM;
  96  100                  return ((void *)-1);
  97  101          }
  98  102          if (_brk_unlocked(new_brk) != 0)
  99  103                  return ((void *)-1);
 100  104          _nd = new_brk;
 101  105          return (old_brk);
↓ open down ↓ 9 lines elided ↑ open up ↑
 111  115   * not allow shrinking the heap.
 112  116   */
 113  117  void *
 114  118  _sbrk_grow_aligned(size_t min_size, size_t low_align, size_t high_align,
 115  119      size_t *actual_size)
 116  120  {
 117  121          uintptr_t old_brk;
 118  122          uintptr_t ret_brk;
 119  123          uintptr_t high_brk;
 120  124          uintptr_t new_brk;
 121      -        int brk_result;
      125 +        intptr_t brk_result;
 122  126  
 123  127          if (!primary_link_map) {
 124  128                  errno = ENOTSUP;
 125  129                  return ((void *)-1);
 126  130          }
 127  131          if ((low_align & (low_align - 1)) != 0 ||
 128  132              (high_align & (high_align - 1)) != 0) {
 129  133                  errno = EINVAL;
 130  134                  return ((void *)-1);
 131  135          }
 132  136          low_align = MAX(low_align, ALIGNSZ);
 133  137          high_align = MAX(high_align, ALIGNSZ);
 134  138  
 135  139          lmutex_lock(&__sbrk_lock);
 136  140  
      141 +        if (_nd == NULL)
      142 +                _nd = (void *)_brk_unlocked(0);
      143 +
 137  144          old_brk = (uintptr_t)BRKALIGN(_nd);
 138  145          ret_brk = P2ROUNDUP(old_brk, low_align);
 139  146          high_brk = ret_brk + min_size;
 140  147          new_brk = P2ROUNDUP(high_brk, high_align);
 141  148  
 142  149          /*
 143  150           * Check for overflow
 144  151           */
 145  152          if (ret_brk < old_brk || high_brk < ret_brk || new_brk < high_brk) {
 146  153                  lmutex_unlock(&__sbrk_lock);
↓ open down ↓ 9 lines elided ↑ open up ↑
 156  163                  return ((void *)-1);
 157  164  
 158  165          if (actual_size != NULL)
 159  166                  *actual_size = (new_brk - ret_brk);
 160  167          return ((void *)ret_brk);
 161  168  }
 162  169  
 163  170  int
 164  171  brk(void *new_brk)
 165  172  {
 166      -        int result;
      173 +        intptr_t result;
      174 +
      175 +        /*
      176 +         * brk(2) will return the current brk if given an argument of 0, so we
      177 +         * need to fail it here
      178 +         */
      179 +        if (new_brk == 0) {
      180 +                errno = ENOMEM;
      181 +                return (-1);
      182 +        }
 167  183  
 168  184          if (!primary_link_map) {
 169  185                  errno = ENOTSUP;
 170  186                  return (-1);
 171  187          }
 172  188          /*
 173  189           * Need to align this here;  _brk_unlocked won't do it for us.
 174  190           */
 175  191          new_brk = BRKALIGN(new_brk);
 176  192  
 177  193          lmutex_lock(&__sbrk_lock);
 178  194          if ((result = _brk_unlocked(new_brk)) == 0)
 179  195                  _nd = new_brk;
 180  196          lmutex_unlock(&__sbrk_lock);
 181  197  
 182  198          return (result);
 183  199  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX