summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorCorey Minyard <cminyard@mvista.com>2019-01-21 17:47:02 +1000
committerPauli <paul.dale@oracle.com>2019-01-21 17:50:04 +1000
commit492f70645ca912d82af02b9bc06e9472bf0730a0 (patch)
tree6b58c5526e48edfd33f2c3f53777b9e8c6743824 /crypto
parent781378dacaac8357e8df5b3ab5e811962dd72bc2 (diff)
Fix a memory leak in the mem bio
If you use a BIO and set up your own buffer that is not freed, the memory bio will leak the BIO_BUF_MEM object it allocates. The trouble is that the BIO_BUF_MEM is allocated and kept around, but it is not freed if BIO_NOCLOSE is set. The freeing of BIO_BUF_MEM was fairly confusing, simplify things so mem_buf_free only frees the memory buffer and free the BIO_BUF_MEM in mem_free(), where it should be done. Alse add a test for a leak in the memory bio Setting a memory buffer caused a leak. Signed-off-by: Corey Minyard <minyard@acm.org> Reviewed-by: Bernd Edlinger <bernd.edlinger@hotmail.de> Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8051) (cherry picked from commit c6048af23c577bcf85f15122dd03b65f959c9ecb)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/bio/bss_mem.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index e0a97c3b43..26caa65a64 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -20,7 +20,7 @@ static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int mem_new(BIO *h);
static int secmem_new(BIO *h);
static int mem_free(BIO *data);
-static int mem_buf_free(BIO *data, int free_all);
+static int mem_buf_free(BIO *data);
static int mem_buf_sync(BIO *h);
static const BIO_METHOD mem_method = {
@@ -140,10 +140,20 @@ static int secmem_new(BIO *bi)
static int mem_free(BIO *a)
{
- return mem_buf_free(a, 1);
+ BIO_BUF_MEM *bb;
+
+ if (a == NULL)
+ return 0;
+
+ bb = (BIO_BUF_MEM *)a->ptr;
+ if (!mem_buf_free(a))
+ return 0;
+ OPENSSL_free(bb->readp);
+ OPENSSL_free(bb);
+ return 1;
}
-static int mem_buf_free(BIO *a, int free_all)
+static int mem_buf_free(BIO *a)
{
if (a == NULL)
return 0;
@@ -155,11 +165,6 @@ static int mem_buf_free(BIO *a, int free_all)
if (a->flags & BIO_FLAGS_MEM_RDONLY)
b->data = NULL;
BUF_MEM_free(b);
- if (free_all) {
- OPENSSL_free(bb->readp);
- OPENSSL_free(bb);
- }
- a->ptr = NULL;
}
return 1;
}
@@ -266,11 +271,10 @@ static long mem_ctrl(BIO *b, int cmd, long num, void *ptr)
}
break;
case BIO_C_SET_BUF_MEM:
- mem_buf_free(b, 0);
+ mem_buf_free(b);
b->shutdown = (int)num;
bbm->buf = ptr;
*bbm->readp = *bbm->buf;
- b->ptr = bbm;
break;
case BIO_C_GET_BUF_MEM_PTR:
if (ptr != NULL) {