pluto uses the libstrongswan leak detective and a stripped-down version of library_t
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
# include <execinfo.h>
|
||||
#endif /* HAVE_BACKTRACE */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "backtrace.h"
|
||||
|
||||
typedef struct private_backtrace_t private_backtrace_t;
|
||||
|
||||
@@ -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 $@ $<
|
||||
|
||||
|
||||
+5
-3
@@ -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
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ike_alg.h"
|
||||
|
||||
extern void init_crypto(void);
|
||||
extern void free_crypto(void);
|
||||
|
||||
/* Oakley group descriptions */
|
||||
|
||||
|
||||
+6
-119
@@ -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
|
||||
|
||||
+1
-6
@@ -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); }
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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_ @}*/
|
||||
+3
-5
@@ -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;
|
||||
|
||||
+4
-12
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user