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