Merge pull request #2731 from elfiesmelfie/ovs_fixes
authorRuben Kerkhof <ruben@rubenkerkhof.com>
Sat, 31 Mar 2018 09:17:08 +0000 (11:17 +0200)
committerGitHub <noreply@github.com>
Sat, 31 Mar 2018 09:17:08 +0000 (11:17 +0200)
Ovs Fixes

src/ovs_events.c
src/ovs_stats.c
src/utils_ovs.c

index bf457fd..ef59b4c 100644 (file)
@@ -404,14 +404,14 @@ static int ovs_events_get_iface_info(yajl_val jobject,
   if (!YAJL_IS_OBJECT(jobject))
     return -1;
 
-  /* zero the interface info structure */
-  memset(ifinfo, 0, sizeof(*ifinfo));
-
   /* try to find external_ids, name and link_state fields */
   jexternal_ids = ovs_utils_get_value_by_key(jobject, "external_ids");
   if (jexternal_ids == NULL || ifinfo == NULL)
     return -1;
 
+  /* zero the interface info structure */
+  memset(ifinfo, 0, sizeof(*ifinfo));
+
   /* get iface-id from external_ids field */
   jvalue = ovs_utils_get_map_value(jexternal_ids, "iface-id");
   if (jvalue != NULL && YAJL_IS_STRING(jvalue))
index e027845..f513e72 100644 (file)
@@ -244,6 +244,9 @@ static port_list_t *ovs_stats_get_port_by_name(const char *name) {
 /* Create or get port by port uuid */
 static port_list_t *ovs_stats_new_port(bridge_list_t *bridge,
                                        const char *uuid) {
+  if (uuid == NULL)
+    return NULL;
+
   port_list_t *port = ovs_stats_get_port(uuid);
 
   if (port == NULL) {
@@ -357,21 +360,33 @@ static int ovs_stats_update_bridge(yajl_val bridge) {
           yajl_val *array = YAJL_GET_ARRAY(br_ports)->values;
           size_t array_len = YAJL_GET_ARRAY(br_ports)->len;
           if (array != NULL && array_len > 0 && YAJL_IS_ARRAY(array[1])) {
-            yajl_val *ports_arr = YAJL_GET_ARRAY(array[1])->values;
-            size_t ports_num = YAJL_GET_ARRAY(array[1])->len;
-            for (size_t i = 0; i < ports_num && ports_arr != NULL; i++)
-              ovs_stats_new_port(
-                  br, YAJL_GET_STRING(ports_arr[i]->u.array.values[1]));
+            if (YAJL_GET_ARRAY(array[1]) == NULL)
+              goto failure;
+            else {
+              yajl_val *ports_arr = YAJL_GET_ARRAY(array[1])->values;
+              size_t ports_num = YAJL_GET_ARRAY(array[1])->len;
+              for (size_t i = 0; i < ports_num && ports_arr != NULL; i++) {
+                tmp = YAJL_GET_STRING(ports_arr[i]->u.array.values[1]);
+                if (tmp != NULL)
+                  ovs_stats_new_port(br, tmp);
+                else
+                  goto failure;
+              }
+            }
           }
         } else
           ovs_stats_new_port(br, YAJL_GET_STRING(br_ports->u.array.values[1]));
       }
     }
   } else {
-    ERROR("Incorrect JSON Bridge data");
-    return -1;
+    goto failure;
   }
+
   return 0;
+
+failure:
+  ERROR("Incorrect JSON Bridge data");
+  return -1;
 }
 
 /* Handle JSON with Bridge Table change event */
@@ -629,10 +644,15 @@ static int ovs_stats_update_iface(yajl_val iface) {
     ovs_stats_update_iface_ext_ids(port,
                                    YAJL_GET_ARRAY(iface_ext_ids)->values[1]);
   if (iface_uuid && YAJL_IS_ARRAY(iface_uuid) &&
-      YAJL_GET_ARRAY(iface_uuid)->len == 2)
+      YAJL_GET_ARRAY(iface_uuid)->len == 2 &&
+      YAJL_GET_STRING(YAJL_GET_ARRAY(iface_uuid)->values[1]) != NULL)
     sstrncpy(port->iface_uuid,
              YAJL_GET_STRING(YAJL_GET_ARRAY(iface_uuid)->values[1]),
              sizeof(port->iface_uuid));
+  else {
+    ERROR("ovs_stats plugin: incorrect JSON interface data");
+    return -1;
+  }
 
   return 0;
 }
@@ -833,6 +853,7 @@ static int ovs_stats_plugin_config(oconfig_item_t *ci) {
             char *br_name_dup = strdup(br_name);
             if (br_name_dup == NULL) {
               ERROR("%s: strdup() copy bridge name fail", plugin_name);
+              sfree(bridge);
               goto cleanup_fail;
             }
 
index 0ee05e0..ca63181 100644 (file)
@@ -1001,6 +1001,8 @@ static int ovs_db_poll_thread_destroy(ovs_db_t *pdb) {
 
 ovs_db_t *ovs_db_init(const char *node, const char *service,
                       const char *unix_path, ovs_db_callback_t *cb) {
+  int ret;
+
   /* sanity check */
   if (node == NULL || service == NULL || unix_path == NULL)
     return NULL;
@@ -1046,16 +1048,25 @@ ovs_db_t *ovs_db_init(const char *node, const char *service,
 
   /* init event thread */
   if (ovs_db_event_thread_init(pdb) < 0) {
-    ovs_db_destroy(pdb);
-    return NULL;
+    ret = ovs_db_destroy(pdb);
+    if (ret > 0)
+      goto failure;
   }
 
   /* init polling thread */
   if (ovs_db_poll_thread_init(pdb) < 0) {
-    ovs_db_destroy(pdb);
-    return NULL;
+    ret = ovs_db_destroy(pdb);
+    if (ret > 0) {
+      ovs_db_event_thread_data_destroy(pdb);
+      goto failure;
+    }
   }
   return pdb;
+
+failure:
+  pthread_mutex_destroy(&pdb->mutex);
+  sfree(pdb);
+  return NULL;
 }
 
 int ovs_db_send_request(ovs_db_t *pdb, const char *method, const char *params,
@@ -1265,7 +1276,7 @@ int ovs_db_destroy(ovs_db_t *pdb) {
   /* try to lock the structure before releasing */
   if ((ret = pthread_mutex_lock(&pdb->mutex))) {
     OVS_ERROR("pthread_mutex_lock() DB mutex lock failed (%d)", ret);
-    return -1;
+    return ret;
   }
 
   /* stop poll thread and destroy thread's private data */
@@ -1364,15 +1375,18 @@ yajl_val ovs_utils_get_map_value(yajl_val jval, const char *key) {
 
   /* check first element of the array */
   str_val = YAJL_GET_STRING(array_values[0]);
-  if (strcmp("map", str_val) != 0)
+  if (str_val == NULL || strcmp("map", str_val) != 0)
     return NULL;
 
   /* try to find map value by map key */
+  if (YAJL_GET_ARRAY(array_values[1]) == NULL)
+    return NULL;
+
   map_len = YAJL_GET_ARRAY(array_values[1])->len;
   map_values = YAJL_GET_ARRAY(array_values[1])->values;
   for (size_t i = 0; i < map_len; i++) {
     /* check YAJL array */
-    if (!YAJL_IS_ARRAY(map_values[i]))
+    if (!YAJL_IS_ARRAY(map_values[i]) || YAJL_GET_ARRAY(map_values[i]) == NULL)
       break;
 
     /* check a database pair value (2-element, first one represents a key
@@ -1384,7 +1398,7 @@ yajl_val ovs_utils_get_map_value(yajl_val jval, const char *key) {
 
     /* return map value if given key equals map key */
     str_val = YAJL_GET_STRING(array_values[0]);
-    if (strcmp(key, str_val) == 0)
+    if (str_val != NULL && strcmp(key, str_val) == 0)
       return array_values[1];
   }
   return NULL;