Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fuzzing: Update to afl++, adding persisten-fuzzing example #19562

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
fuzzing: Update to afl++, adding persisten-fuzzing example
  • Loading branch information
Teufelchen1 committed May 9, 2023
commit 4c696ac46603cb39c1987cb2341b8b0f23dc77b1
8 changes: 4 additions & 4 deletions fuzzing/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Fuzzing

Automated fuzzing tests for RIOT network applications.
Automated fuzzing tests for RIOT applications.

## Setup

The following additional dependencies are required:

* [afl][afl homepage]
* [afl++][afl++ homepage]
* [libasan][sanitizers github] (optional but recommended)

## Writing a fuzzing application
## Writing a network fuzzing application

The fuzzing setup relies heavily on RIOT's [netapi][netapi doc]
interface, or more generally RIOT's message passing algorithm. RIOT
Expand Down Expand Up @@ -81,6 +81,6 @@ Parallel fuzzing is supported through `FLAGS_FOR_AFL`, e.g.:
FLAGS_FOR_AFL="-S fuzzer02" make -C fuzzing/gnrc_tcp/ fuzz

[sanitizers github]: https://github.com/google/sanitizers
[afl homepage]: http://lcamtuf.coredump.cx/afl/
[afl++ homepage]: https://aflplus.plus/
[netapi doc]: https://riot-os.org/api/netapi_8h.html
[afl-fuzz approach]: https://github.com/google/AFL/blob/ca01f9a4c4ccb59d349c729ad3018e339f9aae0c/README.md#2-the-afl-fuzz-approach
1 change: 1 addition & 0 deletions fuzzing/gcoap/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include ../Makefile.fuzzing_common

USEMODULE += nanocoap_resources
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for waiting.

Otherwise coap_resources and coap_resources_numof are not defined. See /sys/net/application_layer/nanocoap/nanocoap.c:448. The file gets pulled in as soon as you use the gcoap module.

With normal llvm/gcc this isn't an issue, only AFL++ is affected.

As far as I understand it, this is usually not a problem as the code paths containing the undefined values aren't used and get removed during build. AFL++ seems to do this differently and immediately complains about the undefined references even though they aren't used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhm sounds a bit vague, to make my explanation clear:

You can comment out coap_well_known_core_default_handler and coap_handle_req in nanocoap.c and still compile & run examples/gcoap/ using gcc/llvm. In this modified state, the gcoap fuzzing examples also builds fine via AFL++ without the nanocoap_resources module.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's a bit concerning because the if (IS_USED(MODULE_…)) { pattern is used quite a lot in RIOT.
What is the error you are getting?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/usr/bin/ld: RIOT/fuzzing/gcoap/bin/native/nanocoap/nanocoap.o: in function `coap_handle_req':
RIOT/sys/net/application_layer/nanocoap/nanocoap.c:449: undefined reference to `coap_resources_numof'
/usr/bin/ld: RIOT/sys/net/application_layer/nanocoap/nanocoap.c:448: undefined reference to `coap_resources'
/usr/bin/ld: RIOT/fuzzing/gcoap/bin/native/nanocoap/nanocoap.o: in function `coap_well_known_core_default_handler':
RIOT/sys/net/application_layer/nanocoap/nanocoap.c:(.text.coap_well_known_core_default_handler[coap_well_known_core_default_handler]+0x387): undefined reference to `coap_resources_numof'
/usr/bin/ld: RIOT/sys/net/application_layer/nanocoap/nanocoap.c:1262: undefined reference to `coap_resources'

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see what's happening, looks like --gc-sections does not happen with AFL++.

In the 'old style' applications were expected to define coap_resources/coap_resources_numof, now with nanocoap_resources this is an XFA and the definitions are inside nanoCoAP. But to not break applications we keep support for the legacy definitions unless the application requests nanocoap_resources.

The GCoAP fuzzing example doesn't make use of nanoCoAP resources at all (as GCoAP has it's own way to define resources as a linked list of resource arrays) but the functions that would interact with nanocoap_resources are still compiled as they are part of common code, they are just not used by GCoAP so they are normally discarded on linking.

USEMODULE += gcoap

include $(RIOTBASE)/Makefile.include
18 changes: 18 additions & 0 deletions fuzzing/uri_parser_persistent/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
include ../Makefile.fuzzing_common
# name of your application
APPLICATION = uriparser

USEMODULE += uri_parser

# Comment this out to disable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
DEVELHELP ?= 1

# Change this to 0 show compiler invocation lines by default:
QUIET ?= 0

# Needed when using afl++ and persistent fuzzing
CFLAGS += -Wno-gnu-statement-expression

include $(RIOTBASE)/Makefile.include
1 change: 1 addition & 0 deletions fuzzing/uri_parser_persistent/input/input0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coap:///R@[2008::1]:5own//R@[2008::1]:5own/?v=1
1 change: 1 addition & 0 deletions fuzzing/uri_parser_persistent/input/input1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coap://user@[2001:db8::1]:12345
1 change: 1 addition & 0 deletions fuzzing/uri_parser_persistent/input/input2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ftp://riot-os.org:99/bar/foo
1 change: 1 addition & 0 deletions fuzzing/uri_parser_persistent/input/input3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
http://riot-os.org:99/bar/foo
1 change: 1 addition & 0 deletions fuzzing/uri_parser_persistent/input/input4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coap://user@[2001:db8::1%eth0]:12345
27 changes: 27 additions & 0 deletions fuzzing/uri_parser_persistent/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <err.h>

#include "uri_parser.h"
#include "fuzzing.h"

__AFL_FUZZ_INIT()

#pragma clang optimize off

int main(void)
{
__AFL_INIT();
unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
while (__AFL_LOOP(10000)) {
int len = __AFL_FUZZ_TESTCASE_LEN;
uri_parser_result_t uri_res;
uri_parser_process(&uri_res, (char *)buf, len);
}

exit(EXIT_SUCCESS);
return 0;
}
10 changes: 5 additions & 5 deletions makefiles/toolchain/afl.inc.mk
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include $(RIOTMAKE)/toolchain/gnu.inc.mk
include $(RIOTMAKE)/toolchain/llvm.inc.mk

CC = $(PREFIX)afl-gcc
CXX = $(PREFIX)afl-g++
LINK = $(PREFIX)afl-gcc
LINKXX = $(PREFIX)afl-g++
CC = $(PREFIX)afl-clang-fast
CXX = $(PREFIX)afl-clang-fast++
LINK = $(PREFIX)afl-clang-fast
LINKXX = $(PREFIX)afl-clang-fast++