summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorschwarze <>2022-12-06 17:59:21 +0000
committerschwarze <>2022-12-06 17:59:21 +0000
commit63e1e004d5a60eea51f7c1fcc42d54aca4f605b9 (patch)
tree72250057930a6e3053a58f75395ccc2a7e41c53c /src/lib
parent73e2daf0f78d5a05d5bb4c92a2a82363f1e98378 (diff)
downloadopenbsd-63e1e004d5a60eea51f7c1fcc42d54aca4f605b9.tar.gz
openbsd-63e1e004d5a60eea51f7c1fcc42d54aca4f605b9.tar.bz2
openbsd-63e1e004d5a60eea51f7c1fcc42d54aca4f605b9.zip
Make sure BIO_push(3) always preserves all invariants of the prev_bio
and next_bio fields of all BIO objects in all affected chains, no matter what the arguments are. In particular, if the second argument (the one to be appended) is not at the beginning of its chain, properly detach the beginning of its chain before appending. We have weak indications that this bug might affect real-world code. For example, in FreeRDP, file libfreerdp/crypto/tls.c, function bio_rdp_tls_ctrl(), case BIO_C_SET_SSL, BIO_push(3) is definitely called with a second argument that is *not* at the beginning of its chain. Admittedly, that code is hard to fathom, but it does appear to result in a bogus prev_bio pointer without this patch. The practical impact of this bug in this and other software remains unknown; the consequences might possibly escalate up to use-after-free issues if BIO_pop(3) is afterwards called on corrupted BIO objects. OK tb@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bio/bio_lib.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/lib/libcrypto/bio/bio_lib.c b/src/lib/libcrypto/bio/bio_lib.c
index 2ffa0a765c..4c3d7ed5f5 100644
--- a/src/lib/libcrypto/bio/bio_lib.c
+++ b/src/lib/libcrypto/bio/bio_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: bio_lib.c,v 1.40 2022/12/06 16:10:55 schwarze Exp $ */ 1/* $OpenBSD: bio_lib.c,v 1.41 2022/12/06 17:59:21 schwarze Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -625,7 +625,11 @@ BIO_ctrl_wpending(BIO *bio)
625} 625}
626 626
627 627
628/* put the 'bio' on the end of b's list of operators */ 628/*
629 * Append "bio" to the end of the chain containing "b":
630 * Two chains "b -> lb" and "oldhead -> bio"
631 * become two chains "b -> lb -> bio" and "oldhead".
632 */
629BIO * 633BIO *
630BIO_push(BIO *b, BIO *bio) 634BIO_push(BIO *b, BIO *bio)
631{ 635{
@@ -637,8 +641,11 @@ BIO_push(BIO *b, BIO *bio)
637 while (lb->next_bio != NULL) 641 while (lb->next_bio != NULL)
638 lb = lb->next_bio; 642 lb = lb->next_bio;
639 lb->next_bio = bio; 643 lb->next_bio = bio;
640 if (bio != NULL) 644 if (bio != NULL) {
645 if (bio->prev_bio != NULL)
646 bio->prev_bio->next_bio = NULL;
641 bio->prev_bio = lb; 647 bio->prev_bio = lb;
648 }
642 /* called to do internal processing */ 649 /* called to do internal processing */
643 BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); 650 BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb);
644 return (b); 651 return (b);