Make sure BIO_push(3) always preserves all invariants of the prev_bio
authorschwarze <schwarze@openbsd.org>
Tue, 6 Dec 2022 17:59:21 +0000 (17:59 +0000)
committerschwarze <schwarze@openbsd.org>
Tue, 6 Dec 2022 17:59:21 +0000 (17:59 +0000)
commit46665642565a159e2ac7f0f7095bc41fe08d50ef
tree6c20c94de9a2505448e953b55c51315f1d8fcd65
parent0584fd6289e1e8e7fb91651556141fbc5687b992
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@
lib/libcrypto/bio/bio_lib.c