diff --git a/Makefile.include b/Makefile.include index 5659b5098a..db8a0fd2a5 100644 --- a/Makefile.include +++ b/Makefile.include @@ -909,7 +909,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) # Default OBJDUMPFLAGS for platforms which do not specify it: OBJDUMPFLAGS ?= -S -D -h diff --git a/examples/gcoap/client.c b/examples/gcoap/client.c index 8c4275c485..ee9416bec4 100644 --- a/examples/gcoap/client.c +++ b/examples/gcoap/client.c @@ -294,6 +294,11 @@ int gcoap_cli_cmd(int argc, char **argv) uri_len = strlen(argv[apos+1]); } + if (uri && ((uri_len <= 0) || (uri[0] != '/'))) { + puts("ERROR: URI-Path must start with a \"/\""); + return _print_usage(argv); + } + if (_proxied) { sock_udp_ep_t tmp_remote; if (sock_udp_name2ep(&tmp_remote, argv[apos]) != 0) { @@ -329,7 +334,7 @@ int gcoap_cli_cmd(int argc, char **argv) gcoap_req_init(&pdu, &buf[0], CONFIG_GCOAP_PDU_BUF_SIZE, code_pos, NULL); } - else{ + else { gcoap_req_init(&pdu, &buf[0], CONFIG_GCOAP_PDU_BUF_SIZE, code_pos, uri); } coap_hdr_set_type(pdu.hdr, msg_type); diff --git a/fuzzing/Makefile.fuzzing_common b/fuzzing/Makefile.fuzzing_common index 8766f575fe..bb033589c1 100644 --- a/fuzzing/Makefile.fuzzing_common +++ b/fuzzing/Makefile.fuzzing_common @@ -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 USEMODULE += fuzzing USEMODULE += ssp diff --git a/fuzzing/README.md b/fuzzing/README.md index 793a92c45a..c087e0ff3c 100644 --- a/fuzzing/README.md +++ b/fuzzing/README.md @@ -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/ diff --git a/fuzzing/gcoap/Makefile b/fuzzing/gcoap/Makefile index 51e6a9c4ca..284a37cf72 100644 --- a/fuzzing/gcoap/Makefile +++ b/fuzzing/gcoap/Makefile @@ -1,6 +1,5 @@ include ../Makefile.fuzzing_common -USEMODULE += gnrc_ipv6 USEMODULE += gcoap include $(RIOTBASE)/Makefile.include diff --git a/fuzzing/gnrc_tcp/Makefile b/fuzzing/gnrc_tcp/Makefile index d2761c2dec..86a3178b2b 100644 --- a/fuzzing/gnrc_tcp/Makefile +++ b/fuzzing/gnrc_tcp/Makefile @@ -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 diff --git a/fuzzing/uri_parser/Makefile b/fuzzing/uri_parser/Makefile new file mode 100644 index 0000000000..2f27215a92 --- /dev/null +++ b/fuzzing/uri_parser/Makefile @@ -0,0 +1,5 @@ +include ../Makefile.fuzzing_common + +USEMODULE += uri_parser + +include $(RIOTBASE)/Makefile.include diff --git a/fuzzing/uri_parser/input/input0.txt b/fuzzing/uri_parser/input/input0.txt new file mode 100644 index 0000000000..4288fd7e2c --- /dev/null +++ b/fuzzing/uri_parser/input/input0.txt @@ -0,0 +1 @@ +coap:///R@[2008::1]:5own//R@[2008::1]:5own/?v=1 \ No newline at end of file diff --git a/fuzzing/uri_parser/input/input1.txt b/fuzzing/uri_parser/input/input1.txt new file mode 100644 index 0000000000..1d62eaa7b1 --- /dev/null +++ b/fuzzing/uri_parser/input/input1.txt @@ -0,0 +1 @@ +coap://user@[2001:db8::1]:12345 \ No newline at end of file diff --git a/fuzzing/uri_parser/input/input2.txt b/fuzzing/uri_parser/input/input2.txt new file mode 100644 index 0000000000..549eebcebd --- /dev/null +++ b/fuzzing/uri_parser/input/input2.txt @@ -0,0 +1 @@ +ftp://riot-os.org:99/bar/foo \ No newline at end of file diff --git a/fuzzing/uri_parser/input/input3.txt b/fuzzing/uri_parser/input/input3.txt new file mode 100644 index 0000000000..8f328c62f7 --- /dev/null +++ b/fuzzing/uri_parser/input/input3.txt @@ -0,0 +1 @@ +http://riot-os.org:99/bar/foo \ No newline at end of file diff --git a/fuzzing/uri_parser/input/input4.txt b/fuzzing/uri_parser/input/input4.txt new file mode 100644 index 0000000000..5193b18e48 --- /dev/null +++ b/fuzzing/uri_parser/input/input4.txt @@ -0,0 +1 @@ +coap://user@[2001:db8::1%eth0]:12345 \ No newline at end of file diff --git a/fuzzing/uri_parser/main.c b/fuzzing/uri_parser/main.c new file mode 100644 index 0000000000..2378de7416 --- /dev/null +++ b/fuzzing/uri_parser/main.c @@ -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 +#include + +#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); + return EXIT_SUCCESS; +} diff --git a/makefiles/vars.inc.mk b/makefiles/vars.inc.mk index 5c1b380cda..eec39e761a 100644 --- a/makefiles/vars.inc.mk +++ b/makefiles/vars.inc.mk @@ -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 diff --git a/sys/fuzzing/fuzzing.c b/sys/fuzzing/fuzzing.c index 3f7f1e5794..1dd620590f 100644 --- a/sys/fuzzing/fuzzing.c +++ b/sys/fuzzing/fuzzing.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2019 Sören Tempel + * Copyright (C) 2022 Bennet Blischke * * 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 @@ -8,6 +9,7 @@ #include #include +#include #include #include "assert.h" @@ -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) { @@ -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; } diff --git a/sys/include/fuzzing.h b/sys/include/fuzzing.h index f5e8e4c93d..feb8bb4fba 100644 --- a/sys/include/fuzzing.h +++ b/sys/include/fuzzing.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2019 Sören Tempel + * Copyright (C) 2022 Bennet Blischke * * 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 @@ -25,6 +26,8 @@ extern "C" { #endif +#include + #include "net/ipv6/addr.h" #include "net/gnrc/pkt.h" @@ -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