]>
git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.5.2/examples/alloc-torture/duk_alloc_torture.c
2 * Example torture memory allocator with memory wiping and check for
3 * out-of-bounds writes.
5 * Allocation structure:
7 * [ alloc_hdr | red zone before | user area | red zone after ]
10 * | `--- pointer returned to Duktape
11 * `--- underlying malloc ptr
20 #define RED_ZONE_SIZE 16
21 #define RED_ZONE_BYTE 0x5a
22 #define INIT_BYTE 0xa5
23 #define WIPE_BYTE 0x27
26 /* The double value in the union is there to ensure alignment is
27 * good for IEEE doubles too. In many 32-bit environments 4 bytes
28 * would be sufficiently aligned and the double value is unnecessary.
36 static void check_red_zone(alloc_hdr
*hdr
) {
41 unsigned char *userptr
;
44 userptr
= (unsigned char *) hdr
+ sizeof(alloc_hdr
) + RED_ZONE_SIZE
;
47 p
= (unsigned char *) hdr
+ sizeof(alloc_hdr
);
48 for (i
= 0; i
< RED_ZONE_SIZE
; i
++) {
49 if (p
[i
] != RED_ZONE_BYTE
) {
54 fprintf(stderr
, "RED ZONE CORRUPTED BEFORE ALLOC: hdr=%p ptr=%p size=%ld\n",
55 (void *) hdr
, (void *) userptr
, (long) size
);
60 p
= (unsigned char *) hdr
+ sizeof(alloc_hdr
) + RED_ZONE_SIZE
+ size
;
61 for (i
= 0; i
< RED_ZONE_SIZE
; i
++) {
62 if (p
[i
] != RED_ZONE_BYTE
) {
67 fprintf(stderr
, "RED ZONE CORRUPTED AFTER ALLOC: hdr=%p ptr=%p size=%ld\n",
68 (void *) hdr
, (void *) userptr
, (long) size
);
73 void *duk_alloc_torture(void *udata
, duk_size_t size
) {
76 (void) udata
; /* Suppress warning. */
82 p
= (unsigned char *) malloc(size
+ sizeof(alloc_hdr
) + 2 * RED_ZONE_SIZE
);
87 ((alloc_hdr
*) (void *) p
)->u
.sz
= size
;
88 p
+= sizeof(alloc_hdr
);
89 memset((void *) p
, RED_ZONE_BYTE
, RED_ZONE_SIZE
);
91 memset((void *) p
, INIT_BYTE
, size
);
93 memset((void *) p
, RED_ZONE_BYTE
, RED_ZONE_SIZE
);
98 void *duk_realloc_torture(void *udata
, void *ptr
, duk_size_t size
) {
99 unsigned char *p
, *old_p
;
102 (void) udata
; /* Suppress warning. */
104 /* Handle the ptr-NULL vs. size-zero cases explicitly to minimize
105 * platform assumptions. You can get away with much less in specific
106 * well-behaving environments.
110 old_p
= (unsigned char *) ptr
- sizeof(alloc_hdr
) - RED_ZONE_SIZE
;
111 old_size
= ((alloc_hdr
*) (void *) old_p
)->u
.sz
;
112 check_red_zone((alloc_hdr
*) (void *) old_p
);
115 memset((void *) old_p
, WIPE_BYTE
, old_size
+ sizeof(alloc_hdr
) + 2 * RED_ZONE_SIZE
);
116 free((void *) old_p
);
119 /* Force address change on every realloc. */
120 p
= (unsigned char *) malloc(size
+ sizeof(alloc_hdr
) + 2 * RED_ZONE_SIZE
);
125 ((alloc_hdr
*) (void *) p
)->u
.sz
= size
;
126 p
+= sizeof(alloc_hdr
);
127 memset((void *) p
, RED_ZONE_BYTE
, RED_ZONE_SIZE
);
129 if (size
> old_size
) {
130 memcpy((void *) p
, (void *) (old_p
+ sizeof(alloc_hdr
) + RED_ZONE_SIZE
), old_size
);
131 memset((void *) (p
+ old_size
), INIT_BYTE
, size
- old_size
);
133 memcpy((void *) p
, (void *) (old_p
+ sizeof(alloc_hdr
) + RED_ZONE_SIZE
), size
);
136 memset((void *) p
, RED_ZONE_BYTE
, RED_ZONE_SIZE
);
139 memset((void *) old_p
, WIPE_BYTE
, old_size
+ sizeof(alloc_hdr
) + 2 * RED_ZONE_SIZE
);
140 free((void *) old_p
);
148 p
= (unsigned char *) malloc(size
+ sizeof(alloc_hdr
) + 2 * RED_ZONE_SIZE
);
153 ((alloc_hdr
*) (void *) p
)->u
.sz
= size
;
154 p
+= sizeof(alloc_hdr
);
155 memset((void *) p
, RED_ZONE_BYTE
, RED_ZONE_SIZE
);
157 memset((void *) p
, INIT_BYTE
, size
);
159 memset((void *) p
, RED_ZONE_BYTE
, RED_ZONE_SIZE
);
166 void duk_free_torture(void *udata
, void *ptr
) {
170 (void) udata
; /* Suppress warning. */
176 p
= (unsigned char *) ptr
- sizeof(alloc_hdr
) - RED_ZONE_SIZE
;
177 old_size
= ((alloc_hdr
*) (void *) p
)->u
.sz
;
179 check_red_zone((alloc_hdr
*) (void *) p
);
180 memset((void *) p
, WIPE_BYTE
, old_size
+ sizeof(alloc_hdr
) + 2 * RED_ZONE_SIZE
);