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.

@@ -22,12 +22,10 @@
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident   "%Z%%M% %I%     %E% SMI"
-
 #pragma weak _sbrk = sbrk
 #pragma weak _brk = brk
 
 #include "lint.h"
 #include <synch.h>

@@ -38,16 +36,15 @@
 #include <inttypes.h>
 #include <unistd.h>
 #include "mtlib.h"
 #include "libc.h"
 
-extern int _end;
-void *_nd = &_end;
+void *_nd = NULL;
 mutex_t __sbrk_lock = DEFAULTMUTEX;
 
-extern int _brk_unlocked(void *);
-extern void *_sbrk_unlocked(intptr_t);
+extern intptr_t _brk_unlocked(void *);
+void *_sbrk_unlocked(intptr_t);
 
 /*
  * The break must always be at least 8-byte aligned
  */
 #if (_MAX_ALIGNMENT < 8)

@@ -85,12 +82,19 @@
  *   - the addend is positive and brk + addend > ULONG_MAX
  */
 void *
 _sbrk_unlocked(intptr_t addend)
 {
-        char *old_brk = BRKALIGN(_nd);
-        char *new_brk = BRKALIGN(old_brk + addend);
+        char *old_brk;
+        char *new_brk;
+
+        if (_nd == NULL) {
+                _nd = (void *)_brk_unlocked(0);
+        }
+
+        old_brk = BRKALIGN(_nd);
+        new_brk = BRKALIGN(old_brk + addend);
 
         if ((addend > 0 && new_brk < old_brk) ||
             (addend < 0 && new_brk > old_brk)) {
                 errno = ENOMEM;
                 return ((void *)-1);

@@ -132,10 +136,14 @@
         low_align = MAX(low_align, ALIGNSZ);
         high_align = MAX(high_align, ALIGNSZ);
 
         lmutex_lock(&__sbrk_lock);
 
+        if (_nd == NULL) {
+                _nd = (void *)_brk_unlocked(0);
+        }
+
         old_brk = (uintptr_t)BRKALIGN(_nd);
         ret_brk = P2ROUNDUP(old_brk, low_align);
         high_brk = ret_brk + min_size;
         new_brk = P2ROUNDUP(high_brk, high_align);
 

@@ -146,11 +154,11 @@
                 lmutex_unlock(&__sbrk_lock);
                 errno = ENOMEM;
                 return ((void *)-1);
         }
 
-        if ((brk_result = _brk_unlocked((void *)new_brk)) == 0)
+        if ((brk_result = (int)_brk_unlocked((void *)new_brk)) == 0)
                 _nd = (void *)new_brk;
         lmutex_unlock(&__sbrk_lock);
 
         if (brk_result != 0)
                 return ((void *)-1);

@@ -163,21 +171,30 @@
 int
 brk(void *new_brk)
 {
         int result;
 
+        /*
+         * brk(2) will return the current brk if given an argument of 0, so we
+         * need to fail it here
+         */
+        if (new_brk == 0) {
+                errno = ENOMEM;
+                return (-1);
+        }
+
         if (!primary_link_map) {
                 errno = ENOTSUP;
                 return (-1);
         }
         /*
          * Need to align this here;  _brk_unlocked won't do it for us.
          */
         new_brk = BRKALIGN(new_brk);
 
         lmutex_lock(&__sbrk_lock);
-        if ((result = _brk_unlocked(new_brk)) == 0)
+        if ((result = (int)_brk_unlocked(new_brk)) == 0)
                 _nd = new_brk;
         lmutex_unlock(&__sbrk_lock);
 
         return (result);
 }