DF-0785 / harness_fixed.c
/* DF-0785 harness WITH the proposed fix: kmalloc(max(blsize,rdsize)). * Identical to harness.c except the poisoned allocation sizes the buffer to * max(blsize,rdsize) -- so the rdsize-byte memcpy fits and no overflow occurs. * Build: cc -O2 -o harness_fixed harness_fixed.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <sys/mman.h> #include <unistd.h> static long PAGE=0; static unsigned char *poison_alloc(uint32_t n){ char *base=mmap(NULL,PAGE*2,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0); if(base==MAP_FAILED){perror("mmap");exit(2);} if(mprotect(base+PAGE,PAGE,PROT_NONE)!=0){perror("mprotect");exit(2);} return (unsigned char*)(base+PAGE-n); } int main(int argc,char**argv){ PAGE=sysconf(_SC_PAGESIZE); uint32_t blsize=(argc>1)?(uint32_t)strtoul(argv[1],0,0):16; uint32_t rdsize=(argc>2)?(uint32_t)strtoul(argv[2],0,0):200; uint32_t allocsz = (blsize<rdsize)?rdsize:blsize; /* <-- THE FIX */ printf("[harness-fixed] blsize=%u rdsize=%u -> kmalloc(max)=%u\n",blsize,rdsize,allocsz); unsigned char *attacker=malloc(rdsize); memset(attacker,0x44,rdsize); unsigned char *rdbuf=poison_alloc(allocsz); printf("[harness-fixed] rdbuf=%p (last %u bytes of page; next page PROT_NONE)\n",(void*)rdbuf,allocsz); printf("[harness-fixed] performing memcpy of %u bytes (fits in %u-byte buffer)...\n",rdsize,allocsz); fflush(stdout); memcpy(rdbuf,attacker,rdsize); /* no overflow: allocsz>=rdsize */ printf("[harness-fixed] memcpy completed cleanly -- NO OVERFLOW (fix effective)\n"); return 0; } |