mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 14:50:49 +02:00
Guard against negative length in BIO, I/O callbacks and PKCS12 PBKDF
- src/bio.c: Add BIO self-cycle UAF guard and negative nread/nwrite checks - src/wolfio.c: Add negative sz guards to EmbedSend/EmbedReceive - wolfcrypt/src/pwdbased.c: Add pLen/sLen/totalLen overflow checks in wc_PKCS12_PBKDF_ex
This commit is contained in:
committed by
Mattia Moffa
parent
3181e2bcf8
commit
37d66b8be9
@@ -281,6 +281,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
return WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
|
||||
/* start at end of list (or a WOLFSSL_BIO_SSL object since it takes care of
|
||||
* the rest of the chain) and work backwards */
|
||||
while (bio != NULL && bio->next != NULL && bio->type != WOLFSSL_BIO_SSL) {
|
||||
@@ -699,6 +703,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
|
||||
}
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
return WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
|
||||
while (bio != NULL && ret >= 0) {
|
||||
#ifdef WOLFSSL_BIO_HAVE_FLOW_STATS
|
||||
int inhibit_flow_increment = 0;
|
||||
@@ -1569,6 +1577,10 @@ int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (num < 0) {
|
||||
return WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
|
||||
/* get amount able to read and set buffer pointer */
|
||||
sz = wolfSSL_BIO_nread0(bio, buf);
|
||||
if (sz < 0) {
|
||||
@@ -1623,6 +1635,10 @@ int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (num < 0) {
|
||||
return WOLFSSL_BIO_ERROR;
|
||||
}
|
||||
|
||||
if (bio->wrIdx < bio->rdIdx) {
|
||||
/* if wrapped around only write up to read index. In this case
|
||||
* rdIdx is always greater then wrIdx so sz will not be negative. */
|
||||
@@ -3137,6 +3153,14 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
|
||||
if (top == NULL) {
|
||||
return append;
|
||||
}
|
||||
{
|
||||
WOLFSSL_BIO* cur = append;
|
||||
while (cur != NULL) {
|
||||
if (cur == top)
|
||||
return top; /* would create cycle */
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
top->next = append;
|
||||
if (append != NULL) {
|
||||
append->prev = top;
|
||||
|
||||
@@ -675,6 +675,9 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||
WOLFSSL_ENTER("EmbedReceiveFrom");
|
||||
(void)ret; /* possibly unused */
|
||||
|
||||
if (sz < 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
XMEMSET(&lclPeer, 0, sizeof(lclPeer));
|
||||
|
||||
#ifdef WOLFSSL_RW_THREADED
|
||||
@@ -918,6 +921,9 @@ int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
|
||||
|
||||
WOLFSSL_ENTER("EmbedSendTo");
|
||||
|
||||
if (sz < 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
if (!isDGramSock(sd)) {
|
||||
/* Probably a TCP socket. peer and peerSz MUST be NULL and 0 */
|
||||
}
|
||||
@@ -964,6 +970,9 @@ int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||
|
||||
WOLFSSL_ENTER("EmbedReceiveFromMcast");
|
||||
|
||||
if (sz < 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, ssl->rflags, NULL, NULL);
|
||||
|
||||
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
|
||||
@@ -994,6 +1003,9 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (sz < 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XMEMSET(&peer, 0, sizeof(peer));
|
||||
if (getpeername(sd, (SOCKADDR*)&peer, &peerSz) != 0) {
|
||||
WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie");
|
||||
@@ -1222,6 +1234,9 @@ int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags)
|
||||
{
|
||||
int recvd;
|
||||
|
||||
if (sz < 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
recvd = (int)RECV_FUNCTION(sd, buf, (size_t)sz, rdFlags);
|
||||
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
|
||||
|
||||
@@ -1232,6 +1247,9 @@ int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags)
|
||||
{
|
||||
int sent;
|
||||
|
||||
if (sz < 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
sent = (int)SEND_FUNCTION(sd, buf, (size_t)sz, wrFlags);
|
||||
sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
|
||||
|
||||
@@ -1245,6 +1263,9 @@ int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int
|
||||
int recvd;
|
||||
socklen_t addr_len = (socklen_t)sizeof(*addr);
|
||||
|
||||
if (sz < 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, rdFlags,
|
||||
addr ? &addr->sa : NULL,
|
||||
addr ? &addr_len : 0);
|
||||
@@ -1258,6 +1279,9 @@ int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wr
|
||||
int sent;
|
||||
socklen_t addr_len = addr ? wolfSSL_BIO_ADDR_size(addr) : 0;
|
||||
|
||||
if (sz < 0)
|
||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||
|
||||
sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, (size_t)sz, wrFlags,
|
||||
addr ? &addr->sa : NULL,
|
||||
addr_len);
|
||||
|
||||
@@ -442,8 +442,22 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
|
||||
/* with passLen checked at the top of the function for >= 0 then passLen
|
||||
* must be 1 or greater here and is always 'true' */
|
||||
pLen = v * (((word32)passLen + v - 1) / v);
|
||||
|
||||
/* Guard against overflow in iLen = sLen + pLen and totalLen = dLen + iLen.
|
||||
* Individual sLen/pLen values fit in word32 (max 0x80000000 for INT_MAX
|
||||
* inputs), but their sum can overflow. */
|
||||
if (sLen > 0xFFFFFFFFU - pLen) {
|
||||
WC_FREE_VAR_EX(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
WC_FREE_VAR_EX(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
iLen = sLen + pLen;
|
||||
|
||||
if (iLen > 0xFFFFFFFFU - v) {
|
||||
WC_FREE_VAR_EX(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
WC_FREE_VAR_EX(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
totalLen = dLen + sLen + pLen;
|
||||
|
||||
if (totalLen > sizeof(staticBuffer)) {
|
||||
@@ -635,8 +649,19 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
|
||||
sLen = v * (((word32)saltLen + v - 1) / v);
|
||||
/* RFC 7292 B.2 step 3: P = password repeated to ceil(passLen/v)*v bytes */
|
||||
pLen = v * (((word32)passLen + v - 1) / v);
|
||||
|
||||
/* Guard against overflow in iLen = sLen + pLen and totalLen = v + iLen.
|
||||
* Individual sLen/pLen values fit in word32 (max 0x80000000 for INT_MAX
|
||||
* inputs), but their sum can overflow. */
|
||||
if (sLen > 0xFFFFFFFFU - pLen) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
/* RFC 7292 B.2 step 4: I = S || P */
|
||||
iLen = sLen + pLen;
|
||||
|
||||
if (iLen > 0xFFFFFFFFU - v) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
totalLen = v + iLen;
|
||||
|
||||
nwc = v / (word32)sizeof(PKCS12_WORD);
|
||||
|
||||
Reference in New Issue
Block a user