Most of these were found with valgrind by repeatedly doing lxc_container_new
followed by lxc_container_put. Also free memory when config items are
re-parsed, as happens when lxcapi_set_config_item() is called. Refactored
path type config items to use a common underlying routine.

Signed-off-by: Dwight Engen <dwight.en...@oracle.com>
---
 src/lxc/conf.c         |    9 +++++
 src/lxc/confile.c      |   93 +++++++++++++++++++++--------------------------
 src/lxc/lxccontainer.c |   13 ++++---
 3 files changed, 59 insertions(+), 56 deletions(-)

diff --git a/src/lxc/conf.c b/src/lxc/conf.c
index fe574ac..5ff64f6 100644
--- a/src/lxc/conf.c
+++ b/src/lxc/conf.c
@@ -2396,6 +2396,7 @@ static void lxc_remove_nic(struct lxc_list *it)
                free(it2->elem);
                free(it2);
        }
+       free(netdev);
        free(it);
 }
 
@@ -2578,6 +2579,14 @@ void lxc_conf_free(struct lxc_conf *conf)
                free(conf->console.path);
        if (conf->rootfs.mount != default_rootfs_mount)
                free(conf->rootfs.mount);
+       if (conf->rootfs.path)
+               free(conf->rootfs.path);
+       if (conf->utsname)
+               free(conf->utsname);
+       if (conf->ttydir)
+               free(conf->ttydir);
+       if (conf->fstab)
+               free(conf->fstab);
        lxc_clear_config_network(conf);
 #if HAVE_APPARMOR
        if (conf->aa_profile)
diff --git a/src/lxc/confile.c b/src/lxc/confile.c
index cf1c891..bacad01 100644
--- a/src/lxc/confile.c
+++ b/src/lxc/confile.c
@@ -486,17 +486,21 @@ static int config_network_hwaddr(const char *key, char 
*value,
                                 struct lxc_conf *lxc_conf)
 {
        struct lxc_netdev *netdev;
+       char *hwaddr;
 
        netdev = network_netdev(key, value, &lxc_conf->network);
        if (!netdev)
                return -1;
 
-       netdev->hwaddr = strdup(value);
-       if (!netdev->hwaddr) {
+       hwaddr = strdup(value);
+       if (!hwaddr) {
                SYSERROR("failed to dup string '%s'", value);
                return -1;
        }
 
+       if (netdev->hwaddr)
+               free(netdev->hwaddr);
+       netdev->hwaddr = hwaddr;
        return 0;
 }
 
@@ -519,17 +523,21 @@ static int config_network_mtu(const char *key, char 
*value,
                              struct lxc_conf *lxc_conf)
 {
        struct lxc_netdev *netdev;
+       char *mtu;
 
        netdev = network_netdev(key, value, &lxc_conf->network);
        if (!netdev)
                return -1;
 
-       netdev->mtu = strdup(value);
-       if (!netdev->mtu) {
+       mtu = strdup(value);
+       if (!mtu) {
                SYSERROR("failed to dup string '%s'", value);
                return -1;
        }
 
+       if (netdev->mtu)
+               free(netdev->mtu);
+       netdev->mtu = mtu;
        return 0;
 }
 
@@ -785,6 +793,8 @@ static int config_seccomp(const char *key, char *value,
                return -1;
        }
 
+       if (lxc_conf->seccomp)
+               free(lxc_conf->seccomp);
        lxc_conf->seccomp = path;
 
        return 0;
@@ -857,6 +867,8 @@ static int config_ttydir(const char *key, char *value,
                return -1;
        }
 
+       if (lxc_conf->ttydir)
+               free(lxc_conf->ttydir);
        lxc_conf->ttydir = path;
 
        return 0;
@@ -875,6 +887,8 @@ static int config_aa_profile(const char *key, char *value, 
struct lxc_conf *lxc_
                return -1;
        }
 
+       if (lxc_conf->aa_profile)
+               free(lxc_conf->aa_profile);
        lxc_conf->aa_profile = path;
 
        return 0;
@@ -939,22 +953,33 @@ out:
        return -1;
 }
 
-static int config_fstab(const char *key, char *value, struct lxc_conf 
*lxc_conf)
+static int config_path_item(const char *key, const char *value,
+                           struct lxc_conf *lxc_conf, char **conf_item)
 {
+       char *valdup;
        if (strlen(value) >= MAXPATHLEN) {
                ERROR("%s path is too long", value);
                return -1;
        }
 
-       lxc_conf->fstab = strdup(value);
-       if (!lxc_conf->fstab) {
+       valdup = strdup(value);
+       if (!valdup) {
                SYSERROR("failed to duplicate string %s", value);
                return -1;
        }
+       if (*conf_item)
+               free(*conf_item);
+       *conf_item = valdup;
 
        return 0;
 }
 
+static int config_fstab(const char *key, const char *value,
+                       struct lxc_conf *lxc_conf)
+{
+       return config_path_item(key, value, lxc_conf, &lxc_conf->fstab);
+}
+
 static int config_mount(const char *key, char *value, struct lxc_conf 
*lxc_conf)
 {
        char *fstab_token = "lxc.mount";
@@ -994,7 +1019,7 @@ static int config_mount(const char *key, char *value, 
struct lxc_conf *lxc_conf)
 static int config_cap_drop(const char *key, char *value,
                           struct lxc_conf *lxc_conf)
 {
-       char *dropcaps, *sptr, *token;
+       char *dropcaps, *dropptr, *sptr, *token;
        struct lxc_list *droplist;
        int ret = -1;
 
@@ -1009,13 +1034,12 @@ static int config_cap_drop(const char *key, char *value,
 
        /* in case several capability drop is specified in a single line
         * split these caps in a single element for the list */
-       for (;;) {
-                token = strtok_r(dropcaps, " \t", &sptr);
+       for (dropptr = dropcaps;;dropptr = NULL) {
+                token = strtok_r(dropptr, " \t", &sptr);
                 if (!token) {
                        ret = 0;
                         break;
                }
-               dropcaps = NULL;
 
                droplist = malloc(sizeof(*droplist));
                if (!droplist) {
@@ -1023,10 +1047,6 @@ static int config_cap_drop(const char *key, char *value,
                        break;
                }
 
-               /* note - i do believe we're losing memory here,
-                  note that token is already pointing into dropcaps
-                  which is strdup'd.  we never free that bit.
-                */
                droplist->elem = strdup(token);
                if (!droplist->elem) {
                        SYSERROR("failed to dup '%s'", token);
@@ -1053,6 +1073,8 @@ static int config_console(const char *key, char *value,
                return -1;
        }
 
+       if (lxc_conf->console.path)
+               free(lxc_conf->console.path);
        lxc_conf->console.path = path;
 
        return 0;
@@ -1066,50 +1088,17 @@ static int config_includefile(const char *key, char 
*value,
 
 static int config_rootfs(const char *key, char *value, struct lxc_conf 
*lxc_conf)
 {
-       if (strlen(value) >= MAXPATHLEN) {
-               ERROR("%s path is too long", value);
-               return -1;
-       }
-
-       lxc_conf->rootfs.path = strdup(value);
-       if (!lxc_conf->rootfs.path) {
-               SYSERROR("failed to duplicate string %s", value);
-               return -1;
-       }
-
-       return 0;
+       return config_path_item(key, value, lxc_conf, &lxc_conf->rootfs.path);
 }
 
 static int config_rootfs_mount(const char *key, char *value, struct lxc_conf 
*lxc_conf)
 {
-       if (strlen(value) >= MAXPATHLEN) {
-               ERROR("%s path is too long", value);
-               return -1;
-       }
-
-       lxc_conf->rootfs.mount = strdup(value);
-       if (!lxc_conf->rootfs.mount) {
-               SYSERROR("failed to duplicate string '%s'", value);
-               return -1;
-       }
-
-       return 0;
+       return config_path_item(key, value, lxc_conf, &lxc_conf->rootfs.mount);
 }
 
 static int config_pivotdir(const char *key, char *value, struct lxc_conf 
*lxc_conf)
 {
-       if (strlen(value) >= MAXPATHLEN) {
-               ERROR("%s path is too long", value);
-               return -1;
-       }
-
-       lxc_conf->rootfs.pivot = strdup(value);
-       if (!lxc_conf->rootfs.pivot) {
-               SYSERROR("failed to duplicate string %s", value);
-               return -1;
-       }
-
-       return 0;
+       return config_path_item(key, value, lxc_conf, &lxc_conf->rootfs.pivot);
 }
 
 static int config_utsname(const char *key, char *value, struct lxc_conf 
*lxc_conf)
@@ -1129,6 +1118,8 @@ static int config_utsname(const char *key, char *value, 
struct lxc_conf *lxc_con
        }
 
        strcpy(utsname->nodename, value);
+       if (lxc_conf->utsname)
+               free(lxc_conf->utsname);
        lxc_conf->utsname = utsname;
 
        return 0;
diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c
index 37f5ed7..ac995a6 100644
--- a/src/lxc/lxccontainer.c
+++ b/src/lxc/lxccontainer.c
@@ -65,6 +65,10 @@ static void lxc_container_free(struct lxc_container *c)
                free(c->error_string);
                c->error_string = NULL;
        }
+       if (c->slock) {
+               sem_close(c->slock);
+               c->slock = NULL;
+       }
        if (c->privlock) {
                sem_destroy(c->privlock);
                free(c->privlock);
@@ -74,11 +78,10 @@ static void lxc_container_free(struct lxc_container *c)
                free(c->name);
                c->name = NULL;
        }
-       /*
-        * XXX TODO
-        * note, c->lxc_conf is going to have to be freed, but the fn
-        * to do that hasn't been written yet near as I can tell
-        */
+       if (c->lxc_conf) {
+               lxc_conf_free(c->lxc_conf);
+               c->lxc_conf = NULL;
+       }
        free(c);
 }
 
-- 
1.7.1


------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to