From 6319cd74ea27c9405a8097029b3079693a707a22 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Thu, 16 Apr 2009 08:25:47 +0000 Subject: [PATCH] pluto uses the libstrongswan leak detective and a stripped-down version of library_t --- src/libstrongswan/settings.c | 1 + src/libstrongswan/utils/backtrace.c | 2 + src/pluto/Makefile.am | 12 +++ src/pluto/asn1.c | 8 +- src/pluto/crypto.c | 13 +++ src/pluto/crypto.h | 1 + src/pluto/defs.c | 125 ++-------------------------- src/pluto/defs.h | 7 +- src/pluto/library.c | 88 ++++++++++++++++++++ src/pluto/library.h | 58 +++++++++++++ src/pluto/modecfg.c | 8 +- src/pluto/plutomain.c | 16 +--- src/starter/invokepluto.c | 2 + 13 files changed, 196 insertions(+), 145 deletions(-) create mode 100644 src/pluto/library.c create mode 100644 src/pluto/library.h diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c index a02823ba0..59436c6f8 100644 --- a/src/libstrongswan/settings.c +++ b/src/libstrongswan/settings.c @@ -17,6 +17,7 @@ #define _GNU_SOURCE #include +#include #include #include diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c index 3caafdc38..321c97230 100644 --- a/src/libstrongswan/utils/backtrace.c +++ b/src/libstrongswan/utils/backtrace.c @@ -25,6 +25,8 @@ # include #endif /* HAVE_BACKTRACE */ +#include + #include "backtrace.h" typedef struct private_backtrace_t private_backtrace_t; diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am index d3e7ddc89..400b794b3 100644 --- a/src/pluto/Makefile.am +++ b/src/pluto/Makefile.am @@ -35,6 +35,7 @@ kernel_noklips.c kernel_noklips.h \ kernel_pfkey.c kernel_pfkey.h \ keys.c keys.h \ lex.c lex.h \ +library.c library.h \ log.c log.h \ md2.c md2.h \ md5.c md5.h \ @@ -94,6 +95,11 @@ $(LIBFREESWANDIR)/libfreeswan.a \ $(LIBCRYPTODIR)/libcrypto.a \ -lgmp -lresolv -lpthread -ldl +if USE_LEAK_DETECTIVE + AM_CFLAGS += -DLEAK_DETECTIVE + pluto_LDADD += backtrace.o leak_detective.o +endif + _pluto_adns_LDADD = \ $(LIBFREESWANDIR)/libfreeswan.a \ -lresolv -ldl @@ -107,6 +113,12 @@ oid.o : $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h debug.o : $(LIBSTRONGSWANDIR)/debug.c $(LIBSTRONGSWANDIR)/debug.h $(COMPILE) -c -o $@ $< +backtrace.o : $(LIBSTRONGSWANDIR)/utils/backtrace.c $(LIBSTRONGSWANDIR)/utils/backtrace.h + $(COMPILE) -c -o $@ $< + +leak_detective.o : $(LIBSTRONGSWANDIR)/utils/leak_detective.c $(LIBSTRONGSWANDIR)/utils/leak_detective.h + $(COMPILE) -c -o $@ $< + linked_list.o : $(LIBSTRONGSWANDIR)/utils/linked_list.c $(LIBSTRONGSWANDIR)/utils/linked_list.h $(COMPILE) -c -o $@ $< diff --git a/src/pluto/asn1.c b/src/pluto/asn1.c index 4ef7e6ac2..0262e6977 100644 --- a/src/pluto/asn1.c +++ b/src/pluto/asn1.c @@ -149,10 +149,10 @@ asn1_known_oid(chunk_t object) } /* - * Converts an known OID index to ASN.1 OID + * Converts a known OID index to an ASN.1 OID */ chunk_t -asn1_get_known_oid(int n) +asn1_build_known_oid(int n) { chunk_t oid; int i; @@ -163,8 +163,10 @@ asn1_get_known_oid(int n) } i = oid_names[n].level + 1; - oid.ptr = alloc_bytes(i, "known oid"); + oid.ptr = alloc_bytes(2 + i, "known oid"); oid.len = i; + oid.ptr[0] = ASN1_OID; + oid.ptr[1] = i; do { diff --git a/src/pluto/crypto.c b/src/pluto/crypto.c index caea0de81..9d9155bac 100644 --- a/src/pluto/crypto.c +++ b/src/pluto/crypto.c @@ -473,6 +473,19 @@ init_crypto(void) ike_alg_test(); } +void +free_crypto(void) +{ + mpz_clear(&groupgenerator); + mpz_clear(&modp1024_modulus); + mpz_clear(&modp1536_modulus); + mpz_clear(&modp2048_modulus); + mpz_clear(&modp3072_modulus); + mpz_clear(&modp4096_modulus); + mpz_clear(&modp6144_modulus); + mpz_clear(&modp8192_modulus); +} + /* Oakley group description * * See RFC2409 "The Internet key exchange (IKE)" 6. diff --git a/src/pluto/crypto.h b/src/pluto/crypto.h index 2a50c95c5..2e249bdc9 100644 --- a/src/pluto/crypto.h +++ b/src/pluto/crypto.h @@ -20,6 +20,7 @@ #include "ike_alg.h" extern void init_crypto(void); +extern void free_crypto(void); /* Oakley group descriptions */ diff --git a/src/pluto/defs.c b/src/pluto/defs.c index c513506f7..fa4383545 100644 --- a/src/pluto/defs.c +++ b/src/pluto/defs.c @@ -42,127 +42,14 @@ all_zero(const unsigned char *m, size_t len) return TRUE; } -/* memory allocation - * - * LEAK_DETECTIVE puts a wrapper around each allocation and maintains - * a list of live ones. If a dead one is freed, an assertion MIGHT fail. - * If the live list is currupted, that will often be detected. - * In the end, report_leaks() is called, and the names of remaining - * live allocations are printed. At the moment, it is hoped, not that - * the list is empty, but that there will be no surprises. - * - * Accepted Leaks: - * - "struct iface" and "device name" (for "discovered" net interfaces) - * - "struct event in event_schedule()" (events not associated with states) - * - "Pluto lock name" (one only, needed until end -- why bother?) - */ - -#ifdef LEAK_DETECTIVE - -/* this magic number is 3671129837 decimal (623837458 complemented) */ -#define LEAK_MAGIC 0xDAD0FEEDul - -union mhdr { - struct { - const char *name; - union mhdr *older, *newer; - unsigned long magic; - } i; /* info */ - unsigned long junk; /* force maximal alignment */ -}; - -static union mhdr *allocs = NULL; - -void *alloc_bytes(size_t size, const char *name) -{ - union mhdr *p = malloc(sizeof(union mhdr) + size); - - if (p == NULL) - exit_log("unable to malloc %lu bytes for %s" - , (unsigned long) size, name); - p->i.name = name; - p->i.older = allocs; - if (allocs != NULL) - allocs->i.newer = p; - allocs = p; - p->i.newer = NULL; - p->i.magic = LEAK_MAGIC; - - memset(p+1, '\0', size); - return p+1; -} - -void * -clone_bytes(const void *orig, size_t size, const char *name) -{ - void *p = alloc_bytes(size, name); - - memcpy(p, orig, size); - return p; -} - -void -pfree(void *ptr) -{ - union mhdr *p; - - passert(ptr != NULL); - p = ((union mhdr *)ptr) - 1; - passert(p->i.magic == LEAK_MAGIC); - if (p->i.older != NULL) - { - passert(p->i.older->i.newer == p); - p->i.older->i.newer = p->i.newer; - } - if (p->i.newer == NULL) - { - passert(p == allocs); - allocs = p->i.older; - } - else - { - passert(p->i.newer->i.older == p); - p->i.newer->i.older = p->i.older; - } - p->i.magic = ~LEAK_MAGIC; - free(p); -} - -void -report_leaks(void) -{ - union mhdr - *p = allocs, - *pprev = NULL; - unsigned long n = 0; - - while (p != NULL) - { - passert(p->i.magic == LEAK_MAGIC); - passert(pprev == p->i.newer); - pprev = p; - p = p->i.older; - n++; - if (p == NULL || pprev->i.name != p->i.name) - { - if (n != 1) - plog("leak: %lu * %s", n, pprev->i.name); - else - plog("leak: %s", pprev->i.name); - n = 0; - } - } -} - -#else /* !LEAK_DETECTIVE */ - void *alloc_bytes(size_t size, const char *name) { void *p = malloc(size); if (p == NULL) - exit_log("unable to malloc %lu bytes for %s" - , (unsigned long) size, name); + { + exit_log("unable to malloc %lu bytes for %s", (unsigned long) size, name); + } memset(p, '\0', size); return p; } @@ -172,12 +59,12 @@ void *clone_bytes(const void *orig, size_t size, const char *name) void *p = malloc(size); if (p == NULL) - exit_log("unable to malloc %lu bytes for %s" - , (unsigned long) size, name); + { + exit_log("unable to malloc %lu bytes for %s", (unsigned long) size, name); + } memcpy(p, orig, size); return p; } -#endif /* !LEAK_DETECTIVE */ /* Note that there may be as many as six IDs that are temporary at * one time before unsharing the two ends of a connection. So we need diff --git a/src/pluto/defs.h b/src/pluto/defs.h index 30a152120..3c887f303 100644 --- a/src/pluto/defs.h +++ b/src/pluto/defs.h @@ -49,12 +49,7 @@ extern void *clone_bytes(const void *orig, size_t size, const char *name); #define clone_str(str, name) \ ((str) == NULL? NULL : clone_bytes((str), strlen((str))+1, (name))) -#ifdef LEAK_DETECTIVE - extern void pfree(void *ptr); - extern void report_leaks(void); -#else -# define pfree(ptr) free(ptr) /* ordinary stdc free */ -#endif +#define pfree(ptr) free(ptr) /* ordinary stdc free */ #define pfreeany(p) { if ((p) != NULL) pfree(p); } #define replace(p, q) { pfreeany(p); (p) = (q); } diff --git a/src/pluto/library.c b/src/pluto/library.c new file mode 100644 index 000000000..b8f406ae4 --- /dev/null +++ b/src/pluto/library.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009 Tobias Brunner + * Copyright (C) 2008 Martin Willi + * 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + * + * $Id: library.c 4936 2009-03-12 18:07:32Z tobias $ + */ + +#include "library.h" + +#include + +#include +#ifdef LEAK_DETECTIVE +#include +#endif + +typedef struct private_library_t private_library_t; + +/** + * private data of library + */ +struct private_library_t { + + /** + * public functions + */ + library_t public; + +#ifdef LEAK_DETECTIVE + /** + * Memory leak detective, if enabled + */ + leak_detective_t *detective; +#endif /* LEAK_DETECTIVE */ +}; + +/** + * library instance + */ +library_t *lib; + +/** + * Implementation of library_t.destroy + */ +void library_deinit() +{ + private_library_t *this = (private_library_t*)lib; + + this->public.settings->destroy(this->public.settings); + +#ifdef LEAK_DETECTIVE + if (this->detective) + { + this->detective->destroy(this->detective); + } +#endif /* LEAK_DETECTIVE */ + free(this); + lib = NULL; +} + +/* + * see header file + */ +void library_init(char *settings) +{ + private_library_t *this = malloc_thing(private_library_t); + lib = &this->public; + + lib->leak_detective = FALSE; + +#ifdef LEAK_DETECTIVE + this->detective = leak_detective_create(); +#endif /* LEAK_DETECTIVE */ + + this->public.settings = settings_create(settings); +} + diff --git a/src/pluto/library.h b/src/pluto/library.h new file mode 100644 index 000000000..f4b570271 --- /dev/null +++ b/src/pluto/library.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008 Martin Willi + * 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program 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 General Public License + * for more details. + * + * $Id: library.h 5003 2009-03-24 17:43:01Z martin $ + */ + +#ifndef LIBRARY_H_ +#define LIBRARY_H_ + +#include +#include + +typedef struct library_t library_t; + +/** + * Libstrongswan library context, contains library relevant globals. + */ +struct library_t { + /** + * various settings loaded from settings file + */ + settings_t *settings; + + /** + * is leak detective running? + */ + bool leak_detective; +}; + +/** + * Initialize library, creates "lib" instance. + * + * @param settings file to read settings from, may be NULL for none + */ +void library_init(char *settings); + +/** + * Deinitialize library, destroys "lib" instance. + */ +void library_deinit(); + +/** + * Library instance, set after between library_init() and library_deinit() calls. + */ +extern library_t *lib; + +#endif /** LIBRARY_H_ @}*/ diff --git a/src/pluto/modecfg.c b/src/pluto/modecfg.c index be7e51bc8..97e3b818d 100644 --- a/src/pluto/modecfg.c +++ b/src/pluto/modecfg.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include "constants.h" #include "defs.h" @@ -59,8 +59,6 @@ #define UNITY_BANNER_STR "Welcome to strongSwan - the Linux VPN Solution!\n" -extern settings_t *settings; - /* * Addresses assigned (usually via ModeCfg) to the Initiator */ @@ -155,7 +153,7 @@ get_internal_addr(struct connection *c, internal_addr_t *ia) char dns_key[16], *dns_str; snprintf(dns_key, sizeof(dns_key), "pluto.dns%d", i); - dns_str = settings->get_str(settings, dns_key, NULL); + dns_str = lib->settings->get_str(lib->settings, dns_key, NULL); if (dns_str) { err_t ugh; @@ -181,7 +179,7 @@ get_internal_addr(struct connection *c, internal_addr_t *ia) char nbns_key[16], *nbns_str; snprintf(nbns_key, sizeof(nbns_key), "pluto.nbns%d", i); - nbns_str = settings->get_str(settings, nbns_key, NULL); + nbns_str = lib->settings->get_str(lib->settings, nbns_key, NULL); if (nbns_str) { err_t ugh; diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c index eedbf2532..e46cd9512 100644 --- a/src/pluto/plutomain.c +++ b/src/pluto/plutomain.c @@ -38,7 +38,7 @@ #endif /* CAPABILITIES */ #include -#include +#include #include #include @@ -198,9 +198,6 @@ delete_lock(void) } } -/* settings defined by strongswan.conf */ -settings_t *settings; - /* by default pluto sends certificate requests to its peers */ bool no_cr_send = FALSE; @@ -242,9 +239,7 @@ main(int argc, char **argv) cap_t caps; int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE }; #endif /* CAPABILITIES */ - - /* getting settings from strongswan.conf */ - settings = settings_create(STRONGSWAN_CONF); + library_init(STRONGSWAN_CONF); /* handle arguments */ for (;;) @@ -626,7 +621,6 @@ main(int argc, char **argv) init_fetch(); /* drop unneeded capabilities and change UID/GID */ - prctl(PR_SET_KEEPCAPS, 1); #ifdef IPSEC_GROUP @@ -710,13 +704,11 @@ exit_pluto(int status) free_ifaces(); scx_finalize(); /* finalize and unload PKCS #11 module */ xauth_finalize(); /* finalize and unload XAUTH module */ - settings->destroy(settings); stop_adns(); free_md_pool(); + free_crypto(); delete_lock(); -#ifdef LEAK_DETECTIVE - report_leaks(); -#endif /* LEAK_DETECTIVE */ + library_deinit(); close_log(); exit(status); } diff --git a/src/starter/invokepluto.c b/src/starter/invokepluto.c index 5e840bac2..30294c968 100644 --- a/src/starter/invokepluto.c +++ b/src/starter/invokepluto.c @@ -266,6 +266,8 @@ starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb) } setsid(); sigprocmask(SIG_SETMASK, 0, NULL); + /* disable glibc's malloc checker, conflicts with leak detective */ + setenv("MALLOC_CHECK_", "0", 1); execv(arg[0], arg); plog("can't execv(%s,...): %s", arg[0], strerror(errno)); exit(1);