Skip to content

Commit 7e9635d

Browse files
authored
Merge pull request #10208 from ColtonWilley/bio-io-negative-length-checks
Guard against negative length in BIO, I/O callbacks and PKCS12 PBKDF
2 parents c278b61 + bfd8834 commit 7e9635d

3 files changed

Lines changed: 73 additions & 0 deletions

File tree

src/bio.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len)
272272
WOLFSSL_ENTER("wolfSSL_BIO_read");
273273
}
274274

275+
if (len < 0) {
276+
return WOLFSSL_BIO_ERROR;
277+
}
278+
275279
/* info cb, abort if user returns <= 0*/
276280
if (front != NULL && front->infoCb != NULL) {
277281
ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_READ, (const char*)buf,
@@ -690,6 +694,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len)
690694

691695
WOLFSSL_ENTER("wolfSSL_BIO_write");
692696

697+
if (len < 0) {
698+
return WOLFSSL_BIO_ERROR;
699+
}
700+
693701
/* info cb, abort if user returns <= 0*/
694702
if (front != NULL && front->infoCb != NULL) {
695703
ret = (int)front->infoCb(front, WOLFSSL_BIO_CB_WRITE,
@@ -1569,6 +1577,10 @@ int wolfSSL_BIO_nread(WOLFSSL_BIO *bio, char **buf, int num)
15691577
return 0;
15701578
}
15711579

1580+
if (num < 0) {
1581+
return WOLFSSL_BIO_ERROR;
1582+
}
1583+
15721584
/* get amount able to read and set buffer pointer */
15731585
sz = wolfSSL_BIO_nread0(bio, buf);
15741586
if (sz < 0) {
@@ -1623,6 +1635,10 @@ int wolfSSL_BIO_nwrite(WOLFSSL_BIO *bio, char **buf, int num)
16231635
return 0;
16241636
}
16251637

1638+
if (num < 0) {
1639+
return WOLFSSL_BIO_ERROR;
1640+
}
1641+
16261642
if (bio->wrIdx < bio->rdIdx) {
16271643
/* if wrapped around only write up to read index. In this case
16281644
* rdIdx is always greater then wrIdx so sz will not be negative. */
@@ -3143,6 +3159,14 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
31433159
if (top == NULL) {
31443160
return append;
31453161
}
3162+
{
3163+
WOLFSSL_BIO* cur = append;
3164+
while (cur != NULL) {
3165+
if (cur == top)
3166+
return top; /* would create cycle */
3167+
cur = cur->next;
3168+
}
3169+
}
31463170
top->next = append;
31473171
if (append != NULL) {
31483172
append->prev = top;

src/wolfio.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,9 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx)
677677
WOLFSSL_ENTER("EmbedReceiveFrom");
678678
(void)ret; /* possibly unused */
679679

680+
if (sz < 0)
681+
return WOLFSSL_CBIO_ERR_GENERAL;
682+
680683
XMEMSET(&lclPeer, 0, sizeof(lclPeer));
681684

682685
#ifdef WOLFSSL_RW_THREADED
@@ -920,6 +923,9 @@ int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx)
920923

921924
WOLFSSL_ENTER("EmbedSendTo");
922925

926+
if (sz < 0)
927+
return WOLFSSL_CBIO_ERR_GENERAL;
928+
923929
if (!isDGramSock(sd)) {
924930
/* Probably a TCP socket. peer and peerSz MUST be NULL and 0 */
925931
}
@@ -966,6 +972,9 @@ int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, int sz, void *ctx)
966972

967973
WOLFSSL_ENTER("EmbedReceiveFromMcast");
968974

975+
if (sz < 0)
976+
return WOLFSSL_CBIO_ERR_GENERAL;
977+
969978
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, ssl->rflags, NULL, NULL);
970979

971980
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
@@ -996,6 +1005,9 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx)
9961005

9971006
(void)ctx;
9981007

1008+
if (sz < 0)
1009+
return BAD_FUNC_ARG;
1010+
9991011
XMEMSET(&peer, 0, sizeof(peer));
10001012
if (getpeername(sd, (SOCKADDR*)&peer, &peerSz) != 0) {
10011013
WOLFSSL_MSG("getpeername failed in EmbedGenerateCookie");
@@ -1224,6 +1236,9 @@ int wolfIO_Recv(SOCKET_T sd, char *buf, int sz, int rdFlags)
12241236
{
12251237
int recvd;
12261238

1239+
if (sz < 0)
1240+
return WOLFSSL_CBIO_ERR_GENERAL;
1241+
12271242
recvd = (int)RECV_FUNCTION(sd, buf, (size_t)sz, rdFlags);
12281243
recvd = TranslateIoReturnCode(recvd, sd, SOCKET_RECEIVING);
12291244

@@ -1234,6 +1249,9 @@ int wolfIO_Send(SOCKET_T sd, char *buf, int sz, int wrFlags)
12341249
{
12351250
int sent;
12361251

1252+
if (sz < 0)
1253+
return WOLFSSL_CBIO_ERR_GENERAL;
1254+
12371255
sent = (int)SEND_FUNCTION(sd, buf, (size_t)sz, wrFlags);
12381256
sent = TranslateIoReturnCode(sent, sd, SOCKET_SENDING);
12391257

@@ -1247,6 +1265,9 @@ int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int
12471265
int recvd;
12481266
socklen_t addr_len = (socklen_t)sizeof(*addr);
12491267

1268+
if (sz < 0)
1269+
return WOLFSSL_CBIO_ERR_GENERAL;
1270+
12501271
recvd = (int)DTLS_RECVFROM_FUNCTION(sd, buf, (size_t)sz, rdFlags,
12511272
addr ? &addr->sa : NULL,
12521273
addr ? &addr_len : 0);
@@ -1260,6 +1281,9 @@ int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wr
12601281
int sent;
12611282
socklen_t addr_len = addr ? wolfSSL_BIO_ADDR_size(addr) : 0;
12621283

1284+
if (sz < 0)
1285+
return WOLFSSL_CBIO_ERR_GENERAL;
1286+
12631287
sent = (int)DTLS_SENDTO_FUNCTION(sd, buf, (size_t)sz, wrFlags,
12641288
addr ? &addr->sa : NULL,
12651289
addr_len);

wolfcrypt/src/pwdbased.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,22 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
442442
/* with passLen checked at the top of the function for >= 0 then passLen
443443
* must be 1 or greater here and is always 'true' */
444444
pLen = v * (((word32)passLen + v - 1) / v);
445+
446+
/* Guard against overflow in iLen = sLen + pLen and totalLen = dLen + iLen.
447+
* Individual sLen/pLen values fit in word32 (max 0x80000000 for INT_MAX
448+
* inputs), but their sum can overflow. */
449+
if (sLen > 0xFFFFFFFFU - pLen) {
450+
WC_FREE_VAR_EX(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
451+
WC_FREE_VAR_EX(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
452+
return BAD_FUNC_ARG;
453+
}
445454
iLen = sLen + pLen;
446455

456+
if (iLen > 0xFFFFFFFFU - dLen) {
457+
WC_FREE_VAR_EX(Ai, heap, DYNAMIC_TYPE_TMP_BUFFER);
458+
WC_FREE_VAR_EX(B, heap, DYNAMIC_TYPE_TMP_BUFFER);
459+
return BAD_FUNC_ARG;
460+
}
447461
totalLen = dLen + sLen + pLen;
448462

449463
if (totalLen > sizeof(staticBuffer)) {
@@ -635,8 +649,19 @@ int wc_PKCS12_PBKDF_ex(byte* output, const byte* passwd, int passLen,
635649
sLen = v * (((word32)saltLen + v - 1) / v);
636650
/* RFC 7292 B.2 step 3: P = password repeated to ceil(passLen/v)*v bytes */
637651
pLen = v * (((word32)passLen + v - 1) / v);
652+
653+
/* Guard against overflow in iLen = sLen + pLen and totalLen = v + iLen.
654+
* Individual sLen/pLen values fit in word32 (max 0x80000000 for INT_MAX
655+
* inputs), but their sum can overflow. */
656+
if (sLen > 0xFFFFFFFFU - pLen) {
657+
return BAD_FUNC_ARG;
658+
}
638659
/* RFC 7292 B.2 step 4: I = S || P */
639660
iLen = sLen + pLen;
661+
662+
if (iLen > 0xFFFFFFFFU - v) {
663+
return BAD_FUNC_ARG;
664+
}
640665
totalLen = v + iLen;
641666

642667
nwc = v / (word32)sizeof(PKCS12_WORD);

0 commit comments

Comments
 (0)