简体   繁体   中英

Valgrind shows memory leak in ssl after closing the connection

I have one client which will continuously talk to the server. When I run it through valgrind and got the following report:

Below are the leaks which is still there in my ssl code.

==6850== 600 bytes in 1 blocks are still reachable in loss record 116 of 118
==6850==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6850==    by 0x50F4D32: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x517DA85: ERR_get_state (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x517DB5D: ERR_put_error (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51AA9DC: PEM_read_bio (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51A8D39: PEM_X509_INFO_read_bio (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51B7A7D: X509_load_cert_crl_file (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51B7BAC: by_file_ctrl (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x51AEF2E: X509_STORE_load_locations (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x40AD4A: CloudConnection::establishConnection(int) (CloudConnection.cpp:1046)
==6850==    by 0x409F1C: connectWithCloud() main.cpp:423)
==6850==    by 0x409ADB: main (main.cpp:391)

==6850== 176 bytes in 1 blocks are still reachable in loss record 111 of 118
==6850==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6850==    by 0x50F4D32: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x517A8EF: lh_new (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x50F5FF4: ex_data_check (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x50F6084: def_get_class (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x50F66C8: int_free_ex_data (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6850==    by 0x4E70D3C: SSL_free (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==6850==    by 0x40A6AE: CloudConnection::closeConnection() (CloudConnection.cpp:1554)
==6850==    by 0x40D9BB: CloudConnection::receiveData() (CloudConnection.cpp:696)
==6850==    by 0x40DB88: CloudConnection::receiveDataHelper(void*) (CloudConnection.cpp:276)
==6850==    by 0x5477181: start_thread (pthread_create.c:312)
==6850==    by 0x651FFBC: clone (clone.S:111)

Here is my code snippet to close ssl connection.

    if (ssl) {
        int count = 0;
        while (err != 1) {
            err = SSL_shutdown(ssl);
            if (err != 1) {
                LOGINFO("SSL_shutdown failed");
                count++;
            }
            if (count == 3) {
                LOGINFO("SSL_shutdown failed - final");
                break;
            }
            sleep(1);
        }
    }
    CRYPTO_cleanup_all_ex_data();

    ERR_free_strings();
    ERR_remove_state(0);
    EVP_cleanup();

    if (lockarray) {
        kill_locks();
        lockarray = NULL;
    }
    /* Terminate communication on a socket */
    if (sock) {
        err = close(sock);
        if (-1 == err) {
            LOG(Logger::ERROR, "Could not close the socket. "
                    "Returning error, but also making the structure NULL.");
            //ssl = NULL;
            //return -1;
        }
    }

    /* Free the SSL structure */
    if (ssl) {
        SSL_free(ssl);
        ssl = NULL;
    }

    /* Free the SSL_CTX structure */
    if (ctx) {
        SSL_CTX_free(ctx);
        ctx = NULL;
    }

Please note that logger is my custom library

After searching a lot in google this solved my problem

CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
ERR_remove_state(0);
EVP_cleanup();

I see in your code that you have a test for locks:

if (lockarray) ...

And one of the memory leaks clearly comes from a thread (we see that it starts with clone() instead of main() ).

This means you have multiple threads and that can cause leaks too.

Before you quit a thread, you want to call this function:

ERR_remove_thread_state(0);

And before exiting your application, you want to call this function to remove the locking callbacks:

CRYPTO_set_locking_callback(nullptr);

That should do it in your case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM