[PATCH] irmd: Fix memleak when failing to list ipcps

  • From: Dimitri Staessens <dimitri.staessens@xxxxxxxx>
  • To: ouroboros@xxxxxxxxxxxxx
  • Date: Thu, 22 Mar 2018 16:13:19 +0100

The list_ipcps call had a memleak in the failure case. Also fixes a
compiler warning for a possible uninitialized variable and renumbers
the gpb ipcpd message fields.

Signed-off-by: Dimitri Staessens <dimitri.staessens@xxxxxxxx>
---
 include/ouroboros/ipcp.h           |  3 ++-
 src/irmd/main.c                    | 24 +++++++++---------------
 src/lib/ipcpd_messages.proto       | 20 ++++++++++----------
 src/tools/irm/irm_ipcp_bootstrap.c |  2 +-
 4 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/include/ouroboros/ipcp.h b/include/ouroboros/ipcp.h
index dc2c37f..c7013f0 100644
--- a/include/ouroboros/ipcp.h
+++ b/include/ouroboros/ipcp.h
@@ -39,7 +39,8 @@ enum ipcp_type {
         IPCP_RAPTOR,
         IPCP_ETH_LLC,
         IPCP_ETH_DIX,
-        IPCP_UDP
+        IPCP_UDP,
+        IPCP_INVALID
 };
 
 /* Normal IPCP policies */
diff --git a/src/irmd/main.c b/src/irmd/main.c
index e90cbbc..ad121f9 100644
--- a/src/irmd/main.c
+++ b/src/irmd/main.c
@@ -867,7 +867,6 @@ static ssize_t list_ipcps(ipcp_info_msg_t *** ipcps,
         pthread_rwlock_rdlock(&irmd.reg_lock);
 
         *n_ipcps = irmd.n_ipcps;
-
         if (*n_ipcps == 0) {
                 pthread_rwlock_unlock(&irmd.reg_lock);
                 return 0;
@@ -883,18 +882,20 @@ static ssize_t list_ipcps(ipcp_info_msg_t *** ipcps,
         list_for_each(p, &irmd.ipcps) {
                 struct ipcp_entry * e = list_entry(p, struct ipcp_entry, next);
                 (*ipcps)[i] = malloc(sizeof(***ipcps));
-                if ((*ipcps)[i] == NULL)
-                        goto fail_malloc;
+                if ((*ipcps)[i] == NULL) {
+                        --i;
+                        goto fail;
+                }
 
                 ipcp_info_msg__init((*ipcps)[i]);
                 (*ipcps)[i]->name = strdup(e->name);
                 if ((*ipcps)[i]->name == NULL)
-                        goto fail_mem;
+                        goto fail;
 
                 (*ipcps)[i]->layer = strdup(
                         e->layer != NULL ? e->layer : "Not enrolled");
                 if ((*ipcps)[i]->layer == NULL)
-                        goto fail_mem;
+                        goto fail;
 
                 (*ipcps)[i]->pid    = e->pid;
                 (*ipcps)[i++]->type = e->type;
@@ -904,22 +905,15 @@ static ssize_t list_ipcps(ipcp_info_msg_t *** ipcps,
 
         return 0;
 
- fail_mem:
-        while (i > 0) {
+ fail:
+        while (i >= 0) {
                 free((*ipcps)[i]->layer);
                 free((*ipcps)[i]->name);
-                free(*ipcps[--i]);
+                free(*ipcps[i--]);
         }
         free(*ipcps);
         *n_ipcps = 0;
         return -ENOMEM;
-
- fail_malloc:
-        while (i > 0)
-                free(*ipcps[--i]);
-        free(*ipcps);
-        *n_ipcps = 0;
-        return -ENOMEM;
 }
 
 static int irm_update_name(const char * name)
diff --git a/src/lib/ipcpd_messages.proto b/src/lib/ipcpd_messages.proto
index de78d80..454af0d 100644
--- a/src/lib/ipcpd_messages.proto
+++ b/src/lib/ipcpd_messages.proto
@@ -40,14 +40,14 @@ enum ipcp_msg_code {
 
 message ipcp_msg {
         required ipcp_msg_code code        =  1;
-        optional bytes hash                =  3;
-        optional int32 port_id             =  4;
-        optional string dst                =  5;
-        optional uint32 qoscube            =  6;
-        optional ipcp_config_msg conf      =  7;
-        optional int32 pid                 =  8;
-        optional layer_info_msg layer_info =  9;
-        optional int32 response            = 10;
-        optional string comp               = 11;
-        optional int32 result              = 12;
+        optional bytes hash                =  2;
+        optional int32 port_id             =  3;
+        optional string dst                =  4;
+        optional uint32 qoscube            =  5;
+        optional ipcp_config_msg conf      =  6;
+        optional int32 pid                 =  7;
+        optional layer_info_msg layer_info =  8;
+        optional int32 response            =  9;
+        optional string comp               = 10;
+        optional int32 result              = 11;
 };
diff --git a/src/tools/irm/irm_ipcp_bootstrap.c 
b/src/tools/irm/irm_ipcp_bootstrap.c
index 07dcea0..9cf6514 100644
--- a/src/tools/irm/irm_ipcp_bootstrap.c
+++ b/src/tools/irm/irm_ipcp_bootstrap.c
@@ -147,7 +147,7 @@ int do_bootstrap_ipcp(int     argc,
         uint32_t           ip_addr        = 0;
         uint32_t           dns_addr       = DEFAULT_DDNS;
         char *             ipcp_type      = NULL;
-        enum ipcp_type     type;
+        enum ipcp_type     type           = IPCP_INVALID;
         char *             layer          = NULL;
         char *             dev            = NULL;
         uint16_t           ethertype      = DEFAULT_ETHERTYPE;
-- 
2.16.2


Other related posts:

  • » [PATCH] irmd: Fix memleak when failing to list ipcps - Dimitri Staessens