diff options
author | schwarze <> | 2021-11-27 13:10:33 +0000 |
---|---|---|
committer | schwarze <> | 2021-11-27 13:10:33 +0000 |
commit | cbb1afa6429df7a3087dd6a337b730e5304ed3bb (patch) | |
tree | f06a4ef6cb4d8f2ab19d76c189b8cd4bb2d5fa22 | |
parent | 6a2276e5a7885ebbd30cb16c476c7652740dc5ef (diff) | |
download | openbsd-cbb1afa6429df7a3087dd6a337b730e5304ed3bb.tar.gz openbsd-cbb1afa6429df7a3087dd6a337b730e5304ed3bb.tar.bz2 openbsd-cbb1afa6429df7a3087dd6a337b730e5304ed3bb.zip |
Fix incomplete initialization bug: BIO_new(BIO_f_asn1()) neglected
initializing five of the fields in BIO_ASN1_BUF_CTX (prefix,
prefix_free, suffix, suffix_free, ex_arg), inviting a segfault in
a subsequent call from the application program to BIO_write(3)
because subroutines of that function assume that the function
pointers are either NULL or valid.
Fix this by using the less error-prone calloc(3) idiom.
While here, inline asn1_bio_init() at the only call site
in asn1_bio_new() to simplify the code and make it easier to read.
Bug found and initial patch by me,
this version (with inlining) by and OK tb@.
-rw-r--r-- | src/lib/libcrypto/asn1/bio_asn1.c | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/src/lib/libcrypto/asn1/bio_asn1.c b/src/lib/libcrypto/asn1/bio_asn1.c index 93bcb33888..9a14d2bb84 100644 --- a/src/lib/libcrypto/asn1/bio_asn1.c +++ b/src/lib/libcrypto/asn1/bio_asn1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: bio_asn1.c,v 1.13 2018/05/01 13:29:09 tb Exp $ */ | 1 | /* $OpenBSD: bio_asn1.c,v 1.14 2021/11/27 13:10:33 schwarze 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 | */ |
@@ -118,7 +118,6 @@ static int asn1_bio_new(BIO *h); | |||
118 | static int asn1_bio_free(BIO *data); | 118 | static int asn1_bio_free(BIO *data); |
119 | static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); | 119 | static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); |
120 | 120 | ||
121 | static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size); | ||
122 | static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, | 121 | static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, |
123 | asn1_ps_func *cleanup, asn1_bio_state_t next); | 122 | asn1_ps_func *cleanup, asn1_bio_state_t next); |
124 | static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, | 123 | static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, |
@@ -148,35 +147,23 @@ static int | |||
148 | asn1_bio_new(BIO *b) | 147 | asn1_bio_new(BIO *b) |
149 | { | 148 | { |
150 | BIO_ASN1_BUF_CTX *ctx; | 149 | BIO_ASN1_BUF_CTX *ctx; |
151 | ctx = malloc(sizeof(BIO_ASN1_BUF_CTX)); | 150 | |
152 | if (!ctx) | 151 | if ((ctx = calloc(1, sizeof(*ctx))) == NULL) |
153 | return 0; | 152 | return 0; |
154 | if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) { | 153 | |
154 | if ((ctx->buf = malloc(DEFAULT_ASN1_BUF_SIZE)) == NULL) { | ||
155 | free(ctx); | 155 | free(ctx); |
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | ctx->bufsize = DEFAULT_ASN1_BUF_SIZE; | ||
159 | ctx->asn1_class = V_ASN1_UNIVERSAL; | ||
160 | ctx->asn1_tag = V_ASN1_OCTET_STRING; | ||
161 | ctx->state = ASN1_STATE_START; | ||
162 | |||
158 | b->init = 1; | 163 | b->init = 1; |
159 | b->ptr = (char *)ctx; | 164 | b->ptr = (char *)ctx; |
160 | b->flags = 0; | 165 | b->flags = 0; |
161 | return 1; | ||
162 | } | ||
163 | 166 | ||
164 | static int | ||
165 | asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) | ||
166 | { | ||
167 | ctx->buf = malloc(size); | ||
168 | if (!ctx->buf) | ||
169 | return 0; | ||
170 | ctx->bufsize = size; | ||
171 | ctx->bufpos = 0; | ||
172 | ctx->buflen = 0; | ||
173 | ctx->copylen = 0; | ||
174 | ctx->asn1_class = V_ASN1_UNIVERSAL; | ||
175 | ctx->asn1_tag = V_ASN1_OCTET_STRING; | ||
176 | ctx->ex_buf = NULL; | ||
177 | ctx->ex_pos = 0; | ||
178 | ctx->ex_len = 0; | ||
179 | ctx->state = ASN1_STATE_START; | ||
180 | return 1; | 167 | return 1; |
181 | } | 168 | } |
182 | 169 | ||