summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2021-03-30 12:54:04 +0000
committerDaiki Ueno <ueno@gnu.org>2021-03-30 12:54:04 +0000
commita6a45ad0a75e950119e8e529a5f7f505ce0311c7 (patch)
tree1be10204a0cd6e457965b0e3af1f6ae6c70d01f1
parenta28a915f4ad820360cdbaaa83d98df206e2f00b7 (diff)
parent043d1bc387238139a4c2b7f7a6fffdac97ab2b73 (diff)
downloadgnutls-a6a45ad0a75e950119e8e529a5f7f505ce0311c7.tar.gz
Merge branch 'wip/dueno/reallocarray' into 'master'
build: avoid potential integer overflow in array allocation Closes #1179 See merge request gnutls/gnutls!1392
-rw-r--r--bootstrap.conf2
-rw-r--r--lib/cert-cred-x509.c23
-rw-r--r--lib/cert-cred.c23
-rw-r--r--lib/hello_ext.c9
-rw-r--r--lib/mem.c33
-rw-r--r--lib/mem.h8
-rw-r--r--lib/pcert.c3
-rw-r--r--lib/pkcs11.c17
-rw-r--r--lib/pkcs11x.c14
-rw-r--r--lib/supplemental.c9
-rw-r--r--lib/x509/crl.c7
-rw-r--r--lib/x509/ocsp.c22
-rw-r--r--lib/x509/pkcs12.c25
-rw-r--r--lib/x509/verify-high.c83
-rw-r--r--lib/x509/verify-high2.c6
-rw-r--r--lib/x509/x509.c9
-rw-r--r--lib/x509/x509_ext.c28
17 files changed, 219 insertions, 102 deletions
diff --git a/bootstrap.conf b/bootstrap.conf
index 271b51f143..f7bdde1025 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -27,7 +27,7 @@ required_submodules="tests/suite/tls-fuzzer/python-ecdsa tests/suite/tls-fuzzer/
# Those modules are common to lib/ and src/.
common_modules="
-alloca attribute byteswap c-ctype c-strcase explicit_bzero fopen-gnu func getline gettext-h gettimeofday hash hash-pjw-bare arpa_inet inet_ntop inet_pton intprops memmem-simple minmax netdb netinet_in read-file secure_getenv setsockopt snprintf stdint stpcpy strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf
+alloca attribute byteswap c-ctype c-strcase explicit_bzero fopen-gnu func getline gettext-h gettimeofday hash hash-pjw-bare arpa_inet inet_ntop inet_pton intprops memmem-simple minmax netdb netinet_in read-file secure_getenv setsockopt snprintf stdint stpcpy strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf xalloc-oversized
"
gnulib_modules="
$common_modules extensions gendocs havelib ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings pmccabe2html warnings
diff --git a/lib/cert-cred-x509.c b/lib/cert-cred-x509.c
index 1b44f3a634..543a1155f4 100644
--- a/lib/cert-cred-x509.c
+++ b/lib/cert-cred-x509.c
@@ -254,7 +254,7 @@ parse_pem_cert_mem(gnutls_certificate_credentials_t res,
goto cleanup;
}
- pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * count);
+ pcerts = _gnutls_reallocarray(NULL, count, sizeof(gnutls_pcert_st));
if (pcerts == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -441,7 +441,8 @@ read_cert_url(gnutls_certificate_credentials_t res, gnutls_privkey_t key, const
_gnutls_str_array_init(&names);
- ccert = gnutls_malloc(sizeof(*ccert)*MAX_PKCS11_CERT_CHAIN);
+ ccert = _gnutls_reallocarray(NULL, MAX_PKCS11_CERT_CHAIN,
+ sizeof(*ccert));
if (ccert == NULL) {
gnutls_assert();
ret = GNUTLS_E_MEMORY_ERROR;
@@ -770,7 +771,8 @@ gnutls_certificate_set_x509_key(gnutls_certificate_credentials_t res,
}
/* load certificates */
- pcerts = gnutls_malloc(sizeof(gnutls_pcert_st) * cert_list_size);
+ pcerts = _gnutls_reallocarray(NULL, cert_list_size,
+ sizeof(gnutls_pcert_st));
if (pcerts == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -901,8 +903,9 @@ gnutls_certificate_get_x509_crt(gnutls_certificate_credentials_t res,
}
*crt_list_size = res->certs[index].cert_list_length;
- *crt_list = gnutls_malloc(
- res->certs[index].cert_list_length * sizeof (gnutls_x509_crt_t));
+ *crt_list = _gnutls_reallocarray(NULL,
+ res->certs[index].cert_list_length,
+ sizeof (gnutls_x509_crt_t));
if (*crt_list == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -1151,7 +1154,8 @@ gnutls_certificate_set_x509_trust(gnutls_certificate_credentials_t res,
if (ca_list == NULL || ca_list_size < 1)
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
- new_list = gnutls_malloc(ca_list_size * sizeof(gnutls_x509_crt_t));
+ new_list = _gnutls_reallocarray(NULL, ca_list_size,
+ sizeof(gnutls_x509_crt_t));
if (!new_list)
return GNUTLS_E_MEMORY_ERROR;
@@ -1335,12 +1339,15 @@ gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res,
int crl_list_size)
{
int ret, i, j;
- gnutls_x509_crl_t *new_crl = gnutls_malloc(crl_list_size * sizeof(gnutls_x509_crl_t));
- unsigned flags = GNUTLS_TL_USE_IN_TLS;
+ gnutls_x509_crl_t *new_crl;
+ unsigned flags;
+ flags = GNUTLS_TL_USE_IN_TLS;
if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;
+ new_crl = _gnutls_reallocarray(NULL, crl_list_size,
+ sizeof(gnutls_x509_crl_t));
if (!new_crl)
return GNUTLS_E_MEMORY_ERROR;
diff --git a/lib/cert-cred.c b/lib/cert-cred.c
index 28b67f60df..c9c5f6ed50 100644
--- a/lib/cert-cred.c
+++ b/lib/cert-cred.c
@@ -43,6 +43,7 @@
#include "x509/common.h"
#include "dh.h"
#include "cert-cred.h"
+#include "intprops.h"
/*
@@ -55,15 +56,19 @@ _gnutls_certificate_credential_append_keypair(gnutls_certificate_credentials_t r
gnutls_pcert_st * crt,
int nr)
{
- res->sorted_cert_idx = gnutls_realloc_fast(res->sorted_cert_idx,
- (1 + res->ncerts) *
- sizeof(unsigned int));
+ if (unlikely(INT_ADD_OVERFLOW(res->ncerts, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ res->sorted_cert_idx = _gnutls_reallocarray_fast(res->sorted_cert_idx,
+ res->ncerts + 1,
+ sizeof(unsigned int));
if (res->sorted_cert_idx == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
- res->certs = gnutls_realloc_fast(res->certs,
- (1 + res->ncerts) *
- sizeof(certs_st));
+ res->certs = _gnutls_reallocarray_fast(res->certs,
+ res->ncerts + 1,
+ sizeof(certs_st));
if (res->certs == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
@@ -204,7 +209,8 @@ gnutls_certificate_set_key(gnutls_certificate_credentials_t res,
gnutls_privkey_set_pin_function(key, res->pin.cb,
res->pin.data);
- new_pcert_list = gnutls_malloc(sizeof(gnutls_pcert_st) * pcert_list_size);
+ new_pcert_list = _gnutls_reallocarray(NULL, pcert_list_size,
+ sizeof(gnutls_pcert_st));
if (new_pcert_list == NULL) {
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
}
@@ -451,7 +457,8 @@ static gnutls_pcert_st *alloc_and_load_x509_certs(gnutls_x509_crt_t *
if (certs == NULL)
return NULL;
- local_certs = gnutls_malloc(sizeof(gnutls_pcert_st) * ncerts);
+ local_certs = _gnutls_reallocarray(NULL, ncerts,
+ sizeof(gnutls_pcert_st));
if (local_certs == NULL) {
gnutls_assert();
return NULL;
diff --git a/lib/hello_ext.c b/lib/hello_ext.c
index dbe73fdeb3..32385f4c0e 100644
--- a/lib/hello_ext.c
+++ b/lib/hello_ext.c
@@ -57,6 +57,7 @@
#include <num.h>
#include <ext/client_cert_type.h>
#include <ext/server_cert_type.h>
+#include "intprops.h"
static void
unset_ext_data(gnutls_session_t session, const struct hello_ext_entry_st *, unsigned idx);
@@ -923,7 +924,13 @@ gnutls_session_ext_register(gnutls_session_t session,
tmp_mod.validity |= GNUTLS_EXT_FLAG_TLS;
}
- exts = gnutls_realloc(session->internals.rexts, (session->internals.rexts_size+1)*sizeof(*exts));
+ if (unlikely(INT_ADD_OVERFLOW(session->internals.rexts_size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ exts = _gnutls_reallocarray(session->internals.rexts,
+ session->internals.rexts_size + 1,
+ sizeof(*exts));
if (exts == NULL) {
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
}
diff --git a/lib/mem.c b/lib/mem.c
index 32cab5a47c..c6a78b1edd 100644
--- a/lib/mem.c
+++ b/lib/mem.c
@@ -23,7 +23,7 @@
#include "gnutls_int.h"
#include "errors.h"
#include <num.h>
-#include <xsize.h>
+#include "xalloc-oversized.h"
gnutls_alloc_function gnutls_secure_malloc = malloc;
gnutls_alloc_function gnutls_malloc = malloc;
@@ -33,27 +33,34 @@ gnutls_realloc_function gnutls_realloc = realloc;
void *(*gnutls_calloc) (size_t, size_t) = calloc;
char *(*gnutls_strdup) (const char *) = _gnutls_strdup;
-void *_gnutls_calloc(size_t nmemb, size_t size)
+/* This realloc will free ptr in case realloc
+ * fails.
+ */
+void *gnutls_realloc_fast(void *ptr, size_t size)
{
void *ret;
- size_t n = xtimes(nmemb, size);
- ret = (size_in_bounds_p(n) ? gnutls_malloc(n) : NULL);
- if (ret != NULL)
- memset(ret, 0, size);
+
+ if (size == 0)
+ return ptr;
+
+ ret = gnutls_realloc(ptr, size);
+ if (ret == NULL) {
+ gnutls_free(ptr);
+ }
+
return ret;
}
-/* This realloc will free ptr in case realloc
- * fails.
+/* This will free ptr in case reallocarray fails.
*/
-void *gnutls_realloc_fast(void *ptr, size_t size)
+void *_gnutls_reallocarray_fast(void *ptr, size_t nmemb, size_t size)
{
void *ret;
if (size == 0)
return ptr;
- ret = gnutls_realloc(ptr, size);
+ ret = _gnutls_reallocarray(ptr, nmemb, size);
if (ret == NULL) {
gnutls_free(ptr);
}
@@ -77,6 +84,12 @@ char *_gnutls_strdup(const char *str)
return ret;
}
+void *_gnutls_reallocarray(void *ptr, size_t nmemb, size_t size)
+{
+ return xalloc_oversized(nmemb, size) ? NULL :
+ gnutls_realloc(ptr, nmemb * size);
+}
+
#if 0
/* don't use them. They are included for documentation.
*/
diff --git a/lib/mem.h b/lib/mem.h
index d3eea97a40..10a8db742d 100644
--- a/lib/mem.h
+++ b/lib/mem.h
@@ -25,14 +25,16 @@
#include <config.h>
-/* this realloc function will return ptr if size==0, and
- * will free the ptr if the new allocation failed.
+/* These realloc functions will return ptr if size==0, and will free
+ * the ptr if the new allocation failed.
*/
void *gnutls_realloc_fast(void *ptr, size_t size);
+void *_gnutls_reallocarray_fast(void *ptr, size_t nmemb, size_t size);
-void *_gnutls_calloc(size_t nmemb, size_t size);
char *_gnutls_strdup(const char *);
+void *_gnutls_reallocarray(void *, size_t, size_t);
+
unsigned _gnutls_mem_is_zero(const uint8_t *ptr, unsigned size);
#define zrelease_mpi_key(mpi) if (*mpi!=NULL) { \
diff --git a/lib/pcert.c b/lib/pcert.c
index 89d3d40e63..e5057aec51 100644
--- a/lib/pcert.c
+++ b/lib/pcert.c
@@ -185,7 +185,8 @@ gnutls_pcert_list_import_x509_raw(gnutls_pcert_st *pcert_list,
unsigned int i = 0, j;
gnutls_x509_crt_t *crt;
- crt = gnutls_malloc((*pcert_list_size) * sizeof(gnutls_x509_crt_t));
+ crt = _gnutls_reallocarray(NULL, *pcert_list_size,
+ sizeof(gnutls_x509_crt_t));
if (crt == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 0d5e83a0c6..364c0c49a9 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -40,6 +40,7 @@
#include "x509/x509_int.h"
#include <atfork.h>
+#include "intprops.h"
#define MAX_PROVIDERS 16
@@ -3059,8 +3060,8 @@ find_privkeys(struct pkcs11_session_info *sinfo,
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
}
- list->key_ids =
- gnutls_malloc(sizeof(gnutls_buffer_st) * list->key_ids_size);
+ list->key_ids = _gnutls_reallocarray(NULL, list->key_ids_size,
+ sizeof(gnutls_buffer_st));
if (list->key_ids == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -3277,7 +3278,7 @@ find_multi_objs_cb(struct ck_function_list *module, struct pkcs11_session_info *
return pkcs11_rv_to_err(rv);
}
- ctx = gnutls_malloc(OBJECTS_A_TIME*sizeof(ctx[0]));
+ ctx = _gnutls_reallocarray(NULL, OBJECTS_A_TIME, sizeof(ctx[0]));
if (ctx == NULL) {
ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
goto fail;
@@ -3291,7 +3292,15 @@ find_multi_objs_cb(struct ck_function_list *module, struct pkcs11_session_info *
unsigned j;
gnutls_datum_t id;
- find_data->p_list = gnutls_realloc_fast(find_data->p_list, (find_data->current+count)*sizeof(find_data->p_list[0]));
+ if (unlikely(INT_ADD_OVERFLOW(find_data->current, count))) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto fail;
+ }
+
+ find_data->p_list =
+ _gnutls_reallocarray_fast(find_data->p_list,
+ find_data->current + count,
+ sizeof(find_data->p_list[0]));
if (find_data->p_list == NULL) {
ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
goto fail;
diff --git a/lib/pkcs11x.c b/lib/pkcs11x.c
index 0041b924cb..dfaee58a39 100644
--- a/lib/pkcs11x.c
+++ b/lib/pkcs11x.c
@@ -28,6 +28,7 @@
#include <pkcs11_int.h>
#include <p11-kit/p11-kit.h>
#include "pkcs11x.h"
+#include "intprops.h"
struct find_ext_data_st {
/* in */
@@ -217,10 +218,17 @@ find_ext_cb(struct ck_function_list *module, struct pkcs11_session_info *sinfo,
rv = pkcs11_get_attribute_avalue(sinfo->module, sinfo->pks, obj, CKA_VALUE, &ext);
if (rv == CKR_OK) {
- find_data->exts = gnutls_realloc_fast(find_data->exts, (1+find_data->exts_size)*sizeof(find_data->exts[0]));
+ if (unlikely(INT_ADD_OVERFLOW(find_data->exts_size, 1))) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto cleanup;
+ }
+
+ find_data->exts =
+ _gnutls_reallocarray_fast(find_data->exts,
+ find_data->exts_size + 1,
+ sizeof(find_data->exts[0]));
if (find_data->exts == NULL) {
- gnutls_assert();
- ret = pkcs11_rv_to_err(rv);
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
goto cleanup;
}
diff --git a/lib/supplemental.c b/lib/supplemental.c
index 07b38cc938..becb01e50c 100644
--- a/lib/supplemental.c
+++ b/lib/supplemental.c
@@ -48,6 +48,7 @@
#include "supplemental.h"
#include "errors.h"
#include "num.h"
+#include "intprops.h"
typedef struct gnutls_supplemental_entry_st {
char *name;
@@ -252,8 +253,12 @@ _gnutls_supplemental_register(gnutls_supplemental_entry_st *entry)
return gnutls_assert_val(GNUTLS_E_ALREADY_REGISTERED);
}
- p = gnutls_realloc_fast(suppfunc,
- sizeof(*suppfunc) * (suppfunc_size + 1));
+ if (unlikely(INT_ADD_OVERFLOW(suppfunc_size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ p = _gnutls_reallocarray_fast(suppfunc, suppfunc_size + 1,
+ sizeof(*suppfunc));
if (!p) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
diff --git a/lib/x509/crl.c b/lib/x509/crl.c
index 8705be3b6c..aea8bc6d33 100644
--- a/lib/x509/crl.c
+++ b/lib/x509/crl.c
@@ -1262,7 +1262,7 @@ gnutls_x509_crl_list_import2(gnutls_x509_crl_t ** crls,
unsigned int init = 1024;
int ret;
- *crls = gnutls_malloc(sizeof(gnutls_x509_crl_t) * init);
+ *crls = _gnutls_reallocarray(NULL, init, sizeof(gnutls_x509_crl_t));
if (*crls == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -1272,9 +1272,8 @@ gnutls_x509_crl_list_import2(gnutls_x509_crl_t ** crls,
gnutls_x509_crl_list_import(*crls, &init, data, format,
flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
- *crls =
- gnutls_realloc_fast(*crls,
- sizeof(gnutls_x509_crl_t) * init);
+ *crls = _gnutls_reallocarray_fast(*crls, init,
+ sizeof(gnutls_x509_crl_t));
if (*crls == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
index 0c71a6e462..e750ac4724 100644
--- a/lib/x509/ocsp.c
+++ b/lib/x509/ocsp.c
@@ -38,6 +38,7 @@
#include <auth/cert.h>
#include <assert.h>
+#include "intprops.h"
typedef struct gnutls_ocsp_req_int {
ASN1_TYPE req;
@@ -1905,9 +1906,13 @@ gnutls_ocsp_resp_get_certs(gnutls_ocsp_resp_const_t resp,
goto error;
}
- tmpcerts2 =
- gnutls_realloc_fast(tmpcerts,
- (ctr + 2) * sizeof(*tmpcerts));
+ if (unlikely(INT_ADD_OVERFLOW(ctr, 2))) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto error;
+ }
+
+ tmpcerts2 = _gnutls_reallocarray_fast(tmpcerts, ctr + 2,
+ sizeof(*tmpcerts));
if (tmpcerts2 == NULL) {
gnutls_assert();
ret = GNUTLS_E_MEMORY_ERROR;
@@ -2458,7 +2463,14 @@ gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t **ocsps,
goto fail;
}
- new_ocsps = gnutls_realloc(*ocsps, (*size + 1)*sizeof(gnutls_ocsp_resp_t));
+ if (unlikely(INT_ADD_OVERFLOW(*size, 1))) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto fail;
+ }
+
+ new_ocsps = _gnutls_reallocarray(*ocsps,
+ *size + 1,
+ sizeof(gnutls_ocsp_resp_t));
if (new_ocsps == NULL) {
resp = NULL;
gnutls_assert();
@@ -2492,7 +2504,7 @@ gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t **ocsps,
goto cleanup;
}
- *ocsps = gnutls_malloc(1*sizeof(gnutls_ocsp_resp_t));
+ *ocsps = gnutls_malloc(sizeof(gnutls_ocsp_resp_t));
if (*ocsps == NULL) {
gnutls_assert();
ret = GNUTLS_E_MEMORY_ERROR;
diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c
index 2dc0823905..965de6fe02 100644
--- a/lib/x509/pkcs12.c
+++ b/lib/x509/pkcs12.c
@@ -37,6 +37,7 @@
#include "x509_int.h"
#include "pkcs7_int.h"
#include <random.h>
+#include "intprops.h"
/* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
@@ -1455,10 +1456,13 @@ static int make_chain(gnutls_x509_crt_t ** chain, unsigned int *chain_len,
!= 0)
goto skip;
- *chain =
- gnutls_realloc_fast(*chain,
- sizeof((*chain)[0]) *
- ++(*chain_len));
+ if (unlikely(INT_ADD_OVERFLOW(*chain_len, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ *chain = _gnutls_reallocarray_fast(*chain,
+ ++(*chain_len),
+ sizeof((*chain)[0]));
if (*chain == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -1778,12 +1782,15 @@ gnutls_pkcs12_simple_parse(gnutls_pkcs12_t p12,
}
if (memcmp(cert_id, key_id, cert_id_size) != 0) { /* they don't match - skip the certificate */
+ if (unlikely(INT_ADD_OVERFLOW(_extra_certs_len, 1))) {
+ ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ goto done;
+ }
+
_extra_certs =
- gnutls_realloc_fast
- (_extra_certs,
- sizeof(_extra_certs
- [0]) *
- ++_extra_certs_len);
+ _gnutls_reallocarray_fast(_extra_certs,
+ ++_extra_certs_len,
+ sizeof(_extra_certs[0]));
if (!_extra_certs) {
gnutls_assert();
ret =
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 736326ee18..ab8e006ca7 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -34,6 +34,7 @@
#include <common.h>
#include <gnutls/x509-ext.h>
#include "verify-high.h"
+#include "intprops.h"
struct named_cert_st {
gnutls_x509_crt_t cert;
@@ -128,10 +129,14 @@ cert_set_add(struct cert_set_st *set, const gnutls_x509_crt_t cert)
hash = hash_pjw_bare(cert->raw_dn.data, cert->raw_dn.size);
hash %= set->size;
+ if (unlikely(INT_ADD_OVERFLOW(set->node[hash].size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
set->node[hash].certs =
- gnutls_realloc_fast(set->node[hash].certs,
- (set->node[hash].size + 1) *
- sizeof(*set->node[hash].certs));
+ _gnutls_reallocarray_fast(set->node[hash].certs,
+ set->node[hash].size + 1,
+ sizeof(*set->node[hash].certs));
if (!set->node[hash].certs) {
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
}
@@ -297,11 +302,14 @@ static int
trust_list_add_compat(gnutls_x509_trust_list_t list,
gnutls_x509_crt_t cert)
{
+ if (unlikely(INT_ADD_OVERFLOW(list->keep_certs_size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
list->keep_certs =
- gnutls_realloc_fast(list->keep_certs,
- (list->keep_certs_size +
- 1) *
- sizeof(list->keep_certs[0]));
+ _gnutls_reallocarray_fast(list->keep_certs,
+ list->keep_certs_size + 1,
+ sizeof(list->keep_certs[0]));
if (list->keep_certs == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -379,12 +387,15 @@ gnutls_x509_trust_list_add_cas(gnutls_x509_trust_list_t list,
}
}
+ if (unlikely(INT_ADD_OVERFLOW(list->node[hash].trusted_ca_size, 1))) {
+ gnutls_assert();
+ return i;
+ }
+
list->node[hash].trusted_cas =
- gnutls_realloc_fast(list->node[hash].trusted_cas,
- (list->node[hash].trusted_ca_size +
- 1) *
- sizeof(list->node[hash].
- trusted_cas[0]));
+ _gnutls_reallocarray_fast(list->node[hash].trusted_cas,
+ list->node[hash].trusted_ca_size + 1,
+ sizeof(list->node[hash].trusted_cas[0]));
if (list->node[hash].trusted_cas == NULL) {
gnutls_assert();
return i;
@@ -666,14 +677,18 @@ gnutls_x509_trust_list_remove_cas(gnutls_x509_trust_list_t list,
}
}
+ if (unlikely(INT_ADD_OVERFLOW(list->blacklisted_size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
/* Add the CA (or plain) certificate to the black list as well.
* This will prevent a subordinate CA from being valid, and
* ensure that a server certificate will also get rejected.
*/
list->blacklisted =
- gnutls_realloc_fast(list->blacklisted,
- (list->blacklisted_size + 1) *
- sizeof(list->blacklisted[0]));
+ _gnutls_reallocarray_fast(list->blacklisted,
+ list->blacklisted_size + 1,
+ sizeof(list->blacklisted[0]));
if (list->blacklisted == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
@@ -728,11 +743,14 @@ gnutls_x509_trust_list_add_named_crt(gnutls_x509_trust_list_t list,
cert->raw_issuer_dn.size);
hash %= list->size;
+ if (unlikely(INT_ADD_OVERFLOW(list->node[hash].named_cert_size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
list->node[hash].named_certs =
- gnutls_realloc_fast(list->node[hash].named_certs,
- (list->node[hash].named_cert_size +
- 1) *
- sizeof(list->node[hash].named_certs[0]));
+ _gnutls_reallocarray_fast(list->node[hash].named_certs,
+ list->node[hash].named_cert_size + 1,
+ sizeof(list->node[hash].named_certs[0]));
if (list->node[hash].named_certs == NULL)
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
@@ -842,19 +860,17 @@ gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list,
}
}
- tmp =
- gnutls_realloc(list->node[hash].crls,
- (list->node[hash].crl_size +
- 1) *
- sizeof(list->node[hash].
- crls[0]));
+ if (unlikely(INT_ADD_OVERFLOW(list->node[hash].crl_size, 1))) {
+ gnutls_assert();
+ goto error;
+ }
+
+ tmp = _gnutls_reallocarray(list->node[hash].crls,
+ list->node[hash].crl_size + 1,
+ sizeof(list->node[hash].crls[0]));
if (tmp == NULL) {
- ret = i;
gnutls_assert();
- if (flags & GNUTLS_TL_NO_DUPLICATES)
- while (i < crl_size)
- gnutls_x509_crl_deinit(crl_list[i++]);
- return ret;
+ goto error;
}
list->node[hash].crls = tmp;
@@ -868,6 +884,13 @@ gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list,
}
return j;
+
+ error:
+ ret = i;
+ if (flags & GNUTLS_TL_NO_DUPLICATES)
+ while (i < crl_size)
+ gnutls_x509_crl_deinit(crl_list[i++]);
+ return ret;
}
/* Takes a certificate list and shortens it if there are
diff --git a/lib/x509/verify-high2.c b/lib/x509/verify-high2.c
index 9820595e97..16d757cf8a 100644
--- a/lib/x509/verify-high2.c
+++ b/lib/x509/verify-high2.c
@@ -216,7 +216,8 @@ int add_trust_list_pkcs11_object_url(gnutls_x509_trust_list_t list, const char *
goto cleanup;
}
- xcrt_list = gnutls_malloc(sizeof(gnutls_x509_crt_t) * pcrt_list_size);
+ xcrt_list = _gnutls_reallocarray(NULL, pcrt_list_size,
+ sizeof(gnutls_x509_crt_t));
if (xcrt_list == NULL) {
ret = GNUTLS_E_MEMORY_ERROR;
goto cleanup;
@@ -264,7 +265,8 @@ int remove_pkcs11_object_url(gnutls_x509_trust_list_t list, const char *url)
goto cleanup;
}
- xcrt_list = gnutls_malloc(sizeof(gnutls_x509_crt_t) * pcrt_list_size);
+ xcrt_list = _gnutls_reallocarray(NULL, pcrt_list_size,
+ sizeof(gnutls_x509_crt_t));
if (xcrt_list == NULL) {
ret = GNUTLS_E_MEMORY_ERROR;
goto cleanup;
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index c3801a83f2..4e494d10e0 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -3700,7 +3700,7 @@ gnutls_x509_crt_list_import2(gnutls_x509_crt_t ** certs,
unsigned int init = 1024;
int ret;
- *certs = gnutls_malloc(sizeof(gnutls_x509_crt_t) * init);
+ *certs = _gnutls_reallocarray(NULL, init, sizeof(gnutls_x509_crt_t));
if (*certs == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -3710,9 +3710,8 @@ gnutls_x509_crt_list_import2(gnutls_x509_crt_t ** certs,
gnutls_x509_crt_list_import(*certs, &init, data, format,
flags | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
- *certs =
- gnutls_realloc_fast(*certs,
- sizeof(gnutls_x509_crt_t) * init);
+ *certs = _gnutls_reallocarray_fast(*certs, init,
+ sizeof(gnutls_x509_crt_t));
if (*certs == NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
@@ -4375,7 +4374,7 @@ gnutls_x509_crt_list_import_url(gnutls_x509_crt_t **certs,
gnutls_free(issuer.data);
}
- *certs = gnutls_malloc(total*sizeof(gnutls_x509_crt_t));
+ *certs = _gnutls_reallocarray(NULL, total, sizeof(gnutls_x509_crt_t));
if (*certs == NULL) {
ret = GNUTLS_E_MEMORY_ERROR;
goto cleanup;
diff --git a/lib/x509/x509_ext.c b/lib/x509/x509_ext.c
index 6aeb159dba..387f5fbea2 100644
--- a/lib/x509/x509_ext.c
+++ b/lib/x509/x509_ext.c
@@ -31,6 +31,7 @@
#include "x509_ext_int.h"
#include "virt-san.h"
#include <gnutls/x509-ext.h>
+#include "intprops.h"
#define MAX_ENTRIES 64
struct gnutls_subject_alt_names_st {
@@ -137,7 +138,11 @@ int subject_alt_names_set(struct name_st **names,
void *tmp;
int ret;
- tmp = gnutls_realloc(*names, (*size + 1) * sizeof((*names)[0]));
+ if (unlikely(INT_ADD_OVERFLOW(*size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ tmp = _gnutls_reallocarray(*names, *size + 1, sizeof((*names)[0]));
if (tmp == NULL) {
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
}
@@ -2316,10 +2321,13 @@ int crl_dist_points_set(gnutls_x509_crl_dist_points_t cdp,
{
void *tmp;
+ if (unlikely(INT_ADD_OVERFLOW(cdp->size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
/* new dist point */
- tmp =
- gnutls_realloc(cdp->points,
- (cdp->size + 1) * sizeof(cdp->points[0]));
+ tmp = _gnutls_reallocarray(cdp->points, cdp->size + 1,
+ sizeof(cdp->points[0]));
if (tmp == NULL) {
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
}
@@ -2734,7 +2742,11 @@ int gnutls_x509_aia_set(gnutls_x509_aia_t aia,
void *tmp;
unsigned indx;
- tmp = gnutls_realloc(aia->aia, (aia->size + 1) * sizeof(aia->aia[0]));
+ if (unlikely(INT_ADD_OVERFLOW(aia->size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+
+ tmp = _gnutls_reallocarray(aia->aia, aia->size + 1, sizeof(aia->aia[0]));
if (tmp == NULL) {
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
}
@@ -2786,7 +2798,11 @@ static int parse_aia(ASN1_TYPE c2, gnutls_x509_aia_t aia)
}
indx = aia->size;
- tmp = gnutls_realloc(aia->aia, (aia->size + 1) * sizeof(aia->aia[0]));
+ if (unlikely(INT_ADD_OVERFLOW(aia->size, 1))) {
+ return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ }
+ tmp = _gnutls_reallocarray(aia->aia, aia->size + 1,
+ sizeof(aia->aia[0]));
if (tmp == NULL) {
return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
}