/* Reproduce a GNU malloc bug. */ #include <malloc.h> #include <stdio.h> #include <string.h> #define size_t unsigned int /* Defined as global variables to avoid warnings about unused variables. */ char *dummy0; char *dummy1; char *fill_info_table1; int main (int argc, char *argv[]) { char *over_top; size_t over_top_size = 0x3000; char *over_top_dup; size_t over_top_dup_size = 0x7000; char *x; size_t i; /* Here's what memory is supposed to look like (hex): size contents 3000 original_info_table, later fill_info_table1 3fa000 dummy0 3fa000 dummy1 6000 info_table_2 3000 over_top */ /* mem: original_info_table */ dummy0 = malloc (0x3fa000); /* mem: original_info_table, dummy0 */ dummy1 = malloc (0x3fa000); /* mem: free, dummy0, dummy1, info_table_2 */ fill_info_table1 = malloc (0x3000); /* mem: fill_info_table1, dummy0, dummy1, info_table_2 */ x = malloc (0x1000); free (x); /* mem: fill_info_table1, dummy0, dummy1, info_table_2, freexx */ /* This is what loses; info_table_2 and freexx get combined unbeknownst to mmalloc, and mmalloc puts over_top in a section of memory which is on the free list as part of another block (where info_table_2 had been). */ over_top = malloc (over_top_size); over_top_dup = malloc (over_top_dup_size); memset (over_top, 0, over_top_size); memset (over_top_dup, 1, over_top_dup_size); for (i = 0; i < over_top_size; ++i) if (over_top[i] != 0) { printf ("FAIL: malloc expands info table\n"); return 0; } for (i = 0; i < over_top_dup_size; ++i) if (over_top_dup[i] != 1) { printf ("FAIL: malloc expands info table\n"); return 0; } printf ("PASS: malloc expands info table\n"); return 0; }