#include <stdlib.h> #include <stdio.h> #include <time.h> #include <unistd.h> #ifdef USE_MTRACE #include <mcheck.h> #endif #ifdef DMALLOC #include <dmalloc.h> #endif #define BLOCK_SIZE 0x10000 #define N_ITERS 10000 int invalid_operations(int level, int is_array) { int i, *p; clock_t t; t = clock(); srand(1); for (i = 0; i != N_ITERS; ++i) { p = (int*)malloc(sizeof(int) * (rand()&0xfffff)); p[0] = 0; free(p); } p = 0; fprintf(stderr, "Time elapses: %.3f sec.\n", (float)(clock() - t) / CLOCKS_PER_SEC); { int *q, r[BLOCK_SIZE]; p = (int*)malloc(sizeof(int) * BLOCK_SIZE); q = (int*)malloc(sizeof(int) * BLOCK_SIZE); /* use q to "protect" the end of p */ fprintf(stderr, "address - end of p: %lx, start of q: %lx\n", (unsigned long)p+sizeof(int)*BLOCK_SIZE, (unsigned long)q); if (level >= 1 && is_array) { fprintf(stderr, "(1) Test for invalid read/write on an array..."); if (r[BLOCK_SIZE] == 6) p[0] = 1; r[BLOCK_SIZE+1] = 2; fprintf(stderr, "done.\n"); } if (level >= 2) { fprintf(stderr, "(2) Test for comparing uninitialized variables..."); if (p[0] == 5) p[0] = 1; fprintf(stderr, "done\n"); } if (level >= 3) { fprintf(stderr, "(3) Test for invalid read..."); if (p[BLOCK_SIZE+9] == 6) p[0] = 2; if (p[BLOCK_SIZE+100] == 6) p[0] = 3; fprintf(stderr, "done.\n"); } if (level >= 4) { fprintf(stderr, "(4) Test for invalid write..."); p[BLOCK_SIZE] = 0; p[BLOCK_SIZE+100] = 100; fprintf(stderr, "done\n"); } free(p); } if (level >= 5) { fprintf(stderr, "(5) Test for double free..."); free(p); fprintf(stderr, "done\n"); } return 0; } int main(int argc, char *argv[]) { int c, is_array, level; is_array = 1; level = 10; while ((c = getopt(argc, argv, "l:ah")) >= 0) { switch (c) { case 'l': level = atoi(optarg); break; case 'a': is_array = 0; break; case 'h': fprintf(stderr, "Usage: %s [-l <level>] [-a]\n", argv[0]); return 1; } } #ifdef USE_MTRACE setenv("MALLOC_TRACE", "mtrace.out", 1); mtrace(); #endif invalid_operations(level, is_array); return 0; }