public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Tomas Mraz <tmraz@fedoraproject.org>
To: git-commits@fedoraproject.org
Subject: [rpms/openssl] rebase_40beta: fix for BIO_get_mem_ptr() regression in 1.1.1b (#1691853)
Date: Tue, 09 Jun 2026 12:44:27 GMT [thread overview]
Message-ID: <178100906711.1.15846498980248219759.rpms-openssl-1aaf4073e34a@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/openssl
Branch : rebase_40beta
Commit : 1aaf4073e34a620385e878140b048aadd09c6a85
Author : Tomas Mraz <tmraz@fedoraproject.org>
Date : 2019-04-16T12:13:00+02:00
Stats : +331/-1 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/openssl/c/1aaf4073e34a620385e878140b048aadd09c6a85?branch=rebase_40beta
Log:
fix for BIO_get_mem_ptr() regression in 1.1.1b (#1691853)
---
diff --git a/openssl-1.1.1-bio-mem-ptr.patch b/openssl-1.1.1-bio-mem-ptr.patch
new file mode 100644
index 0000000..4e131fc
--- /dev/null
+++ b/openssl-1.1.1-bio-mem-ptr.patch
@@ -0,0 +1,325 @@
+diff --git a/crypto/bio/bss_mem.c b/crypto/bio/bss_mem.c
+index 89c54b2d53..a7f2bfbae0 100644
+--- a/crypto/bio/bss_mem.c
++++ b/crypto/bio/bss_mem.c
+@@ -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,11 +197,14 @@ 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)) {
+ memcpy(out, bm->data, ret);
+ bm->length -= ret;
++ bm->max -= ret;
+ bm->data += ret;
+ } else if (bm->length == 0) {
+ ret = b->num;
+@@ -241,29 +249,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 +293,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 +310,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 +333,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)
+diff --git a/doc/man3/BIO_s_mem.pod b/doc/man3/BIO_s_mem.pod
+index bd0824a080..6d9e747b25 100644
+--- a/doc/man3/BIO_s_mem.pod
++++ b/doc/man3/BIO_s_mem.pod
+@@ -88,6 +88,22 @@ a buffering BIO to the chain will speed up the process.
+ Calling BIO_set_mem_buf() on a BIO created with BIO_new_secmem() will
+ give undefined results, including perhaps a program crash.
+
++Switching the memory BIO from read write to read only is not supported and
++can give undefined results including a program crash. There are two notable
++exceptions to the rule. The first one is to assign a static memory buffer
++immediately after BIO creation and set the BIO as read only.
++
++The other supported sequence is to start with read write BIO then temporarily
++switch it to read only and call BIO_reset() on the read only BIO immediately
++before switching it back to read write. Before the BIO is freed it must be
++switched back to the read write mode.
++
++Calling BIO_get_mem_ptr() on read only BIO will return a BUF_MEM that
++contains only the remaining data to be read. If the close status of the
++BIO is set to BIO_NOCLOSE, before freeing the BUF_MEM the data pointer
++in it must be set to NULL as the data pointer does not point to an
++allocated memory.
++
+ =head1 BUGS
+
+ There should be an option to set the maximum size of a memory BIO.
+diff --git a/test/bio_memleak_test.c b/test/bio_memleak_test.c
+index 36680e30a8..fab5ce73cf 100644
+--- a/test/bio_memleak_test.c
++++ b/test/bio_memleak_test.c
+@@ -18,28 +18,170 @@ static int test_bio_memleak(void)
+ int ok = 0;
+ BIO *bio;
+ BUF_MEM bufmem;
+- const char *str = "BIO test\n";
++ static const char str[] = "BIO test\n";
+ char buf[100];
+
+ bio = BIO_new(BIO_s_mem());
+- if (bio == NULL)
++ if (!TEST_ptr(bio))
+ goto finish;
+- bufmem.length = strlen(str) + 1;
++ bufmem.length = sizeof(str);
+ bufmem.data = (char *) str;
+ bufmem.max = bufmem.length;
+ BIO_set_mem_buf(bio, &bufmem, BIO_NOCLOSE);
+ BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
++ if (!TEST_int_eq(BIO_read(bio, buf, sizeof(buf)), sizeof(str)))
++ goto finish;
++ if (!TEST_mem_eq(buf, sizeof(str), str, sizeof(str)))
++ goto finish;
++ ok = 1;
+
+- if (BIO_read(bio, buf, sizeof(buf)) <= 0)
+- goto finish;
++finish:
++ BIO_free(bio);
++ return ok;
++}
+
+- ok = strcmp(buf, str) == 0;
++static int test_bio_get_mem(void)
++{
++ int ok = 0;
++ BIO *bio = NULL;
++ BUF_MEM *bufmem = NULL;
++
++ bio = BIO_new(BIO_s_mem());
++ if (!TEST_ptr(bio))
++ goto finish;
++ if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
++ goto finish;
++ BIO_get_mem_ptr(bio, &bufmem);
++ if (!TEST_ptr(bufmem))
++ goto finish;
++ if (!TEST_int_gt(BIO_set_close(bio, BIO_NOCLOSE), 0))
++ goto finish;
++ BIO_free(bio);
++ bio = NULL;
++ if (!TEST_mem_eq(bufmem->data, bufmem->length, "Hello World\n", 12))
++ goto finish;
++ ok = 1;
+
+ finish:
+ BIO_free(bio);
++ BUF_MEM_free(bufmem);
+ return ok;
+ }
+
++static int test_bio_new_mem_buf(void)
++{
++ int ok = 0;
++ BIO *bio;
++ BUF_MEM *bufmem;
++ char data[16];
++
++ bio = BIO_new_mem_buf("Hello World\n", 12);
++ if (!TEST_ptr(bio))
++ goto finish;
++ if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
++ goto finish;
++ if (!TEST_mem_eq(data, 5, "Hello", 5))
++ goto finish;
++ if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
++ goto finish;
++ if (!TEST_int_lt(BIO_write(bio, "test", 4), 0))
++ goto finish;
++ if (!TEST_int_eq(BIO_read(bio, data, 16), 7))
++ goto finish;
++ if (!TEST_mem_eq(data, 7, " World\n", 7))
++ goto finish;
++ if (!TEST_int_gt(BIO_reset(bio), 0))
++ goto finish;
++ if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
++ goto finish;
++ if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
++ goto finish;
++ ok = 1;
++
++finish:
++ BIO_free(bio);
++ return ok;
++}
++
++static int test_bio_rdonly_mem_buf(void)
++{
++ int ok = 0;
++ BIO *bio, *bio2 = NULL;
++ BUF_MEM *bufmem;
++ char data[16];
++
++ bio = BIO_new_mem_buf("Hello World\n", 12);
++ if (!TEST_ptr(bio))
++ goto finish;
++ if (!TEST_int_eq(BIO_read(bio, data, 5), 5))
++ goto finish;
++ if (!TEST_mem_eq(data, 5, "Hello", 5))
++ goto finish;
++ if (!TEST_int_gt(BIO_get_mem_ptr(bio, &bufmem), 0))
++ goto finish;
++ (void)BIO_set_close(bio, BIO_NOCLOSE);
++
++ bio2 = BIO_new(BIO_s_mem());
++ if (!TEST_ptr(bio2))
++ goto finish;
++ BIO_set_mem_buf(bio2, bufmem, BIO_CLOSE);
++ BIO_set_flags(bio2, BIO_FLAGS_MEM_RDONLY);
++
++ if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
++ goto finish;
++ if (!TEST_mem_eq(data, 7, " World\n", 7))
++ goto finish;
++ if (!TEST_int_gt(BIO_reset(bio2), 0))
++ goto finish;
++ if (!TEST_int_eq(BIO_read(bio2, data, 16), 7))
++ goto finish;
++ if (!TEST_mem_eq(data, 7, " World\n", 7))
++ goto finish;
++ ok = 1;
++
++finish:
++ BIO_free(bio);
++ BIO_free(bio2);
++ return ok;
++}
++
++static int test_bio_rdwr_rdonly(void)
++{
++ int ok = 0;
++ BIO *bio = NULL;
++ char data[16];
++
++ bio = BIO_new(BIO_s_mem());
++ if (!TEST_ptr(bio))
++ goto finish;
++ if (!TEST_int_eq(BIO_puts(bio, "Hello World\n"), 12))
++ goto finish;
++
++ BIO_set_flags(bio, BIO_FLAGS_MEM_RDONLY);
++ if (!TEST_int_eq(BIO_read(bio, data, 16), 12))
++ goto finish;
++ if (!TEST_mem_eq(data, 12, "Hello World\n", 12))
++ goto finish;
++ if (!TEST_int_gt(BIO_reset(bio), 0))
++ goto finish;
++
++ BIO_clear_flags(bio, BIO_FLAGS_MEM_RDONLY);
++ if (!TEST_int_eq(BIO_puts(bio, "Hi!\n"), 4))
++ goto finish;
++ if (!TEST_int_eq(BIO_read(bio, data, 16), 16))
++ goto finish;
++
++ if (!TEST_mem_eq(data, 16, "Hello World\nHi!\n", 16))
++ goto finish;
++
++ ok = 1;
++
++finish:
++ BIO_free(bio);
++ return ok;
++}
++
++
+ int global_init(void)
+ {
+ CRYPTO_set_mem_debug(1);
+@@ -50,5 +192,9 @@ int global_init(void)
+ int setup_tests(void)
+ {
+ ADD_TEST(test_bio_memleak);
++ ADD_TEST(test_bio_get_mem);
++ ADD_TEST(test_bio_new_mem_buf);
++ ADD_TEST(test_bio_rdonly_mem_buf);
++ ADD_TEST(test_bio_rdwr_rdonly);
+ return 1;
+ }
diff --git a/openssl.spec b/openssl.spec
index c2cfb5d..ff4fa05 100644
--- a/openssl.spec
+++ b/openssl.spec
@@ -22,7 +22,7 @@
Summary: Utilities from the general purpose cryptography library with TLS implementation
Name: openssl
Version: 1.1.1b
-Release: 4%{?dist}
+Release: 5%{?dist}
Epoch: 1
# We have to remove certain patented algorithms from the openssl source
# tarball with the hobble-openssl script which is included below.
@@ -62,6 +62,7 @@ Patch48: openssl-1.1.1-fips-post-rand.patch
Patch49: openssl-1.1.1-evp-kdf.patch
Patch50: openssl-1.1.1-ssh-kdf.patch
# Backported fixes including security fixes
+Patch51: openssl-1.1.1-bio-mem-ptr.patch
License: OpenSSL
URL: http://www.openssl.org/
@@ -158,6 +159,7 @@ cp %{SOURCE13} test/
%patch48 -p1 -b .fips-post-rand
%patch49 -p1 -b .evp-kdf
%patch50 -p1 -b .ssh-kdf
+%patch51 -p1 -b .bio-mem-ptr
%build
@@ -444,6 +446,9 @@ export LD_LIBRARY_PATH
%ldconfig_scriptlets libs
%changelog
+* Tue Apr 16 2019 Tomáš Mráz <tmraz@redhat.com> 1.1.1b-5
+- fix for BIO_get_mem_ptr() regression in 1.1.1b (#1691853)
+
* Wed Mar 27 2019 Tomáš Mráz <tmraz@redhat.com> 1.1.1b-4
- drop unused BuildRequires and Requires in the -devel subpackage
reply other threads:[~2026-06-09 12:44 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178100906711.1.15846498980248219759.rpms-openssl-1aaf4073e34a@fedoraproject.org \
--to=tmraz@fedoraproject.org \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox