summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2023-03-11 15:50:13 +0000
committertb <>2023-03-11 15:50:13 +0000
commit33942a676ff7c43cef9927e118be7372ff5a588d (patch)
treecaf652d414bbecd178c600173b9af8bb1d4f71fa /src/lib
parent41f7f65096b8335fece23db719c013b6f69b9f15 (diff)
downloadopenbsd-33942a676ff7c43cef9927e118be7372ff5a588d.tar.gz
openbsd-33942a676ff7c43cef9927e118be7372ff5a588d.tar.bz2
openbsd-33942a676ff7c43cef9927e118be7372ff5a588d.zip
Fix double free after BIO_new_NDEF()
Once the asn_bio is prepended to the out chain, and before the asn1_cb() has done its thing, asn_bio needs to be popped off again on error. Failing to do this can cause write after frees or double frees when the out BIO is used after the function returned. Based on a very complicated diff by Matt Caswell and Viktor Dukhovni. This was part of the fixes in OpenSSL 1.1.1t. ok jsing
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/asn1/bio_ndef.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/lib/libcrypto/asn1/bio_ndef.c b/src/lib/libcrypto/asn1/bio_ndef.c
index 6266d68bbd..7ef08764aa 100644
--- a/src/lib/libcrypto/asn1/bio_ndef.c
+++ b/src/lib/libcrypto/asn1/bio_ndef.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bio_ndef.c,v 1.12 2023/03/06 19:10:14 tb Exp $ */ 1/* $OpenBSD: bio_ndef.c,v 1.13 2023/03/11 15:50:13 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project. 3 * project.
4 */ 4 */
@@ -101,7 +101,7 @@ BIO *
101BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) 101BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
102{ 102{
103 NDEF_SUPPORT *ndef_aux = NULL; 103 NDEF_SUPPORT *ndef_aux = NULL;
104 BIO *asn_bio = NULL; 104 BIO *asn_bio = NULL, *pop_bio = NULL;
105 const ASN1_AUX *aux = it->funcs; 105 const ASN1_AUX *aux = it->funcs;
106 ASN1_STREAM_ARG sarg; 106 ASN1_STREAM_ARG sarg;
107 107
@@ -112,12 +112,12 @@ BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
112 ndef_aux = malloc(sizeof(NDEF_SUPPORT)); 112 ndef_aux = malloc(sizeof(NDEF_SUPPORT));
113 asn_bio = BIO_new(BIO_f_asn1()); 113 asn_bio = BIO_new(BIO_f_asn1());
114 114
115 /* ASN1 bio needs to be next to output BIO */ 115 if (!ndef_aux || !asn_bio)
116 116 goto err;
117 out = BIO_push(asn_bio, out);
118 117
119 if (!ndef_aux || !asn_bio || !out) 118 if ((out = BIO_push(asn_bio, out)) == NULL)
120 goto err; 119 goto err;
120 pop_bio = asn_bio;
121 121
122 BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free); 122 BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
123 BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free); 123 BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
@@ -144,6 +144,7 @@ BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
144 return sarg.ndef_bio; 144 return sarg.ndef_bio;
145 145
146 err: 146 err:
147 BIO_pop(pop_bio);
147 BIO_free(asn_bio); 148 BIO_free(asn_bio);
148 free(ndef_aux); 149 free(ndef_aux);
149 return NULL; 150 return NULL;