diff options
| author | tb <> | 2026-06-09 12:29:47 +0000 |
|---|---|---|
| committer | tb <> | 2026-06-09 12:29:47 +0000 |
| commit | 329187ca76781997d3a01eafa23caac7f93779f7 (patch) | |
| tree | 0668d9b6df43809007da7636c70b7dc4dd1741f2 /src/lib/libcrypto | |
| parent | 256315fc6aeff5ec985bfee63fae84e6cafc4555 (diff) | |
| download | openbsd-329187ca76781997d3a01eafa23caac7f93779f7.tar.gz openbsd-329187ca76781997d3a01eafa23caac7f93779f7.tar.bz2 openbsd-329187ca76781997d3a01eafa23caac7f93779f7.zip | |
Add some missing bounds checks to ASN1_mbstring_copy()
If the in string is unreasonably long, assigning strlen(in) to an int
may overflow, so exclude this situation.
Moreover, the code would unconditionally multiply nchar by 2 or 4,
which could again overflow an int. Check for this situation and error
out to avoid an out of bounds write.
More may be needed in here, which will be revisited later.
Based on a diff by Viktor Dukhovni via OpenSSL.
Diffstat (limited to 'src/lib/libcrypto')
| -rw-r--r-- | src/lib/libcrypto/asn1/a_mbstr.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c index 38398ad1d1..21368543ce 100644 --- a/src/lib/libcrypto/asn1/a_mbstr.c +++ b/src/lib/libcrypto/asn1/a_mbstr.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: a_mbstr.c,v 1.28 2025/05/10 05:54:38 tb Exp $ */ | 1 | /* $OpenBSD: a_mbstr.c,v 1.29 2026/06/09 12:29:47 tb Exp $ */ |
| 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
| 3 | * project 1999. | 3 | * project 1999. |
| 4 | */ | 4 | */ |
| @@ -57,6 +57,7 @@ | |||
| 57 | */ | 57 | */ |
| 58 | 58 | ||
| 59 | #include <ctype.h> | 59 | #include <ctype.h> |
| 60 | #include <limits.h> | ||
| 60 | #include <stdio.h> | 61 | #include <stdio.h> |
| 61 | #include <string.h> | 62 | #include <string.h> |
| 62 | 63 | ||
| @@ -105,8 +106,16 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, | |||
| 105 | int nchar; | 106 | int nchar; |
| 106 | int (*cpyfunc)(unsigned long, void *) = NULL; | 107 | int (*cpyfunc)(unsigned long, void *) = NULL; |
| 107 | 108 | ||
| 108 | if (len < 0) | 109 | if (len < 0) { |
| 109 | len = strlen((const char *)in); | 110 | size_t length; |
| 111 | |||
| 112 | if ((length = strlen((const char *)in)) >= INT_MAX) { | ||
| 113 | ASN1error(ASN1_R_STRING_TOO_LONG); | ||
| 114 | return -1; | ||
| 115 | } | ||
| 116 | len = length; | ||
| 117 | } | ||
| 118 | |||
| 110 | if (!mask) | 119 | if (!mask) |
| 111 | mask = DIRSTRING_TYPE; | 120 | mask = DIRSTRING_TYPE; |
| 112 | 121 | ||
| @@ -221,11 +230,19 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, | |||
| 221 | break; | 230 | break; |
| 222 | 231 | ||
| 223 | case MBSTRING_BMP: | 232 | case MBSTRING_BMP: |
| 233 | if (nchar > INT_MAX / 2) { | ||
| 234 | ASN1error(ASN1_R_STRING_TOO_LONG); | ||
| 235 | goto err; | ||
| 236 | } | ||
| 224 | outlen = nchar << 1; | 237 | outlen = nchar << 1; |
| 225 | cpyfunc = cpy_bmp; | 238 | cpyfunc = cpy_bmp; |
| 226 | break; | 239 | break; |
| 227 | 240 | ||
| 228 | case MBSTRING_UNIV: | 241 | case MBSTRING_UNIV: |
| 242 | if (nchar > INT_MAX / 4) { | ||
| 243 | ASN1error(ASN1_R_STRING_TOO_LONG); | ||
| 244 | goto err; | ||
| 245 | } | ||
| 229 | outlen = nchar << 2; | 246 | outlen = nchar << 2; |
| 230 | cpyfunc = cpy_univ; | 247 | cpyfunc = cpy_univ; |
| 231 | break; | 248 | break; |
