On 30/01/17 10:13, Mischa Salle wrote:
> Hi all,
> 
> I noticed a doublefree when calling SSL_set_bio(ssl, bio, bio) followed
> by either SSL_set_bio(ssl, NULL, NULL) or SSL_set_io_SSL_free(ssl).
> Valgrind shows the double free, and I see the assert in
> https://github.com/openssl/openssl/blob/master/crypto/bio/bio_lib.c#L122
> fail. This is all due to the same bio being using for read and write.
> I found that in
> https://github.com/openssl/openssl/blob/master/ssl/bio_ssl.c#L331-L332
> the ref-count is manually adjusted, which indeed also fixes my
> doublefree. However, it seems that in a number of other places where
> SSL_set_bio is called with equal rbio and wbio, this is not the case,
> e.g. in apps/s_server.c (L2157, L2735, L3099) and also in
> https://github.com/openssl/openssl/blob/master/ssl/ssl_lib.c#L1161 itself.
> So the question is, when exactly is it necessary to manually adjust the
> ref count, and couldn't this be done automatically in e.g. the
> SSL_set_bio(ssl, bio, bio) ?


SSL_set_bio() is a curious beast and its memory management semantics are
confusing at best. It's behaviour is retained for historical
consistency. The man page now recommends using SSL_set0_rbio() and
SSL_set0_wbio() in preference because of this. However they only exist
in OpenSSL 1.1.0, so if you need to support 1.0.2 then you are stuck
with it.

The memory management rules are documented on the latest version of the
man page, here:

https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_bio.html


SSL_set_bio() passes ownership of the BIO's to the SSL object. They will
get freed when the SSL object gets freed. Once called you should not
then attempt to free them yourself directly, *unless* you have called
BIO_up_ref().

If the rbio and wbio are different then ownership of both objects is
transferred. If the rbio and the wbio are the same object then ownership
is still transferred - but only one reference is consumed, i.e. you are
not transferring ownership of two references even though you have passed
the BIO to the function "twice" (once for the rbio and once for the wbio).

You references a few places in the code:

https://github.com/openssl/openssl/blob/master/ssl/bio_ssl.c#L331-L332

Here we up ref before passing the same bio in both arguments in a call
to SSL_set_bio(). This is processing a BIO_ctrl call with a
BIO_CTRL_PUSH operation. This operation is typically only used
internally. It's semantics does *not* transfer ownership of its argument
to the BIO_CTRL_PUSH code. However, we want to call SSL_set_bio() with
it which will transfer an ownership that we don't currently hold!
Therefore we need to up ref first.


You also mention apps/s_server.c (L2157, L2735, L3099.

In this case we just created the BIO and therefore own a reference to
it. We then transfer that ownership to the SSL object in the
SSL_set_bio() call. You will notice that after that call we never then
attempt to free the BIO again...we no longer own it, so we don't need
to. It will get freed when we free the SSL object.


Finally you mention this code:
https://github.com/openssl/openssl/blob/master/ssl/ssl_lib.c#L1161

Again, in this case, we just created the BIO object and therefore own a
reference to it. We then transfer that ownership to the SSL object in
the SSL_set_bio() call. You will note that, again, we never explicitly
free the BIO object we just created. It will get freed when we free the
SSL object.

I hope that helps,

Matt
-- 
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

Reply via email to