From 91aad90c59739c00beb5004756e7ddb60313baac Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 24 Jan 2025 17:16:08 -0600 Subject: [PATCH] wolfssl/internal.h and src/internal.c: change Buffers.prevSent and .plainSz from int to word32; change SendData() sz arg from int sz to size_t sz; add asserts in SendData() and ReceiveData() to prevent sz > INT_MAX (assuring no overflow internally or in the returned int). wolfssl/ssl.h and src/ssl.c: change WOLFSSL_BUFFER_INFO.length from unsigned int to word32 (no functional change, just for consistency); add wolfSSL_write_internal(), refactor wolfSSL_write() to call it, and fix wolfSSL_write_ex() to take size_t sz, not int sz. --- src/internal.c | 26 ++++++++++++++++++-------- src/ssl.c | 22 ++++++++++++++++------ wolfssl/internal.h | 6 +++--- wolfssl/ssl.h | 4 ++-- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/internal.c b/src/internal.c index ce90accaf2..6bf9e06ea2 100644 --- a/src/internal.c +++ b/src/internal.c @@ -25300,16 +25300,21 @@ static int ssl_in_handshake(WOLFSSL *ssl, int send) return 0; } -int SendData(WOLFSSL* ssl, const void* data, int sz) +int SendData(WOLFSSL* ssl, const void* data, size_t sz) { - int sent = 0, /* plainText size */ - sendSz, + word32 sent = 0; /* plainText size */ + int sendSz, ret; #if defined(WOLFSSL_EARLY_DATA) && defined(WOLFSSL_EARLY_DATA_GROUP) int groupMsgs = 0; #endif int error = ssl->error; + if (sz > INT_MAX) { + WOLFSSL_MSG("SendData sz overflow"); + return WOLFSSL_FATAL_ERROR; + } + if (error == WC_NO_ERR_TRACE(WANT_WRITE) #ifdef WOLFSSL_ASYNC_CRYPT || error == WC_NO_ERR_TRACE(WC_PENDING_E) @@ -25414,7 +25419,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) sent = ssl->buffers.prevSent + ssl->buffers.plainSz; WOLFSSL_MSG("sent write buffered data"); - if (sent > sz) { + if (sent > (word32)sz) { WOLFSSL_MSG("error: write() after WANT_WRITE with short size"); return (ssl->error = BAD_FUNC_ARG); } @@ -25503,19 +25508,19 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent); + buffSz = wolfSSL_GetMaxFragSize(ssl, (word32)sz - sent); } else #endif { - buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent); + buffSz = wolfSSL_GetMaxFragSize(ssl, (word32)sz - sent); } - if (sent == sz) break; + if (sent == (word32)sz) break; #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_DTLS_SIZE_CHECK) - if (ssl->options.dtls && (buffSz < sz - sent)) { + if (ssl->options.dtls && ((size_t)buffSz < (word32)sz - sent)) { error = DTLS_SIZE_ERROR; ssl->error = error; WOLFSSL_ERROR(error); @@ -25693,6 +25698,11 @@ int ReceiveData(WOLFSSL* ssl, byte* output, size_t sz, int peek) WOLFSSL_ENTER("ReceiveData"); + if (sz > INT_MAX) { + WOLFSSL_MSG("ReceiveData sz overflow"); + return WOLFSSL_FATAL_ERROR; + } + /* reset error state */ if (error == WC_NO_ERR_TRACE(WANT_READ) || error == WOLFSSL_ERROR_WANT_READ) { diff --git a/src/ssl.c b/src/ssl.c index c37be0a9b6..c2eabbd8b1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2970,14 +2970,13 @@ int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl) #endif /* !NO_DH */ -WOLFSSL_ABI -int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz) +static int wolfSSL_write_internal(WOLFSSL* ssl, const void* data, size_t sz) { int ret; WOLFSSL_ENTER("wolfSSL_write"); - if (ssl == NULL || data == NULL || sz < 0) + if (ssl == NULL || data == NULL) return BAD_FUNC_ARG; #ifdef WOLFSSL_QUIC @@ -3037,6 +3036,17 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz) return ret; } +WOLFSSL_ABI +int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz) +{ + WOLFSSL_ENTER("wolfSSL_write"); + + if (sz < 0) + return BAD_FUNC_ARG; + + return wolfSSL_write_internal(ssl, data, sz); +} + int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz) { int maxLength; @@ -3074,7 +3084,7 @@ int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz) } -int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, int sz, size_t* wr) +int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, size_t sz, size_t* wr) { int ret; @@ -3082,7 +3092,7 @@ int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, int sz, size_t* wr) *wr = 0; } - ret = wolfSSL_write(ssl, data, sz); + ret = wolfSSL_write_internal(ssl, data, sz); if (ret >= 0) { if (wr != NULL) { *wr = (size_t)ret; @@ -3093,7 +3103,7 @@ int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, int sz, size_t* wr) if (ret == 0 && ssl->options.partialWrite) { ret = 0; } - else if (ret < sz && !ssl->options.partialWrite) { + else if ((size_t)ret < sz && !ssl->options.partialWrite) { ret = 0; } else { diff --git a/wolfssl/internal.h b/wolfssl/internal.h index fefe594c78..c229299710 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4801,9 +4801,9 @@ typedef struct Buffers { buffer clearOutputBuffer; buffer sig; /* signature data */ buffer digest; /* digest data */ - int prevSent; /* previous plain text bytes sent + word32 prevSent; /* previous plain text bytes sent when got WANT_WRITE */ - int plainSz; /* plain text bytes in buffer to send + word32 plainSz; /* plain text bytes in buffer to send when got WANT_WRITE */ byte weOwnCert; /* SSL own cert flag */ byte weOwnCertChain; /* SSL own cert chain flag */ @@ -6500,7 +6500,7 @@ WOLFSSL_LOCAL int DoClientTicket_ex(const WOLFSSL* ssl, PreSharedKey* psk, WOLFSSL_LOCAL int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len); #endif /* HAVE_SESSION_TICKET */ -WOLFSSL_LOCAL int SendData(WOLFSSL* ssl, const void* data, int sz); +WOLFSSL_LOCAL int SendData(WOLFSSL* ssl, const void* data, size_t sz); #ifdef WOLFSSL_THREADED_CRYPT WOLFSSL_LOCAL int SendAsyncData(WOLFSSL* ssl); #endif diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index cb7bbb24af..2e0c57aba6 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -604,7 +604,7 @@ struct WOLFSSL_EVP_PKEY { typedef struct WOLFSSL_BUFFER_INFO { unsigned char* buffer; - unsigned int length; + word32 length; } WOLFSSL_BUFFER_INFO; typedef struct WOLFSSL_BUF_MEM { @@ -1365,7 +1365,7 @@ WOLFSSL_API int wolfSSL_get_wfd(const WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_connect(WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_write( WOLFSSL* ssl, const void* data, int sz); -WOLFSSL_API int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, int sz, +WOLFSSL_API int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, size_t sz, size_t* wr); WOLFSSL_ABI WOLFSSL_API int wolfSSL_read(WOLFSSL* ssl, void* data, int sz); WOLFSSL_API int wolfSSL_read_ex(WOLFSSL* ssl, void* data, size_t sz, size_t* rd);