Skip to content

Commit

Permalink
Fix two leaks in BIO_dup_chain()
Browse files Browse the repository at this point in the history
If CRYPTO_dup_ex_data() fails, the new_bio is leaked. If an error occurs
after the first iteration, all members of the new chain except the head
are leaked.

ok jsing
  • Loading branch information
tb committed Aug 7, 2023
1 parent c1cf983 commit 3592d78
Showing 1 changed file with 17 additions and 19 deletions.
36 changes: 17 additions & 19 deletions src/lib/libcrypto/bio/bio_lib.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: bio_lib.c,v 1.47 2023/07/10 02:33:33 tb Exp $ */
/* $OpenBSD: bio_lib.c,v 1.48 2023/08/07 10:58:56 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young ([email protected])
* All rights reserved.
*
Expand Down Expand Up @@ -816,7 +816,8 @@ LCRYPTO_ALIAS(BIO_free_all);
BIO *
BIO_dup_chain(BIO *in)
{
BIO *ret = NULL, *eoc = NULL, *bio, *new_bio;
BIO *new_chain = NULL, *new_bio = NULL, *tail = NULL;
BIO *bio;

for (bio = in; bio != NULL; bio = bio->next_bio) {
if ((new_bio = BIO_new(bio->method)) == NULL)
Expand All @@ -827,33 +828,30 @@ BIO_dup_chain(BIO *in)
new_bio->init = bio->init;
new_bio->shutdown = bio->shutdown;
new_bio->flags = bio->flags;

/* This will let SSL_s_sock() work with stdin/stdout */
new_bio->num = bio->num;

if (!BIO_dup_state(bio, (char *)new_bio)) {
BIO_free(new_bio);
if (!BIO_dup_state(bio, new_bio))
goto err;
}

/* copy app data */
if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO,
&new_bio->ex_data, &bio->ex_data))
goto err;

if (ret == NULL) {
eoc = new_bio;
ret = eoc;
} else {
BIO_push(eoc, new_bio);
eoc = new_bio;
}
if (BIO_push(tail, new_bio) == NULL)
goto err;

tail = new_bio;
if (new_chain == NULL)
new_chain = new_bio;
}
return (ret);
err:
BIO_free(ret);
return (NULL);

return new_chain;

err:
BIO_free(new_bio);
BIO_free_all(new_chain);

return NULL;
}
LCRYPTO_ALIAS(BIO_dup_chain);

Expand Down

0 comments on commit 3592d78

Please sign in to comment.