/* This file is in the public domain. */ #define FENCE #include #include #include #include #include "malwrap.h" #define FENCE_BEFORE 16 #define FENCE_AFTER 16 #define MHSIZE 65536 static char malhist[2][MHSIZE]; static char *othermalhist = &malhist[1][0]; static char *curmalhist = &malhist[0][0]; static int mhptr = 0; static int recursion = 0; void mhdump(int nb, const char *fn) { int fd; if (fn == 0) { fd = dup(1); } else { fd = open(fn,O_WRONLY|O_CREAT|O_TRUNC,0666); if (fd < 0) { write(2,"open ",5); write(2,fn,strlen(fn)); write(2," failed\n",8); return; } } if (nb > MHSIZE) nb = MHSIZE; if (nb > mhptr) { write(fd,&othermalhist[MHSIZE-(nb-mhptr)],nb-mhptr); write(fd,&curmalhist[0],mhptr); } else { write(fd,&curmalhist[mhptr-nb],nb); } close(fd); } static void mh_c(char c) { if (mhptr >= MHSIZE) { char *t; t = curmalhist; curmalhist = othermalhist; othermalhist = t; mhptr = 0; } curmalhist[mhptr++] = c; } static void mh_s(const char *s) { for (;*s;s++) mh_c(*s); } static void mh_u(unsigned long int v) { char nbuf[32]; int i; i = 0; do { nbuf[i++] = '0' + (v % 10); v /= 10; } while (v); while (i > 0) mh_c(nbuf[--i]); } static void mh_x(unsigned long int v) { int n; mh_c('0'); mh_c('x'); for (n=(sizeof(v)*8)-4;(n>0)&&!(v>>n);n-=4) ; for (;n>=0;n-=4) mh_c("0123456789abcdef"[(v>>n)&0xf]); } #ifdef FENCE #if FENCE_BEFORE != 16 #error FENCE_BEFORE wrong for fence code #endif #if FENCE_AFTER != 16 #error FENCE_AFTER wrong for fence code #endif static void gen_fences(unsigned char *before, unsigned char *after, void *addr, int nb) { int i; for (i=0;i<16;i++) { before[i] = (i * 0x10) | ((15-i) * 0x01); after[i] = (i * 0x01) | ((15-i) * 0x10); } if (sizeof(void *)+sizeof(int) > 12) abort(); bcopy(&addr,&before[3],sizeof(void *)); bcopy(&nb,&before[3+sizeof(void *)],sizeof(int)); } static void set_fences(void *blk, int nb) { gen_fences(((char *)blk)-16,((char *)blk)+nb,blk,nb); } static void check_fences(void *blk) { int nb; unsigned char before[16]; unsigned char after[16]; bcopy(((char *)blk)-13+sizeof(void *),&nb,sizeof(int)); gen_fences(&before[0],&after[0],blk,nb); if (bcmp(&before[0],((char *)blk)-16,16)) abort(); if (bcmp(&after[0],((char *)blk)+nb,16)) abort(); } static void wreck_fences(void *blk) { int nb; bcopy(((char *)blk)-13+sizeof(void *),&nb,sizeof(int)); bzero(((char *)blk)-16,16); bzero(((char *)blk)+nb,16); } #else #undef FENCE_BEFORE #undef FENCE_AFTER #define FENCE_BEFORE 0 #define FENCE_AFTER 0 #endif void *wrapped_malloc(size_t nb, unsigned long int pc) { void *rv; if (recursion) abort(); recursion ++; mh_s("malloc("); mh_u(nb); mh_s(")@"); mh_x(pc); mh_s("="); rv = __real_malloc(FENCE_BEFORE+nb+FENCE_AFTER); #ifdef FENCE if (rv) { rv = FENCE_BEFORE + (char *)rv; set_fences(rv,nb); } #endif mh_x((unsigned long int)rv); mh_s("\n"); recursion --; if (recursion) abort(); return(rv); } void *wrapped_calloc(size_t a, size_t b, unsigned long int pc) { void *rv; if (recursion) abort(); recursion ++; mh_s("calloc("); mh_u(a); mh_s(","); mh_u(b); mh_s(")@"); mh_x(pc); mh_s("="); /* Calling __real_calloc here can lead to the recursion test tripping, because some implementations of calloc call malloc. */ rv = __real_malloc(FENCE_BEFORE+(a*b)+FENCE_AFTER); #ifdef FENCE if (rv) { rv = FENCE_BEFORE + (char *)rv; set_fences(rv,a*b); } #endif bzero(rv,a*b); mh_x((unsigned long int)rv); mh_s("\n"); recursion --; if (recursion) abort(); return(rv); } void *wrapped_realloc(void *blk, size_t nb, unsigned long int pc) { void *rv; if (recursion) abort(); recursion ++; mh_s("realloc("); mh_x((unsigned long int)blk); mh_s(","); mh_u(nb); mh_s(")@"); mh_x(pc); mh_s("="); #ifdef FENCE if (blk) { check_fences(blk); wreck_fences(blk); } rv = __real_realloc(blk?((char *)blk)-FENCE_BEFORE:0,FENCE_BEFORE+nb+FENCE_AFTER); if (rv) { rv = FENCE_BEFORE + (char *)rv; set_fences(rv,nb); } #else rv = __real_realloc(blk,nb); #endif mh_x((unsigned long int)rv); mh_s("\n"); recursion --; if (recursion) abort(); return(rv); } void wrapped_free(void *blk, unsigned long int pc) { if (recursion) abort(); recursion ++; mh_s("free("); mh_x((unsigned long int)blk); mh_s(")@"); mh_x(pc); #ifdef FENCE if (blk) { check_fences(blk); wreck_fences(blk); } __real_free(blk?((char *)blk)-FENCE_BEFORE:0); #else __real_free(blk); #endif mh_s("\n"); recursion --; if (recursion) abort(); }