-
Notifications
You must be signed in to change notification settings - Fork 284
Open
Description
This was initial to report a much bigger memory leak report, but after reading #762 #704 #687 and #730 it seems to be a known issue with no real solution.
Using OPENSSL_cleanup() reduced it to the following:
valgrind -s --leak-check=full --show-leak-kinds=all ./example
==13514== Memcheck, a memory error detector
==13514== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13514== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==13514== Command: ./example
==13514==
HTTP/1.0 200 OK
Date: Sun, 05 Oct 2025 18:30:53 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-zJrL9sfw63uri4JWt6c1jA' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
Accept-CH: Sec-CH-Prefers-Color-Scheme
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Set-Cookie: AEC=AaJma5uQAHJb-Pz6FK-qk1FvM64gbU3m2M7paKE-bSyQ2NDO5s11vxjuzT4; expires=Fri, 03-Apr-2026 18:30:53 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
Set-Cookie: NID=525=MVeXBL7kgOHxWV5MUV8N-CmH31FnsVwA6Q7LMZys-_m4jjfWSYptvRXB2YvhVcLQYOtQJTJuoA9nzSn9GpvDpMLvVWO8NnPeXMwlP3Frvnehr4yuFH2thBLBdXA5ejGdTW5Q6YpXnjWbTZaSrF2DzUrSdtsYUE9HXFC_Iwv_x1ce9X8rWHK9kU95mocbTWF5O5kwFuanGfJd_XnvsUvucK8; expires=Mon, 06-Apr-2026 18:30:53 GMT; path=/; domain=.google.com; HttpOnly
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Accept-Ranges: none
Vary: Accept-Encoding
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en"><head><meta content="Search the world's information, including webpages, images, videos and more. Google has many special features to help
==13514==
==13514== HEAP SUMMARY:
==13514== in use at exit: 833 bytes in 5 blocks
==13514== total heap usage: 3,208 allocs, 3,203 frees, 504,542 bytes allocated
==13514==
==13514== 17 bytes in 1 blocks are still reachable in loss record 1 of 5
==13514== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==13514== by 0x48ED157: __vasprintf_internal (vasprintf.c:71)
==13514== by 0x48C59E9: asprintf (asprintf.c:31)
==13514== by 0x4916751: strerror_l (strerror_l.c:45)
==13514== by 0x1BF9A1: err_build_SYS_str_reasons (err.c:499)
==13514== by 0x1BFFDD: ERR_load_ERR_strings_internal (err.c:684)
==13514== by 0x1C0E8C: ERR_load_crypto_strings_internal (err_all.c:104)
==13514== by 0x48FEEE7: __pthread_once_slow (pthread_once.c:116)
==13514== by 0x1C0F28: ERR_load_crypto_strings (err_all.c:149)
==13514== by 0x18F438: OPENSSL_init_crypto_internal (crypto_init.c:53)
==13514== by 0x48FEEE7: __pthread_once_slow (pthread_once.c:116)
==13514== by 0x18F4C3: OPENSSL_init_crypto (crypto_init.c:67)
==13514==
==13514== 24 bytes in 1 blocks are still reachable in loss record 2 of 5
==13514== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==13514== by 0x1D247C: lh_insert (lhash.c:273)
==13514== by 0x1BF770: err_thread_set_item (err.c:422)
==13514== by 0x1BFC5C: ERR_get_state (err.c:574)
==13514== by 0x1C0331: ERR_clear_error (err.c:816)
==13514== by 0x14131B: tls_handshake_client (tls_client.c:473)
==13514== by 0x13FF63: tls_handshake (tls.c:854)
==13514== by 0x140144: tls_write (tls.c:913)
==13514== by 0x13BEDF: main (example.c:35)
==13514==
==13514== 72 bytes in 1 blocks are still reachable in loss record 3 of 5
==13514== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==13514== by 0x1D2277: lh_new (lhash.c:212)
==13514== by 0x1BF593: err_thread_get (err.c:369)
==13514== by 0x1BF72B: err_thread_set_item (err.c:417)
==13514== by 0x1BFC5C: ERR_get_state (err.c:574)
==13514== by 0x1C0331: ERR_clear_error (err.c:816)
==13514== by 0x14131B: tls_handshake_client (tls_client.c:473)
==13514== by 0x13FF63: tls_handshake (tls.c:854)
==13514== by 0x140144: tls_write (tls.c:913)
==13514== by 0x13BEDF: main (example.c:35)
==13514==
==13514== 128 bytes in 1 blocks are still reachable in loss record 4 of 5
==13514== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==13514== by 0x1D229B: lh_new (lhash.c:214)
==13514== by 0x1BF593: err_thread_get (err.c:369)
==13514== by 0x1BF72B: err_thread_set_item (err.c:417)
==13514== by 0x1BFC5C: ERR_get_state (err.c:574)
==13514== by 0x1C0331: ERR_clear_error (err.c:816)
==13514== by 0x14131B: tls_handshake_client (tls_client.c:473)
==13514== by 0x13FF63: tls_handshake (tls.c:854)
==13514== by 0x140144: tls_write (tls.c:913)
==13514== by 0x13BEDF: main (example.c:35)
==13514==
==13514== 592 bytes in 1 blocks are still reachable in loss record 5 of 5
==13514== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==13514== by 0x1BFBAA: ERR_get_state (err.c:564)
==13514== by 0x1C0331: ERR_clear_error (err.c:816)
==13514== by 0x14131B: tls_handshake_client (tls_client.c:473)
==13514== by 0x13FF63: tls_handshake (tls.c:854)
==13514== by 0x140144: tls_write (tls.c:913)
==13514== by 0x13BEDF: main (example.c:35)
==13514==
==13514== LEAK SUMMARY:
==13514== definitely lost: 0 bytes in 0 blocks
==13514== indirectly lost: 0 bytes in 0 blocks
==13514== possibly lost: 0 bytes in 0 blocks
==13514== still reachable: 833 bytes in 5 blocks
==13514== suppressed: 0 bytes in 0 blocks
==13514==
==13514== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)The example:
#include <stdio.h>
#include <tls.h>
#include <openssl/crypto.h>
int main()
{
struct tls *tls;
struct tls_config *tls_config;
ssize_t written, read;
char buf[4096];
if (tls_init() != 0) {
fprintf(stderr, "tls_init failed");
return 1;
}
if ((tls = tls_client()) == NULL)
goto err;
if ((tls_config = tls_config_new()) == NULL)
goto err;
if (tls_config_set_ciphers(tls_config, "compat") != 0)
goto err;
tls_config_insecure_noverifycert(tls_config);
tls_config_insecure_noverifyname(tls_config);
if (tls_configure(tls, tls_config) != 0)
goto err;
if (tls_connect(tls, "google.com", "443") != 0)
goto err;
if ((written = tls_write(tls, "GET /\r\n", 7)) < 0)
goto err;
if ((read = tls_read(tls, buf, sizeof(buf))) < 0)
goto err;
buf[read - 1] = '\0';
puts(buf);
if (tls_close(tls) != 0)
goto err;
tls_config_free(tls_config);
tls_free(tls);
OPENSSL_cleanup();
return 0;
err:
fprintf(stderr, "Error: %s\n", tls_error(tls));
return 1;
}I'm working on openTLS building your libtls only for the installed OpenSSL version, it's being used to develop c-asio.
Adding a atexit() routine for the never freed tls_config_default in tls.c solved my issue without using OPENSSL_cleanup.
The same example produces:
valgrind -s --leak-check=full --show-leak-kinds=all ./example
==6788== Memcheck, a memory error detector
==6788== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6788== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==6788== Command: ./example
==6788==
HTTP/1.0 200 OK
Date: Sun, 05 Oct 2025 16:49:25 GMT
Expires: -1
...
...
...
...
==6788==
==6788== HEAP SUMMARY:
==6788== in use at exit: 0 bytes in 0 blocks
==6788== total heap usage: 14,865 allocs, 14,865 frees, 2,158,115 bytes allocated
==6788==
==6788== All heap blocks were freed -- no leaks are possible
==6788==
==6788== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)Metadata
Metadata
Assignees
Labels
No labels