BIO_flush Segmentation Fault Issue
Jay Foster
jayf0ster at roadrunner.com
Mon Oct 3 16:35:47 UTC 2022
Your response makes sense. I am a bit puzzled by the BIO reference
counting. For example
BIO_new() (or BIO_new_socket() which calls BIO_new()) produces a
BIO with a reference count of 1.
BIO_free() drops 1 reference and if the reference count is 0, frees
the BIO.
BIO_push() connects the BIO to the BIO chain. No references are
directly changed. However, the BIO_CTRL_PUSH command is sent to the
BIO. For the SSL BIO, this results in a call to SSL_set_bio() and
adding 1 to the next_bio reference (socket BIO).
BIO_pop() calls BIO_CTRL_POP and disconnects the BIO from the BIO
chain. For the SSL BIO, the BIO_CTRL_POP subtracts one from the
next_bio reference (undoing BIO_push()).
The problem case is calling BIO_free_all() on the BIO chain.
BIO_free_all() does not use BIO_pop(). It simply detaches each BIO from
the chain, and calls BIO_free() for it. If the next_bio reference count
is > 1 (which it will be for the SSL BIO next_bio), it stops unlinking
and freeing BIOs. This seems asymmetrical with respect to the BIO
reference counting, and leaks the next_bio (socket BIO in this case).
What am I missing here?
Jay
On 9/29/2022 11:50 PM, Tomas Mraz wrote:
> The SSL BIO should have the rbio from the SSL object as the next BIO.
> If you create the SSL BIO and then BIO_push() the TCP socket BIO into
> the SSL BIO, it will work correctly.
>
> Otherwise, you can just fix the next BIO of the SSL BIO by using
>
> BIO_up_ref(socketbio);
> BIO_set_next(sslbio, socketbio);
>
> The SSL BIO should always have a next BIO if properly initialized.
>
> Tomas Mraz, OpenSSL
>
> On Thu, 2022-09-29 at 13:02 -0700, Jay Foster wrote:
>> I have an application that constructs a chain of BIOs. Sometimes
>> this
>> chain also includes an SSL BIO. Years ago, I ran into a problem that
>> caused BIO_flush() to segfault on the SSL BIO. This turned out to
>> happen because the SSL BIO is added using SSL_set_bio() instead of
>> BIO_push(). SSL_set_bio() results in the SSL BIO always having a
>> NULL
>> bio_next value, so BIO_flush then crashes dereferencing this NULL
>> pointer when it calls BIO_copy_next_retry() on the SSL BIO (see
>> BIO_CTRL_FLUSH in ssl/bio_ssl.c).
>>
>> This was reported as ticket 2615 years ago.
>>
>> My question is, how could calling BIO_flush() on a BIO chain with an
>> SSL
>> BIO ever work? Is there a way to add the SSL BIO using BIO_push()
>> instead of SSL_set_bio()?
>>
>> Jay
>>
More information about the openssl-users
mailing list