Skip to content

Commit 801c412

Browse files
committed
src/tls.c, wolfssl/ssl.h, tests/api.c: followup to ff7a32d (#10182):
* Fix OOB heap reads via TLSX_ExtractEch() by preemptively rejecting oversized SNI names in TLSX_UseSNI(). * In TLSX_EchChangeSNI(), don't attempt to truncate if an oversized name is seen, just return error. * Move definition of WOLFSSL_HOST_NAME_MAX to an ungated context in ssl.h, and use it consistently in tls.c, eliminating the duplicative WOLFSSL_HOST_NAME_MAX.
1 parent f086e91 commit 801c412

3 files changed

Lines changed: 19 additions & 19 deletions

File tree

src/tls.c

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,6 +2613,9 @@ int TLSX_UseSNI(TLSX** extensions, byte type, const void* data, word16 size,
26132613
if (extensions == NULL || data == NULL)
26142614
return BAD_FUNC_ARG;
26152615

2616+
if ((type == WOLFSSL_SNI_HOST_NAME) && (size >= WOLFSSL_HOST_NAME_MAX))
2617+
return BAD_LENGTH_E;
2618+
26162619
if ((sni = TLSX_SNI_New(type, data, size, heap)) == NULL)
26172620
return MEMORY_E;
26182621

@@ -13445,7 +13448,6 @@ void TLSX_Remove(TLSX** list, TLSX_Type type, void* heap)
1344513448

1344613449
#if defined(WOLFSSL_TLS13) && defined(HAVE_ECH)
1344713450
#define GREASE_ECH_SIZE 160
13448-
#define MAX_PUBLIC_NAME_SZ 256
1344913451
#define TLS_INFO_CONST_STRING "tls ech"
1345013452
#define TLS_INFO_CONST_STRING_SZ 7
1345113453

@@ -16101,14 +16103,10 @@ static int TLSX_EchChangeSNI(WOLFSSL* ssl, TLSX** pEchX,
1610116103
char* hostName = ((SNI*)serverNameX->data)->data.host_name;
1610216104
word32 hostNameSz = (word32)XSTRLEN(hostName) + 1;
1610316105

16104-
/* truncate if too long */
16105-
if (hostNameSz > MAX_PUBLIC_NAME_SZ)
16106-
hostNameSz = MAX_PUBLIC_NAME_SZ;
16107-
16108-
XMEMCPY(serverName, hostName, hostNameSz);
16109-
/* Guarantee NUL termination after truncation so that
16110-
* TLSX_EchRestoreSNI's XSTRLEN cannot read past the buffer. */
16111-
serverName[hostNameSz - 1] = '\0';
16106+
if (hostNameSz > WOLFSSL_HOST_NAME_MAX)
16107+
ret = BAD_LENGTH_E;
16108+
else
16109+
XMEMCPY(serverName, hostName, hostNameSz);
1611216110
}
1611316111

1611416112
/* only swap the SNI if one was found; extensions is non-NULL if an
@@ -16161,9 +16159,9 @@ static int TLSX_GetSizeWithEch(WOLFSSL* ssl, byte* semaphore, byte msgType,
1616116159
TLSX* echX = NULL;
1616216160
TLSX* serverNameX = NULL;
1616316161
TLSX** extensions = NULL;
16164-
WC_DECLARE_VAR(serverName, char, MAX_PUBLIC_NAME_SZ, 0);
16162+
WC_DECLARE_VAR(serverName, char, WOLFSSL_HOST_NAME_MAX, 0);
1616516163

16166-
WC_ALLOC_VAR_EX(serverName, char, MAX_PUBLIC_NAME_SZ, NULL,
16164+
WC_ALLOC_VAR_EX(serverName, char, WOLFSSL_HOST_NAME_MAX, NULL,
1616716165
DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
1616816166
r = TLSX_EchChangeSNI(ssl, &echX, serverName, &serverNameX, &extensions);
1616916167
if (r == 0 && ssl->extensions)
@@ -16303,9 +16301,9 @@ static int TLSX_WriteWithEch(WOLFSSL* ssl, byte* output, byte* semaphore,
1630316301
TLSX* echX = NULL;
1630416302
TLSX* serverNameX = NULL;
1630516303
TLSX** extensions = NULL;
16306-
WC_DECLARE_VAR(serverName, char, MAX_PUBLIC_NAME_SZ, 0);
16304+
WC_DECLARE_VAR(serverName, char, WOLFSSL_HOST_NAME_MAX, 0);
1630716305

16308-
WC_ALLOC_VAR_EX(serverName, char, MAX_PUBLIC_NAME_SZ, NULL,
16306+
WC_ALLOC_VAR_EX(serverName, char, WOLFSSL_HOST_NAME_MAX, NULL,
1630916307
DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
1631016308
r = TLSX_EchChangeSNI(ssl, &echX, serverName, &serverNameX, &extensions);
1631116309
ret = r;

tests/api.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15202,13 +15202,15 @@ static int test_wolfSSL_Tls13_ECH_long_SNI(void)
1520215202
ExpectIntEQ(wolfSSL_SetEchConfigs(test_ctx.c_ssl, echCbTestConfigs,
1520315203
echCbTestConfigsLen), WOLFSSL_SUCCESS);
1520415204

15205-
/* Set the over-long SNI as the inner hostname */
15205+
/* Try to set the over-long SNI as the inner hostname -- after the fix, this
15206+
* is expected to fail.
15207+
*/
1520615208
ExpectIntEQ(wolfSSL_UseSNI(test_ctx.c_ssl, WOLFSSL_SNI_HOST_NAME,
15207-
longName, (word16)XSTRLEN(longName)), WOLFSSL_SUCCESS);
15209+
longName, (word16)XSTRLEN(longName)), BAD_LENGTH_E);
1520815210

15209-
/* The handshake triggers TLSX_EchChangeSNI / TLSX_EchRestoreSNI.
15210-
* Before the fix this would stack-buffer-overflow in XSTRLEN.
15211-
* The connection may fail (SNI mismatch) but must not crash. */
15211+
/* Before the fix, the handshake would trigger TLSX_EchChangeSNI /
15212+
* TLSX_EchRestoreSNI, which would then stack-buffer-overflow in XSTRLEN.
15213+
*/
1521215214
(void)test_ssl_memio_do_handshake(&test_ctx, 10, NULL);
1521315215

1521415216
test_ssl_memio_cleanup(&test_ctx);

wolfssl/ssl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ struct WOLFSSL_ASN1_STRING {
455455

456456
#define WOLFSSL_MAX_SNAME 40
457457

458+
#define WOLFSSL_HOST_NAME_MAX 256
458459

459460
#define WOLFSSL_ASN1_DYNAMIC 0x1
460461
#define WOLFSSL_ASN1_DYNAMIC_DATA 0x2
@@ -861,7 +862,6 @@ struct WOLFSSL_X509_STORE {
861862
#define WOLFSSL_USE_CHECK_TIME 0x2
862863
#define WOLFSSL_NO_CHECK_TIME 0x200000
863864
#define WOLFSSL_PARTIAL_CHAIN 0x80000
864-
#define WOLFSSL_HOST_NAME_MAX 256
865865

866866
#define WOLFSSL_VPARAM_DEFAULT 0x1
867867
#define WOLFSSL_VPARAM_OVERWRITE 0x2

0 commit comments

Comments
 (0)