Skip to content

Commit 6492f4a

Browse files
nathaniel-broughhathach
authored andcommitted
feat(fuzz): Adds net class fuzzer
1 parent 9cc93e6 commit 6492f4a

File tree

14 files changed

+824
-31
lines changed

14 files changed

+824
-31
lines changed

.github/workflows/build_fuzzers.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
fuzz_harness:
2020
- "device/cdc"
2121
- "device/msc"
22+
- "device/net"
2223

2324
steps:
2425
- name: Setup Python
@@ -28,6 +29,9 @@ jobs:
2829
uses: actions/checkout@v3
2930

3031
- name: Fetch deps
31-
run: sudo apt update && sudo apt install libc++abi-dev libc++-dev
32+
run: |
33+
sudo apt update && sudo apt install libc++abi-dev libc++-dev
34+
make CC=clang CXX=clang++ -C fuzz/${{ matrix.fuzz_harness }} get-deps
35+
3236
- name: Build Fuzzer
3337
run: make CC=clang CXX=clang++ -C fuzz/${{ matrix.fuzz_harness }}

fuzz/dcd_fuzz.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,13 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer,
172172
std::copy(temp.begin(), temp.end(), buffer);
173173
}
174174
// Ignore output data as it's not useful for fuzzing without a more
175-
// complex fuzzed backend.
175+
// complex fuzzed backend. But we need to make sure it's not
176+
// optimised out.
177+
volatile uint8_t *dont_optimise0 = buffer;
178+
volatile uint16_t dont_optimise1 = total_bytes;
179+
UNUSED(dont_optimise0);
180+
UNUSED(dont_optimise1);
181+
176182

177183
return _fuzz_data_provider->ConsumeBool();
178184
}

fuzz/device/cdc/src/fuzz.cc

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -142,33 +142,33 @@ void cdc_task(FuzzedDataProvider *provider) {
142142

143143
// TODO: Fuzz interface number
144144
(void)tud_cdc_n_write(0, buffer.data(), buffer.size());
145-
break;
146-
}
147-
case kCdcNWriteChar:
148-
// TODO: Fuzz interface number
149-
(void)tud_cdc_n_write_char(0, provider->ConsumeIntegral<char>());
150-
break;
151-
case kCdcNWriteStr: {
152-
std::string str = provider->ConsumeRandomLengthString(kMaxBufferSize);
153-
// TODO: Fuzz interface number
154-
(void)tud_cdc_n_write_str(0, str.c_str());
155-
break;
156-
}
157-
case kCdcNWriteFlush:
158-
// TODO: Fuzz interface number
159-
(void)tud_cdc_n_write_flush(0);
160-
break;
161-
case kCdcNWriteAvailable:
162-
// TODO: Fuzz interface number
163-
(void)tud_cdc_n_write_available(0);
164-
break;
165-
case kCdcNWriteClear:
166-
// TODO: Fuzz interface number
167-
(void)tud_cdc_n_write_clear(0);
168-
break;
169-
case kMaxValue:
170-
// Noop.
171-
break;
172-
}
145+
} break;
146+
147+
case kCdcNWriteChar:
148+
// TODO: Fuzz interface number
149+
(void)tud_cdc_n_write_char(0, provider->ConsumeIntegral<char>());
150+
break;
151+
case kCdcNWriteStr: {
152+
std::string str = provider->ConsumeRandomLengthString(kMaxBufferSize);
153+
// TODO: Fuzz interface number
154+
(void)tud_cdc_n_write_str(0, str.c_str());
155+
break;
156+
}
157+
case kCdcNWriteFlush:
158+
// TODO: Fuzz interface number
159+
(void)tud_cdc_n_write_flush(0);
160+
break;
161+
case kCdcNWriteAvailable:
162+
// TODO: Fuzz interface number
163+
(void)tud_cdc_n_write_available(0);
164+
break;
165+
case kCdcNWriteClear:
166+
// TODO: Fuzz interface number
167+
(void)tud_cdc_n_write_clear(0);
168+
break;
169+
case kMaxValue:
170+
// Noop.
171+
break;
172+
}
173173
}
174174
}

fuzz/device/net/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
4+
5+
# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
6+
family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
7+
8+
project(${PROJECT})
9+
10+
# Checks this example is valid for the family and initializes the project
11+
family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
12+
13+
add_executable(${PROJECT})
14+
15+
# Example source
16+
target_sources(${PROJECT} PUBLIC
17+
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
18+
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
19+
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
20+
)
21+
22+
# Example include
23+
target_include_directories(${PROJECT} PUBLIC
24+
${CMAKE_CURRENT_SOURCE_DIR}/src
25+
)
26+
27+
# Configure compilation flags and libraries for the example... see the corresponding function
28+
# in hw/bsp/FAMILY/family.cmake for details.
29+
family_configure_device_example(${PROJECT})

fuzz/device/net/Makefile

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
DEPS_SUBMODULES += lib/lwip
2+
3+
include ../../../tools/top.mk
4+
include ../../make.mk
5+
6+
# suppress warning caused by lwip
7+
CFLAGS += \
8+
-Wno-error=null-dereference \
9+
-Wno-error=unused-parameter \
10+
-Wno-error=unused-variable
11+
12+
INC += \
13+
src \
14+
$(TOP)/hw \
15+
$(TOP)/lib/lwip/src/include \
16+
$(TOP)/lib/lwip/src/include/ipv4 \
17+
$(TOP)/lib/lwip/src/include/lwip/apps \
18+
$(TOP)/lib/networking
19+
20+
# Example source
21+
SRC_C += $(addprefix $(CURRENT_PATH)/, $(wildcard src/*.c))
22+
SRC_CXX += $(addprefix $(CURRENT_PATH)/, $(wildcard src/*.cc))
23+
24+
# lwip sources
25+
SRC_C += \
26+
lib/lwip/src/core/altcp.c \
27+
lib/lwip/src/core/altcp_alloc.c \
28+
lib/lwip/src/core/altcp_tcp.c \
29+
lib/lwip/src/core/def.c \
30+
lib/lwip/src/core/dns.c \
31+
lib/lwip/src/core/inet_chksum.c \
32+
lib/lwip/src/core/init.c \
33+
lib/lwip/src/core/ip.c \
34+
lib/lwip/src/core/mem.c \
35+
lib/lwip/src/core/memp.c \
36+
lib/lwip/src/core/netif.c \
37+
lib/lwip/src/core/pbuf.c \
38+
lib/lwip/src/core/raw.c \
39+
lib/lwip/src/core/stats.c \
40+
lib/lwip/src/core/sys.c \
41+
lib/lwip/src/core/tcp.c \
42+
lib/lwip/src/core/tcp_in.c \
43+
lib/lwip/src/core/tcp_out.c \
44+
lib/lwip/src/core/timeouts.c \
45+
lib/lwip/src/core/udp.c \
46+
lib/lwip/src/core/ipv4/autoip.c \
47+
lib/lwip/src/core/ipv4/dhcp.c \
48+
lib/lwip/src/core/ipv4/etharp.c \
49+
lib/lwip/src/core/ipv4/icmp.c \
50+
lib/lwip/src/core/ipv4/igmp.c \
51+
lib/lwip/src/core/ipv4/ip4.c \
52+
lib/lwip/src/core/ipv4/ip4_addr.c \
53+
lib/lwip/src/core/ipv4/ip4_frag.c \
54+
lib/lwip/src/core/ipv6/dhcp6.c \
55+
lib/lwip/src/core/ipv6/ethip6.c \
56+
lib/lwip/src/core/ipv6/icmp6.c \
57+
lib/lwip/src/core/ipv6/inet6.c \
58+
lib/lwip/src/core/ipv6/ip6.c \
59+
lib/lwip/src/core/ipv6/ip6_addr.c \
60+
lib/lwip/src/core/ipv6/ip6_frag.c \
61+
lib/lwip/src/core/ipv6/mld6.c \
62+
lib/lwip/src/core/ipv6/nd6.c \
63+
lib/lwip/src/netif/ethernet.c \
64+
lib/lwip/src/netif/slipif.c \
65+
lib/lwip/src/apps/http/httpd.c \
66+
lib/lwip/src/apps/http/fs.c \
67+
lib/networking/dhserver.c \
68+
lib/networking/dnserver.c \
69+
lib/networking/rndis_reports.c
70+
71+
include ../../rules.mk

fuzz/device/net/skip.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mcu:SAMD11

fuzz/device/net/src/arch/cc.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification,
6+
* are permitted provided that the following conditions are met:
7+
*
8+
* 1. Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright notice,
11+
* this list of conditions and the following disclaimer in the documentation
12+
* and/or other materials provided with the distribution.
13+
* 3. The name of the author may not be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
19+
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
21+
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24+
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25+
* OF SUCH DAMAGE.
26+
*
27+
* This file is part of the lwIP TCP/IP stack.
28+
*
29+
* Author: Adam Dunkels <[email protected]>
30+
*
31+
*/
32+
#ifndef __CC_H__
33+
#define __CC_H__
34+
35+
//#include "cpu.h"
36+
37+
typedef int sys_prot_t;
38+
39+
40+
41+
/* define compiler specific symbols */
42+
#if defined (__ICCARM__)
43+
44+
#define PACK_STRUCT_BEGIN
45+
#define PACK_STRUCT_STRUCT
46+
#define PACK_STRUCT_END
47+
#define PACK_STRUCT_FIELD(x) x
48+
#define PACK_STRUCT_USE_INCLUDES
49+
50+
#elif defined (__CC_ARM)
51+
52+
#define PACK_STRUCT_BEGIN __packed
53+
#define PACK_STRUCT_STRUCT
54+
#define PACK_STRUCT_END
55+
#define PACK_STRUCT_FIELD(x) x
56+
57+
#elif defined (__GNUC__)
58+
59+
#define PACK_STRUCT_BEGIN
60+
#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))
61+
#define PACK_STRUCT_END
62+
#define PACK_STRUCT_FIELD(x) x
63+
64+
#elif defined (__TASKING__)
65+
66+
#define PACK_STRUCT_BEGIN
67+
#define PACK_STRUCT_STRUCT
68+
#define PACK_STRUCT_END
69+
#define PACK_STRUCT_FIELD(x) x
70+
71+
#endif
72+
73+
#define LWIP_PLATFORM_ASSERT(x) do { if(!(x)) while(1); } while(0)
74+
75+
#endif /* __CC_H__ */

fuzz/device/net/src/fuzz.cc

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2022 Nathaniel Brough
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
*/
25+
26+
#include <cassert>
27+
#include <fuzzer/FuzzedDataProvider.h>
28+
#include <stdio.h>
29+
#include <stdlib.h>
30+
#include <string.h>
31+
32+
#include "class/cdc/cdc_device.h"
33+
#include "class/net/net_device.h"
34+
#include "fuzz/fuzz.h"
35+
#include "tusb.h"
36+
#include <cstdint>
37+
#include <string>
38+
#include <vector>
39+
40+
extern "C" {
41+
42+
#define FUZZ_ITERATIONS 500
43+
44+
//--------------------------------------------------------------------+
45+
// MACRO CONSTANT TYPEDEF PROTYPES
46+
//--------------------------------------------------------------------+
47+
48+
void net_task(FuzzedDataProvider *provider);
49+
50+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
51+
FuzzedDataProvider provider(Data, Size);
52+
std::vector<uint8_t> callback_data = provider.ConsumeBytes<uint8_t>(
53+
provider.ConsumeIntegralInRange<size_t>(0, Size));
54+
fuzz_init(callback_data.data(), callback_data.size());
55+
// init device stack on configured roothub port
56+
tud_init(BOARD_TUD_RHPORT);
57+
58+
for (int i = 0; i < FUZZ_ITERATIONS; i++) {
59+
if (provider.remaining_bytes() == 0) {
60+
return 0;
61+
}
62+
tud_int_handler(provider.ConsumeIntegral<uint8_t>());
63+
tud_task(); // tinyusb device task
64+
net_task(&provider);
65+
}
66+
67+
return 0;
68+
}
69+
70+
//--------------------------------------------------------------------+
71+
// USB CDC
72+
//--------------------------------------------------------------------+
73+
enum NetApiFuncs {
74+
kNetworkRecvRenew,
75+
kNetworkCanXmit,
76+
kNetworkXmit,
77+
kMaxValue,
78+
};
79+
80+
void net_task(FuzzedDataProvider *provider) {
81+
82+
assert(provider != NULL);
83+
switch (provider->ConsumeEnum<NetApiFuncs>()) {
84+
85+
case kNetworkRecvRenew:
86+
tud_network_recv_renew();
87+
break;
88+
case kNetworkCanXmit:
89+
(void)tud_network_can_xmit(provider->ConsumeIntegral<uint16_t>());
90+
case kNetworkXmit:
91+
// TODO: Actuall pass real values here later.
92+
tud_network_xmit(NULL, 0);
93+
94+
case kMaxValue:
95+
// Noop.
96+
break;
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)