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 | |
parent | 584783a3fc2048ca6673ccdc4f44d0ffc46080cb (diff) | |
download | gnutls-f79af112029d3146d8b1926561ed5834e95c6666.tar.gz |
build: avoid integer overflow in additions
Signed-off-by: Daiki Ueno <ueno@gnu.org>
-rw-r--r-- | lib/cert-cred.c | 5 | ||||
-rw-r--r-- | lib/hello_ext.c | 5 | ||||
-rw-r--r-- | lib/pkcs11.c | 6 | ||||
-rw-r--r-- | lib/pkcs11x.c | 6 | ||||
-rw-r--r-- | lib/supplemental.c | 5 | ||||
-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 |
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) { |