Skip to content

Commit 8b44b00

Browse files
committed
Fix issues found during src/ code review
- ECH: add bounds check on hpkePubkeyLen against HPKE_Npk_MAX to prevent heap buffer overflow from untrusted ECH config data - Sniffer: fix reassembly memory limit check typo, MaxRecoveryMemory -1 should be MaxRecoveryMemory != -1 - Sniffer: add bounds check in IPv6 extension header parsing loop to prevent OOB read when next_header never matches TCP or NO_NEXT_HEADER - Sniffer: validate tlsFragOffset + rhSize against tlsFragSize before XMEMCPY in both TLS handshake fragment reassembly paths - Internal: use WC_SAFE_SUM_WORD32 in GrowAnOutputBuffer to prevent integer overflow on allocation size, matching existing pattern in GrowOutputBuffer
1 parent 4fe05d7 commit 8b44b00

3 files changed

Lines changed: 29 additions & 6 deletions

File tree

src/internal.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11294,6 +11294,7 @@ static WC_INLINE int GrowAnOutputBuffer(WOLFSSL* ssl,
1129411294
#else
1129511295
const byte align = WOLFSSL_GENERAL_ALIGNMENT;
1129611296
#endif
11297+
word32 newSz = 0;
1129711298

1129811299
#if WOLFSSL_GENERAL_ALIGNMENT > 0
1129911300
/* the encrypted data will be offset from the front of the buffer by
@@ -11304,8 +11305,13 @@ static WC_INLINE int GrowAnOutputBuffer(WOLFSSL* ssl,
1130411305
align *= 2;
1130511306
#endif
1130611307

11307-
tmp = (byte*)XMALLOC(size + outputBuffer->length + align,
11308-
ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
11308+
if (!WC_SAFE_SUM_WORD32(outputBuffer->length, (word32)size, newSz))
11309+
return BUFFER_E;
11310+
#if WOLFSSL_GENERAL_ALIGNMENT > 0
11311+
if (!WC_SAFE_SUM_WORD32(newSz, align, newSz))
11312+
return BUFFER_E;
11313+
#endif
11314+
tmp = (byte*)XMALLOC(newSz, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER);
1130911315
WOLFSSL_MSG("growing output buffer");
1131011316

1131111317
if (tmp == NULL)
@@ -11318,7 +11324,7 @@ static WC_INLINE int GrowAnOutputBuffer(WOLFSSL* ssl,
1131811324
#ifdef WOLFSSL_STATIC_MEMORY
1131911325
/* can be from IO memory pool which does not need copy if same buffer */
1132011326
if (outputBuffer->length && tmp == outputBuffer->buffer) {
11321-
outputBuffer->bufferSize = size + outputBuffer->length;
11327+
outputBuffer->bufferSize = newSz - align;
1132211328
return 0;
1132311329
}
1132411330
#endif
@@ -11339,7 +11345,7 @@ static WC_INLINE int GrowAnOutputBuffer(WOLFSSL* ssl,
1133911345

1134011346
outputBuffer->buffer = tmp;
1134111347
outputBuffer->dynamicFlag = 1;
11342-
outputBuffer->bufferSize = size + outputBuffer->length;
11348+
outputBuffer->bufferSize = newSz - align;
1134311349
return 0;
1134411350
}
1134511351
#endif

src/sniffer.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,8 +2146,13 @@ static int CheckIp6Hdr(Ip6Hdr* iphdr, IpInfo* info, int length, char* error)
21462146
exthdrsz += hdrsz;
21472147
exthdr = (Ip6ExtHdr*)((byte*)exthdr + hdrsz);
21482148
}
2149-
while (exthdr->next_header != TCP_PROTOCOL &&
2149+
while (exthdrsz < length &&
2150+
exthdr->next_header != TCP_PROTOCOL &&
21502151
exthdr->next_header != NO_NEXT_HEADER);
2152+
if (exthdrsz >= length) {
2153+
SetError(PACKET_HDR_SHORT_STR, error, NULL, 0);
2154+
return WOLFSSL_FATAL_ERROR;
2155+
}
21512156
}
21522157

21532158
#ifndef WOLFSSL_SNIFFER_WATCH
@@ -4571,6 +4576,10 @@ static int DoHandShake(const byte* input, int* sslBytes,
45714576

45724577
#ifdef HAVE_MAX_FRAGMENT
45734578
if (session->tlsFragBuf) {
4579+
if (session->tlsFragOffset + rhSize > session->tlsFragSize) {
4580+
SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
4581+
return WOLFSSL_FATAL_ERROR;
4582+
}
45744583
XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
45754584
session->tlsFragOffset += rhSize;
45764585
*sslBytes -= rhSize;
@@ -4625,6 +4634,10 @@ static int DoHandShake(const byte* input, int* sslBytes,
46254634
*sslBytes += HANDSHAKE_HEADER_SZ;
46264635
}
46274636

4637+
if (session->tlsFragOffset + rhSize > session->tlsFragSize) {
4638+
SetError(HANDSHAKE_INPUT_STR, error, session, FATAL_ERROR_STATE);
4639+
return WOLFSSL_FATAL_ERROR;
4640+
}
46284641
XMEMCPY(session->tlsFragBuf + session->tlsFragOffset, input, rhSize);
46294642
session->tlsFragOffset += rhSize;
46304643
*sslBytes -= rhSize;
@@ -5622,7 +5635,7 @@ static int AddToReassembly(byte from, word32 seq, const byte* sslFrame,
56225635
if (end >= curr->begin)
56235636
end = curr->begin - 1;
56245637

5625-
if (MaxRecoveryMemory -1 &&
5638+
if (MaxRecoveryMemory != -1 &&
56265639
(int)(*reassemblyMemory + sslBytes) > MaxRecoveryMemory) {
56275640
SetError(REASSEMBLY_MAX_STR, error, session, FATAL_ERROR_STATE);
56285641
return WOLFSSL_FATAL_ERROR;

src/ssl_ech.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,10 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap,
580580
ato16(echConfig, &hpkePubkeyLen);
581581
echConfig += 2;
582582
/* hpke public_key */
583+
if (hpkePubkeyLen > HPKE_Npk_MAX) {
584+
ret = BUFFER_E;
585+
break;
586+
}
583587
XMEMCPY(workingConfig->receiverPubkey, echConfig, hpkePubkeyLen);
584588
echConfig += hpkePubkeyLen;
585589
/* cipherSuitesLen */

0 commit comments

Comments
 (0)