/* * fda_free - check chunk of memory for overruns and free it */ void fda_free(void* p) { if (p) { size_t size; BlkHdr* bh = find_blk(p); void* bp; /* p already freed or not allocated? */ assert(0 != bh); assert(p == bh->buf); bp = BASE_PTR(p); /* buffer underflow? */ assert(DEADBEEF == *((size_t*) bp)); /* * buffer overflow? * Note: it's possible to have up to 3 bytes of unchecked space * between size and DEADBEEF */ size = BASE_SIZE(bh->size); assert(DEADBEEF == *((size_t*)(BYTE_PTR(bp) + size - S_SIZE))); SHRED_MEM(bp, size); free_blk(p); free(bp); } }
/* * fda_realloc - resize a buffer, force reallocation if new size is * larger than old size */ void* fda_realloc(void* p, size_t size, const char* file, int line) { void* np; size_t old_size; size_t blk_size; /* * don't allow malloc or free through realloc */ assert(0 != p); assert(0 < size); old_size = fda_sizeof(p); if (size < old_size) SHRED_MEM(BYTE_PTR(p) + size, old_size - size); else if (size > old_size) { void* t = fda_malloc(size, __FILE__, __LINE__); memmove(t, p, old_size); fda_free(p); p = t; } blk_size = BASE_SIZE(size); if ((np = realloc(BASE_PTR(p), blk_size)) == 0) { lowMemFn(); if ((np = realloc(BASE_PTR(p), blk_size)) == 0) noMemFn(); } /* * don't allow noMemFn to return */ assert(0 != np); *((size_t*)(BYTE_PTR(np) + blk_size - S_SIZE)) = DEADBEEF; np = BYTE_PTR(np) + S_SIZE; update_blk(p, np, size, file, line); /* * shred tail */ if (size > old_size) SHRED_MEM(BYTE_PTR(np) + old_size, size - old_size); return np; }
// reading and writing through a pointer field int main(void) { struct st *p; p = __VERIFIER_nondet_st(); assume(p > 0); BASE_PTR(p); if (p->x == 42) { if (p->next != 0) { PTR(p->next, sizeof(struct st)); p->next->y = 474; if (p->next->x == 526) { if (p->next->x + p->next->y == 1000) { __VERIFIER_error(); } } } } return 0; }