summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/malloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/malloc.c')
-rw-r--r--src/lib/libc/stdlib/malloc.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c
index 15feb6d2d3..689fa8996a 100644
--- a/src/lib/libc/stdlib/malloc.c
+++ b/src/lib/libc/stdlib/malloc.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#if defined(LIBC_SCCS) && !defined(lint) 10#if defined(LIBC_SCCS) && !defined(lint)
11static char rcsid[] = "$OpenBSD: malloc.c,v 1.63 2003/10/15 21:37:01 tedu Exp $"; 11static char rcsid[] = "$OpenBSD: malloc.c,v 1.64 2003/10/16 17:05:05 tedu Exp $";
12#endif /* LIBC_SCCS and not lint */ 12#endif /* LIBC_SCCS and not lint */
13 13
14/* 14/*
@@ -193,6 +193,12 @@ static int malloc_silent;
193/* always realloc ? */ 193/* always realloc ? */
194static int malloc_realloc; 194static int malloc_realloc;
195 195
196/* mprotect free pages PROT_NONE? */
197static int malloc_freeprot;
198
199/* use guard pages after allocations? */
200static int malloc_guard = 0;
201
196#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE)) 202#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
197/* pass the kernel a hint on free pages ? */ 203/* pass the kernel a hint on free pages ? */
198static int malloc_hint; 204static int malloc_hint;
@@ -386,7 +392,7 @@ map_pages(size_t pages)
386 errno = ENOMEM; 392 errno = ENOMEM;
387 return (NULL); 393 return (NULL);
388 } 394 }
389 tail = result + pages; 395 tail = result + pages + malloc_guard;
390 396
391 if (brk(tail) == (char *)-1) { 397 if (brk(tail) == (char *)-1) {
392#ifdef MALLOC_EXTRA_SANITY 398#ifdef MALLOC_EXTRA_SANITY
@@ -394,6 +400,8 @@ map_pages(size_t pages)
394#endif /* MALLOC_EXTRA_SANITY */ 400#endif /* MALLOC_EXTRA_SANITY */
395 return (NULL); 401 return (NULL);
396 } 402 }
403 if (malloc_guard)
404 mprotect(result + pages, malloc_pagesize, PROT_NONE);
397 405
398 last_index = ptr2index(tail) - 1; 406 last_index = ptr2index(tail) - 1;
399 malloc_brk = tail; 407 malloc_brk = tail;
@@ -500,6 +508,10 @@ malloc_init(void)
500 case 'd': malloc_stats = 0; break; 508 case 'd': malloc_stats = 0; break;
501 case 'D': malloc_stats = 1; break; 509 case 'D': malloc_stats = 1; break;
502#endif /* MALLOC_STATS */ 510#endif /* MALLOC_STATS */
511 case 'f': malloc_freeprot = 0; break;
512 case 'F': malloc_freeprot = 1; break;
513 case 'g': malloc_guard = 0; break;
514 case 'G': malloc_guard = malloc_pagesize; break;
503#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE)) 515#if defined(__FreeBSD__) || (defined(__OpenBSD__) && defined(MADV_FREE))
504 case 'h': malloc_hint = 0; break; 516 case 'h': malloc_hint = 0; break;
505 case 'H': malloc_hint = 1; break; 517 case 'H': malloc_hint = 1; break;
@@ -586,7 +598,7 @@ malloc_pages(size_t size)
586 struct pgfree *pf; 598 struct pgfree *pf;
587 u_long index; 599 u_long index;
588 600
589 size = pageround(size); 601 size = pageround(size) + malloc_guard;
590 602
591 p = NULL; 603 p = NULL;
592 /* Look for free pages before asking for more */ 604 /* Look for free pages before asking for more */
@@ -627,11 +639,16 @@ malloc_pages(size_t size)
627 break; 639 break;
628 } 640 }
629 641
642 size -= malloc_guard;
643
630#ifdef MALLOC_EXTRA_SANITY 644#ifdef MALLOC_EXTRA_SANITY
631 if (p != NULL && page_dir[ptr2index(p)] != MALLOC_FREE) 645 if (p != NULL && page_dir[ptr2index(p)] != MALLOC_FREE)
632 wrterror("(ES): allocated non-free page on free-list\n"); 646 wrterror("(ES): allocated non-free page on free-list\n");
633#endif /* MALLOC_EXTRA_SANITY */ 647#endif /* MALLOC_EXTRA_SANITY */
634 648
649 if ((malloc_guard || malloc_freeprot) && p != NULL)
650 mprotect(p, size, PROT_READ|PROT_WRITE);
651
635 size >>= malloc_pageshift; 652 size >>= malloc_pageshift;
636 653
637 /* Map new pages */ 654 /* Map new pages */
@@ -798,6 +815,26 @@ malloc_bytes(size_t size)
798 u += u; 815 u += u;
799 k++; 816 k++;
800 } 817 }
818
819 if (malloc_guard) {
820 /* Walk to a random position. */
821 i = arc4random() % bp->free;
822 while (i > 0) {
823 u += u;
824 k++;
825 if (k >= MALLOC_BITS) {
826 lp++;
827 u = 1;
828 k = 0;
829 }
830#ifdef MALLOC_EXTRA_SANITY
831 if (lp - bp->bits > (bp->total - 1) / MALLOC_BITS)
832 wrterror("chunk overflow\n");
833#endif /* MALLOC_EXTRA_SANITY */
834 if (*lp & u)
835 i--;
836 }
837 }
801 *lp ^= u; 838 *lp ^= u;
802 839
803 /* If there are no more free, remove from free-list */ 840 /* If there are no more free, remove from free-list */
@@ -992,13 +1029,17 @@ free_pages(void *ptr, int index, struct pginfo *info)
992 madvise(ptr, l, MADV_FREE); 1029 madvise(ptr, l, MADV_FREE);
993#endif 1030#endif
994 1031
1032 l += malloc_guard;
995 tail = (char *)ptr+l; 1033 tail = (char *)ptr+l;
996 1034
1035 if (malloc_freeprot)
1036 mprotect(ptr, tail - ptr, PROT_NONE);
1037
997 /* add to free-list */ 1038 /* add to free-list */
998 if (px == NULL) 1039 if (px == NULL)
999 px = imalloc(sizeof *px); /* This cannot fail... */ 1040 px = imalloc(sizeof *px); /* This cannot fail... */
1000 px->page = ptr; 1041 px->page = ptr;
1001 px->end = tail; 1042 px->end = tail;
1002 px->size = l; 1043 px->size = l;
1003 1044
1004 if (free_list.next == NULL) { 1045 if (free_list.next == NULL) {