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