diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 15:22:37 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 15:22:37 +0000 |
commit | 19ca40f571f10833b02548789b53d57fd685a437 (patch) | |
tree | 46fc3cee9c8bce8ee346650a77ecc5f36253e9a3 | |
parent | 7eb36bf69cf0fbbe03c489954b689cb23cab500a (diff) | |
download | glibc-19ca40f571f10833b02548789b53d57fd685a437.tar glibc-19ca40f571f10833b02548789b53d57fd685a437.tar.gz glibc-19ca40f571f10833b02548789b53d57fd685a437.tar.bz2 glibc-19ca40f571f10833b02548789b53d57fd685a437.zip |
2007-05-07 Ulrich Drepper <drepper@redhat.com>
Jakub Jelinek <jakub@redhat.com>
* malloc/arena.c (heap_info): Add mprotect_size field, adjust pad.
(new_heap): Initialize mprotect_size.
(grow_heap): When growing, only mprotect from mprotect_size till
new_size if mprotect_size is smaller. When shrinking, use PROT_NONE
MMAP for __libc_enable_secure only, otherwise use MADV_DONTNEED.
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | malloc/arena.c | 34 |
2 files changed, 36 insertions, 7 deletions
@@ -1,3 +1,12 @@ +2007-05-07 Ulrich Drepper <drepper@redhat.com> + Jakub Jelinek <jakub@redhat.com> + + * malloc/arena.c (heap_info): Add mprotect_size field, adjust pad. + (new_heap): Initialize mprotect_size. + (grow_heap): When growing, only mprotect from mprotect_size till + new_size if mprotect_size is smaller. When shrinking, use PROT_NONE + MMAP for __libc_enable_secure only, otherwise use MADV_DONTNEED. + 2007-05-06 Ulrich Drepper <drepper@redhat.com> * stdio-common/vfprintf.c (process_string_arg): Optimize diff --git a/malloc/arena.c b/malloc/arena.c index 2179174d64..84decaff0e 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -59,10 +59,12 @@ typedef struct _heap_info { mstate ar_ptr; /* Arena for this heap. */ struct _heap_info *prev; /* Previous heap. */ size_t size; /* Current size in bytes. */ + size_t mprotect_size; /* Size in bytes that has been mprotected + PROT_READ|PROT_WRITE. */ /* Make sure the following data is properly aligned, particularly that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of - MALLOG_ALIGNMENT. */ - char pad[-5 * SIZE_SZ & MALLOC_ALIGN_MASK]; + MALLOC_ALIGNMENT. */ + char pad[-6 * SIZE_SZ & MALLOC_ALIGN_MASK]; } heap_info; /* Get a compile-time error if the heap_info padding is not correct @@ -692,6 +694,7 @@ new_heap(size, top_pad) size_t size, top_pad; } h = (heap_info *)p2; h->size = size; + h->mprotect_size = size; THREAD_STAT(stat_n_heaps++); return h; } @@ -714,17 +717,34 @@ grow_heap(h, diff) heap_info *h; long diff; new_size = (long)h->size + diff; if((unsigned long) new_size > (unsigned long) HEAP_MAX_SIZE) return -1; - if(mprotect((char *)h + h->size, diff, PROT_READ|PROT_WRITE) != 0) - return -2; + if((unsigned long) new_size > h->mprotect_size) { + if (mprotect((char *)h + h->mprotect_size, + (unsigned long) new_size - h->mprotect_size, + PROT_READ|PROT_WRITE) != 0) + return -2; + h->mprotect_size = new_size; + } } else { new_size = (long)h->size + diff; if(new_size < (long)sizeof(*h)) return -1; /* Try to re-map the extra heap space freshly to save memory, and make it inaccessible. */ - if((char *)MMAP((char *)h + new_size, -diff, PROT_NONE, - MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED) - return -2; +#ifdef _LIBC + if (__builtin_expect (__libc_enable_secure, 0)) +#else + if (1) +#endif + { + if((char *)MMAP((char *)h + new_size, -diff, PROT_NONE, + MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED) + return -2; + h->mprotect_size = new_size; + } +#ifdef _LIBC + else + madvise ((char *)h + new_size, -diff, MADV_DONTNEED); +#endif /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/ } h->size = new_size; |