Commit 2b59d1be authored by Matt Caswell's avatar Matt Caswell
Browse files

Implement GET_MODULE_HANDLE_EX_FLAG_PIN for windows



Rather than leaking a reference, just call GetModuleHandleEx and pin the
module on Windows.

Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
parent b6d5ba1a
Loading
Loading
Loading
Loading
+43 −8
Original line number Diff line number Diff line
@@ -82,6 +82,19 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base)
    base_inited = 1;

#ifndef OPENSSL_USE_NODELETE
# ifdef DSO_WIN32
    {
        HMODULE handle = NULL;
        BOOL ret;

        /* We don't use the DSO route for WIN32 because there is a better way */
        ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
                                | GET_MODULE_HANDLE_EX_FLAG_PIN,
                                (void *)&base_inited, &handle);

        return (ret == TRUE) ? 1 : 0;
    }
# else
    /*
     * Deliberately leak a reference to ourselves. This will force the library
     * to remain loaded until the atexit() handler is run a process exit.
@@ -92,6 +105,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_base)
        dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
        DSO_free(dso);
    }
# endif
#endif

    return 1;
@@ -591,24 +605,45 @@ int OPENSSL_atexit(void (*handler)(void))
    OPENSSL_INIT_STOP *newhand;

#ifndef OPENSSL_USE_NODELETE
    /*
     * Deliberately leak a reference to the handler. This will force the
     * library/code containing the handler to remain loaded until we run the
     * atexit handler. If -znodelete has been used then this is unneccessary.
     */
    {
        DSO *dso = NULL;
        union {
            void *sym;
            void (*func)(void);
        } handlersym;

        handlersym.func = handler;
# ifdef DSO_WIN32
        {
            HMODULE handle = NULL;
            BOOL ret;

            /*
             * We don't use the DSO route for WIN32 because there is a better
             * way
             */
            ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
                                    | GET_MODULE_HANDLE_EX_FLAG_PIN,
                                    handlersym.sym, &handle);

            if (!ret)
                return 0;
        }
# else
        /*
         * Deliberately leak a reference to the handler. This will force the
         * library/code containing the handler to remain loaded until we run the
         * atexit handler. If -znodelete has been used then this is
         * unneccessary.
         */
        {
            DSO *dso = NULL;

            dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
            DSO_free(dso);
        }
# endif
    }
#endif

    newhand = OPENSSL_malloc(sizeof(*newhand));
    if (newhand == NULL)