@@ -237,7 +237,7 @@ static zend_mm_heap * orig_zheap = NULL;
237
237
#define ALLOC_LIST_INSERT_HEAD (head , elem ) alloc_list_insert_head(head, elem)
238
238
#define ALLOC_LIST_REMOVE (elem ) alloc_list_remove(elem)
239
239
240
- static void out_of_memory () {
240
+ ZEND_NORETURN static void out_of_memory () {
241
241
fprintf (stderr , "memprof: System out of memory, try lowering memory_limit\n" );
242
242
exit (1 );
243
243
}
@@ -258,6 +258,22 @@ static inline void * realloc_check(void * ptr, size_t size) {
258
258
return newptr ;
259
259
}
260
260
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
+
261
277
static inline void alloc_init (alloc * alloc , size_t size ) {
262
278
alloc -> size = size ;
263
279
alloc -> list .le_next = NULL ;
@@ -331,10 +347,10 @@ static void alloc_buckets_grow(alloc_buckets * buckets)
331
347
alloc_bucket_item * bucket ;
332
348
333
349
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 ) );
335
351
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 ) );
338
354
buckets -> buckets [buckets -> nbuckets - 1 ] = bucket ;
339
355
340
356
for (i = 1 ; i < buckets -> growsize ; ++ i ) {
@@ -410,7 +426,7 @@ static void frame_dtor(zval * pDest)
410
426
static void init_frame (frame * f , frame * prev , char * name , size_t name_len )
411
427
{
412
428
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 ) );
414
430
memcpy (f -> name , name , name_len + 1 );
415
431
f -> name_len = name_len ;
416
432
f -> calls = 0 ;
0 commit comments