Skip to content

Commit 7802a75

Browse files
committed
bio: various fixes and improvements
* simplify wolfSSL_BIO_set_conn_hostname, fixing OOB read * restructure wolfSSL_BIO_ctrl_pending, fixing inverted check and * ctrlCB checking * return WOLFSSL_FAILURE in wolfSSL_BIO_up_ref when refInc fails, updated test to reflect this * check arguments for NULL in wolfSSL_BIO_ADDR_size * replace non-portable type long usigned int with size_t * wolfSSL_BIO_MEMORY_write: return WOLFSSL_BIO_ERROR on failure instead of WOLFSSL_FAILURE, return 0 when len is 0 * wolfSSL_BIO_get_fp: fix type mismatch comparing XFILE* pointer against XBADFILE * wolfSSL_BIO_ctrl: add NULL check on bio before switch * wolfSSL_BIO_pop: clear bio prev and next pointers after unlinking * wolfSSL_BIO_gets: place null terminator after actual bytes read from BIO_BIO nread
1 parent 750f3b1 commit 7802a75

2 files changed

Lines changed: 60 additions & 77 deletions

File tree

src/bio.c

Lines changed: 59 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len)
164164
/* Resize the memory so we are not taking up more than necessary.
165165
* memmove reverts internally to memcpy if areas don't overlap */
166166
XMEMMOVE(bio->mem_buf->data, bio->mem_buf->data + bio->rdIdx,
167-
(long unsigned int)bio->wrSz - (size_t)bio->rdIdx);
167+
(size_t)bio->wrSz - (size_t)bio->rdIdx);
168168
bio->wrSz -= bio->rdIdx;
169169
bio->rdIdx = 0;
170170
/* Resize down to WOLFSSL_BIO_RESIZE_THRESHOLD for fewer
@@ -602,24 +602,24 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data,
602602

603603
if (bio == NULL || bio->mem_buf == NULL || data == NULL) {
604604
WOLFSSL_MSG("one of input parameters is null");
605-
return WOLFSSL_FAILURE;
605+
return WOLFSSL_BIO_ERROR;
606606
}
607607
if (bio->flags & WOLFSSL_BIO_FLAG_MEM_RDONLY) {
608-
return WOLFSSL_FAILURE;
608+
return WOLFSSL_BIO_ERROR;
609609
}
610610

611611
if (len == 0)
612-
return WOLFSSL_SUCCESS; /* Return early to make logic simpler */
612+
return 0; /* Nothing to write */
613613

614614
if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, ((size_t)bio->wrSz) +
615615
((size_t)len), 0) == 0) {
616616
WOLFSSL_MSG("Error growing memory area");
617-
return WOLFSSL_FAILURE;
617+
return WOLFSSL_BIO_ERROR;
618618
}
619619

620620
if (bio->mem_buf->data == NULL) {
621621
WOLFSSL_MSG("Buffer data is NULL");
622-
return WOLFSSL_FAILURE;
622+
return WOLFSSL_BIO_ERROR;
623623
}
624624

625625
XMEMCPY(bio->mem_buf->data + bio->wrSz, data, (size_t)len);
@@ -868,7 +868,11 @@ long wolfSSL_BIO_ctrl(WOLFSSL_BIO *bio, int cmd, long larg, void *parg)
868868

869869
WOLFSSL_ENTER("wolfSSL_BIO_ctrl");
870870

871-
if (bio && bio->method && bio->method->ctrlCb) {
871+
if (bio == NULL) {
872+
return WOLFSSL_FAILURE;
873+
}
874+
875+
if (bio->method && bio->method->ctrlCb) {
872876
return bio->method->ctrlCb(bio, cmd, larg, parg);
873877
}
874878

@@ -952,6 +956,7 @@ int wolfSSL_BIO_up_ref(WOLFSSL_BIO* bio)
952956
#ifdef WOLFSSL_REFCNT_ERROR_RETURN
953957
if (ret != 0) {
954958
WOLFSSL_MSG("Failed to lock BIO mutex");
959+
return WOLFSSL_FAILURE;
955960
}
956961
#else
957962
(void)ret;
@@ -984,6 +989,8 @@ void wolfSSL_BIO_ADDR_clear(WOLFSSL_BIO_ADDR *addr) {
984989
}
985990

986991
socklen_t wolfSSL_BIO_ADDR_size(const WOLFSSL_BIO_ADDR *addr) {
992+
if (addr == NULL)
993+
return 0;
987994
switch (addr->sa.sa_family) {
988995
#ifndef WOLFSSL_NO_BIO_ADDR_IN
989996
case AF_INET:
@@ -1144,6 +1151,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz)
11441151
ret = wolfSSL_BIO_nread(bio, &c, cSz);
11451152
if (ret > 0 && ret < sz) {
11461153
XMEMCPY(buf, c, (size_t)ret);
1154+
buf[ret] = '\0';
11471155
}
11481156
break;
11491157
}
@@ -1299,51 +1307,42 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio)
12991307
WOLFSSL_ENTER("wolfSSL_BIO_ctrl_pending");
13001308
#endif
13011309

1302-
if (bio == NULL) {
1303-
return 0;
1304-
}
1305-
1306-
if (bio->method != NULL && bio->method->ctrlCb != NULL) {
1307-
long ret;
1308-
WOLFSSL_MSG("Calling custom BIO ctrl pending callback");
1309-
ret = bio->method->ctrlCb(bio, WOLFSSL_BIO_CTRL_PENDING, 0, NULL);
1310-
return (ret < 0) ? 0 : (size_t)ret;
1311-
}
1312-
1313-
if (bio->type == WOLFSSL_BIO_MD ||
1314-
bio->type == WOLFSSL_BIO_BASE64) {
1315-
/* these are wrappers only, get next bio */
1316-
while (bio->next != NULL) {
1317-
bio = bio->next;
1318-
if (bio->type == WOLFSSL_BIO_MD ||
1319-
bio->type == WOLFSSL_BIO_BASE64) {
1320-
break;
1321-
}
1310+
for (; bio != NULL; bio = bio->next) {
1311+
if (bio->method != NULL && bio->method->ctrlCb != NULL) {
1312+
long ret;
1313+
WOLFSSL_MSG("Calling custom BIO ctrl pending callback");
1314+
ret = bio->method->ctrlCb(bio, WOLFSSL_BIO_CTRL_PENDING, 0, NULL);
1315+
return (ret < 0) ? 0 : (size_t)ret;
13221316
}
1323-
}
13241317

1318+
switch (bio->type) {
1319+
case WOLFSSL_BIO_MD:
1320+
case WOLFSSL_BIO_BASE64:
1321+
/* wrappers only, skip to next bio in chain */
1322+
continue;
13251323
#ifndef WOLFCRYPT_ONLY
1326-
if (bio->type == WOLFSSL_BIO_SSL && bio->ptr.ssl != NULL) {
1327-
return (size_t)wolfSSL_pending(bio->ptr.ssl);
1328-
}
1324+
case WOLFSSL_BIO_SSL:
1325+
if (bio->ptr.ssl != NULL)
1326+
return (size_t)wolfSSL_pending(bio->ptr.ssl);
1327+
return 0;
13291328
#endif
1330-
1331-
if (bio->type == WOLFSSL_BIO_MEMORY) {
1332-
return (size_t)(bio->wrSz - bio->rdIdx);
1333-
}
1334-
1335-
/* type BIO_BIO then check paired buffer */
1336-
if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) {
1337-
WOLFSSL_BIO* pair = bio->pair;
1338-
if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) {
1339-
/* in wrap around state where beginning of buffer is being
1340-
* overwritten */
1341-
return ((size_t)pair->wrSz) - ((size_t)pair->rdIdx) +
1342-
((size_t)pair->wrIdx);
1343-
}
1344-
else {
1345-
/* simple case where has not wrapped around */
1346-
return (size_t)(pair->wrIdx - pair->rdIdx);
1329+
case WOLFSSL_BIO_MEMORY:
1330+
return (size_t)(bio->wrSz - bio->rdIdx);
1331+
case WOLFSSL_BIO_BIO:
1332+
if (bio->pair != NULL) {
1333+
WOLFSSL_BIO* pair = bio->pair;
1334+
if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) {
1335+
/* wrap around state */
1336+
return ((size_t)pair->wrSz) - ((size_t)pair->rdIdx) +
1337+
((size_t)pair->wrIdx);
1338+
}
1339+
else {
1340+
return (size_t)(pair->wrIdx - pair->rdIdx);
1341+
}
1342+
}
1343+
return 0;
1344+
default:
1345+
return 0;
13471346
}
13481347
}
13491348
return 0;
@@ -1827,7 +1826,7 @@ long wolfSSL_BIO_get_fp(WOLFSSL_BIO *bio, XFILE* fp)
18271826
{
18281827
WOLFSSL_ENTER("wolfSSL_BIO_get_fp");
18291828

1830-
if (bio == NULL || fp == XBADFILE) {
1829+
if (bio == NULL || fp == NULL) {
18311830
return WOLFSSL_FAILURE;
18321831
}
18331832

@@ -2830,39 +2829,17 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
28302829
}
28312830

28322831
newLen = XSTRLEN(name);
2832+
if (b->ip != NULL && XSTRLEN(b->ip) != newLen) {
2833+
XFREE(b->ip, b->heap, DYNAMIC_TYPE_OPENSSL);
2834+
b->ip = NULL;
2835+
}
28332836
if (b->ip == NULL) {
2834-
/* +1 for null char */
28352837
b->ip = (char*)XMALLOC(newLen + 1, b->heap, DYNAMIC_TYPE_OPENSSL);
28362838
if (b->ip == NULL) {
28372839
WOLFSSL_MSG("Hostname malloc failed.");
28382840
return WOLFSSL_FAILURE;
28392841
}
28402842
}
2841-
else {
2842-
size_t currLen = XSTRLEN(b->ip);
2843-
#ifdef WOLFSSL_NO_REALLOC
2844-
char* tmp = NULL;
2845-
#endif
2846-
2847-
if (currLen != newLen) {
2848-
#ifdef WOLFSSL_NO_REALLOC
2849-
tmp = b->ip;
2850-
b->ip = (char*)XMALLOC(newLen+1, b->heap, DYNAMIC_TYPE_OPENSSL);
2851-
if (b->ip != NULL && tmp != NULL) {
2852-
XMEMCPY(b->ip, tmp, newLen);
2853-
XFREE(tmp, b->heap, DYNAMIC_TYPE_OPENSSL);
2854-
tmp = NULL;
2855-
}
2856-
#else
2857-
b->ip = (char*)XREALLOC(b->ip, newLen + 1, b->heap,
2858-
DYNAMIC_TYPE_OPENSSL);
2859-
#endif
2860-
if (b->ip == NULL) {
2861-
WOLFSSL_MSG("Hostname realloc failed.");
2862-
return WOLFSSL_FAILURE;
2863-
}
2864-
}
2865-
}
28662843

28672844
XMEMCPY(b->ip, name, newLen);
28682845
b->ip[newLen] = '\0';
@@ -3183,6 +3160,8 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
31833160
*/
31843161
WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* bio)
31853162
{
3163+
WOLFSSL_BIO* next;
3164+
31863165
if (bio == NULL) {
31873166
WOLFSSL_MSG("Bad argument passed in");
31883167
return NULL;
@@ -3196,7 +3175,11 @@ WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO* bio)
31963175
bio->next->prev = bio->prev;
31973176
}
31983177

3199-
return bio->next;
3178+
next = bio->next;
3179+
bio->prev = NULL;
3180+
bio->next = NULL;
3181+
3182+
return next;
32003183
}
32013184

32023185

tests/api/test_ossl_bio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ int test_wolfSSL_BIO_reset(void)
11501150
ExpectIntEQ(BIO_read(bio, buf, 16), 10);
11511151
ExpectIntEQ(XMEMCMP(buf, " your data", 10), 0);
11521152
/* You cannot write to MEM BIO with read-only mode. */
1153-
ExpectIntEQ(BIO_write(bio, "WriteToReadonly", 15), 0);
1153+
ExpectIntEQ(BIO_write(bio, "WriteToReadonly", 15), WOLFSSL_BIO_ERROR);
11541154
ExpectIntEQ(BIO_read(bio, buf, 16), -1);
11551155
XMEMSET(buf, 0, 16);
11561156
ExpectIntEQ(BIO_reset(bio), 1);

0 commit comments

Comments
 (0)