Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/crypto/dist/ipsec-tools/src/racoon avoid some memory leaks /...
details: https://anonhg.NetBSD.org/src/rev/4a0d4e94e838
branches: trunk
changeset: 763236:4a0d4e94e838
user: vanhu <vanhu%NetBSD.org@localhost>
date: Mon Mar 14 15:50:36 2011 +0000
description:
avoid some memory leaks / free memory access when reloading conf and have inherited config. patch from Roman Hoog Antink <rha%open.ch@localhost>
diffstat:
crypto/dist/ipsec-tools/src/racoon/cfparse.y | 81 ++++++++++++-
crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c | 41 ++++++-
crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h | 3 +-
crypto/dist/ipsec-tools/src/racoon/remoteconf.c | 137 +++++++++++++++++++--
crypto/dist/ipsec-tools/src/racoon/remoteconf.h | 6 +-
crypto/dist/ipsec-tools/src/racoon/rsalist.c | 44 ++++++-
crypto/dist/ipsec-tools/src/racoon/rsalist.h | 3 +-
7 files changed, 290 insertions(+), 25 deletions(-)
diffs (truncated from 511 to 300 lines):
diff -r d55df4485566 -r 4a0d4e94e838 crypto/dist/ipsec-tools/src/racoon/cfparse.y
--- a/crypto/dist/ipsec-tools/src/racoon/cfparse.y Mon Mar 14 15:21:22 2011 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/cfparse.y Mon Mar 14 15:50:36 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cfparse.y,v 1.41 2011/03/02 14:58:27 vanhu Exp $ */
+/* $NetBSD: cfparse.y,v 1.42 2011/03/14 15:50:36 vanhu Exp $ */
/* Id: cfparse.y,v 1.66 2006/08/22 18:17:17 manubsd Exp */
@@ -145,6 +145,7 @@
static struct secprotospec *newspspec __P((void));
static void insspspec __P((struct remoteconf *, struct secprotospec *));
+void dupspspec_list __P((struct remoteconf *dst, struct remoteconf *src));
void flushspspec __P((struct remoteconf *));
static void adminsock_conf __P((vchar_t *, vchar_t *, vchar_t *, int));
@@ -1629,7 +1630,7 @@
return -1;
}
- new = duprmconf(from);
+ new = duprmconf_shallow(from);
if (new == NULL) {
yyerror("failed to duplicate remoteconf from \"%s\".",
$4->v);
@@ -1674,13 +1675,14 @@
return -1;
}
- new = duprmconf(from);
+ new = duprmconf_shallow(from);
if (new == NULL) {
yyerror("failed to duplicate remoteconf from %s.",
saddr2str($4));
return -1;
}
+ racoon_free($4);
new->remote = $2;
cur_rmconf = new;
}
@@ -1727,11 +1729,19 @@
return -1;
}
}
-
+
+ if (duprmconf_finish(cur_rmconf))
+ return -1;
+
+#if 0
+ /* this pointer copy will never happen, because duprmconf_shallow
+ * already copied all pointers.
+ */
if (cur_rmconf->spspec == NULL &&
cur_rmconf->inherited_from != NULL) {
cur_rmconf->spspec = cur_rmconf->inherited_from->spspec;
}
+#endif
if (set_isakmp_proposal(cur_rmconf) != 0)
return -1;
@@ -2415,6 +2425,62 @@
rmconf->spspec = spspec;
}
+static struct secprotospec *
+dupspspec(spspec)
+ struct secprotospec *spspec;
+{
+ struct secprotospec *new;
+
+ new = newspspec();
+ if (new == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "dupspspec: malloc failed\n");
+ return NULL;
+ }
+ memcpy(new, spspec, sizeof(*new));
+
+ if (spspec->gssid) {
+ new->gssid = racoon_strdup(spspec->gssid);
+ STRDUP_FATAL(new->gssid);
+ }
+ if (spspec->remote) {
+ new->remote = racoon_malloc(sizeof(*new->remote));
+ if (new->remote == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "dupspspec: malloc failed (remote)\n");
+ return NULL;
+ }
+ memcpy(new->remote, spspec->remote, sizeof(*new->remote));
+ }
+
+ return new;
+}
+
+/*
+ * copy the whole list
+ */
+void
+dupspspec_list(dst, src)
+ struct remoteconf *dst, *src;
+{
+ struct secprotospec *p, *new, *last;
+
+ for(p = src->spspec, last = NULL; p; p = p->next, last = new) {
+ new = dupspspec(p);
+ if (new == NULL)
+ exit(1);
+
+ new->prev = last;
+ new->next = NULL; /* not necessary but clean */
+
+ if (last)
+ last->next = new;
+ else /* first element */
+ dst->spspec = new;
+
+ }
+}
+
/*
* delete the whole list
*/
@@ -2430,8 +2496,13 @@
if (p->next != NULL)
p->next->prev = NULL; /* not necessary but clean */
- racoon_free(p);
+ if (p->gssid)
+ racoon_free(p->gssid);
+ if (p->remote)
+ racoon_free(p->remote);
+ racoon_free(p);
}
+ rmconf->spspec = NULL;
}
/* set final acceptable proposal */
diff -r d55df4485566 -r 4a0d4e94e838 crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c Mon Mar 14 15:21:22 2011 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.c Mon Mar 14 15:50:36 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: isakmp_xauth.c,v 1.21 2010/09/27 11:57:59 vanhu Exp $ */
+/* $NetBSD: isakmp_xauth.c,v 1.22 2011/03/14 15:50:36 vanhu Exp $ */
/* Id: isakmp_xauth.c,v 1.38 2006/08/22 18:17:17 manubsd Exp */
@@ -1764,3 +1764,42 @@
return;
}
+
+struct xauth_rmconf *
+xauth_rmconf_dup(xauth_rmconf)
+ struct xauth_rmconf *xauth_rmconf;
+{
+ struct xauth_rmconf *new;
+
+ if (xauth_rmconf != NULL) {
+ new = racoon_malloc(sizeof(*new));
+ if (new == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "xauth_rmconf_dup: malloc failed\n");
+ return NULL;
+ }
+
+ memcpy(new, xauth_rmconf, sizeof(*new));
+
+ if (xauth_rmconf->login != NULL) {
+ new->login = vdup(xauth_rmconf->login);
+ if (new->login == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "xauth_rmconf_dup: malloc failed (login)\n");
+ return NULL;
+ }
+ }
+ if (xauth_rmconf->pass != NULL) {
+ new->pass = vdup(xauth_rmconf->pass);
+ if (new->pass == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "xauth_rmconf_dup: malloc failed (password)\n");
+ return NULL;
+ }
+ }
+
+ return new;
+ }
+
+ return NULL;
+}
diff -r d55df4485566 -r 4a0d4e94e838 crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h
--- a/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h Mon Mar 14 15:21:22 2011 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/isakmp_xauth.h Mon Mar 14 15:50:36 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: isakmp_xauth.h,v 1.6 2008/09/19 11:01:08 tteras Exp $ */
+/* $NetBSD: isakmp_xauth.h,v 1.7 2011/03/14 15:50:36 vanhu Exp $ */
/* $KAME$ */
@@ -114,6 +114,7 @@
int xauth_reply(struct ph1handle *, int, int, int);
int xauth_rmconf_used(struct xauth_rmconf **);
void xauth_rmconf_delete(struct xauth_rmconf **);
+struct xauth_rmconf * xauth_rmconf_dup(struct xauth_rmconf *);
#ifdef HAVE_LIBPAM
int xauth_login_pam(int, struct sockaddr *, char *, char *);
diff -r d55df4485566 -r 4a0d4e94e838 crypto/dist/ipsec-tools/src/racoon/remoteconf.c
--- a/crypto/dist/ipsec-tools/src/racoon/remoteconf.c Mon Mar 14 15:21:22 2011 +0000
+++ b/crypto/dist/ipsec-tools/src/racoon/remoteconf.c Mon Mar 14 15:50:36 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: remoteconf.c,v 1.25 2011/03/02 15:04:01 vanhu Exp $ */
+/* $NetBSD: remoteconf.c,v 1.26 2011/03/14 15:50:36 vanhu Exp $ */
/* Id: remoteconf.c,v 1.38 2006/05/06 15:52:44 manubsd Exp */
@@ -570,8 +570,25 @@
return NULL;
}
+void *
+duprsa(entry, arg)
+ void *entry;
+ void *arg;
+{
+ struct rsa_key *new;
+
+ new = rsa_key_dup((struct rsa_key *)entry);
+ if (new == NULL)
+ return (void *) -1;
+ genlist_append(arg, new);
+
+ /* keep genlist_foreach going */
+ return NULL;
+}
+
+/* Creates shallow copy of a remote config. Used for "inherit" keyword. */
struct remoteconf *
-duprmconf (rmconf)
+duprmconf_shallow (rmconf)
struct remoteconf *rmconf;
{
struct remoteconf *new;
@@ -585,31 +602,113 @@
new->name = NULL;
new->inherited_from = rmconf;
- /* duplicate dynamic structures */
- if (new->etypes)
+ new->proposal = NULL; /* will be filled by set_isakmp_proposal() */
+
+ return new;
+}
+
+/* Copies pointer structures of an inherited remote config.
+ * Used by "inherit" mechanism in a two step copy method, necessary to
+ * prevent both double free() and memory leak during config reload.
+ */
+int
+duprmconf_finish (new)
+ struct remoteconf *new;
+{
+ struct remoteconf *rmconf;
+ int i;
+
+ if (new->inherited_from == NULL)
+ return 0; /* nothing todo, no inheritance */
+
+ rmconf = new->inherited_from;
+
+ /* duplicate dynamic structures unless value overridden */
+ if (new->etypes != NULL && new->etypes == rmconf->etypes)
new->etypes = dupetypes(new->etypes);
- new->idvl_p = genlist_init();
- genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p);
+ if (new->idvl_p == rmconf->idvl_p) {
+ new->idvl_p = genlist_init();
+ genlist_foreach(rmconf->idvl_p, dupidvl, new->idvl_p);
+ }
- /* duplicate strings */
- if (new->mycertfile != NULL) {
+ if (new->rsa_private == rmconf->rsa_private) {
+ new->rsa_private = genlist_init();
+ genlist_foreach(rmconf->rsa_private, duprsa, new->rsa_private);
+ }
+ if (new->rsa_public == rmconf->rsa_public) {
+ new->rsa_public = genlist_init();
+ genlist_foreach(rmconf->rsa_public, duprsa, new->rsa_public);
+ }
+ if (new->remote != NULL && new->remote == rmconf->remote) {
+ new->remote = racoon_malloc(sizeof(*new->remote));
+ if (new->remote == NULL) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "duprmconf_finish: malloc failed (remote)\n");
+ exit(1);
+ }
Home |
Main Index |
Thread Index |
Old Index