[openssl-dev] [openssl.org #4129] [PATCH] Can BIO_new_mem_buf take a const void* instead of a void* ?

Daniel Kahn Gillmor via RT rt at openssl.org
Sun Nov 8 11:37:57 UTC 2015


The documentation asserts that BIO_new_mem_buf is forced to a
read-only state ("The BIO is set to a read only state and as a result
cannot be written to"), but it requires passing in a void*.  This
makes it hard to use from a function that has a const buffer.

Presumably most code that tries to use a const buffer with
BIO_new_mem_buf either casts away the constness (bad practice, since
OpenSSL's API itself isn't guaranteeing it will actually remain const)
or copies the memory to a non-const buffer before passing it in (an
unnecessary memcpy).

The changeset proposed here makes OpenSSL's API offer the guarantee
that its documentation appears to make by casting away the constness
internally to BIO_new_mem_buf, but i haven't analyzed all the possible
ways that an arbitrary BIO can be (mis)used internally code to be sure
this is safe.

If this is not a safe thing to do, we should instead modify the
documentation to avoid the implication that such a buffer will remain
read-only.
---
 crypto/bio/bss_mem.c     | 6 ++++--
 doc/crypto/BIO_s_mem.pod | 2 +-
 include/openssl/bio.h    | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
index 485a8bf..e50db43 100644
--- a/crypto/bio/bss_mem.c
+++ b/crypto/bio/bss_mem.c
@@ -109,7 +109,7 @@ BIO_METHOD *BIO_s_secmem(void)
     return(&secmem_method);
 }
 
-BIO *BIO_new_mem_buf(void *buf, int len)
+BIO *BIO_new_mem_buf(const void *buf, int len)
 {
     BIO *ret;
     BUF_MEM *b;
@@ -123,7 +123,9 @@ BIO *BIO_new_mem_buf(void *buf, int len)
     if ((ret = BIO_new(BIO_s_mem())) == NULL)
         return NULL;
     b = (BUF_MEM *)ret->ptr;
-    b->data = buf;
+    b->data = (void*) buf; /* is it safe to cast away constness here
+                              and rely on the MEM_RDONLY flags set
+                              below? */
     b->length = sz;
     b->max = sz;
     ret->flags |= BIO_FLAGS_MEM_RDONLY;
diff --git a/doc/crypto/BIO_s_mem.pod b/doc/crypto/BIO_s_mem.pod
index 1aa7e6e..1fa62b5 100644
--- a/doc/crypto/BIO_s_mem.pod
+++ b/doc/crypto/BIO_s_mem.pod
@@ -17,7 +17,7 @@ BIO_get_mem_ptr, BIO_new_mem_buf - memory BIO
  BIO_set_mem_buf(BIO *b,BUF_MEM *bm,int c)
  BIO_get_mem_ptr(BIO *b,BUF_MEM **pp)
 
- BIO *BIO_new_mem_buf(void *buf, int len);
+ BIO *BIO_new_mem_buf(const void *buf, int len);
 
 =head1 DESCRIPTION
 
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index f0fbc5b..c2be049 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -672,7 +672,7 @@ long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi,
 
 BIO_METHOD *BIO_s_mem(void);
 BIO_METHOD *BIO_s_secmem(void);
-BIO *BIO_new_mem_buf(void *buf, int len);
+BIO *BIO_new_mem_buf(const void *buf, int len);
 BIO_METHOD *BIO_s_socket(void);
 BIO_METHOD *BIO_s_connect(void);
 BIO_METHOD *BIO_s_accept(void);
-- 
2.6.2

_______________________________________________
openssl-bugs-mod mailing list
openssl-bugs-mod at openssl.org
https://mta.openssl.org/mailman/listinfo/openssl-bugs-mod



More information about the openssl-dev mailing list