Fix incomplete initialization bug: BIO_new(BIO_f_asn1()) neglected
authorschwarze <schwarze@openbsd.org>
Sat, 27 Nov 2021 13:10:33 +0000 (13:10 +0000)
committerschwarze <schwarze@openbsd.org>
Sat, 27 Nov 2021 13:10:33 +0000 (13:10 +0000)
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@.

lib/libcrypto/asn1/bio_asn1.c

index 93bcb33..9a14d2b 100644 (file)
@@ -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;
 }