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: Add uri_parser setup #19057

Merged
merged 3 commits into from
Jan 16, 2023
Merged
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
2 changes: 1 addition & 1 deletion Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -904,7 +904,7 @@ include $(RIOTMAKE)/tests/tests.inc.mk
.PHONY: fuzz
fuzz:
env FLASHFILE="$(FLASHFILE)" PORT="$(PORT)" TERMFLAGS="$(TERMFLAGS)" \
"$(RIOTBASE)"/dist/tools/fuzzing/afl.sh $(AFL_FLAGS)
"$(RIOTBASE)"/dist/tools/fuzzing/afl.sh $(FLAGS_FOR_AFL)
Copy link
Member

Choose a reason for hiding this comment

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

Could you elaborate why renaming the environment variable is necessary?

Copy link
Contributor Author

@Teufelchen1 Teufelchen1 Dec 19, 2022

Choose a reason for hiding this comment

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

Sure!

If you try to compile using AFL++ (instead of the old AFL) you will encounter this warning:

[!] WARNING: Mistyped AFL environment variable: AFL_FLAGS=
"make" -C RIOT/core/lib
Did you mean AFL_AS?
Did you mean AFL_CC?

This was introduced in Version ++3.10c of AFL++:
printing suggestions for mistyped AFL_ env variables
Check the changelog of AFL++ here.

I am aware that RIOTs fuzzing documentation states to use the old AFL 2.52b - where this warning isn't present. However, AFL is no longer maintained. Tho, we should move on towards AFL++. So far all my fuzzing with AFL++ is without issues and the backwards compatibility is nice. This warning being the only issue.

Edit:
Just realised: This can be turned of by setting AFL_IGNORE_UNKNOWN_ENVS.
I believe changing our name is the better approach as this way we still get hints if we do have typo in some of the AFL envs.

Copy link
Member

Choose a reason for hiding this comment

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

Moving to AFL++ is definitely a good idea! Maybe it also makes sense to update the documentation in this regard. However, I also wouldn't mind doing that in a separate merge request.


# Default OBJDUMPFLAGS for platforms which do not specify it:
OBJDUMPFLAGS ?= -S -D -h
Expand Down
1 change: 1 addition & 0 deletions fuzzing/Makefile.fuzzing_common
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ CFLAGS += -ggdb # Make ASAN output more useful error messages
CFLAGS += -D_FORTIFY_SOURCE=2 # Compiler hardening

# Various utilitiy modules
USEMODULE += gnrc_ipv6
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change was done due to gnrc_ipv6 being mandatory (for all harness types) at the moment because sys/fuzzing/ needs refactoring. :)

USEMODULE += fuzzing
USEMODULE += ssp

Expand Down
6 changes: 3 additions & 3 deletions fuzzing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ Afterwards invoke afl using:

### Parallel Fuzzing

Parallel fuzzing is supported through `AFL_FLAGS`, e.g.:
Parallel fuzzing is supported through `FLAGS_FOR_AFL`, e.g.:

# Start first AFL instance
AFL_FLAGS="-M fuzzer01" make -C fuzzing/gnrc_tcp/ fuzz
FLAGS_FOR_AFL="-M fuzzer01" make -C fuzzing/gnrc_tcp/ fuzz

# Start second AFL instance in a different terminal
AFL_FLAGS="-S fuzzer02" make -C fuzzing/gnrc_tcp/ fuzz
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/
Expand Down
1 change: 0 additions & 1 deletion fuzzing/gcoap/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
include ../Makefile.fuzzing_common

USEMODULE += gnrc_ipv6
USEMODULE += gcoap

include $(RIOTBASE)/Makefile.include
1 change: 0 additions & 1 deletion fuzzing/gnrc_tcp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ CFLAGS += -DSERVER_ADDR=\"$(TCP_SERVER_ADDR)\"
CFLAGS += -DSERVER_ADDR_PREFIX=$(TCP_SERVER_ADDR_PREFIX)
CFLAGS += -DSERVER_PORT=$(TCP_SERVER_PORT)

USEMODULE += gnrc_ipv6
USEMODULE += gnrc_tcp

include $(RIOTBASE)/Makefile.include
5 changes: 5 additions & 0 deletions fuzzing/uri_parser/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include ../Makefile.fuzzing_common

USEMODULE += uri_parser

include $(RIOTBASE)/Makefile.include
1 change: 1 addition & 0 deletions fuzzing/uri_parser/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/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/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/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/input/input4.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
coap://user@[2001:db8::1%eth0]:12345
30 changes: 30 additions & 0 deletions fuzzing/uri_parser/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2022 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

#include <err.h>
#include <unistd.h>

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

int main(void)
{
size_t input_len;
char *input_buf = (char *)fuzzing_read_bytes(STDIN_FILENO, &input_len);

if (input_buf == NULL) {
errx(EXIT_FAILURE, "fuzzing_read_bytes failed");
}

uri_parser_result_t uri_res;

uri_parser_process(&uri_res, input_buf, input_len);

exit(EXIT_SUCCESS);
Copy link
Member

Choose a reason for hiding this comment

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

For the uri_parser you might also be able to just use NATIVE_AUTO_EXIT but explicitly calling exit is of cause also fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why would one prefer one over the other?

return EXIT_SUCCESS;
}
2 changes: 1 addition & 1 deletion makefiles/vars.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export UNZIP_HERE # Use `cd $(SOME_FOLDER) && $(UNZIP_HERE) $(SOME_FI
export LAZYSPONGE # Command saving stdin to a file only on content update.
export LAZYSPONGE_FLAGS # Parameters supplied to LAZYSPONGE.

export AFL_FLAGS # Additional command-line flags passed to afl during fuzzing.
export FLAGS_FOR_AFL # Additional command-line flags passed to afl during fuzzing.

# LOG_LEVEL # Logging level as integer (NONE: 0, ERROR: 1, WARNING: 2, INFO: 3, DEBUG: 4, default: 3)
# KCONFIG_ADD_CONFIG # List of .config files to be merged used by Boards and CPUs. See kconfig.mk
Expand Down
59 changes: 41 additions & 18 deletions sys/fuzzing/fuzzing.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2019 Sören Tempel <tempel@uni-bremen.de>
* Copyright (C) 2022 Bennet Blischke <bennet.blischke@haw-hamburg.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
Expand All @@ -8,6 +9,7 @@

#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>

#include "assert.h"
Expand All @@ -21,13 +23,13 @@
extern int fuzzing_netdev(gnrc_netif_t *);
extern void fuzzing_netdev_wait(void);

/* used by gnrc_pktbuf_malloc to exit on free */
gnrc_pktsnip_t *gnrc_pktbuf_fuzzptr = NULL;

/* buffer sizes for reading from an fd */
#define FUZZING_BSIZE 1024
#define FUZZING_BSTEP 128

/* used by gnrc_pktbuf_malloc to exit on free */
gnrc_pktsnip_t *gnrc_pktbuf_fuzzptr = NULL;

int
fuzzing_init(ipv6_addr_t *addr, unsigned pfx_len)
{
Expand All @@ -50,40 +52,61 @@ fuzzing_init(ipv6_addr_t *addr, unsigned pfx_len)
int
fuzzing_read_packet(int fd, gnrc_pktsnip_t *pkt)
{
ssize_t r;
size_t csiz, rsiz;
size_t rsiz;

/* can only be called once currently */
assert(gnrc_pktbuf_fuzzptr == NULL);

csiz = 0;
rsiz = FUZZING_BSIZE;
uint8_t *input = fuzzing_read_bytes(fd, &rsiz);
if (input == NULL) {
return -errno;
}

if (gnrc_pktbuf_realloc_data(pkt, rsiz)) {
return -ENOMEM;
}

while ((r = read(fd, &((char *)pkt->data)[csiz], rsiz)) > 0) {
memcpy(pkt->data, input, rsiz);

gnrc_pktbuf_fuzzptr = pkt;
return 0;
}

uint8_t *
fuzzing_read_bytes(int fd, size_t *size)
{
uint8_t *buffer = NULL;
ssize_t r;
size_t csiz, rsiz;

csiz = 0;
rsiz = FUZZING_BSIZE;
if ((buffer = realloc(buffer, rsiz)) == NULL) {
return NULL;
}

while ((r = read(fd, &(buffer[csiz]), rsiz)) > 0) {
assert((size_t)r <= rsiz);

csiz += r;
rsiz -= r;

if (rsiz == 0) {
if (gnrc_pktbuf_realloc_data(pkt, csiz + FUZZING_BSTEP)) {
return -ENOMEM;
}
rsiz += FUZZING_BSTEP;
if ((buffer = realloc(buffer, csiz + FUZZING_BSTEP)) == NULL) {
return NULL;
}
rsiz += FUZZING_BSTEP;
}
}
if (r == -1) {
return -errno;
return NULL;
}

/* shrink packet to actual size */
if (gnrc_pktbuf_realloc_data(pkt, csiz)) {
return -ENOMEM;
/* shrink buffer to actual size */
if ((buffer = realloc(buffer, csiz)) == NULL) {
return NULL;
}

gnrc_pktbuf_fuzzptr = pkt;
return 0;
*size = csiz;
return buffer;
}
13 changes: 13 additions & 0 deletions sys/include/fuzzing.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2019 Sören Tempel <tempel@uni-bremen.de>
* Copyright (C) 2022 Bennet Blischke <bennet.blischke@haw-hamburg.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
Expand All @@ -25,6 +26,8 @@
extern "C" {
#endif

#include <stdint.h>

#include "net/ipv6/addr.h"
#include "net/gnrc/pkt.h"

Expand All @@ -49,6 +52,16 @@ int fuzzing_init(ipv6_addr_t *addr, unsigned pfx_len);
*/
int fuzzing_read_packet(int fd, gnrc_pktsnip_t *pkt);

/**
* @brief Read data from the given file descriptor.
*
* @param fd File descriptor to read data from.
* @param size Byte count of the data read.
*
* @return pointer to the data on success, NULL otherwise.
*/
uint8_t *fuzzing_read_bytes(int fd, size_t *size);

#ifdef __cplusplus
}
#endif
Expand Down