From 4eb192d4c8e9a02cf2cc61a58015fc760ccd25fa Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Fri, 21 Aug 2026 15:47:05 -0400 Subject: [PATCH] wolfssl_local_MatchBaseName: fix 1-byte read out of bounds looking for "@" Fixes F-7106 --- tests/api/test_asn.c | 27 +++++++++++++++++++++++++++ wolfcrypt/src/asn.c | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/api/test_asn.c b/tests/api/test_asn.c index e3fe6c8b92..05eafef57b 100644 --- a/tests/api/test_asn.c +++ b/tests/api/test_asn.c @@ -1036,6 +1036,33 @@ int test_wolfssl_local_MatchBaseName(void) ExpectIntEQ(wolfssl_local_MatchBaseName(ASN_RFC822_TYPE, "user@domain.com", 15, "user@", 5), 0); + /* Regression: the scan for '@' in the base must test the length bound + * before dereferencing. The base is passed with an explicit length and + * is not required to be NUL terminated, so a bare-domain constraint + * (no '@' anywhere in it) used to read base[baseSz]. Run the same + * cases against a heap buffer holding exactly baseSz bytes with no + * terminator, so that the over-read is a heap overflow that ASAN or + * valgrind will catch. */ + { + const char* bases[] = { "domain.com", ".domain.com", "user@domain.com" }; + const int expect[] = { 1, 0, 1 }; + size_t i; + + for (i = 0; i < XELEM_CNT(bases); i++) { + char* base = NULL; + int baseSz = (int)XSTRLEN(bases[i]); + + ExpectNotNull(base = (char*)XMALLOC((size_t)baseSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER)); + if (base != NULL) { + XMEMCPY(base, bases[i], (size_t)baseSz); + ExpectIntEQ(wolfssl_local_MatchBaseName(ASN_RFC822_TYPE, + "user@domain.com", 15, base, baseSz), expect[i]); + XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + } + } + /* * Tests for directory type (ASN_DIR_TYPE = 0x04) * diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ad2e09c14f..79691ec234 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -19236,7 +19236,7 @@ int wolfssl_local_MatchBaseName(int type, const char* name, int nameSz, count = 0; /* find the '@' in the base */ - while (*p != '@' && count < baseSz) { + while (count < baseSz && *p != '@') { count++; p++; }