From 1709b7ddc6f0856be42640524f4e7fbff08035ac Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 3 May 2016 20:57:55 +0200 Subject: alloc: check multiplications for overflows --- src/alloc.h | 33 ++++++++++++++++++++++++++++++++- src/vector.c | 2 +- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/alloc.h b/src/alloc.h index 0b03242..eae752f 100644 --- a/src/alloc.h +++ b/src/alloc.h @@ -48,6 +48,28 @@ static inline void * fastd_alloc(size_t size) { return ret; } +/** + Multiplies two size_t values, checking for overflows + + Both arguments are limited to the size of a uint32_t. + + Terminates the process on failure. +*/ +static inline size_t fastd_mul_check(size_t members, size_t size) { + uint64_t v = (uint64_t)members * size; + + if (members > UINT32_MAX || size > UINT32_MAX || v > SIZE_MAX) { + errno = EOVERFLOW; + exit_errno("memory allocation error"); + } + + return v; +} + +static inline void * fastd_alloc_array(size_t members, size_t size) { + return fastd_alloc(fastd_mul_check(members, size)); +} + /** Allocates a block of uninitialized memory on the heap, aligned to 16 bytes @@ -97,6 +119,15 @@ static inline void * fastd_realloc(void *ptr, size_t size) { return ret; } +/** + Reallocates a block of memory for an array on the heap + + Terminates the process on failure. +*/ +static inline void * fastd_realloc_array(void *ptr, size_t members, size_t size) { + return fastd_realloc(ptr, fastd_mul_check(members, size)); +} + /** Allocates a block of uninitialized memory in the size of a given type */ #define fastd_new(type) ((type *)fastd_alloc(sizeof(type))) @@ -108,7 +139,7 @@ static inline void * fastd_realloc(void *ptr, size_t size) { #define fastd_new0(type) ((type *)fastd_alloc0(sizeof(type))) /** Allocates a block of undefined memory for an array of elements of a given type */ -#define fastd_new_array(members, type) ((type *)fastd_alloc(members * sizeof(type))) +#define fastd_new_array(members, type) ((type *)fastd_alloc_array(members, sizeof(type))) /** Allocates a block of memory set to zero for an array of elements of a given type */ #define fastd_new0_array(members, type) ((type *)fastd_alloc0_array(members, sizeof(type))) diff --git a/src/vector.c b/src/vector.c index 07eb274..aeeeebb 100644 --- a/src/vector.c +++ b/src/vector.c @@ -62,7 +62,7 @@ void _fastd_vector_resize(fastd_vector_desc_t *desc, void **data, size_t n, size if (alloc != desc->allocated) { desc->allocated = alloc; - *data = fastd_realloc(*data, alloc * elemsize); + *data = fastd_realloc_array(*data, alloc, elemsize); } } -- cgit v1.2.3