Home | History | Annotate | Download | only in tests
      1 #include <unistd.h>
      2 #include "tests/sys_mman.h"
      3 #include <assert.h>
      4 #include <stdlib.h>
      5 
      6 #include "../drd.h"
      7 
      8 #define SUPERBLOCK_SIZE    100000
      9 
     10 //-------------------------------------------------------------------------
     11 // Allocator
     12 //-------------------------------------------------------------------------
     13 
     14 void* get_superblock(void)
     15 {
     16    void* p = mmap( 0, SUPERBLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
     17                    MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 );
     18 
     19    assert(p != ((void*)(-1)));
     20 
     21    return p;
     22 }
     23 
     24 // has a redzone
     25 static void* custom_alloc(int size)
     26 {
     27 #define RZ  8
     28    static void* hp     = 0;    // current heap pointer
     29    static void* hp_lim = 0;    // maximum usable byte in current block
     30    int          size2  = size + RZ*2;
     31    void*        p;
     32 
     33    if (hp + size2 > hp_lim) {
     34       hp = get_superblock();
     35       hp_lim = hp + SUPERBLOCK_SIZE - 1;
     36    }
     37 
     38    p = hp + RZ;
     39    hp += size2;
     40 
     41    VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 );
     42    return (void*)p;
     43 }
     44 
     45 static void custom_free(void* p)
     46 {
     47    // don't actually free any memory... but mark it as freed
     48    VALGRIND_FREELIKE_BLOCK( p, RZ );
     49 }
     50 #undef RZ
     51 
     52 
     53 
     54 //-------------------------------------------------------------------------
     55 // Rest
     56 //-------------------------------------------------------------------------
     57 
     58 void make_leak(void)
     59 {
     60    int* array2 __attribute__((unused)) = custom_alloc(sizeof(int) * 10);
     61    array2 = 0;          // leak
     62    return;
     63 }
     64 
     65 int main(void)
     66 {
     67    int* array;
     68    int* array3;
     69 
     70    array = custom_alloc(sizeof(int) * 10);
     71    array[8]  = 8;
     72    array[9]  = 8;
     73    array[10] = 10;      // invalid write (ok w/o MALLOCLIKE -- in superblock)
     74 
     75    custom_free(array);  // ok
     76 
     77    custom_free(NULL);   // invalid free (ok without MALLOCLIKE)
     78 
     79    array3 = malloc(sizeof(int) * 10);
     80    custom_free(array3); // mismatched free (ok without MALLOCLIKE)
     81 
     82    make_leak();
     83    return array[0];     // use after free (ok without MALLOCLIKE)
     84                         // (nb: initialised because is_zeroed==1 above)
     85                         // unfortunately not identified as being in a free'd
     86                         // block because the freeing of the block and shadow
     87                         // chunk isn't postponed.
     88 
     89    // leak from make_leak()
     90 }
     91