diff options
author | tb <> | 2023-03-11 15:50:13 +0000 |
---|---|---|
committer | tb <> | 2023-03-11 15:50:13 +0000 |
commit | 33942a676ff7c43cef9927e118be7372ff5a588d (patch) | |
tree | caf652d414bbecd178c600173b9af8bb1d4f71fa /src/lib | |
parent | 41f7f65096b8335fece23db719c013b6f69b9f15 (diff) | |
download | openbsd-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.c | 13 |
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 * | |||
101 | BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) | 101 | BIO_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; |