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