From 6c1c94bd2360f5778beb397ba5508d5084b7f0ee Mon Sep 17 00:00:00 2001 From: David Cook Date: Sat, 7 Nov 2020 10:12:44 -0600 Subject: [PATCH] Check for arithmetic overflows before allocating --- p11-kit/iter.c | 4 ++-- p11-kit/lists.c | 2 ++ p11-kit/proxy.c | 2 +- p11-kit/rpc-message.c | 13 +++++++++++++ p11-kit/rpc-message.h | 4 ++++ p11-kit/rpc-server.c | 8 ++++---- trust/index.c | 4 ++-- 7 files changed, 28 insertions(+), 9 deletions(-) diff --git a/p11-kit/iter.c b/p11-kit/iter.c index b5a9bbff3..d8c820739 100644 --- a/p11-kit/iter.c +++ b/p11-kit/iter.c @@ -549,7 +549,7 @@ move_next_session (P11KitIter *iter) if (rv != CKR_OK) return finish_iterating (iter, rv); - slots = realloc (iter->slots, sizeof (CK_SLOT_ID) * (num_slots + 1)); + slots = reallocarray (iter->slots, num_slots + 1, sizeof (CK_SLOT_ID)); return_val_if_fail (slots != NULL, CKR_HOST_MEMORY); iter->slots = slots; @@ -705,7 +705,7 @@ p11_kit_iter_next (P11KitIter *iter) CK_OBJECT_HANDLE *objects; iter->max_objects = iter->max_objects ? iter->max_objects * 2 : 64; - objects = realloc (iter->objects, iter->max_objects * sizeof (CK_ULONG)); + objects = reallocarray (iter->objects, iter->max_objects, sizeof (CK_ULONG)); return_val_if_fail (objects != NULL, CKR_HOST_MEMORY); iter->objects = objects; } diff --git a/p11-kit/lists.c b/p11-kit/lists.c index 5804be2a7..365a6d895 100644 --- a/p11-kit/lists.c +++ b/p11-kit/lists.c @@ -64,6 +64,8 @@ hex_encode (const unsigned char *data, size_t i; size_t o; + if ((SIZE_MAX - 1) / 3 < n_data) + return NULL; result = malloc (n_data * 3 + 1); if (result == NULL) return NULL; diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c index df18ac0a4..d24e97755 100644 --- a/p11-kit/proxy.c +++ b/p11-kit/proxy.c @@ -283,7 +283,7 @@ proxy_list_slots (Proxy *py, Mapping *mappings, unsigned int n_mappings) new_slots = calloc (count, sizeof(CK_SLOT_ID)); return_val_if_fail (new_slots != NULL, CKR_HOST_MEMORY); - new_mappings = realloc (py->mappings, sizeof (Mapping) * (py->n_mappings + count)); + new_mappings = reallocarray (py->mappings, (py->n_mappings + count), sizeof (Mapping)); return_val_if_fail (new_mappings != NULL, CKR_HOST_MEMORY); py->mappings = new_mappings; diff --git a/p11-kit/rpc-message.c b/p11-kit/rpc-message.c index 21283588c..875adafa0 100644 --- a/p11-kit/rpc-message.c +++ b/p11-kit/rpc-message.c @@ -43,6 +43,7 @@ #include "rpc-message.h" #include +#include #include #define ELEMS(x) (sizeof (x) / sizeof (x[0])) @@ -114,6 +115,18 @@ p11_rpc_message_alloc_extra (p11_rpc_message *msg, return (void *)(data + 1); } +void * +p11_rpc_message_alloc_extra_array (p11_rpc_message *msg, + size_t nmemb, + size_t size) +{ + if ((SIZE_MAX - sizeof (void *)) / nmemb < size) { + errno = ENOMEM; + return NULL; + } + return p11_rpc_message_alloc_extra (msg, nmemb * size); +} + bool p11_rpc_message_prep (p11_rpc_message *msg, int call_id, diff --git a/p11-kit/rpc-message.h b/p11-kit/rpc-message.h index 989bbc0cd..62e7b188e 100644 --- a/p11-kit/rpc-message.h +++ b/p11-kit/rpc-message.h @@ -255,6 +255,10 @@ void p11_rpc_message_clear (p11_rpc_message *msg); void * p11_rpc_message_alloc_extra (p11_rpc_message *msg, size_t length); +void * p11_rpc_message_alloc_extra_array (p11_rpc_message *msg, + size_t nmemb, + size_t size); + bool p11_rpc_message_prep (p11_rpc_message *msg, int call_id, p11_rpc_message_type type); diff --git a/p11-kit/rpc-server.c b/p11-kit/rpc-server.c index 846ee94e5..dfdb76d91 100644 --- a/p11-kit/rpc-server.c +++ b/p11-kit/rpc-server.c @@ -88,7 +88,7 @@ proto_read_byte_buffer (p11_rpc_message *msg, if (length == 0) return CKR_OK; - *buffer = p11_rpc_message_alloc_extra (msg, length * sizeof (CK_BYTE)); + *buffer = p11_rpc_message_alloc_extra_array (msg, length, sizeof (CK_BYTE)); if (*buffer == NULL) return CKR_DEVICE_MEMORY; @@ -186,7 +186,7 @@ proto_read_ulong_buffer (p11_rpc_message *msg, if (length == 0) return CKR_OK; - *buffer = p11_rpc_message_alloc_extra (msg, length * sizeof (CK_ULONG)); + *buffer = p11_rpc_message_alloc_extra_array (msg, length, sizeof (CK_ULONG)); if (!*buffer) return CKR_DEVICE_MEMORY; @@ -246,7 +246,7 @@ proto_read_attribute_buffer (p11_rpc_message *msg, return PARSE_ERROR; /* Allocate memory for the attribute structures */ - attrs = p11_rpc_message_alloc_extra (msg, n_attrs * sizeof (CK_ATTRIBUTE)); + attrs = p11_rpc_message_alloc_extra_array (msg, n_attrs, sizeof (CK_ATTRIBUTE)); if (attrs == NULL) return CKR_DEVICE_MEMORY; @@ -300,7 +300,7 @@ proto_read_attribute_array (p11_rpc_message *msg, return PARSE_ERROR; /* Allocate memory for the attribute structures */ - attrs = p11_rpc_message_alloc_extra (msg, n_attrs * sizeof (CK_ATTRIBUTE)); + attrs = p11_rpc_message_alloc_extra_array (msg, n_attrs, sizeof (CK_ATTRIBUTE)); if (attrs == NULL) return CKR_DEVICE_MEMORY; diff --git a/trust/index.c b/trust/index.c index 27b9717c5..a57f7ec94 100644 --- a/trust/index.c +++ b/trust/index.c @@ -273,7 +273,7 @@ bucket_insert (index_bucket *bucket, alloc = alloc ? alloc * 2 : 1; return_if_fail (alloc != 0); - elem = realloc (bucket->elem, alloc * sizeof (CK_OBJECT_HANDLE)); + elem = reallocarray (bucket->elem, alloc, sizeof (CK_OBJECT_HANDLE)); return_if_fail (elem != NULL); bucket->elem = elem; } @@ -297,7 +297,7 @@ bucket_push (index_bucket *bucket, alloc = alloc ? alloc * 2 : 1; return_val_if_fail (alloc != 0, false); - elem = realloc (bucket->elem, alloc * sizeof (CK_OBJECT_HANDLE)); + elem = reallocarray (bucket->elem, alloc, sizeof (CK_OBJECT_HANDLE)); return_val_if_fail (elem != NULL, false); bucket->elem = elem; }