[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] Memory leak when using MHD in TLS mode with bad certific
From: |
Nicolas Mora |
Subject: |
[libmicrohttpd] Memory leak when using MHD in TLS mode with bad certificates |
Date: |
Fri, 11 Jan 2019 10:11:24 -0500 |
User-agent: |
Roundcube Webmail/1.3.8 |
Hello,
While testing memory leaks in my code with valgrind, I found the
following problem, but I'm not sure if it comes from MHD or GnuTLS, or
even my use of libmicrohttpd.
I use libmicrohttpd 0.9.62 and GnuTLS 3.6.5 on Debian.
When you execute MHD_start_daemon with TLS support but use bad
certificates, the function MHD_start_daemon returns NULL, which is
expected, but seems to leak data.
Although, with the same code but with a valid certificate, there is no
memory leak.
Valgrind reports the following problem:
==7543== 6,336 (168 direct, 6,168 indirect) bytes in 1 blocks are
definitely lost in loss record 3 of 3
==7543== at 0x4837B65: calloc (vg_replace_malloc.c:752)
==7543== by 0x4A92966: gnutls_certificate_allocate_credentials (in
/usr/lib/x86_64-linux-gnu/libgnutls.so.30.23.0)
==7543== by 0x4864BCB: MHD_TLS_init (daemon.c:602)
==7543== by 0x4864BCB: MHD_start_daemon_va (daemon.c:6165)
==7543== by 0x486538A: MHD_start_daemon (daemon.c:4674)
==7543== by 0x10932B: main (minimal_example.c:133)
I have attached a modified minimal_example.c to show the problem.
/Nicolas
/*
This file is part of libmicrohttpd
Copyright (C) 2007 Christian Grothoff (and other contributing authors)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file minimal_example.c
* @brief minimal example for how to use libmicrohttpd
* @author Christian Grothoff
*/
//#include "platform.h"
#include
#include
#include
#include
#define PAGE "libmicrohttpd demo"
static char cert_key[] =
"-----BEGIN PRIVATE KEY-----\
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDIRxhHwaYPEw+N\
OzpPN9Wwoz8UOfP+26Bp111KQnQfLrFnghkOu/2jAAH+r2rwbi+pvsc1mWE3odp/\
jyJDFBbZQiVisla/hIHwOS1nSEk4XvNmSqyIglRTwNEkqszeFjNsuzSo5ODuPfd2\
FmoYzW+zHaq7m5VCHdlV7FSsBpXNCoSxgCApQLpQlT26YsEweq6mqusptUhJwvZE\
fwCXeoMRklW2d4CPB0q/7lE3zHzVsgpTLQF35wK6InKGODken0OT+hiRY0a2ojur\
KOoKnmExISismrm0rcK9qnxErFoKSFXZo7A2oThj2PXeqFM55dLIrNta8P0bsrvI\
9XM33vCDAgMBAAECggEBAKvHJtEtDBQz4gvduAaIOlWVvx3HEzsN/0moudBerSCt\
uOWx1XIo1cQ/1nYu2Qc9Ss5J3q1fT94aicEM8HMeQPa5YD2F/xenPJfhQssqWfrq\
ndOnytIPDusDH59Wi/8UhakF7IXMQgy1w5Faake5tMupb24YZO3fkjC7Umh2AXhp\
v7RpduTG7B41PlGbamuEFSLsDMuYEm2j/z6DP3b2YjoaDU9sS38M5TaGKQSJUCyh\
tQOYYWHb8Cx2l+0F/jwXZukZnoap/UoWuxtTKGwDi55uW8jEbyhZB/zal5K2EfCf\
7OY39YQif4bkcQjQKQsryb5RZOJ8dPpvVzhMGb0W4VkCgYEA5C/dTj56JexOtzEf\
oSKLo9WXfrLDDSlLR1k3QtMYmKuKyBFQFD2jXmQcg27KTsJQI6tNKD/fV035pDLk\
qjWEwUQucW5CnzW/srqYkyD51jBcYhwVh0CWnk1D4hwcBBHuOSbNCudmTsqdCvZ7\
N7YEsnW45gX8HU2cvne4NNVD7p0CgYEA4LBgLjeku5lLbZas/TNvlWFb2yc4RDNC\
07OaIMtPalI57RrhC97gQhdDLzh5BTg48jHk74wfgarJRPBI+2gRsSQV9keurMI7\
6DEljoT+WavYZiVB1dIVyJyjaKlJi708+wmOk12Azcir5Mxqw4nxIDSEIu4DzQ9l\
r62FWxcBoZ8CgYAG6jRopJgLAig4gPKWbXeR1W0r17r1cSTo2plEGyWJqtkfyvaE\
RoHm4F3E1dynmlfXXN+Psq/P83r3MNuhFNIbETffFBpMvNI8Vk89Vih8ByclifhV\
Cu4Fig3ekj9/GBQCA1z/UZfWF2m+5U1CmO93gP3DarcDJFD1rKcWYsgWOQKBgQCc\
XuNxBtSkorj12ckmpidgBNPSn2bvP+WgQ/xeGmB4lCUwOGaqxj+4f0wIjvragRhQ\
phy4AgLjUSKl0bxZC0JUz9JhBd4w6TScEagbmb8SVSBTZlZ9Iqp6ZVjsO/StRdQs\
uaf6MzazAJdwsjsTPusLCMF1NcR7b93K9645iLdf7QKBgQDdkXFkzjGsXO2J46Io\
HBgA+EkFhoTqFnUbSMyuydxjPiaDBvA4pTnHt2H4M0FUYD8VqooQ8zlW1qJraLm5\
swCOCs4U/K5qxRz1dwfTBHJRK95LU8PMO57B7aGESh9bhxlldW5/MQfO6UyZ7zpg\
ZkCVq1MFtfiDpShMcyzWjf9Cwg==\
-----END PRIVATE KEY-----";
static char cert_pem[] =
"-----BEGIN CERTIFICATE-----\
MIIDkzCCAnugAwIBAgIUUjNGJ7KB00RyVTX4O5d8K3RSJeIwDQYJKoZIhvcNAQEL\
BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM\
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X\
DTE5MDExMTE0MDE1MFoXDTIwMDExMTE0MDE1MFowWTELMAkGA1UEBhMCQVUxEzAR\
BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5\
IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\
MIIBCgKCAQEAyEcYR8GmDxMPjTs6TzfVsKM/FDnz/tugadddSkJ0Hy6xZ4IZDrv9\
owAB/q9q8G4vqb7HNZlhN6Haf48iQxQW2UIlYrJWv4SB8DktZ0hJOF7zZkqsiIJU\
U8DRJKrM3hYzbLs0qOTg7j33dhZqGM1vsx2qu5uVQh3ZVexUrAaVzQqEsYAgKUC6\
UJU9umLBMHqupqrrKbVIScL2RH8Al3qDEZJVtneAjwdKv+5RN8x81bIKUy0Bd+cC\
uiJyhjg5Hp9Dk/oYkWNGtqI7qyjqCp5hMSEorJq5tK3Cvap8RKxaCkhV2aOwNqE4\
Y9j13qhTOeXSyKzbWvD9G7K7yPVzN97wgwIDAQABo1MwUTAdBgNVHQ4EFgQU5vg5\
3el0SpQSL5gF4wQT5VbRo/cwHwYDVR0jBBgwFoAU5vg53el0SpQSL5gF4wQT5VbR\
o/cwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEABg9KL4H/ODWl\
G85F1KeE8Dq3uf6TqG6b7jcBrQ2IDv2XSr+cAnRAYwkn1WU1hYPN9pl5tF+8eFfi\
8pj0oZWF6EUioVR4cO4j+5fPbpQBWOZKjPsSsfudv9z+wcBMW9UtqH8dTIYRQA7T\
fDUAJOwZ0xa9C5Oi1K4qD0clQpbaGm/ogbUgaXK+EXIlyxPoQb2HyX1qxORRIKWG\
/lqTMANE1zuobzMXI2/WdMEYLZFfNpnisV0HitX5yl2S99BehyBN6PVeDkBsKRih\
F6CRjinUBK3tqjiB+EL0gZThq8HEEA/tL1M9zMrjRWQWVwoYrNOLPuwdIq3zvZ2c\
nhw7ERaxYw==\
-----END CERTIFICATE-----";
static char err[] = "error";
static int
ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data, size_t *upload_data_size, void **ptr)
{
static int aptr;
const char *me = cls;
struct MHD_Response *response;
int ret;
(void)url; /* Unused. Silent compiler warning. */
(void)version; /* Unused. Silent compiler warning. */
(void)upload_data; /* Unused. Silent compiler warning. */
(void)upload_data_size; /* Unused. Silent compiler warning. */
if (0 != strcmp (method, "GET"))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
{
/* do never respond on first call */
*ptr = &aptr;
return MHD_YES;
}
*ptr = NULL; /* reset when done */
response = MHD_create_response_from_buffer (strlen (me),
(void *) me,
MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
return ret;
}
int
main (int argc, char *const *argv)
{
struct MHD_Daemon *d;
if (argc != 2)
{
printf ("%s PORT\n", argv[0]);
return 1;
}
d = MHD_start_daemon (/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_TLS,
/* MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
/* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG | MHD_USE_POLL, */
/* MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_ERROR_LOG, */
atoi (argv[1]),
NULL, NULL, &ahc_echo, PAGE,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120,
MHD_OPTION_STRICT_FOR_CLIENT, (int) 1,
MHD_OPTION_HTTPS_MEM_KEY, err, //cert_key
MHD_OPTION_HTTPS_MEM_CERT, cert_pem, // replace cert_pem with err to get a memory leak
MHD_OPTION_END);
if (d == NULL)
return 1;
(void) getc (stdin);
MHD_stop_daemon (d);
return 0;
}
valgrind.txt
Description: Text document
- [libmicrohttpd] Memory leak when using MHD in TLS mode with bad certificates,
Nicolas Mora <=