Code

ovs_stats plugin: Fix null dereference of "port".
authorFlorian Forster <octo@collectd.org>
Fri, 17 Nov 2017 16:26:28 +0000 (17:26 +0100)
committerFlorian Forster <octo@collectd.org>
Fri, 17 Nov 2017 16:28:37 +0000 (17:28 +0100)
This also refactors the ovs_stats_update_iface_ext_ids() function to
handle errors, instead of many nested if blocks.

CID: 179231

src/ovs_stats.c

index e7859da20eff651384316f28b80abac7dfd9fb53..e2103744c955ef2f493e03f407dc45c50e214a72 100644 (file)
@@ -583,56 +583,57 @@ static int ovs_stats_update_iface_ext_ids(port_list_t *port, yajl_val ext_ids) {
 
 /* Get interface statistic and external_ids */
 static int ovs_stats_update_iface(yajl_val iface) {
-  yajl_val row;
-  port_list_t *port = NULL;
-  if (iface && YAJL_IS_OBJECT(iface)) {
-    row = ovs_utils_get_value_by_key(iface, "new");
-    if (row && YAJL_IS_OBJECT(row)) {
-      yajl_val iface_name = ovs_utils_get_value_by_key(row, "name");
-      yajl_val iface_stats = ovs_utils_get_value_by_key(row, "statistics");
-      yajl_val iface_ext_ids = ovs_utils_get_value_by_key(row, "external_ids");
-      yajl_val iface_uuid = ovs_utils_get_value_by_key(row, "_uuid");
-      if (iface_name && YAJL_IS_STRING(iface_name)) {
-        port = ovs_stats_get_port_by_name(YAJL_GET_STRING(iface_name));
-        if (port == NULL)
-          return 0;
-      }
-      /*
-       * {
-            "statistics": [
-              "map",
-              [
-                [
-                  "collisions",
-                  0
-                ],
-                . . .
-                [
-                  "tx_packets",
-                  0
-                ]
-              ]
-            ]
-          }
-       Check that statistics is an array with 2 elements
-       */
-      if (iface_stats && YAJL_IS_ARRAY(iface_stats) &&
-          YAJL_GET_ARRAY(iface_stats)->len == 2)
-        ovs_stats_update_iface_stats(port,
-                                     YAJL_GET_ARRAY(iface_stats)->values[1]);
-      if (iface_ext_ids && YAJL_IS_ARRAY(iface_ext_ids))
-        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)
-        sstrncpy(port->iface_uuid,
-                 YAJL_GET_STRING(YAJL_GET_ARRAY(iface_uuid)->values[1]),
-                 sizeof(port->iface_uuid));
-    }
-  } else {
-    ERROR("Incorrect JSON Port data");
+  if (!iface || !YAJL_IS_OBJECT(iface)) {
+    ERROR("ovs_stats plugin: incorrect JSON port data");
     return -1;
   }
+
+  yajl_val row = ovs_utils_get_value_by_key(iface, "new");
+  if (!row || !YAJL_IS_OBJECT(row))
+    return 0;
+
+  yajl_val iface_name = ovs_utils_get_value_by_key(row, "name");
+  if (!iface_name || !YAJL_IS_STRING(iface_name))
+    return 0;
+
+  port_list_t *port = ovs_stats_get_port_by_name(YAJL_GET_STRING(iface_name));
+  if (port == NULL)
+    return 0;
+
+  yajl_val iface_stats = ovs_utils_get_value_by_key(row, "statistics");
+  yajl_val iface_ext_ids = ovs_utils_get_value_by_key(row, "external_ids");
+  yajl_val iface_uuid = ovs_utils_get_value_by_key(row, "_uuid");
+  /*
+   * {
+        "statistics": [
+          "map",
+          [
+            [
+              "collisions",
+              0
+            ],
+            . . .
+            [
+              "tx_packets",
+              0
+            ]
+          ]
+        ]
+      }
+   Check that statistics is an array with 2 elements
+   */
+  if (iface_stats && YAJL_IS_ARRAY(iface_stats) &&
+      YAJL_GET_ARRAY(iface_stats)->len == 2)
+    ovs_stats_update_iface_stats(port, YAJL_GET_ARRAY(iface_stats)->values[1]);
+  if (iface_ext_ids && YAJL_IS_ARRAY(iface_ext_ids))
+    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)
+    sstrncpy(port->iface_uuid,
+             YAJL_GET_STRING(YAJL_GET_ARRAY(iface_uuid)->values[1]),
+             sizeof(port->iface_uuid));
+
   return 0;
 }