diff options
author | Daiki Ueno <ueno@gnu.org> | 2021-03-29 11:06:37 +0200 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2021-03-29 13:09:23 +0200 |
commit | f79af112029d3146d8b1926561ed5834e95c6666 (patch) | |
tree | 3ea51fc1d71d6905e587e3d4e05ed287a8e4005b /lib/x509 | |
parent | 584783a3fc2048ca6673ccdc4f44d0ffc46080cb (diff) | |
download | gnutls-f79af112029d3146d8b1926561ed5834e95c6666.tar.gz |
build: avoid integer overflow in additions
Signed-off-by: Daiki Ueno <ueno@gnu.org>
Diffstat (limited to 'lib/x509')
-rw-r--r-- | lib/x509/ocsp.c | 11 | ||||
-rw-r--r-- | lib/x509/pkcs12.c | 10 | ||||
-rw-r--r-- | lib/x509/verify-high.c | 40 | ||||
-rw-r--r-- | lib/x509/x509_ext.c | 16 |
4 files changed, 72 insertions, 5 deletions
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) { |