[ovs-dev] [PATCH] ossfuzz: Add new target for ODP parsing

Bhargava Shastry bshastry at sect.tu-berlin.de
Thu Oct 4 09:55:30 UTC 2018


Hi,

Sorry that I was vague about this. The bug manifests as follows:

There is a function in test-odp.c called "parse_filter" that looks like so:

```
1. static int
2. parse_filter(char *filter_parse)
3. {
4.     struct ds in;
5.     struct flow flow_filter;
6.     struct flow_wildcards wc_filter;
7.     char *error, *filter = NULL;

8.     vlog_set_levels_from_string_assert("odp_util:console:dbg");
9.     if (filter_parse && !strncmp(filter_parse, "filter=", 7)) {
10.       filter = xstrdup(filter_parse + 7);
11.       memset(&flow_filter, 0, sizeof(flow_filter));
12.       memset(&wc_filter, 0, sizeof(wc_filter));
13.       error = parse_ofp_exact_flow(&flow_filter, &wc_filter, NULL,
14.                                    filter, NULL);
15.       if (error) {
16.           ovs_fatal(0, "Failed to parse filter (%s)", error);
17.       }
18.       else {
19.           ovs_fatal(0, "No filter to parse.");
20.       }
```

My understanding of this function is as follows:
  - it takes a filter string and an ODP flow as string as inputs (ODP
string is fetched via stdin and hence not seen in the code above)
  - before dealing with the ODP string it invokes the
`parse_ofp_exact_flow` function passing the filter string as input
  - if there is an error in `parse_ofp_exact_flow`, the `parse_filter`
function aborts with a "Failed to parse filter" error printed to stdout.

Now, I experimented with several filter strings such as the following
(copied from odp.at)

const char *filters[num_filters] = {
    "filter=\'dl_type=0x1235\'",
    "filter=\'dl_vlan=99\'",
    "filter=\'dl_vlan=99,ip\'",
    "filter=\'ip,nw_src=35.8.2.199\'",
    "filter=\'ip,nw_dst=172.16.0.199\'",
    "filter=\'dl_type=0x0800,nw_src=35.8.2.199,nw_dst=172.16.0.199\'",
    "filter=\'icmp,nw_src=35.8.2.199\'",
    "filter=\'arp,arp_spa=1.2.3.5\'",
    "filter=\'tcp,tp_src=90\'",
    "filter=\'tcp6,tp_src=90\'"
};

For example, when we feed the filter string "filter=\'dl_vlan=99,ip\'"
to the function `parse_ofp_exact_flow` we get the following error:

```
unknown field `dl_van`
```

and aborts the test.

I don't know how `parse_ofp_exact_flow` is implemented so I don't know
what I am doing wrong. Any suggestions?

==== Test integration ====

My original idea was to integrate parse_filter as follows:

- Take one random filter string from the const char array above
- Feed this to a modified parse_filter function declaration like so

parse_filter(const char *filter, const char *input)

where
- filter is a randomly chosen filter string from the list above (see
filters[])
- input is the fuzzed input

A simple way to make selection random is to use the modulo operator like so
```
int
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
...
    /* Parse filter. */
    int idx = size % 10;
    parse_filter(filters[idx], input);
```

Does this make sense?

Thanks,
Bhargava


More information about the dev mailing list