summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2022-06-10 12:33:45 +0100
committerMatt Caswell <matt@openssl.org>2022-07-22 09:00:56 +0100
commitbb2e11081aa9ec923680227d62b82a6ee416f0be (patch)
tree7d7dc02456b5aa74a8489864cbef04a3fa73c7fe /crypto
parent32eb729a420e2eaaa05e9fa4abb4c93ce132cdbd (diff)
Fix a crash in v2i_IPAddrBlocks()
If an IP address prefix value is supplied that is too large then a crash can result. v2i_IPAddrBlocks() should sanity check the prefix value, as should X509v3_addr_add_prefix(). Reported by Theo Buehler (@botovq) Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> (Merged from https://github.com/openssl/openssl/pull/18523) (cherry picked from commit b91ad3c69c27c35be4fd7f1e8811c33c31b02afd)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/x509/v3_addr.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/crypto/x509/v3_addr.c b/crypto/x509/v3_addr.c
index 4205e7d7af..3fc5f3d620 100644
--- a/crypto/x509/v3_addr.c
+++ b/crypto/x509/v3_addr.c
@@ -393,12 +393,14 @@ static int range_should_be_prefix(const unsigned char *min,
/*
* Construct a prefix.
*/
-static int make_addressPrefix(IPAddressOrRange **result,
- unsigned char *addr, const int prefixlen)
+static int make_addressPrefix(IPAddressOrRange **result, unsigned char *addr,
+ const int prefixlen, const int afilen)
{
int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8;
IPAddressOrRange *aor = IPAddressOrRange_new();
+ if (prefixlen < 0 || prefixlen > (afilen * 8))
+ return 0;
if (aor == NULL)
return 0;
aor->type = IPAddressOrRange_addressPrefix;
@@ -438,7 +440,7 @@ static int make_addressRange(IPAddressOrRange **result,
return 0;
if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0)
- return make_addressPrefix(result, min, prefixlen);
+ return make_addressPrefix(result, min, prefixlen, length);
if ((aor = IPAddressOrRange_new()) == NULL)
return 0;
@@ -600,7 +602,9 @@ int X509v3_addr_add_prefix(IPAddrBlocks *addr,
{
IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi);
IPAddressOrRange *aor;
- if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen))
+
+ if (aors == NULL
+ || !make_addressPrefix(&aor, a, prefixlen, length_from_afi(afi)))
return 0;
if (sk_IPAddressOrRange_push(aors, aor))
return 1;
@@ -995,7 +999,10 @@ static void *v2i_IPAddrBlocks(const struct v3_ext_method *method,
switch (delim) {
case '/':
prefixlen = (int)strtoul(s + i2, &t, 10);
- if (t == s + i2 || *t != '\0') {
+ if (t == s + i2
+ || *t != '\0'
+ || prefixlen > (length * 8)
+ || prefixlen < 0) {
ERR_raise(ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
X509V3_conf_add_error_name_value(val);
goto err;