diff options
author | tb <> | 2021-12-23 23:41:26 +0000 |
---|---|---|
committer | tb <> | 2021-12-23 23:41:26 +0000 |
commit | fd87613173bbc28c5d6544f9d6b096e65bfe707c (patch) | |
tree | 43faad4048f0935461e4a49b8d3647e2e202393f | |
parent | a92becc0304c2a08497aa001a61f8744d671aa5c (diff) | |
download | openbsd-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.c | 10 |
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; |