[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