From: tb Date: Thu, 23 Dec 2021 23:41:26 +0000 (+0000) Subject: Fix an arbitrary out-of-bounds stack read in v2i_IPAddrBlocks() X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=9addd72264df6ee29cbfe1edebcb8f3accc809d1;p=openbsd Fix an arbitrary out-of-bounds stack read in v2i_IPAddrBlocks() Switch an insufficiently checked strtoul() to strtonum(). This can be used to trigger a read of a user-controlled size from the stack. $ openssl req -new -addext 'sbgp-ipAddrBlock = IPv4:192.0.2.0/12341234' Segmentation fault (core dumped) The bogus prefix length 12341234 is fed into X509v3_addr_add_prefix() and used to read (prefixlen + 7) / 8 bytes from the stack variable 'min[16]' that ends up as 'data' in the memmove in ASN1_STRING_set(). The full fix will add length checks to X509v3_addr_add_prefix() and make_addressPrefix() and will be dealt with later. The entire X509v3_{addr,asid}_* API will need a thorough review before it can be exposed. This code is only enabled in -current and can only be reached from openssl.cnf files that contain sbgp-ipAddrBlock or from the openssl(1) command line. ok jsing --- diff --git a/lib/libcrypto/x509/x509_addr.c b/lib/libcrypto/x509/x509_addr.c index d543bddd7d4..f628009eaa1 100644 --- a/lib/libcrypto/x509/x509_addr.c +++ b/lib/libcrypto/x509/x509_addr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_addr.c,v 1.20 2021/12/18 16:58:20 tb Exp $ */ +/* $OpenBSD: x509_addr.c,v 1.21 2021/12/23 23:41:26 tb Exp $ */ /* * Contributed to the OpenSSL Project by the American Registry for * Internet Numbers ("ARIN"). @@ -1181,6 +1181,7 @@ v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; unsigned afi, *safi = NULL, safi_; const char *addr_chars = NULL; + const char *errstr; int prefixlen, i1, i2, delim, length; if (!name_cmp(val->name, "IPv4")) { @@ -1260,8 +1261,11 @@ v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx, switch (delim) { case '/': - prefixlen = (int)strtoul(s + i2, &t, 10); - if (t == s + i2 || *t != '\0') { + /* length contains the size of the address in bytes. */ + if (length != 4 && length != 16) + goto err; + prefixlen = strtonum(s + i2, 0, 8 * length, &errstr); + if (errstr != NULL) { X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); X509V3_conf_err(val); goto err;