[ovs-dev] [PATCH v2 3/3] ossfuzz: ODP test harness

bshastry at sect.tu-berlin.de bshastry at sect.tu-berlin.de
Tue Oct 2 23:16:00 UTC 2018


From: Bhargava Shastry <bshastry at sect.tu-berlin.de>

This commit adds the ODP parser test harness for
 oss-fuzz.

Signed-off-by: Bhargava Shastry <bshastry at sect.tu-berlin.de>
---
 tests/oss-fuzz/odp_target.c | 147 ++++++++++++++++++++++++++++++++++++
 1 file changed, 147 insertions(+)
 create mode 100644 tests/oss-fuzz/odp_target.c

diff --git a/tests/oss-fuzz/odp_target.c b/tests/oss-fuzz/odp_target.c
new file mode 100644
index 000000000..93231bde3
--- /dev/null
+++ b/tests/oss-fuzz/odp_target.c
@@ -0,0 +1,147 @@
+#include <config.h>
+#include "fuzzer.h"
+#undef NDEBUG
+#include "odp-util.h"
+#include <stdio.h>
+#include "openvswitch/dynamic-string.h"
+#include "flow.h"
+#include "openvswitch/match.h"
+#include "openvswitch/ofpbuf.h"
+#include "util.h"
+#include "openvswitch/ofp-flow.h"
+#include "openvswitch/vlog.h"
+
+static int
+parse_keys(bool wc_keys, const char *in)
+{
+    int exit_code = 0;
+
+    enum odp_key_fitness fitness;
+    struct ofpbuf odp_key;
+    struct ofpbuf odp_mask;
+    struct flow flow;
+    struct ds out;
+    int error;
+
+    /* Convert string to OVS DP key. */
+    ofpbuf_init(&odp_key, 0);
+    ofpbuf_init(&odp_mask, 0);
+    error = odp_flow_from_string(in, NULL,
+                                 &odp_key, &odp_mask);
+    if (error) {
+        printf("odp_flow_from_string: error\n");
+        goto next;
+    }
+
+    if (!wc_keys) {
+        struct odp_flow_key_parms odp_parms = {
+            .flow = &flow,
+            .support = {
+                .recirc = true,
+                .ct_state = true,
+                .ct_zone = true,
+                .ct_mark = true,
+                .ct_label = true,
+                .max_vlan_headers = SIZE_MAX,
+            },
+        };
+
+        /* Convert odp_key to flow. */
+        fitness = odp_flow_key_to_flow(odp_key.data, odp_key.size, &flow);
+        switch (fitness) {
+            case ODP_FIT_PERFECT:
+                break;
+
+            case ODP_FIT_TOO_LITTLE:
+                printf("ODP_FIT_TOO_LITTLE: ");
+                break;
+
+            case ODP_FIT_TOO_MUCH:
+                printf("ODP_FIT_TOO_MUCH: ");
+                break;
+
+            case ODP_FIT_ERROR:
+                printf("odp_flow_key_to_flow: error\n");
+                goto next;
+        }
+        /* Convert cls_rule back to odp_key. */
+        ofpbuf_uninit(&odp_key);
+        ofpbuf_init(&odp_key, 0);
+        odp_flow_key_from_flow(&odp_parms, &odp_key);
+
+        if (odp_key.size > ODPUTIL_FLOW_KEY_BYTES) {
+            printf ("too long: %"PRIu32" > %d\n",
+                    odp_key.size, ODPUTIL_FLOW_KEY_BYTES);
+            exit_code = 1;
+        }
+    }
+
+    /* Convert odp_key to string. */
+    ds_init(&out);
+    if (wc_keys) {
+        odp_flow_format(odp_key.data, odp_key.size,
+                        odp_mask.data, odp_mask.size, NULL, &out, false);
+    } else {
+        odp_flow_key_format(odp_key.data, odp_key.size, &out);
+    }
+    puts(ds_cstr(&out));
+    ds_destroy(&out);
+
+next:
+    ofpbuf_uninit(&odp_key);
+    ofpbuf_uninit(&odp_mask);
+
+    return exit_code;
+}
+
+static int
+parse_actions(const char *in)
+{
+    struct ofpbuf odp_actions;
+    struct ds out;
+    int error;
+
+    /* Convert string to OVS DP actions. */
+    ofpbuf_init(&odp_actions, 0);
+    error = odp_actions_from_string(in, NULL, &odp_actions);
+    if (error) {
+        printf("odp_actions_from_string: error\n");
+        goto next;
+    }
+
+    /* Convert odp_actions back to string. */
+    ds_init(&out);
+    format_odp_actions(&out, odp_actions.data, odp_actions.size, NULL);
+    puts(ds_cstr(&out));
+    ds_destroy(&out);
+
+next:
+    ofpbuf_uninit(&odp_actions);
+    return 0;
+}
+
+int
+LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    /* Bail out if we cannot construct at least a 1 char string. */
+    const char *input = (const char *) data;
+    if (size < 2 || input[size - 1] != '\0' || strchr(input, '\n')) {
+        return 0;
+    }
+
+    /* Disable logging to avoid write to disk. */
+    static bool isInit = false;
+    if (!isInit) {
+        vlog_set_verbosity("off");
+        isInit = true;
+    }
+
+    /* Parse keys and wc keys. */
+    parse_keys(false, input);
+    parse_keys(true, input);
+
+    /* Parse actions. */
+    parse_actions(input);
+
+    return 0;
+}
-- 
2.17.1



More information about the dev mailing list