diff options
author | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2021-11-27 13:10:34 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@cvs.openbsd.org> | 2021-11-27 13:10:34 +0000 |
commit | ddb0641d47e384e516f09cf825f7201d924a303d (patch) | |
tree | 3d22e34d3d9879f4f0b3df7a2f86f6cd5c931054 | |
parent | 741d2d74df3b48d83e8506ddededbb1ba65b412d (diff) |
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-- | lib/libcrypto/asn1/bio_asn1.c | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/lib/libcrypto/asn1/bio_asn1.c b/lib/libcrypto/asn1/bio_asn1.c index 93bcb33888e..9a14d2bb848 100644 --- a/lib/libcrypto/asn1/bio_asn1.c +++ b/lib/libcrypto/asn1/bio_asn1.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bio_asn1.c,v 1.13 2018/05/01 13:29:09 tb Exp $ */ +/* $OpenBSD: bio_asn1.c,v 1.14 2021/11/27 13:10:33 schwarze Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. */ @@ -118,7 +118,6 @@ static int asn1_bio_new(BIO *h); static int asn1_bio_free(BIO *data); static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size); static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, asn1_ps_func *cleanup, asn1_bio_state_t next); static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, @@ -148,35 +147,23 @@ static int asn1_bio_new(BIO *b) { BIO_ASN1_BUF_CTX *ctx; - ctx = malloc(sizeof(BIO_ASN1_BUF_CTX)); - if (!ctx) + + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) return 0; - if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) { + + if ((ctx->buf = malloc(DEFAULT_ASN1_BUF_SIZE)) == NULL) { free(ctx); return 0; } + ctx->bufsize = DEFAULT_ASN1_BUF_SIZE; + ctx->asn1_class = V_ASN1_UNIVERSAL; + ctx->asn1_tag = V_ASN1_OCTET_STRING; + ctx->state = ASN1_STATE_START; + b->init = 1; b->ptr = (char *)ctx; b->flags = 0; - return 1; -} -static int -asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) -{ - ctx->buf = malloc(size); - if (!ctx->buf) - return 0; - ctx->bufsize = size; - ctx->bufpos = 0; - ctx->buflen = 0; - ctx->copylen = 0; - ctx->asn1_class = V_ASN1_UNIVERSAL; - ctx->asn1_tag = V_ASN1_OCTET_STRING; - ctx->ex_buf = NULL; - ctx->ex_pos = 0; - ctx->ex_len = 0; - ctx->state = ASN1_STATE_START; return 1; } |