From 4f1c6bc5a6195c0189858b920ab5c2bcf645a169 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 10:06:28 +0200 Subject: [PATCH 01/18] leak-detective: Optionally write report to a log file --- src/libstrongswan/library.c | 46 +++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index e130b93eee..f694509d15 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -55,6 +55,13 @@ struct private_library_t { */ bool integrity_failed; +#ifdef LEAK_DETECTIVE + /** + * Where to write leak detective output to + */ + FILE *ld_out; +#endif + /** * Number of times we have been initialized */ @@ -95,32 +102,34 @@ library_t *lib = NULL; /** * Default leak report callback */ -static void report_leaks(void *user, int count, size_t bytes, - backtrace_t *bt, bool detailed) +CALLBACK(report_leaks, void, + private_library_t *this, int count, size_t bytes, backtrace_t *bt, + bool detailed) { - fprintf(stderr, "%zu bytes total, %d allocations, %zu bytes average:\n", + fprintf(this->ld_out, "%zu bytes total, %d allocations, %zu bytes average:\n", bytes, count, bytes / count); - bt->log(bt, stderr, detailed); + bt->log(bt, this->ld_out, detailed); } /** * Default leak report summary callback */ -static void sum_leaks(void* user, int count, size_t bytes, int whitelisted) +CALLBACK(sum_leaks, void, + private_library_t *this, int count, size_t bytes, int whitelisted) { switch (count) { case 0: - fprintf(stderr, "No leaks detected"); + fprintf(this->ld_out, "No leaks detected"); break; case 1: - fprintf(stderr, "One leak detected"); + fprintf(this->ld_out, "One leak detected"); break; default: - fprintf(stderr, "%d leaks detected, %zu bytes", count, bytes); + fprintf(this->ld_out, "%d leaks detected, %zu bytes", count, bytes); break; } - fprintf(stderr, ", %d suppressed by whitelist\n", whitelisted); + fprintf(this->ld_out, ", %d suppressed by whitelist\n", whitelisted); } #endif /* LEAK_DETECTIVE */ @@ -166,12 +175,18 @@ void library_deinit() this->public.integrity->destroy(this->public.integrity); } +#ifdef LEAK_DETECTIVE if (lib->leak_detective) { lib->leak_detective->report(lib->leak_detective, detailed); lib->leak_detective->destroy(lib->leak_detective); lib->leak_detective = NULL; } + if (this->ld_out && this->ld_out != stderr) + { + fclose(this->ld_out); + } +#endif /* LEAK_DETECTIVE */ backtrace_deinit(); arrays_deinit(); @@ -301,11 +316,22 @@ bool library_init(char *settings, const char *namespace) backtrace_init(); #ifdef LEAK_DETECTIVE + { + FILE *out = NULL; + char *log; + + log = getenv("LEAK_DETECTIVE_LOG"); + if (log) + { + out = fopen(log, "a"); + } + this->ld_out = out ?: stderr; + } lib->leak_detective = leak_detective_create(); if (lib->leak_detective) { lib->leak_detective->set_report_cb(lib->leak_detective, - report_leaks, sum_leaks, NULL); + report_leaks, sum_leaks, this); } #endif /* LEAK_DETECTIVE */ From d8b2980aa5a9fcc87ec43089e0fc1e91907e4501 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 11:50:09 +0200 Subject: [PATCH 02/18] testing: Log leaks and fail tests if any are detected --- testing/do-tests | 31 ++++++++++++++++++++++- testing/hosts/default/etc/ssh/sshd_config | 1 + testing/ssh_config | 1 + 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/testing/do-tests b/testing/do-tests index 8fcd7c82e9..e24cbe5f47 100755 --- a/testing/do-tests +++ b/testing/do-tests @@ -357,7 +357,7 @@ do ########################################################################## - # copy test specific configurations to uml hosts and clear auth.log files + # copy test specific configurations to hosts and clear log files # DBDIR=/etc/db.d @@ -409,6 +409,16 @@ do ssh $SSHCONF root@`eval echo \\\$ipv4_$host` 'conntrack -F' >/dev/null 2>&1 done + ########################################################################## + # remove leak detective log on all hosts + # + + export LEAK_DETECTIVE_LOG=/var/log/leak-detective.log + for host in $STRONGSWANHOSTS + do + ssh $SSHCONF root@`eval echo \\\$ipv4_$host` 'rm -f $LEAK_DETECTIVE_LOG' >/dev/null 2>&1 + done + ########################################################################## # flush IPsec state on all hosts # @@ -802,6 +812,25 @@ do fi done + + ########################################################################## + # make sure there were no leaks + # + + for host in $STRONGSWANHOSTS + do + eval HOSTLOGIN=root@\$ipv4_${host} + LEAKS=`ssh $SSHCONF $HOSTLOGIN 'cat $LEAK_DETECTIVE_LOG 2>/dev/null | grep -v "No leaks detected.*"'` + if [ -n "$LEAKS" ] + then + echo -e "\n$host# cat $LEAK_DETECTIVE_LOG [NO]" >> $CONSOLE_LOG + echo "$LEAKS" >> $CONSOLE_LOG + echo "<<< $host $LEAK_DETECTIVE_LOG >>>" >> $CONSOLE_LOG + STATUS="failed" + fi + done + + ########################################################################## # get a copy of /var/log/auth.log # diff --git a/testing/hosts/default/etc/ssh/sshd_config b/testing/hosts/default/etc/ssh/sshd_config index ae2e4cc844..ecd7f4fd18 100644 --- a/testing/hosts/default/etc/ssh/sshd_config +++ b/testing/hosts/default/etc/ssh/sshd_config @@ -12,3 +12,4 @@ PermitEmptyPasswords yes PrintMotd no PrintLastLog no UsePAM no +AcceptEnv LEAK_DETECTIVE_LOG diff --git a/testing/ssh_config b/testing/ssh_config index 831b9dc1a2..3676830187 100644 --- a/testing/ssh_config +++ b/testing/ssh_config @@ -1,6 +1,7 @@ Host * # debian default SendEnv LANG LC_* + SendEnv LEAK_DETECTIVE_LOG StrictHostKeyChecking no UserKnownHostsFile /dev/null GSSAPIAuthentication yes From 6307a18fe127fcc08b3e36d8df3e2826bc134eb5 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 12:26:55 +0200 Subject: [PATCH 03/18] testing: Fix totals if post test checks fail --- testing/do-tests | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/testing/do-tests b/testing/do-tests index e24cbe5f47..fd5cfe61be 100755 --- a/testing/do-tests +++ b/testing/do-tests @@ -495,18 +495,6 @@ do }' $TESTDIR/evaltest.dat` >> $CONSOLE_LOG 2>&1 - ########################################################################## - # set counters - # - - if [ $STATUS = "failed" ] - then - let "failed_cnt += 1" - else - let "passed_cnt += 1" - fi - - ########################################################################## # log statusall and listall output # get copies of ipsec.conf, ipsec.secrets @@ -887,6 +875,18 @@ do $DIR/scripts/restore-defaults $testname + ########################################################################## + # set counters + # + + if [ $STATUS = "failed" ] + then + let "failed_cnt += 1" + else + let "passed_cnt += 1" + fi + + ########################################################################## # write test status to html file # From f44e0efb11ad6ebeb2e5b7e207c4dda85aee9c9c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 12:27:33 +0200 Subject: [PATCH 04/18] leak-detective: Whitelist leak in libldap --- src/libstrongswan/utils/leak_detective.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index d0f646c315..f199f52934 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -551,6 +551,8 @@ char *whitelist[] = { "xmlInitParserCtxt", /* libcurl */ "Curl_client_write", + /* libldap */ + "ldap_int_initialize", /* ClearSilver */ "nerr_init", /* libgcrypt */ From 8c33a1897a8d8ef1f2712da1e33970b3244dc143 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 12:33:27 +0200 Subject: [PATCH 05/18] pool: Fix (known) memory leak when querying leases --- src/pool/pool.c | 59 +++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/pool/pool.c b/src/pool/pool.c index 2659748607..cd9fb62933 100644 --- a/src/pool/pool.c +++ b/src/pool/pool.c @@ -1,6 +1,7 @@ /* + * Copyright (C) 2011-2016 Tobias Brunner * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -23,6 +24,7 @@ #include #include +#include #include #include #include @@ -586,11 +588,11 @@ static void resize(char *name, host_t *end) /** * create the lease query using the filter string */ -static enumerator_t *create_lease_query(char *filter) +static enumerator_t *create_lease_query(char *filter, array_t **to_free) { enumerator_t *query; - identification_t *id = NULL; - host_t *addr = NULL; + chunk_t id_chunk = chunk_empty, addr_chunk = chunk_empty; + id_type_t id_type = 0; u_int tstamp = 0; bool online = FALSE, valid = FALSE, expired = FALSE; char *value, *pos, *pool = NULL; @@ -635,18 +637,29 @@ static enumerator_t *create_lease_query(char *filter) case FIL_ID: if (value) { + identification_t *id; + id = identification_create_from_string(value); + id_type = id->get_type(id); + id_chunk = chunk_clone(id->get_encoding(id)); + array_insert_create(to_free, ARRAY_TAIL, id_chunk.ptr); + id->destroy(id); } break; case FIL_ADDR: if (value) { + host_t *addr; + addr = host_create_from_string(value, 0); - } - if (!addr) - { - fprintf(stderr, "invalid 'addr' in filter string.\n"); - exit(EXIT_FAILURE); + if (!addr) + { + fprintf(stderr, "invalid 'addr' in filter string.\n"); + exit(EXIT_FAILURE); + } + addr_chunk = chunk_clone(addr->get_address(addr)); + array_insert_create(to_free, ARRAY_TAIL, addr_chunk.ptr); + addr->destroy(addr); } break; case FIL_TSTAMP: @@ -710,11 +723,11 @@ static enumerator_t *create_lease_query(char *filter) "AND (? OR (identities.type = ? AND identities.data = ?)) " "AND (? OR address = ?)", DB_INT, pool == NULL, DB_TEXT, pool, - DB_INT, id == NULL, - DB_INT, id ? id->get_type(id) : 0, - DB_BLOB, id ? id->get_encoding(id) : chunk_empty, - DB_INT, addr == NULL, - DB_BLOB, addr ? addr->get_address(addr) : chunk_empty, + DB_INT, !id_chunk.ptr, + DB_INT, id_type, + DB_BLOB, id_chunk, + DB_INT, !addr_chunk.ptr, + DB_BLOB, addr_chunk, DB_INT, tstamp == 0, DB_UINT, tstamp, DB_UINT, tstamp, DB_INT, !valid, DB_INT, time(NULL), DB_INT, !expired, DB_INT, time(NULL), @@ -722,14 +735,13 @@ static enumerator_t *create_lease_query(char *filter) /* union */ DB_INT, !(valid || expired), DB_INT, pool == NULL, DB_TEXT, pool, - DB_INT, id == NULL, - DB_INT, id ? id->get_type(id) : 0, - DB_BLOB, id ? id->get_encoding(id) : chunk_empty, - DB_INT, addr == NULL, - DB_BLOB, addr ? addr->get_address(addr) : chunk_empty, + DB_INT, !id_chunk.ptr, + DB_INT, id_type, + DB_BLOB, id_chunk, + DB_INT, !addr_chunk.ptr, + DB_BLOB, addr_chunk, /* res */ DB_TEXT, DB_BLOB, DB_INT, DB_BLOB, DB_UINT, DB_UINT, DB_UINT); - /* id and addr leak but we can't destroy them until query is destroyed. */ return query; } @@ -739,6 +751,7 @@ static enumerator_t *create_lease_query(char *filter) static void leases(char *filter, bool utc) { enumerator_t *query; + array_t *to_free = NULL; chunk_t address_chunk, identity_chunk; int identity_type; char *name; @@ -748,7 +761,7 @@ static void leases(char *filter, bool utc) identification_t *identity; bool found = FALSE; - query = create_lease_query(filter); + query = create_lease_query(filter, &to_free); if (!query) { fprintf(stderr, "querying leases failed.\n"); @@ -809,6 +822,10 @@ static void leases(char *filter, bool utc) identity->destroy(identity); } query->destroy(query); + if (to_free) + { + array_destroy_function(to_free, (void*)free, NULL); + } if (!found) { fprintf(stderr, "no matching leases found.\n"); From 3a25032c16353d4cf6673a074c2cfed74529b04c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 14:12:29 +0200 Subject: [PATCH 06/18] unbound: Fix memory leak --- src/libstrongswan/plugins/unbound/unbound_rr.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libstrongswan/plugins/unbound/unbound_rr.c b/src/libstrongswan/plugins/unbound/unbound_rr.c index fc69eed00f..91b5cdb331 100644 --- a/src/libstrongswan/plugins/unbound/unbound_rr.c +++ b/src/libstrongswan/plugins/unbound/unbound_rr.c @@ -154,11 +154,13 @@ unbound_rr_t *unbound_rr_create_frm_ldns_rr(ldns_rr *rr) if (status != LDNS_STATUS_OK) { DBG1(DBG_LIB, "failed to get the RDATA field of a DNS RR"); + ldns_buffer_free(buf); _destroy(this); return NULL; } this->rdata = ldns_buffer_export(buf); + ldns_buffer_free(buf); return &this->public; } From 15cbe526ac1919da7859f5dc5edc44919ba64c13 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 14:12:49 +0200 Subject: [PATCH 07/18] unbound: Avoid unnecessary cloning of RR list that caused a memory leak --- src/libstrongswan/plugins/unbound/unbound_response.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libstrongswan/plugins/unbound/unbound_response.c b/src/libstrongswan/plugins/unbound/unbound_response.c index 6f6c25e897..950df344c5 100644 --- a/src/libstrongswan/plugins/unbound/unbound_response.c +++ b/src/libstrongswan/plugins/unbound/unbound_response.c @@ -189,7 +189,7 @@ unbound_response_t *unbound_response_create_frm_libub_response( */ rr_list = linked_list_create(); - orig_rr_list = ldns_pkt_get_section_clone(dns_pkt, LDNS_SECTION_ANSWER); + orig_rr_list = ldns_pkt_answer(dns_pkt); orig_rr_count = ldns_rr_list_rr_count(orig_rr_list); for (i = 0; i < orig_rr_count; i++) @@ -253,7 +253,6 @@ unbound_response_t *unbound_response_create_frm_libub_response( this->rr_set = rr_set_create(rr_list, rrsig_list); ldns_pkt_free(dns_pkt); - ldns_rr_list_free(orig_rr_list); } return &this->public; } From 149b7de35c870434704a087135004a60cf3e771f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 14:13:47 +0200 Subject: [PATCH 08/18] dnscert: Properly free enumerated certificates --- src/libcharon/plugins/dnscert/dnscert_cred.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libcharon/plugins/dnscert/dnscert_cred.c b/src/libcharon/plugins/dnscert/dnscert_cred.c index 7902526820..d32794c994 100644 --- a/src/libcharon/plugins/dnscert/dnscert_cred.c +++ b/src/libcharon/plugins/dnscert/dnscert_cred.c @@ -70,6 +70,8 @@ typedef struct { enumerator_t *inner; /** response of the DNS resolver which contains the CERTs */ resolver_response_t *response; + /** most recently enumerated certificate */ + certificate_t *cert; } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, @@ -101,17 +103,17 @@ METHOD(enumerator_t, cert_enumerator_enumerate, bool, /* Try to parse PEM certificate container. Both x509 and PGP should * presumably come as PEM encoded certs. */ certificate = cur_crt->get_certificate(cur_crt); - *cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_ANY, - BUILD_BLOB_PEM, certificate, - BUILD_END); - if (*cert == NULL) + DESTROY_IF(this->cert); + this->cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_ANY, + BUILD_BLOB_PEM, certificate, + BUILD_END); + cur_crt->destroy(cur_crt); + if (!this->cert) { - DBG1(DBG_CFG, " unable to parse certificate, skipping", - cur_crt->get_cert_type(cur_crt)); - cur_crt->destroy(cur_crt); + DBG1(DBG_CFG, " unable to parse certificate, skipping"); continue; } - cur_crt->destroy(cur_crt); + *cert = this->cert; return TRUE; } return FALSE; @@ -120,6 +122,7 @@ METHOD(enumerator_t, cert_enumerator_enumerate, bool, METHOD(enumerator_t, cert_enumerator_destroy, void, cert_enumerator_t *this) { + DESTROY_IF(this->cert); this->inner->destroy(this->inner); this->response->destroy(this->response); free(this); From c0c14af8c26117f4877be9f808517fe3fb9b0bff Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 14:15:41 +0200 Subject: [PATCH 09/18] ipseckey: Properly free public key after creating certificate --- src/libcharon/plugins/ipseckey/ipseckey_cred.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcharon/plugins/ipseckey/ipseckey_cred.c b/src/libcharon/plugins/ipseckey/ipseckey_cred.c index 6c041ce268..6f85994a20 100644 --- a/src/libcharon/plugins/ipseckey/ipseckey_cred.c +++ b/src/libcharon/plugins/ipseckey/ipseckey_cred.c @@ -105,11 +105,11 @@ METHOD(enumerator_t, cert_enumerator_enumerate, bool, BUILD_NOT_BEFORE_TIME, this->notBefore, BUILD_NOT_AFTER_TIME, this->notAfter, BUILD_END); + public->destroy(public); if (*cert == NULL) { DBG1(DBG_CFG, " failed to create certificate from IPSECKEY"); cur_ipseckey->destroy(cur_ipseckey); - public->destroy(public); continue; } cur_ipseckey->destroy(cur_ipseckey); From 0b4ba9c53d43b2aa1668af537308b657c600f9ba Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 14:19:59 +0200 Subject: [PATCH 10/18] ipseckey: Properly free enumerated certificates --- .../plugins/ipseckey/ipseckey_cred.c | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/libcharon/plugins/ipseckey/ipseckey_cred.c b/src/libcharon/plugins/ipseckey/ipseckey_cred.c index 6f85994a20..ff50d8a173 100644 --- a/src/libcharon/plugins/ipseckey/ipseckey_cred.c +++ b/src/libcharon/plugins/ipseckey/ipseckey_cred.c @@ -57,6 +57,8 @@ typedef struct { time_t notAfter; /* identity to which the IPSECKEY belongs */ identification_t *identity; + /** most recently enumerated certificate */ + certificate_t *cert; } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, @@ -91,28 +93,27 @@ METHOD(enumerator_t, cert_enumerator_enumerate, bool, public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_DNSKEY, key, BUILD_END); + cur_ipseckey->destroy(cur_ipseckey); if (!public) { DBG1(DBG_CFG, " failed to create public key from IPSECKEY"); - cur_ipseckey->destroy(cur_ipseckey); continue; } - - *cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, - CERT_TRUSTED_PUBKEY, - BUILD_PUBLIC_KEY, public, - BUILD_SUBJECT, this->identity, - BUILD_NOT_BEFORE_TIME, this->notBefore, - BUILD_NOT_AFTER_TIME, this->notAfter, - BUILD_END); + DESTROY_IF(this->cert); + this->cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, + CERT_TRUSTED_PUBKEY, + BUILD_PUBLIC_KEY, public, + BUILD_SUBJECT, this->identity, + BUILD_NOT_BEFORE_TIME, this->notBefore, + BUILD_NOT_AFTER_TIME, this->notAfter, + BUILD_END); public->destroy(public); - if (*cert == NULL) + if (!this->cert) { DBG1(DBG_CFG, " failed to create certificate from IPSECKEY"); - cur_ipseckey->destroy(cur_ipseckey); continue; } - cur_ipseckey->destroy(cur_ipseckey); + *cert = this->cert; return TRUE; } return FALSE; @@ -121,6 +122,7 @@ METHOD(enumerator_t, cert_enumerator_enumerate, bool, METHOD(enumerator_t, cert_enumerator_destroy, void, cert_enumerator_t *this) { + DESTROY_IF(this->cert); this->inner->destroy(this->inner); this->response->destroy(this->response); free(this); From 70ac90c552ebc4042d287f6e2cab424088085704 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 14:27:54 +0200 Subject: [PATCH 11/18] eap-peap: Fix memory leaks when handling tunneled methods --- src/libcharon/plugins/eap_peap/eap_peap_server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcharon/plugins/eap_peap/eap_peap_server.c b/src/libcharon/plugins/eap_peap/eap_peap_server.c index 7f8348e066..d51d0d0905 100644 --- a/src/libcharon/plugins/eap_peap/eap_peap_server.c +++ b/src/libcharon/plugins/eap_peap/eap_peap_server.c @@ -211,7 +211,7 @@ METHOD(tls_application_t, process, status_t, { DBG1(DBG_IKE, "received tunneled EAP-PEAP AVP [EAP/%N]", eap_code_short_names, code); - + in->destroy(in); /* if EAP_SUCCESS check if to continue phase2 with EAP-TNC */ return (this->phase2_result == EAP_SUCCESS && code == EAP_SUCCESS) ? start_phase2_tnc(this) : FAILED; @@ -250,6 +250,7 @@ METHOD(tls_application_t, process, status_t, { DBG1(DBG_IKE, "%N method not available", eap_type_names, EAP_IDENTITY); + in->destroy(in); return FAILED; } } @@ -258,6 +259,7 @@ METHOD(tls_application_t, process, status_t, { DBG1(DBG_IKE, "%N method failed", eap_type_names, EAP_IDENTITY); + in->destroy(in); return FAILED; } From b69cbacdfb3e310def7dcd23b027748387c6a736 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 15:34:02 +0200 Subject: [PATCH 12/18] testing: Use curl instead of soup plugin in libipsec/rw-suite-b scenario The soup plugin is already used in the openssl-ikev2/rw-suite-b* scenarios. --- .../tests/libipsec/rw-suite-b/hosts/carol/etc/strongswan.conf | 2 +- .../tests/libipsec/rw-suite-b/hosts/dave/etc/strongswan.conf | 2 +- .../tests/libipsec/rw-suite-b/hosts/moon/etc/strongswan.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/strongswan.conf b/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/strongswan.conf index 8d328f00ba..8acfbbffa5 100644 --- a/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/strongswan.conf +++ b/testing/tests/libipsec/rw-suite-b/hosts/carol/etc/strongswan.conf @@ -1,7 +1,7 @@ # /etc/strongswan.conf - strongSwan configuration file charon { - load = pem pkcs1 pkcs8 random nonce x509 revocation openssl soup stroke kernel-libipsec kernel-netlink socket-default updown + load = pem pkcs1 pkcs8 random nonce x509 revocation openssl curl stroke kernel-libipsec kernel-netlink socket-default updown initiator_only = yes diff --git a/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/strongswan.conf b/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/strongswan.conf index 8d328f00ba..8acfbbffa5 100644 --- a/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/strongswan.conf +++ b/testing/tests/libipsec/rw-suite-b/hosts/dave/etc/strongswan.conf @@ -1,7 +1,7 @@ # /etc/strongswan.conf - strongSwan configuration file charon { - load = pem pkcs1 pkcs8 random nonce x509 revocation openssl soup stroke kernel-libipsec kernel-netlink socket-default updown + load = pem pkcs1 pkcs8 random nonce x509 revocation openssl curl stroke kernel-libipsec kernel-netlink socket-default updown initiator_only = yes diff --git a/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/strongswan.conf b/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/strongswan.conf index 0f4c68fdbe..5f39be37ec 100644 --- a/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/strongswan.conf +++ b/testing/tests/libipsec/rw-suite-b/hosts/moon/etc/strongswan.conf @@ -1,7 +1,7 @@ # /etc/strongswan.conf - strongSwan configuration file charon { - load = pem pkcs1 pkcs8 random nonce x509 revocation openssl soup stroke kernel-libipsec kernel-netlink socket-default updown + load = pem pkcs1 pkcs8 random nonce x509 revocation openssl curl stroke kernel-libipsec kernel-netlink socket-default updown plugins { openssl { From 0b5d490e336d04eb958204ce9f234a2707faa28d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 15:38:43 +0200 Subject: [PATCH 13/18] leak-detective: Whitelist some glib/libsoup functions Some of these are pretty broad, so maybe an alternative option is to not use the soup plugin in the openssl-ikev2/rw-suite-b* scenarios. But the plugin is not tested anywhere else so lets go with this for now. --- src/libstrongswan/utils/leak_detective.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index f199f52934..5fdebcd81c 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -551,6 +551,13 @@ char *whitelist[] = { "xmlInitParserCtxt", /* libcurl */ "Curl_client_write", + /* libsoup */ + "soup_message_headers_append", + "soup_message_headers_clear", + "soup_message_headers_get_list", + "soup_message_headers_get_one", + "soup_session_abort", + "soup_session_get_type", /* libldap */ "ldap_int_initialize", /* ClearSilver */ @@ -577,13 +584,18 @@ char *whitelist[] = { /* libapr */ "apr_pool_create_ex", /* glib */ + "g_output_stream_write", + "g_resolver_lookup_by_name", + "g_signal_connect_data", + "g_socket_connection_factory_lookup_type", "g_type_init_with_debug_flags", "g_type_register_static", "g_type_class_ref", "g_type_create_instance", "g_type_add_interface_static", "g_type_interface_add_prerequisite", - "g_socket_connection_factory_lookup_type", + "g_private_set", + "g_queue_pop_tail", /* libgpg */ "gpg_err_init", /* gnutls */ From b71f5f9305e2cd623f4303ce438633dfa189921f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 16:24:30 +0200 Subject: [PATCH 14/18] charon-tkm: Deinitialize tkm before libstrongswan In particular because of leak-detective. --- src/charon-tkm/src/charon-tkm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c index 13352e55aa..41b364fcfc 100644 --- a/src/charon-tkm/src/charon-tkm.c +++ b/src/charon-tkm/src/charon-tkm.c @@ -382,7 +382,7 @@ int main(int argc, char *argv[]) deinit: destroy_dh_mapping(); libcharon_deinit(); - library_deinit(); tkm_deinit(); + library_deinit(); return status; } From 8bc2ddb2ccdf3a015047a3c98b0b8bab1d915056 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 16:27:12 +0200 Subject: [PATCH 15/18] charon-tkm: Free name of the PID file --- src/charon-tkm/src/charon-tkm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c index 41b364fcfc..3136b8083e 100644 --- a/src/charon-tkm/src/charon-tkm.c +++ b/src/charon-tkm/src/charon-tkm.c @@ -373,6 +373,7 @@ int main(int argc, char *argv[]) run(); unlink_pidfile(); + free(pidfile_name); status = 0; charon->bus->remove_listener(charon->bus, &listener->listener); listener->destroy(listener); From fd2ade993580511a45fd53b7d1376df5f23a5f8b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 16:28:01 +0200 Subject: [PATCH 16/18] leak-detective: Whitelist functions of the Ada runtime related to Tasking --- src/libstrongswan/utils/leak_detective.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index 5fdebcd81c..e78938cfce 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -600,6 +600,10 @@ char *whitelist[] = { "gpg_err_init", /* gnutls */ "gnutls_global_init", + /* Ada runtime */ + "system__tasking__initialize", + "system__tasking__initialization__abort_defer", + "system__tasking__stages__create_task", }; /** From 6250e813ca8f4a70e3f96f13c08415548de62e52 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 17:17:09 +0200 Subject: [PATCH 17/18] charon-tkm: Build C code with debug information --- src/charon-tkm/build_common.gpr | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/charon-tkm/build_common.gpr b/src/charon-tkm/build_common.gpr index 102f6b7a27..4595195649 100644 --- a/src/charon-tkm/build_common.gpr +++ b/src/charon-tkm/build_common.gpr @@ -9,7 +9,8 @@ project Build_Common is C_Compiler_Switches := ("-W", "-Wall", - "-Wno-unused-parameter"); + "-Wno-unused-parameter", + "-g"); Ada_Compiler_Switches := ("-gnatwale", "-gnatygAdISuxo", "-gnata", From 95f9fa82d5574f08dca873941115ce60c8f14341 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 13 Sep 2016 17:28:21 +0200 Subject: [PATCH 18/18] leak-detective: Whitelist thread ID getter In case an external thread calls into our code and logs messages, a thread object is allocated that will never be released. Even if we try to clean up the object via thread value destructor there is no guarantee that the thread actually terminates before we check for leaks, which seems to be the case for the Ada Tasking threads. --- src/libstrongswan/utils/leak_detective.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index e78938cfce..ad67c03807 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -494,7 +494,7 @@ static bool register_hooks() * List of functions using static allocation buffers or should be suppressed * otherwise on leak report. */ -char *whitelist[] = { +static char *whitelist[] = { /* backtraces, including own */ "backtrace_create", "strerror_safe", @@ -604,6 +604,8 @@ char *whitelist[] = { "system__tasking__initialize", "system__tasking__initialization__abort_defer", "system__tasking__stages__create_task", + /* in case external threads call into our code */ + "thread_current_id", }; /**