Skip to content

Commit 2c030dd

Browse files
authored
Merge pull request #10017 from embhorn/zd21388
Fix ssl_DecodePacketInternal chain processing
2 parents 440fb70 + a66e294 commit 2c030dd

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.
@@ -33813,6 +33819,46 @@ int test_wc_LmsKey_reload_cache(void)
3381333819
return EXPECT_RESULT();
3381433820
}
3381533821

33822+
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
33823+
static int test_sniffer_chain_input_overflow(void)
33824+
{
33825+
EXPECT_DECLS;
33826+
struct iovec chain[3];
33827+
byte* data = NULL;
33828+
char error[WOLFSSL_MAX_ERROR_SZ];
33829+
int ret;
33830+
byte dummy[1] = {0};
33831+
33832+
/* Test 1: iov_len values that sum to more than INT_MAX.
33833+
* Before the fix, these size_t values would be truncated when accumulated
33834+
* into an int, causing an undersized allocation followed by an oversized
33835+
* copy (heap buffer overflow). After the fix, the function should detect
33836+
* the overflow and return an error without allocating or copying. */
33837+
chain[0].iov_base = dummy;
33838+
chain[0].iov_len = (size_t)0x80000000UL; /* 2GB */
33839+
chain[1].iov_base = dummy;
33840+
chain[1].iov_len = (size_t)0x80000000UL; /* 2GB */
33841+
chain[2].iov_base = dummy;
33842+
chain[2].iov_len = (size_t)0x80000000UL; /* 2GB */
33843+
33844+
XMEMSET(error, 0, sizeof(error));
33845+
ret = ssl_DecodePacketWithChain(chain, 3, &data, error);
33846+
ExpectIntEQ(ret, WOLFSSL_SNIFFER_ERROR);
33847+
33848+
/* Test 2: total exactly at INT_MAX boundary should also be rejected since
33849+
* it would require a ~2GB allocation that is unreasonable for a packet. */
33850+
chain[0].iov_len = (size_t)0x7FFFFFFFUL; /* INT_MAX */
33851+
chain[1].iov_len = (size_t)1;
33852+
chain[2].iov_len = (size_t)0;
33853+
33854+
XMEMSET(error, 0, sizeof(error));
33855+
ret = ssl_DecodePacketWithChain(chain, 2, &data, error);
33856+
ExpectIntEQ(ret, WOLFSSL_SNIFFER_ERROR);
33857+
33858+
return EXPECT_RESULT();
33859+
}
33860+
#endif /* WOLFSSL_SNIFFER && WOLFSSL_SNIFFER_CHAIN_INPUT */
33861+
3381633862
TEST_CASE testCases[] = {
3381733863
TEST_DECL(test_fileAccess),
3381833864

@@ -34619,6 +34665,11 @@ TEST_CASE testCases[] = {
3461934665
TEST_DECL(test_ocsp_responder),
3462034666
TEST_TLS_DECLS,
3462134667
TEST_DECL(test_wc_DhSetNamedKey),
34668+
34669+
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
34670+
TEST_DECL(test_sniffer_chain_input_overflow),
34671+
#endif
34672+
3462234673
/* This test needs to stay at the end to clean up any caches allocated. */
3462334674
TEST_DECL(test_wolfSSL_Cleanup)
3462434675
};

0 commit comments

Comments
 (0)