Fixes to size checking

In `quic_record_transfer()`, the unsigned subtraction
`qr->end - qr->start` could wrap around if `end < start`, and the
subsequent `len <= 0` check was ineffective on a `word32`. Move the
comparison before the subtraction so the function returns `0` safely.

In `GetEchConfig()`, `XSTRLEN(config->publicName)` was assigned to a
single byte, silently truncating names longer than 255 characters while
`XMEMCPY` still copied the full string. Add a 255-byte length
validation in both `wolfSSL_CTX_GenerateEchConfig()` and
`GetEchConfig()`, and cache the length in a local variable to avoid
redundant `XSTRLEN` calls.
This commit is contained in:
Andrew Hutchings
2026-02-18 13:45:45 +00:00
parent add60da56a
commit b7c3bbf101
2 changed files with 17 additions and 7 deletions
+3 -2
View File
@@ -184,13 +184,14 @@ static word32 add_rec_header(byte* output, word32 length, byte type)
static sword32 quic_record_transfer(QuicRecord* qr, byte* buf, word32 sz)
{
word32 len = qr->end - qr->start;
word32 len;
word32 offset = 0;
word32 rlen;
if (len <= 0) {
if (qr->end <= qr->start) {
return 0;
}
len = qr->end - qr->start;
/* We check if the buf is at least RECORD_HEADER_SZ */
if (sz < RECORD_HEADER_SZ) {
+14 -5
View File
@@ -48,6 +48,10 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName,
if (ctx == NULL || publicName == NULL)
return BAD_FUNC_ARG;
/* ECH spec limits public_name to 255 bytes (1-byte length prefix) */
if (XSTRLEN(publicName) > 255)
return BAD_FUNC_ARG;
WC_ALLOC_VAR_EX(rng, WC_RNG, 1, ctx->heap, DYNAMIC_TYPE_RNG,
return MEMORY_E);
ret = wc_InitRng(rng);
@@ -313,10 +317,16 @@ int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
{
int i;
word16 totalLen = 0;
word16 publicNameLen;
if (config == NULL || (output == NULL && outputLen == NULL))
return BAD_FUNC_ARG;
/* ECH spec limits public_name to 255 bytes (1-byte length prefix) */
if (config->publicName == NULL || XSTRLEN(config->publicName) > 255)
return BAD_FUNC_ARG;
publicNameLen = (word16)XSTRLEN(config->publicName);
/* 2 for version */
totalLen += 2;
/* 2 for length */
@@ -355,7 +365,7 @@ int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
totalLen += 2;
/* public name */
totalLen += XSTRLEN(config->publicName);
totalLen += publicNameLen;
/* trailing zeros */
totalLen += 2;
@@ -435,13 +445,12 @@ int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen)
output++;
/* publicName len */
*output = XSTRLEN(config->publicName);
*output = (byte)publicNameLen;
output++;
/* publicName */
XMEMCPY(output, config->publicName,
XSTRLEN(config->publicName));
output += XSTRLEN(config->publicName);
XMEMCPY(output, config->publicName, publicNameLen);
output += publicNameLen;
/* terminating zeros */
c16toa(0, output);