mirror of
https://github.com/openssl/openssl.git
synced 2025-01-11 04:23:34 +08:00
Fix for BIO_get_mem_ptr and related regressions
Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8649)
This commit is contained in:
parent
3e3dcf9ab8
commit
b238fb7970
@ -57,7 +57,12 @@ static const BIO_METHOD secmem_method = {
|
||||
NULL, /* mem_callback_ctrl */
|
||||
};
|
||||
|
||||
/* BIO memory stores buffer and read pointer */
|
||||
/*
|
||||
* BIO memory stores buffer and read pointer
|
||||
* however the roles are different for read only BIOs.
|
||||
* In that case the readp just stores the original state
|
||||
* to be used for reset.
|
||||
*/
|
||||
typedef struct bio_buf_mem_st {
|
||||
struct buf_mem_st *buf; /* allocated buffer */
|
||||
struct buf_mem_st *readp; /* read pointer */
|
||||
@ -192,6 +197,8 @@ static int mem_read(BIO *b, char *out, int outl)
|
||||
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
|
||||
BUF_MEM *bm = bbm->readp;
|
||||
|
||||
if (b->flags & BIO_FLAGS_MEM_RDONLY)
|
||||
bm = bbm->buf;
|
||||
BIO_clear_retry_flags(b);
|
||||
ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
|
||||
if ((out != NULL) && (ret > 0)) {
|
||||
@ -241,29 +248,36 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)b->ptr;
|
||||
BUF_MEM *bm;
|
||||
|
||||
if (b->flags & BIO_FLAGS_MEM_RDONLY)
|
||||
bm = bbm->buf;
|
||||
else
|
||||
bm = bbm->readp;
|
||||
|
||||
switch (cmd) {
|
||||
case BIO_CTRL_RESET:
|
||||
bm = bbm->buf;
|
||||
if (bm->data != NULL) {
|
||||
/* For read only case reset to the start again */
|
||||
if ((b->flags & BIO_FLAGS_MEM_RDONLY) || (b->flags & BIO_FLAGS_NONCLEAR_RST)) {
|
||||
bm->length = bm->max;
|
||||
if (!(b->flags & BIO_FLAGS_MEM_RDONLY)) {
|
||||
if (b->flags & BIO_FLAGS_NONCLEAR_RST) {
|
||||
bm->length = bm->max;
|
||||
} else {
|
||||
memset(bm->data, 0, bm->max);
|
||||
bm->length = 0;
|
||||
}
|
||||
*bbm->readp = *bbm->buf;
|
||||
} else {
|
||||
memset(bm->data, 0, bm->max);
|
||||
bm->length = 0;
|
||||
/* For read only case just reset to the start again */
|
||||
*bbm->buf = *bbm->readp;
|
||||
}
|
||||
*bbm->readp = *bbm->buf;
|
||||
}
|
||||
break;
|
||||
case BIO_CTRL_EOF:
|
||||
bm = bbm->readp;
|
||||
ret = (long)(bm->length == 0);
|
||||
break;
|
||||
case BIO_C_SET_BUF_MEM_EOF_RETURN:
|
||||
b->num = (int)num;
|
||||
break;
|
||||
case BIO_CTRL_INFO:
|
||||
bm = bbm->readp;
|
||||
ret = (long)bm->length;
|
||||
if (ptr != NULL) {
|
||||
pptr = (char **)ptr;
|
||||
@ -278,8 +292,9 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
break;
|
||||
case BIO_C_GET_BUF_MEM_PTR:
|
||||
if (ptr != NULL) {
|
||||
mem_buf_sync(b);
|
||||
bm = bbm->readp;
|
||||
if (!(b->flags & BIO_FLAGS_MEM_RDONLY))
|
||||
mem_buf_sync(b);
|
||||
bm = bbm->buf;
|
||||
pptr = (char **)ptr;
|
||||
*pptr = (char *)bm;
|
||||
}
|
||||
@ -294,7 +309,6 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
|
||||
ret = 0L;
|
||||
break;
|
||||
case BIO_CTRL_PENDING:
|
||||
bm = bbm->readp;
|
||||
ret = (long)bm->length;
|
||||
break;
|
||||
case BIO_CTRL_DUP:
|
||||
@ -318,6 +332,8 @@ static int mem_gets(BIO *bp, char *buf, int size)
|
||||
BIO_BUF_MEM *bbm = (BIO_BUF_MEM *)bp->ptr;
|
||||
BUF_MEM *bm = bbm->readp;
|
||||
|
||||
if (bp->flags & BIO_FLAGS_MEM_RDONLY)
|
||||
bm = bbm->buf;
|
||||
BIO_clear_retry_flags(bp);
|
||||
j = bm->length;
|
||||
if ((size - 1) < j)
|
||||
|
Loading…
Reference in New Issue
Block a user