diff --git a/.github/workflows/mdns__host-tests.yml b/.github/workflows/mdns__host-tests.yml index 19733621a..759a74357 100644 --- a/.github/workflows/mdns__host-tests.yml +++ b/.github/workflows/mdns__host-tests.yml @@ -68,3 +68,43 @@ jobs: diff -q $file /tmp/$file || exit 1 echo "OK" done + + fuzz_test: + if: contains(github.event.pull_request.labels.*.name, 'mdns-fuzz') || github.event_name == 'push' + name: Fuzzer tests for mdns lib + strategy: + matrix: + idf_ver: ["latest"] + + runs-on: ubuntu-22.04 + container: aflplusplus/aflplusplus + steps: + - name: Checkout esp-protocols + uses: actions/checkout@v4 + + - name: Checkout ESP-IDF + uses: actions/checkout@v4 + with: + repository: espressif/esp-idf + path: idf + submodules: recursive + + - name: Install Necessary Libs + run: | + apt-get update -y + apt-get install -y libbsd-dev + + - name: Run AFL++ + shell: bash + run: | + export IDF_PATH=$GITHUB_WORKSPACE/idf + cd components/mdns/tests/test_afl_fuzz_host/ + make fuzz + + - name: Upload Crash Artifacts + if: failure() + uses: actions/upload-artifact@v4 + with: + name: fuzz-crashes + path: components/mdns/tests/test_afl_fuzz_host/out/default/crashes.tar.gz + if-no-files-found: ignore diff --git a/components/mdns/tests/test_afl_fuzz_host/Makefile b/components/mdns/tests/test_afl_fuzz_host/Makefile index 0eac9ae83..c9f08b106 100644 --- a/components/mdns/tests/test_afl_fuzz_host/Makefile +++ b/components/mdns/tests/test_afl_fuzz_host/Makefile @@ -1,7 +1,9 @@ +#INSTR=off TEST_NAME=test FUZZ=afl-fuzz COMPONENTS_DIR=$(IDF_PATH)/components -COMPILER_ICLUDE_DIR=$(shell echo `which xtensa-esp32-elf-gcc | xargs dirname | xargs dirname`/xtensa-esp32-elf) +# Use ESP32 toolchain include path if available, otherwise fall back to system includes for host-based compilation +COMPILER_INCLUDE_DIR=$(shell if command -v xtensa-esp32-elf-gcc >/dev/null 2>&1; then echo `which xtensa-esp32-elf-gcc | xargs dirname | xargs dirname`/xtensa-esp32-elf; else echo /usr; fi) CFLAGS=-g -Wno-unused-value -Wno-missing-declarations -Wno-pointer-bool-conversion -Wno-macro-redefined -Wno-int-to-void-pointer-cast -DHOOK_MALLOC_FAILED -DESP_EVENT_H_ -D__ESP_LOG_H__ \ -I. -I../.. -I../../include -I../../private_include -I ./build/config \ @@ -35,7 +37,7 @@ CFLAGS=-g -Wno-unused-value -Wno-missing-declarations -Wno-pointer-bool-conversi -I$(COMPONENTS_DIR)/xtensa/include \ -I$(COMPONENTS_DIR)/xtensa/esp32/include \ -I$(COMPONENTS_DIR)/esp_hw_support/etm/include \ - -I$(COMPILER_ICLUDE_DIR)/include + -I$(COMPILER_INCLUDE_DIR)/include MDNS_C_DEPENDENCY_INJECTION=-include mdns_di.h @@ -77,7 +79,18 @@ $(TEST_NAME): $(OBJECTS) @$(LD) $(OBJECTS) -o $@ $(LDLIBS) fuzz: $(TEST_NAME) - @$(FUZZ) -i "in" -o "out" -- ./$(TEST_NAME) + # timeout returns 124 if time limit is reached, original return code otherwise + # pass only if: fuzzing was running smoothly until timeout AND no crash found + @timeout 10m $(FUZZ) -i "in" -o "out" -- ./$(TEST_NAME) || \ + if [ $$? -eq 124 ]; then \ + if [ -n "$$(find out/default/crashes -type f 2>/dev/null)" ]; then \ + echo "Crashes found!"; \ + tar -czf out/default/crashes.tar.gz -C out/default crashes; \ + exit 1; \ + fi \ + else \ + exit 1; \ + fi clean: @rm -rf *.o *.SYM $(TEST_NAME) out diff --git a/components/mdns/tests/test_afl_fuzz_host/esp32_mock.h b/components/mdns/tests/test_afl_fuzz_host/esp32_mock.h index 68a346105..70a2037ff 100644 --- a/components/mdns/tests/test_afl_fuzz_host/esp32_mock.h +++ b/components/mdns/tests/test_afl_fuzz_host/esp32_mock.h @@ -55,8 +55,7 @@ #define pdMS_TO_TICKS(a) a #define xSemaphoreTake(s,d) true -#define xTaskDelete(a) -#define vTaskDelete(a) free(a) +#define vTaskDelete(a) free(NULL) #define xSemaphoreGive(s) #define xQueueCreateMutex(s) #define _mdns_pcb_init(a,b) true @@ -66,7 +65,7 @@ #define vSemaphoreDelete(s) free(s) #define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U #define xTaskCreatePinnedToCore(a,b,c,d,e,f,g) *(f) = malloc(1) -#define xTaskCreateStaticPinnedToCore(a,b,c,d,e,f,g,h) true +#define xTaskCreateStaticPinnedToCore(a,b,c,d,e,f,g,h) ((void*)1) #define vTaskDelay(m) usleep((m)*0) #define esp_random() (rand()%UINT32_MAX) @@ -139,4 +138,8 @@ TaskHandle_t xTaskGetCurrentTaskHandle(void); void xTaskNotifyGive(TaskHandle_t task); BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time); +static inline void xTaskGetStaticBuffers(void *pvTaskBuffer, void *pvStackBuffer, void *pvTaskTCB) +{ +} + #endif //_ESP32_COMPAT_H_ diff --git a/components/mdns/tests/test_afl_fuzz_host/test.c b/components/mdns/tests/test_afl_fuzz_host/test.c index afbf02384..d753dc960 100644 --- a/components/mdns/tests/test_afl_fuzz_host/test.c +++ b/components/mdns/tests/test_afl_fuzz_host/test.c @@ -78,30 +78,20 @@ static int mdns_test_service_txt_set(const char *service, const char *proto, ui static int mdns_test_sub_service_add(const char *sub_name, const char *service_name, const char *proto, uint32_t port) { if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) { - // This is expected failure as the service thread is not running + return ESP_FAIL; } - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); if (mdns_test_mdns_get_service_item(service_name, proto) == NULL) { return ESP_FAIL; } - int ret = mdns_service_subtype_add_for_host(NULL, service_name, proto, NULL, sub_name); - a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); - return ret; + return mdns_service_subtype_add_for_host(NULL, service_name, proto, NULL, sub_name); } static int mdns_test_service_add(const char *service_name, const char *proto, uint32_t port) { if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) { - // This is expected failure as the service thread is not running + return ESP_FAIL; } - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); if (mdns_test_mdns_get_service_item(service_name, proto) == NULL) { return ESP_FAIL; @@ -266,9 +256,6 @@ int main(int argc, char **argv) } #ifndef MDNS_NO_SERVICES mdns_service_remove_all(); - mdns_action_t *a = NULL; - GetLastItem(&a); - mdns_test_execute_action(a); #endif ForceTaskDelete(); mdns_free();