Skip to content

Commit 72e9d73

Browse files
authored
Check for overflow in memory allocations (#64)
1 parent 2724b47 commit 72e9d73

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

memprof.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ static zend_mm_heap * orig_zheap = NULL;
237237
#define ALLOC_LIST_INSERT_HEAD(head, elem) alloc_list_insert_head(head, elem)
238238
#define ALLOC_LIST_REMOVE(elem) alloc_list_remove(elem)
239239

240-
static void out_of_memory() {
240+
ZEND_NORETURN static void out_of_memory() {
241241
fprintf(stderr, "memprof: System out of memory, try lowering memory_limit\n");
242242
exit(1);
243243
}
@@ -258,6 +258,22 @@ static inline void * realloc_check(void * ptr, size_t size) {
258258
return newptr;
259259
}
260260

261+
ZEND_NORETURN static void int_overflow() {
262+
fprintf(stderr, "memprof: Integer overflow in memory allocation, try lowering memory_limit\n");
263+
exit(1);
264+
}
265+
266+
static inline size_t safe_size(size_t nmemb, size_t size, size_t offset) {
267+
size_t r = nmemb * size;
268+
if (UNEXPECTED(nmemb != 0 && r / nmemb != size)) {
269+
int_overflow();
270+
}
271+
if (UNEXPECTED(SIZE_MAX - r < offset)) {
272+
int_overflow();
273+
}
274+
return r + offset;
275+
}
276+
261277
static inline void alloc_init(alloc * alloc, size_t size) {
262278
alloc->size = size;
263279
alloc->list.le_next = NULL;
@@ -331,10 +347,10 @@ static void alloc_buckets_grow(alloc_buckets * buckets)
331347
alloc_bucket_item * bucket;
332348

333349
buckets->nbuckets++;
334-
buckets->buckets = realloc_check(buckets->buckets, sizeof(*buckets->buckets)*buckets->nbuckets);
350+
buckets->buckets = realloc_check(buckets->buckets, safe_size(buckets->nbuckets, sizeof(*buckets->buckets), 0));
335351

336-
buckets->growsize <<= 1;
337-
bucket = malloc_check(sizeof(*bucket)*buckets->growsize);
352+
buckets->growsize = safe_size(2, buckets->growsize, 0);
353+
bucket = malloc_check(safe_size(buckets->growsize, sizeof(*bucket), 0));
338354
buckets->buckets[buckets->nbuckets-1] = bucket;
339355

340356
for (i = 1; i < buckets->growsize; ++i) {
@@ -410,7 +426,7 @@ static void frame_dtor(zval * pDest)
410426
static void init_frame(frame * f, frame * prev, char * name, size_t name_len)
411427
{
412428
zend_hash_init(&f->next_cache, 0, NULL, frame_dtor, 0);
413-
f->name = malloc_check(name_len+1);
429+
f->name = malloc_check(safe_size(1, name_len, 1));
414430
memcpy(f->name, name, name_len+1);
415431
f->name_len = name_len;
416432
f->calls = 0;

0 commit comments

Comments
 (0)