summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2021-12-23 23:41:26 +0000
committertb <>2021-12-23 23:41:26 +0000
commitfd87613173bbc28c5d6544f9d6b096e65bfe707c (patch)
tree43faad4048f0935461e4a49b8d3647e2e202393f
parenta92becc0304c2a08497aa001a61f8744d671aa5c (diff)
downloadopenbsd-fd87613173bbc28c5d6544f9d6b096e65bfe707c.tar.gz
openbsd-fd87613173bbc28c5d6544f9d6b096e65bfe707c.tar.bz2
openbsd-fd87613173bbc28c5d6544f9d6b096e65bfe707c.zip
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
-rw-r--r--src/lib/libcrypto/x509/x509_addr.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/src/lib/libcrypto/x509/x509_addr.c b/src/lib/libcrypto/x509/x509_addr.c
index d543bddd7d..f628009eaa 100644
--- a/src/lib/libcrypto/x509/x509_addr.c
+++ b/src/lib/libcrypto/x509/x509_addr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_addr.c,v 1.20 2021/12/18 16:58:20 tb Exp $ */ 1/* $OpenBSD: x509_addr.c,v 1.21 2021/12/23 23:41:26 tb Exp $ */
2/* 2/*
3 * Contributed to the OpenSSL Project by the American Registry for 3 * Contributed to the OpenSSL Project by the American Registry for
4 * Internet Numbers ("ARIN"). 4 * Internet Numbers ("ARIN").
@@ -1181,6 +1181,7 @@ v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx,
1181 unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; 1181 unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN];
1182 unsigned afi, *safi = NULL, safi_; 1182 unsigned afi, *safi = NULL, safi_;
1183 const char *addr_chars = NULL; 1183 const char *addr_chars = NULL;
1184 const char *errstr;
1184 int prefixlen, i1, i2, delim, length; 1185 int prefixlen, i1, i2, delim, length;
1185 1186
1186 if (!name_cmp(val->name, "IPv4")) { 1187 if (!name_cmp(val->name, "IPv4")) {
@@ -1260,8 +1261,11 @@ v2i_IPAddrBlocks(const struct v3_ext_method *method, struct v3_ext_ctx *ctx,
1260 1261
1261 switch (delim) { 1262 switch (delim) {
1262 case '/': 1263 case '/':
1263 prefixlen = (int)strtoul(s + i2, &t, 10); 1264 /* length contains the size of the address in bytes. */
1264 if (t == s + i2 || *t != '\0') { 1265 if (length != 4 && length != 16)
1266 goto err;
1267 prefixlen = strtonum(s + i2, 0, 8 * length, &errstr);
1268 if (errstr != NULL) {
1265 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR); 1269 X509V3error(X509V3_R_EXTENSION_VALUE_ERROR);
1266 X509V3_conf_err(val); 1270 X509V3_conf_err(val);
1267 goto err; 1271 goto err;