summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2021-03-29 11:06:37 +0200
committerDaiki Ueno <ueno@gnu.org>2021-03-29 13:09:23 +0200
commitf79af112029d3146d8b1926561ed5834e95c6666 (patch)
tree3ea51fc1d71d6905e587e3d4e05ed287a8e4005b
parent584783a3fc2048ca6673ccdc4f44d0ffc46080cb (diff)
downloadgnutls-f79af112029d3146d8b1926561ed5834e95c6666.tar.gz
build: avoid integer overflow in additions
Signed-off-by: Daiki Ueno <ueno@gnu.org>
-rw-r--r--lib/cert-cred.c5
-rw-r--r--lib/hello_ext.c5
-rw-r--r--lib/pkcs11.c6
-rw-r--r--lib/pkcs11x.c6
-rw-r--r--lib/supplemental.c5
-rw-r--r--lib/x509/ocsp.c11
-rw-r--r--lib/x509/pkcs12.c10
-rw-r--r--lib/x509/verify-high.c40
-rw-r--r--lib/x509/x509_ext.c16
9 files changed, 99 insertions, 5 deletions
diff --git a/lib/cert-cred.c b/lib/cert-cred.c
index 3f1041f73b..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,6 +56,10 @@ _gnutls_certificate_credential_append_keypair(gnutls_certificate_credentials_t r
gnutls_pcert_st * crt,
int nr)
{
+ 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));
diff --git a/lib/hello_ext.c b/lib/hello_ext.c
index 6943d095b3..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,6 +924,10 @@ gnutls_session_ext_register(gnutls_session_t session,
tmp_mod.validity |= GNUTLS_EXT_FLAG_TLS;
}
+ 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));
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 7e8c0570ac..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
@@ -3291,6 +3292,11 @@ find_multi_objs_cb(struct ck_function_list *module, struct pkcs11_session_info *
unsigned j;
gnutls_datum_t id;
+ 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,
diff --git a/lib/pkcs11x.c b/lib/pkcs11x.c
index 7bb62f64bf..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,6 +218,11 @@ 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) {
+ 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,
diff --git a/lib/supplemental.c b/lib/supplemental.c
index fc9545526a..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,6 +253,10 @@ _gnutls_supplemental_register(gnutls_supplemental_entry_st *entry)
return gnutls_assert_val(GNUTLS_E_ALREADY_REGISTERED);
}
+ 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) {
diff --git a/lib/x509/ocsp.c b/lib/x509/ocsp.c
index 7587a2649a..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,6 +1906,11 @@ gnutls_ocsp_resp_get_certs(gnutls_ocsp_resp_const_t resp,
goto error;
}
+ 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) {
@@ -2457,6 +2463,11 @@ gnutls_ocsp_resp_list_import2(gnutls_ocsp_resp_t **ocsps,
goto fail;
}
+ 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));
diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c
index ac0d2f565f..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,6 +1456,10 @@ static int make_chain(gnutls_x509_crt_t ** chain, unsigned int *chain_len,
!= 0)
goto skip;
+ 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]));
@@ -1777,6 +1782,11 @@ 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_reallocarray_fast(_extra_certs,
++_extra_certs_len,
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 7fdbdc68d5..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,6 +129,10 @@ 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_reallocarray_fast(set->node[hash].certs,
set->node[hash].size + 1,
@@ -297,6 +302,10 @@ 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_reallocarray_fast(list->keep_certs,
list->keep_certs_size + 1,
@@ -378,6 +387,11 @@ 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_reallocarray_fast(list->node[hash].trusted_cas,
list->node[hash].trusted_ca_size + 1,
@@ -663,6 +677,10 @@ 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.
@@ -725,6 +743,10 @@ 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_reallocarray_fast(list->node[hash].named_certs,
list->node[hash].named_cert_size + 1,
@@ -838,16 +860,17 @@ gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list,
}
}
+ 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;
@@ -861,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/x509_ext.c b/lib/x509/x509_ext.c
index fda936e8ff..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,6 +138,10 @@ int subject_alt_names_set(struct name_st **names,
void *tmp;
int ret;
+ 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,6 +2321,10 @@ 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_reallocarray(cdp->points, cdp->size + 1,
sizeof(cdp->points[0]));
@@ -2733,6 +2742,10 @@ int gnutls_x509_aia_set(gnutls_x509_aia_t aia,
void *tmp;
unsigned indx;
+ 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);
@@ -2785,6 +2798,9 @@ static int parse_aia(ASN1_TYPE c2, gnutls_x509_aia_t aia)
}
indx = aia->size;
+ 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) {