[ovs-dev] [ovs-security] RFC: Adding OvS to fuzzer test suite

Bhargava Shastry bshastry at sec.t-labs.tu-berlin.de
Fri Sep 1 15:31:33 UTC 2017


Dear all,

I suppose the following are the agenda points for adding OvS to OSS-Fuzz.

1. [Easy] Write Docker file for getting OvS to build. Feel this should
be easy as I don't see any non-default dependencies

2. [Easy] Add a project.yaml that documents project metadata such as
contact persons, project homepage etc.

3. [Medium] Add a build script to get OSS tests to compile.

4. [Medium] Add relevant OSS tests to OvS trunk/branch. These tests
should ideally cover 100% of the codebase but we most likely start with
a handful I guess. The tests that uncovered CVEs in OvS over previous
months is a good starting point?

dev at OvS is best equipped to handle (1) and (2). As for (3) and (4), you
could use my commit here [1] as a starting point. Like I said, I am
happy to help write more tests with oversight from dev at OvS/KCC. Let me
know how this plan sounds. BTW, here is a reference OSS-Fuzz template
from Wireshark [2] that you could use I guess.

[1]:
https://github.com/bshastry/fuzzer-test-suite/tree/master/openvswitch-2.7.2
[2]: https://github.com/google/oss-fuzz/tree/master/projects/wireshark

Regards,
Bhargava

On 09/01/2017 03:16 PM, Bhargava Shastry wrote:
> Here's another test harness for connection tracking code. This is over
> 30x slower than the other two test cases (speed=2700 exec/s vs 85000
> exec/s for the other two test cases). Just to clarify, I am not testing
> on trunk (as I incorrectly claimed earlier). Rather, I am testing the
> latest release v2.7.2.
> 
> ====== target-ct.c =====
> 
> #include "flow.h"
> #include "dp-packet.h"
> #include "conntrack.h"
> 
> int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
> {
>     struct conntrack ct;
>     conntrack_init(&ct);
>     struct dp_packet_batch pkt_batch;
>     struct flow flow;
>     struct dp_packet pkt;
>     dp_packet_use_const(&pkt, data, size);
> 
>     packet_batch_init_packet(&pkt_batch, &pkt);
>     flow_extract(pkt_batch.packets[0], &flow);
> 
>     conntrack_execute(&ct, &pkt_batch, flow.dl_type, true, 0, NULL,
> NULL, NULL);
> 
>     conntrack_destroy(&ct);
>     return 0;
> }
> 
> ====== target-ct.c =====
> 
> On 09/01/2017 02:04 PM, Bhargava Shastry wrote:
>> Here is another test harness for fuzzing Openflow packet parsing on
>> trunk. Feedback welcome!
>>
>> ===== target-ofp.c =====
>>
>> #include "flow.h"
>> #include "dp-packet.h"
>> #include "pcap-file.h"
>> #include "odp-util.h"
>>
>> static bool
>> is_openflow_port(ovs_be16 port_)
>> {
>>     uint16_t port = ntohs(port_);
>>     return port == OFP_PORT || port == OFP_OLD_PORT;
>> }
>>
>> int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
>> {
>>     struct dp_packet packet;
>>     struct flow flow;
>>     struct tcp_reader *reader;
>>     dp_packet_use_const(&packet, data, size);
>>
>>     pkt_metadata_init(&packet.md, ODPP_NONE);
>>     flow_extract(&packet, &flow);
>>     if (flow.dl_type == htons(ETH_TYPE_IP)
>>         && flow.nw_proto == IPPROTO_TCP
>>         && (is_openflow_port(flow.tp_src) ||
>>             is_openflow_port(flow.tp_dst))) {
>>             struct dp_packet *payload = tcp_reader_run(reader, &flow,
>> &packet);
>>             if (payload) {
>>                 while (dp_packet_size(payload) >= sizeof(struct
>> ofp_header)) {
>>                     const struct ofp_header *oh;
>>                     void *pdata = dp_packet_data(payload);
>>                     int length;
>>
>>                     /* Align OpenFlow on 8-byte boundary for safe access. */
>>                     dp_packet_shift(payload, -((intptr_t) pdata & 7));
>>
>>                     oh = dp_packet_data(payload);
>>                     length = ntohs(oh->length);
>>                     if (dp_packet_size(payload) < length) {
>>                         break;
>>                     }
>>
>>                    ofp_print(stdout, dp_packet_data(payload), length, 4);
>>                    dp_packet_pull(payload, length);
>>                 }
>>             }
>>             tcp_reader_close(reader);
>>         }
>>     return 0;
>> }
>>
>> ===== target-ofp.c =====
>>
>> P.S. Fuzzing for ~10h didn't result in anything. Test coverage saturates
>> early but that's possibly because this isn't doing any deep processing.
>>
>> Regards,
>> Bhargava
>>
>> On 08/31/2017 11:18 PM, Kostya Serebryany wrote:
>>> For the version Bhargava is testing I guess this reads as
>>> int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
>>> {
>>>   struct ofpbuf packet;       
>>>   ofpbuf_use_const(&packet, data, size);                                
>>>                                        
>>>   struct flow flow;                                                    
>>>                                         
>>>   flow_extract(&packet, NULL, &flow);                                  
>>>                                         
>>>   return 0;
>>> }
>>>
>>> Looks great, and runs fast. 
>>>
>>>
>>> On Thu, Aug 31, 2017 at 2:05 PM, Bhargava Shastry
>>> <bshastry at sec.t-labs.tu-berlin.de
>>> <mailto:bshastry at sec.t-labs.tu-berlin.de>> wrote:
>>>
>>>     Hi,
>>>
>>>     > I didn't look at the actual code before, but now that I have, I don't
>>>     > understand at all why it was doing file I/O just to write a packet to
>>>     > disk and then read it back.
>>>
>>>     Sorry, this was due to my ignorance. I was not aware of something like
>>>     dp_packet_use_const(). This should speed things up. I am working on it.
>>>
>>>     >
>>>     > Here is a more natural way to do this:
>>>     >
>>>     > int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
>>>     > {
>>>     >     struct dp_packet packet;
>>>     >     dp_packet_use_const(&packet, data, size);
>>>     >
>>>     >     struct flow flow;
>>>     >     flow_extract(&packet, &flow);
>>>     >
>>>     >     return 0;
>>>     > }
>>>     >
>>>
>>>     --
>>>     Bhargava Shastry <bshastry at sec.t-labs.tu-berlin.de
>>>     <mailto:bshastry at sec.t-labs.tu-berlin.de>>
>>>     Security in Telecommunications
>>>     TU Berlin / Telekom Innovation Laboratories
>>>     Ernst-Reuter-Platz 7, Sekr TEL 17 / D - 10587 Berlin, Germany
>>>     phone: +49 30 8353 58235 <tel:%2B49%2030%208353%2058235>
>>>     Keybase: https://keybase.io/bshastry
>>>
>>>
>>
> 

-- 
Bhargava Shastry <bshastry at sec.t-labs.tu-berlin.de>
Security in Telecommunications
TU Berlin / Telekom Innovation Laboratories
Ernst-Reuter-Platz 7, Sekr TEL 17 / D - 10587 Berlin, Germany
phone: +49 30 8353 58235
Keybase: https://keybase.io/bshastry



More information about the dev mailing list