blob: 0a6ec8b4eae46e06b18317d83cb540399cf65678 [file] [log] [blame]
njn10785452003-05-20 16:38:24 +00001#include <unistd.h>
2#include <sys/mman.h>
3#include <assert.h>
4#include <stdlib.h>
5
6#include "../memcheck.h"
7
8#define SUPERBLOCK_SIZE 100000
9
10//-------------------------------------------------------------------------
11// Allocator
12//-------------------------------------------------------------------------
13
14void* 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 // Mark it no access; although it's addressible we don't want the
22 // program to be using it unless its handed out by custom_alloc()
23
24 // with redzones, better not to have it
25 VALGRIND_MAKE_NOACCESS(p, SUPERBLOCK_SIZE);
26
27 return p;
28}
29
30// has a redzone
31static void* custom_alloc(int size)
32{
33#define RZ 8
34 static void* hp = 0; // current heap pointer
35 static void* hp_lim = 0; // maximum usable byte in current block
36 int size2 = size + RZ*2;
37 void* p;
38
39 if (hp + size2 > hp_lim) {
40 hp = get_superblock();
41 hp_lim = hp + SUPERBLOCK_SIZE - 1;
42 }
43
44 p = hp + RZ;
45 hp += size2;
46
47 VALGRIND_MALLOCLIKE_BLOCK( p, size, RZ, /*is_zeroed*/1 );
48 return (void*)p;
49}
50
51static void custom_free(void* p)
52{
53 // don't actually free any memory... but mark it as freed
54 VALGRIND_FREELIKE_BLOCK( p, RZ );
55}
56#undef RZ
57
58
59
60//-------------------------------------------------------------------------
61// Rest
62//-------------------------------------------------------------------------
63
64void make_leak(void)
65{
66 int* array2 = custom_alloc(sizeof(int) * 10);
67 array2 = 0; // leak
68 return;
69}
70
71int main(void)
72{
73 int* array;
74 int* array3;
75
76 array = custom_alloc(sizeof(int) * 10);
77 array[8] = 8;
78 array[9] = 8;
79 array[10] = 10; // invalid write (ok w/o MALLOCLIKE -- in superblock)
80
81 custom_free(array); // ok
82
83 custom_free(NULL); // invalid free (ok without MALLOCLIKE)
84
85 array3 = malloc(sizeof(int) * 10);
86 custom_free(array3); // mismatched free (ok without MALLOCLIKE)
87
88 make_leak();
89 return array[0]; // use after free (ok without MALLOCLIKE/MAKE_NOACCESS)
90 // (nb: initialised because is_zeroed==1 above)
91 // unfortunately not identified as being in a free'd
92 // block because the freeing of the block and shadow
93 // chunk isn't postponed.
94
95 // leak from make_leak()
96}