From f7f9eddd9eb430fb249db0eadb41b05d36bc9933 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 15 Dec 2022 13:10:19 +0100 Subject: [PATCH 1/4] fuzzing: Rename AFL flag to prevent spelling warning from AFL --- Makefile.include | 2 +- fuzzing/README.md | 6 +++--- makefiles/vars.inc.mk | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile.include b/Makefile.include index 546b8485cb..1d77ebac5d 100644 --- a/Makefile.include +++ b/Makefile.include @@ -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) # Default OBJDUMPFLAGS for platforms which do not specify it: OBJDUMPFLAGS ?= -S -D -h 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/makefiles/vars.inc.mk b/makefiles/vars.inc.mk index 5c1b380cda..8396fce489 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 From 5c51686178ae771f28d85a60c4b00fd466355166 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 15 Dec 2022 13:17:42 +0100 Subject: [PATCH 2/4] fuzzing: Add generic input reader --- fuzzing/Makefile.fuzzing_common | 1 + fuzzing/gcoap/Makefile | 1 - fuzzing/gnrc_tcp/Makefile | 1 - makefiles/vars.inc.mk | 2 +- sys/fuzzing/fuzzing.c | 53 ++++++++++++++++++++++++++++----- sys/include/fuzzing.h | 19 ++++++++++++ 6 files changed, 66 insertions(+), 11 deletions(-) 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/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/makefiles/vars.inc.mk b/makefiles/vars.inc.mk index 8396fce489..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 FLAGS_FOR_AFL # 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..06bd148120 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" @@ -24,10 +26,6 @@ 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 - int fuzzing_init(ipv6_addr_t *addr, unsigned pfx_len) { @@ -69,10 +67,10 @@ fuzzing_read_packet(int fd, gnrc_pktsnip_t *pkt) rsiz -= r; if (rsiz == 0) { - if (gnrc_pktbuf_realloc_data(pkt, csiz + FUZZING_BSTEP)) { - return -ENOMEM; - } - rsiz += FUZZING_BSTEP; + if (gnrc_pktbuf_realloc_data(pkt, csiz + FUZZING_BSTEP)) { + return -ENOMEM; + } + rsiz += FUZZING_BSTEP; } } if (r == -1) { @@ -87,3 +85,42 @@ fuzzing_read_packet(int fd, gnrc_pktsnip_t *pkt) 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 ((buffer = realloc(buffer, csiz + FUZZING_BSTEP)) == NULL) { + return NULL; + } + rsiz += FUZZING_BSTEP; + } + } + if (r == -1) { + return NULL; + } + + /* shrink packet to actual size */ + if ((buffer = realloc(buffer, csiz)) == NULL) { + return NULL; + } + + *size = csiz; + return buffer; +} diff --git a/sys/include/fuzzing.h b/sys/include/fuzzing.h index f5e8e4c93d..1cb2f001bc 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,9 +26,17 @@ extern "C" { #endif + +#include + #include "net/ipv6/addr.h" #include "net/gnrc/pkt.h" + +/* buffer sizes for reading from an fd */ +#define FUZZING_BSIZE 1024 +#define FUZZING_BSTEP 128 + /** * @brief Initialize dummy network interface with given address. * @@ -49,6 +58,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 From 82f44c5b1f6b43718c331c3a9e6f45d841a25996 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 15 Dec 2022 15:18:16 +0100 Subject: [PATCH 3/4] fuzzing: Add uri_parser fuzzer setup --- fuzzing/uri_parser/Makefile | 5 ++++ fuzzing/uri_parser/input/input0.txt | 1 + fuzzing/uri_parser/input/input1.txt | 1 + fuzzing/uri_parser/input/input2.txt | 1 + fuzzing/uri_parser/input/input3.txt | 1 + fuzzing/uri_parser/input/input4.txt | 1 + fuzzing/uri_parser/main.c | 30 +++++++++++++++++++++++ sys/fuzzing/fuzzing.c | 38 +++++++++-------------------- sys/include/fuzzing.h | 8 +----- 9 files changed, 53 insertions(+), 33 deletions(-) create mode 100644 fuzzing/uri_parser/Makefile create mode 100644 fuzzing/uri_parser/input/input0.txt create mode 100644 fuzzing/uri_parser/input/input1.txt create mode 100644 fuzzing/uri_parser/input/input2.txt create mode 100644 fuzzing/uri_parser/input/input3.txt create mode 100644 fuzzing/uri_parser/input/input4.txt create mode 100644 fuzzing/uri_parser/main.c 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/sys/fuzzing/fuzzing.c b/sys/fuzzing/fuzzing.c index 06bd148120..1dd620590f 100644 --- a/sys/fuzzing/fuzzing.c +++ b/sys/fuzzing/fuzzing.c @@ -23,6 +23,10 @@ extern int fuzzing_netdev(gnrc_netif_t *); extern void fuzzing_netdev_wait(void); +/* 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; @@ -48,39 +52,21 @@ 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) { - 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 (r == -1) { - return -errno; - } - - /* shrink packet to actual size */ - if (gnrc_pktbuf_realloc_data(pkt, csiz)) { - return -ENOMEM; - } + memcpy(pkt->data, input, rsiz); gnrc_pktbuf_fuzzptr = pkt; return 0; @@ -116,7 +102,7 @@ fuzzing_read_bytes(int fd, size_t *size) return NULL; } - /* shrink packet to actual size */ + /* shrink buffer to actual size */ if ((buffer = realloc(buffer, csiz)) == NULL) { return NULL; } diff --git a/sys/include/fuzzing.h b/sys/include/fuzzing.h index 1cb2f001bc..feb8bb4fba 100644 --- a/sys/include/fuzzing.h +++ b/sys/include/fuzzing.h @@ -26,17 +26,11 @@ extern "C" { #endif - #include #include "net/ipv6/addr.h" #include "net/gnrc/pkt.h" - -/* buffer sizes for reading from an fd */ -#define FUZZING_BSIZE 1024 -#define FUZZING_BSTEP 128 - /** * @brief Initialize dummy network interface with given address. * @@ -63,7 +57,7 @@ int fuzzing_read_packet(int fd, gnrc_pktsnip_t *pkt); * * @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); From 21ae657e92d4492d07c97b7020fba0dcfd5ba96a Mon Sep 17 00:00:00 2001 From: Marian Buschsieweke Date: Sun, 15 Jan 2023 22:18:07 +0100 Subject: [PATCH 4/4] examples/gcoap: Fix shell parameter validation Executing the shell command with an URI-Path that doesn't start with a slash results in an assertion error while composing the client side message. This is suboptimal user experience, so add an explicit check for a valid URI-Path and a dedicated error message. --- examples/gcoap/client.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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);