# HG changeset patch # User Gerd Moellmann # Date 972391262 0 # Node ID 08e5ab6d998feeb7971e8b757b5db875f74438cb # Parent d78254659f1dd99f7e66da3204336ddd87821946 (state_protected_p, last_state_size, last_heapinfo) [GC_MALLOC_CHECK && GC_PROTECT_MALLOC_STATE]: New variables. (protect_malloc_state) [GC_MALLOC_CHECK && GC_PROTECT_MALLOC_STATE]: New function. (PROTECT_MALLOC_STATE): New macro. (__malloc_initialize, morecore, _malloc_internal) (_free_internal) _realloc_internal): Use it to make _heapinfo read-only outside of gmalloc. diff -r d78254659f1d -r 08e5ab6d998f src/gmalloc.c --- a/src/gmalloc.c Tue Oct 24 12:40:08 2000 +0000 +++ b/src/gmalloc.c Tue Oct 24 12:41:02 2000 +0000 @@ -380,6 +380,53 @@ void (*__malloc_initialize_hook) PP ((void)); void (*__after_morecore_hook) PP ((void)); +#if defined GC_MALLOC_CHECK && defined GC_PROTECT_MALLOC_STATE + +/* Some code for hunting a bug writing into _heapinfo. + + Call this macro with argument PROT non-zero to protect internal + malloc state against writing to it, call it with a zero argument to + make it readable and writable. + + Note that this only works if BLOCKSIZE == page size, which is + the case on the i386. */ + +#include +#include + +static int state_protected_p; +static __malloc_size_t last_state_size; +static malloc_info *last_heapinfo; + +void +protect_malloc_state (protect_p) + int protect_p; +{ + /* If _heapinfo has been relocated, make sure its old location + isn't left read-only; it will be reused by malloc. */ + if (_heapinfo != last_heapinfo + && last_heapinfo + && state_protected_p) + mprotect (last_heapinfo, last_state_size, PROT_READ | PROT_WRITE); + + last_state_size = _heaplimit * sizeof *_heapinfo; + last_heapinfo = _heapinfo; + + if (protect_p != state_protected_p) + { + state_protected_p = protect_p; + if (mprotect (_heapinfo, last_state_size, + protect_p ? PROT_READ : PROT_READ | PROT_WRITE) != 0) + abort (); + } +} + +#define PROTECT_MALLOC_STATE(PROT) protect_malloc_state(PROT) + +#else +#define PROTECT_MALLOC_STATE(PROT) /* empty */ +#endif + /* Aligned allocation. */ static __ptr_t align PP ((__malloc_size_t)); @@ -492,6 +539,7 @@ register_heapinfo (); __malloc_initialized = 1; + PROTECT_MALLOC_STATE (1); return 1; } @@ -516,6 +564,8 @@ if (result == NULL) return NULL; + PROTECT_MALLOC_STATE (0); + /* Check if we need to grow the info table. */ if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize) { @@ -599,6 +649,7 @@ it can relocate or resize the info table. */ _heaplimit = 0; _free_internal (oldinfo); + PROTECT_MALLOC_STATE (0); /* The new heap limit includes the new table just allocated. */ _heaplimit = BLOCK ((char *) newinfo + heapsize * sizeof (malloc_info)); @@ -632,6 +683,8 @@ return NULL; #endif + PROTECT_MALLOC_STATE (0); + if (size < sizeof (struct list)) size = sizeof (struct list); @@ -680,11 +733,15 @@ and break it into fragments, returning the first. */ #ifdef GC_MALLOC_CHECK result = _malloc_internal (BLOCKSIZE); + PROTECT_MALLOC_STATE (0); #else result = malloc (BLOCKSIZE); #endif if (result == NULL) - return NULL; + { + PROTECT_MALLOC_STATE (1); + return NULL; + } /* Link all fragments but the first into the free list. */ next = (struct list *) ((char *) result + (1 << log)); @@ -803,6 +860,7 @@ _heapinfo[block + blocks].busy.info.size = -blocks; } + PROTECT_MALLOC_STATE (1); return result; } @@ -913,6 +971,8 @@ if (ptr == NULL) return; + PROTECT_MALLOC_STATE (0); + for (l = _aligned_blocks; l != NULL; l = l->next) if (l->aligned == ptr) { @@ -1035,6 +1095,7 @@ /* Allocate new space for the info table and move its data. */ newinfo = (malloc_info *) _malloc_internal (info_blocks * BLOCKSIZE); + PROTECT_MALLOC_STATE (0); memmove (newinfo, _heapinfo, info_blocks * BLOCKSIZE); _heapinfo = newinfo; @@ -1133,6 +1194,8 @@ } break; } + + PROTECT_MALLOC_STATE (1); } /* Return memory to the heap. */ @@ -1296,6 +1359,8 @@ block = BLOCK (ptr); + PROTECT_MALLOC_STATE (0); + type = _heapinfo[block].busy.type; switch (type) { @@ -1344,6 +1409,7 @@ _heaplimit = 0; _free_internal (ptr); result = _malloc_internal (size); + PROTECT_MALLOC_STATE (0); if (_heaplimit == 0) _heaplimit = oldlimit; if (result == NULL) @@ -1387,6 +1453,7 @@ break; } + PROTECT_MALLOC_STATE (1); return result; }