pluto uses the libstrongswan leak detective and a stripped-down version of library_t
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 16 Apr 2009 08:25:47 +0000 (08:25 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 16 Apr 2009 08:25:47 +0000 (08:25 -0000)
13 files changed:
src/libstrongswan/settings.c
src/libstrongswan/utils/backtrace.c
src/pluto/Makefile.am
src/pluto/asn1.c
src/pluto/crypto.c
src/pluto/crypto.h
src/pluto/defs.c
src/pluto/defs.h
src/pluto/library.c [new file with mode: 0644]
src/pluto/library.h [new file with mode: 0644]
src/pluto/modecfg.c
src/pluto/plutomain.c
src/starter/invokepluto.c

index a02823b..59436c6 100644 (file)
@@ -17,6 +17,7 @@
 
 #define _GNU_SOURCE
 #include <string.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <errno.h>
 
index 3caafdc..321c972 100644 (file)
@@ -25,6 +25,8 @@
 # include <execinfo.h>
 #endif /* HAVE_BACKTRACE */
 
+#include <string.h>
+
 #include "backtrace.h"
 
 typedef struct private_backtrace_t private_backtrace_t;
index d3e7ddc..400b794 100644 (file)
@@ -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 $@ $<
 
index 4ef7e6a..0262e69 100644 (file)
@@ -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
     {
index caea0de..9d9155b 100644 (file)
@@ -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.
index 2a50c95..2e249bd 100644 (file)
@@ -20,6 +20,7 @@
 #include "ike_alg.h"
 
 extern void init_crypto(void);
+extern void free_crypto(void);
 
 /* Oakley group descriptions */
 
index c513506..fa43835 100644 (file)
@@ -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);
+    void *p = malloc(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;
+       exit_log("unable to malloc %lu bytes for %s", (unsigned long) size, name);
     }
-    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);
     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
index 30a1521..3c887f3 100644 (file)
@@ -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 (file)
index 0000000..b8f406a
--- /dev/null
@@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 <stdlib.h>
+
+#include <utils.h>
+#ifdef LEAK_DETECTIVE
+#include <utils/leak_detective.h>
+#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 (file)
index 0000000..f4b5702
--- /dev/null
@@ -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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 <utils.h>
+#include <settings.h>
+
+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_ @}*/
index be7e51b..97e3b81 100644 (file)
@@ -26,7 +26,7 @@
 #include <string.h>
 
 #include <freeswan.h>
-#include <settings.h>
+#include <library.h>
 
 #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;
index eedbf25..e46cd95 100644 (file)
@@ -38,7 +38,7 @@
 #endif /* CAPABILITIES */
 
 #include <freeswan.h>
-#include <settings.h>
+#include <library.h>
 
 #include <pfkeyv2.h>
 #include <pfkey.h>
@@ -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);
 }
index 5e840ba..30294c9 100644 (file)
@@ -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);