Skip to content

Commit a66e294

Browse files
committed
Fix ssl_DecodePacketInternal chain processing
1 parent 46f4b3b commit a66e294

2 files changed

Lines changed: 63 additions & 3 deletions

File tree

src/sniffer.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6720,20 +6720,29 @@ static int ssl_DecodePacketInternal(const byte* packet, int length, int isChain,
67206720
#ifdef WOLFSSL_SNIFFER_CHAIN_INPUT
67216721
struct iovec* chain;
67226722
word32 i;
6723+
size_t totalLength;
67236724

67246725
word32 chainSz = (word32)length;
67256726

67266727
chain = (struct iovec*)packet;
6727-
length = 0;
6728-
for (i = 0; i < chainSz; i++) length += chain[i].iov_len;
6728+
totalLength = 0;
6729+
for (i = 0; i < chainSz; i++) {
6730+
size_t prev = totalLength;
6731+
totalLength += chain[i].iov_len;
6732+
if (totalLength < prev || totalLength > (size_t)INT_MAX) {
6733+
SetError(BAD_INPUT_STR, error, session, FATAL_ERROR_STATE);
6734+
return WOLFSSL_SNIFFER_ERROR;
6735+
}
6736+
}
6737+
length = (int)totalLength;
67296738

67306739
tmpPacket = (byte*)XMALLOC(length, NULL, DYNAMIC_TYPE_SNIFFER_CHAIN_BUFFER);
67316740
if (tmpPacket == NULL) return MEMORY_E;
67326741

67336742
length = 0;
67346743
for (i = 0; i < chainSz; i++) {
67356744
XMEMCPY(tmpPacket+length,chain[i].iov_base,chain[i].iov_len);
6736-
length += chain[i].iov_len;
6745+
length += (int)chain[i].iov_len;
67376746
}
67386747
packet = (const byte*)tmpPacket;
67396748
#else

tests/api.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@
159159
#include "wolfssl/internal.h"
160160
#endif
161161

162+
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
163+
#include <wolfssl/sniffer.h>
164+
#include <wolfssl/sniffer_error.h>
165+
#include <sys/uio.h>
166+
#endif
167+
162168
/* include misc.c here regardless of NO_INLINE, because misc.c implementations
163169
* have default (hidden) visibility, and in the absence of visibility, it's
164170
* benign to mask out the library implementation.
@@ -33786,6 +33792,46 @@ int test_wc_LmsKey_reload_cache(void)
3378633792
return EXPECT_RESULT();
3378733793
}
3378833794

33795+
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
33796+
static int test_sniffer_chain_input_overflow(void)
33797+
{
33798+
EXPECT_DECLS;
33799+
struct iovec chain[3];
33800+
byte* data = NULL;
33801+
char error[WOLFSSL_MAX_ERROR_SZ];
33802+
int ret;
33803+
byte dummy[1] = {0};
33804+
33805+
/* Test 1: iov_len values that sum to more than INT_MAX.
33806+
* Before the fix, these size_t values would be truncated when accumulated
33807+
* into an int, causing an undersized allocation followed by an oversized
33808+
* copy (heap buffer overflow). After the fix, the function should detect
33809+
* the overflow and return an error without allocating or copying. */
33810+
chain[0].iov_base = dummy;
33811+
chain[0].iov_len = (size_t)0x80000000UL; /* 2GB */
33812+
chain[1].iov_base = dummy;
33813+
chain[1].iov_len = (size_t)0x80000000UL; /* 2GB */
33814+
chain[2].iov_base = dummy;
33815+
chain[2].iov_len = (size_t)0x80000000UL; /* 2GB */
33816+
33817+
XMEMSET(error, 0, sizeof(error));
33818+
ret = ssl_DecodePacketWithChain(chain, 3, &data, error);
33819+
ExpectIntEQ(ret, WOLFSSL_SNIFFER_ERROR);
33820+
33821+
/* Test 2: total exactly at INT_MAX boundary should also be rejected since
33822+
* it would require a ~2GB allocation that is unreasonable for a packet. */
33823+
chain[0].iov_len = (size_t)0x7FFFFFFFUL; /* INT_MAX */
33824+
chain[1].iov_len = (size_t)1;
33825+
chain[2].iov_len = (size_t)0;
33826+
33827+
XMEMSET(error, 0, sizeof(error));
33828+
ret = ssl_DecodePacketWithChain(chain, 2, &data, error);
33829+
ExpectIntEQ(ret, WOLFSSL_SNIFFER_ERROR);
33830+
33831+
return EXPECT_RESULT();
33832+
}
33833+
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_CHAIN_INPUT */
33834+
3378933835
TEST_CASE testCases[] = {
3379033836
TEST_DECL(test_fileAccess),
3379133837

@@ -34591,6 +34637,11 @@ TEST_CASE testCases[] = {
3459134637
TEST_DECL(test_ocsp_responder),
3459234638
TEST_TLS_DECLS,
3459334639
TEST_DECL(test_wc_DhSetNamedKey),
34640+
34641+
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
34642+
TEST_DECL(test_sniffer_chain_input_overflow),
34643+
#endif
34644+
3459434645
/* This test needs to stay at the end to clean up any caches allocated. */
3459534646
TEST_DECL(test_wolfSSL_Cleanup)
3459634647
};

0 commit comments

Comments
 (0)