2 #include "tests/sys_mman.h"
6 #include "../memcheck.h"
8 #define SUPERBLOCK_SIZE 100000
10 //-------------------------------------------------------------------------
12 //-------------------------------------------------------------------------
14 void* get_superblock(void)
16 void* p
= mmap( 0, SUPERBLOCK_SIZE
, PROT_READ
|PROT_WRITE
|PROT_EXEC
,
17 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0 );
19 assert(p
!= ((void*)(-1)));
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()
24 // with redzones, better not to have it
25 (void) VALGRIND_MAKE_MEM_NOACCESS(p
, SUPERBLOCK_SIZE
);
31 static void* custom_alloc(int size
)
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;
39 if (hp
+ size2
> hp_lim
) {
40 hp
= get_superblock();
41 hp_lim
= hp
+ SUPERBLOCK_SIZE
- 1;
47 VALGRIND_MALLOCLIKE_BLOCK( p
, size
, RZ
, /*is_zeroed*/1 );
51 static void custom_free(void* p
)
53 // don't actually free any memory... but mark it as freed
54 VALGRIND_FREELIKE_BLOCK( p
, RZ
);
57 static void checkredzone(void)
59 /* check that accessing the redzone of a MALLOCLIKE block
60 is detected when the superblock was not marked as no access. */
61 char superblock
[1 + RZ
+ 20 + RZ
+ 1];
62 char *p
= 1 + RZ
+ superblock
;
65 // Indicate we have allocated p from our superblock:
66 VALGRIND_MALLOCLIKE_BLOCK( p
, 20, RZ
, /*is_zeroed*/1 );
68 p
[-1] = p
[0]; // error expected
69 p
[-RZ
] = p
[0]; // error expected
70 p
[-RZ
-1] = p
[0]; // no error expected
73 p
[19 + 1] = p
[0]; // error expected
74 p
[19 + RZ
] = p
[0]; // error expected
75 p
[19 + RZ
+ 1] = p
[0]; // no error expected
77 VALGRIND_FREELIKE_BLOCK( p
, RZ
);
79 // Now, indicate we have re-allocated p from our superblock
80 // but with only a size 10.
81 VALGRIND_MALLOCLIKE_BLOCK( p
, 10, RZ
, /*is_zeroed*/1 );
83 p
[-1] = p
[0]; // error expected
84 p
[-RZ
] = p
[0]; // error expected
85 p
[-RZ
-1] = p
[0]; // no error expected
88 p
[9 + 1] = p
[0]; // error expected
89 p
[9 + RZ
] = p
[0]; // error expected
90 p
[9 + RZ
+ 1] = p
[0]; // no error expected
92 VALGRIND_FREELIKE_BLOCK( p
, RZ
);
98 //-------------------------------------------------------------------------
100 //-------------------------------------------------------------------------
104 int* array2
__attribute__((unused
)) = custom_alloc(sizeof(int) * 10);
114 array
= custom_alloc(sizeof(int) * 10);
117 array
[10] = 10; // invalid write (ok w/o MALLOCLIKE -- in superblock)
119 VALGRIND_RESIZEINPLACE_BLOCK(array
, sizeof(int) * 10, sizeof(int) * 5, RZ
);
121 array
[5] = 9; // invalid write
123 // Make the entire array defined again such that it can be verified whether
124 // the red zone is marked properly when resizing in place.
125 (void) VALGRIND_MAKE_MEM_DEFINED(array
, sizeof(int) * 10);
127 VALGRIND_RESIZEINPLACE_BLOCK(array
, sizeof(int) * 5, sizeof(int) * 7, RZ
);
128 if (array
[5]) array
[4]++; // uninitialized read of array[5]
131 array
[7] = 8; // invalid write
134 VALGRIND_RESIZEINPLACE_BLOCK(array
+1, sizeof(int) * 7, sizeof(int) * 8, RZ
);
136 custom_free(array
); // ok
138 custom_free((void*)0x1); // invalid free
140 array3
= malloc(sizeof(int) * 10);
141 custom_free(array3
); // mismatched free (ok without MALLOCLIKE)
144 x
= array
[0]; // use after free (ok without MALLOCLIKE/MAKE_MEM_NOACCESS)
146 // Bug 137073: passing 0 to MALLOCLIKE_BLOCK was causing an assertion
147 // failure. Test for this (and likewise for FREELIKE_BLOCK).
148 VALGRIND_MALLOCLIKE_BLOCK(0,0,0,0);
149 VALGRIND_FREELIKE_BLOCK(0,0);
155 // leak from make_leak()