summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2016-05-03 20:57:55 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2016-05-03 20:57:55 +0200
commit1709b7ddc6f0856be42640524f4e7fbff08035ac (patch)
tree11ee74583b9f3456bf42eb96c0616434d76a84ba
parentdb6424e6390c023d8f502b4938ca0898d53523bb (diff)
downloadfastd-1709b7ddc6f0856be42640524f4e7fbff08035ac.tar
fastd-1709b7ddc6f0856be42640524f4e7fbff08035ac.zip
alloc: check multiplications for overflows
-rw-r--r--src/alloc.h33
-rw-r--r--src/vector.c2
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
@@ -49,6 +49,28 @@ static inline void * fastd_alloc(size_t size) {
}
/**
+ 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
Terminates the process on failure.
@@ -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);
}
}