>Synopsis:      X509_STORE_free does not obey reference count
>Category:      library
>Description:
        The X509_STORE_free routine does not decrement and check the
        reference count, even though it's initialized properly in
        X509_STORE_new. This has been fixed in OpenSSL 1.0.2, but not yet in
        libressl.

        Ruby's OpenSSL bindings, as well as my own Lua OpenSSL bindings
        (luaossl), partially workaround this bug by installing an external
        application data hook on the SSL_CTX object and nulling the
        cert_store member. This depends on the coincidental ordering of
        freeing ex_data before the X509_STORE object in SSL_CTX_free, and
        doesn't work if other application code uses SSL_CTX_set_cert_store.
>How-To-Repeat:
        OpenSSL and libressl also lack SSL_CTX_set1_cert_store. Instead,
        language bindings explicitly increment the reference count on an
        X509_STORE object when using SSL_CTX_set_cert_store. But as
        described above this isn't enough.

        #include <assert.h>
        #include <openssl/x509.h>
        #include <openssl/ssl.h>

        int main(void) {
                X509_STORE *store;
                SSL_CTX *ctx;

                SSL_library_init();

                store = X509_STORE_new();
                ctx = SSL_CTX_new(TLSv1_method());

                SSL_CTX_set_cert_store(ctx, store);
                assert(store->references == 1);
                CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);

                SSL_CTX_free(ctx);
                X509_STORE_free(store); /* <-- double-free */

                return 0;
        }
>Fix:
        Add the following near the top of X509_STORE_free, defined
        in x509_lu.c:

        i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE);

        if (i > 0)
                return;

Reply via email to