Merge pull request #1471 from yanesca/1427_buffer_underflow

Fix buffer underflow in `x509_inet_pton_ipv6()`
This commit is contained in:
David Horstmann
2026-02-16 11:58:35 +00:00
committed by GitHub
5 changed files with 33 additions and 12 deletions

View File

@@ -0,0 +1,4 @@
Security
* Fix a limited buffer underflow in x509_inet_pton_ipv6(). In rare cases
(e.g. on platforms with memory protection when the overread crosses page
boundary) this could lead to DoS. Found and reported by Haruto Kimura.

View File

@@ -2719,22 +2719,25 @@ static int x509_inet_pton_ipv6(const char *src, void *dst)
if (*p == '\0') {
break;
} else if (*p == '.') {
/* Don't accept IPv4 too early or late */
if ((nonzero_groups == 0 && zero_group_start == -1) ||
/* Don't accept IPv4 too early or late:
* - The first 6 nonzero groups must be 16 bit pieces of address delimited by ':'
* - This might be fully or partially represented with compressed syntax (a zero
* group "::")
*/
if ((nonzero_groups < 6 && zero_group_start == -1) ||
nonzero_groups >= 7) {
break;
}
/* Walk back to prior ':', then parse as IPv4-mapped */
int steps = 4;
/* Walk back to prior ':', then parse as IPv4-mapped.
* At this point nonzero_groups == 6 or zero_group_start >= 0. Either way we have a
* ':' before the current position and still inside the buffer. Thus it is safe to
* search back for that ':' without any further checks.
*/
do {
p--;
steps--;
} while (*p != ':' && steps > 0);
} while (*p != ':');
if (*p != ':') {
break;
}
p++;
nonzero_groups--;
if (x509_inet_pton_ipv4((const char *) p,

View File

@@ -28,8 +28,9 @@ component_test_sw_inet_pton () {
# MBEDTLS_TEST_HOOKS required for x509_crt_parse_cn_inet_pton
scripts/config.py set MBEDTLS_TEST_HOOKS
$MAKE_COMMAND CFLAGS="-DMBEDTLS_TEST_SW_INET_PTON"
CC=$ASAN_CC CFLAGS="-DMBEDTLS_TEST_SW_INET_PTON" cmake -D CMAKE_BUILD_TYPE:String=Asan .
make
msg "test: default plus MBEDTLS_TEST_SW_INET_PTON"
$MAKE_COMMAND test
make test
}

View File

@@ -1170,6 +1170,9 @@ x509_crt_parse_cn_inet_pton:"\:\:ffff\:1111.2.3.4":"":0
X509 CRT parse CN: IPv6 invalid address IPv4-mapped #3
x509_crt_parse_cn_inet_pton:"\:\:1.2.3.4\:ffff":"":0
X509 CRT parse CN: IPv6 invalid address IPv4-mapped #4
x509_crt_parse_cn_inet_pton:"1.2.3.4\:":"":0
X509 CRT verification with ca callback: failure
depends_on:MBEDTLS_PEM_PARSE_C:PSA_WANT_ALG_SHA_1:MBEDTLS_RSA_C:MBEDTLS_PKCS1_V15:MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK
x509_verify_ca_cb_failure:"../framework/data_files/server1.crt":"../framework/data_files/test-ca.crt":"NULL":MBEDTLS_ERR_X509_FATAL_ERROR

View File

@@ -488,12 +488,22 @@ exit:
void x509_crt_parse_cn_inet_pton(const char *cn, data_t *exp, int ref_ret)
{
uint32_t addr[4];
size_t addrlen = mbedtls_x509_crt_parse_cn_inet_pton(cn, addr);
char *cn_local = NULL;
size_t cn_local_len = strlen(cn) + 1;
TEST_CALLOC(cn_local, cn_local_len);
memcpy(cn_local, cn, cn_local_len);
size_t addrlen = mbedtls_x509_crt_parse_cn_inet_pton(cn_local, addr);
TEST_EQUAL(addrlen, (size_t) ref_ret);
if (addrlen) {
TEST_MEMORY_COMPARE(exp->x, exp->len, addr, addrlen);
}
exit:
mbedtls_free(cn_local);
}
/* END_CASE */