mirror of
https://github.com/espressif/esp-protocols.git
synced 2026-07-07 17:10:52 +02:00
fix(mdns): Add unit tests for fa84ee6e4
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# mDNS host unit tests and fuzzing
|
||||
|
||||
This directory builds the mDNS component as a Linux host binary with stubs for ESP-IDF networking. It supports two modes:
|
||||
|
||||
- **Unit tests** — Unity/CMock regression tests (ASan/UBSan enabled)
|
||||
- **Fuzzing** — AFL++ harness that feeds random packets into the receive path
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- ESP-IDF installed and `IDF_PATH` set (`. $IDF_PATH/export.sh`)
|
||||
- `libbsd-dev`
|
||||
- For unit tests: `ruby` (CMock code generation)
|
||||
- For fuzzing: AFL++ (`afl-cc`, `afl-fuzz`) and `dnslib` (`pip install dnslib`)
|
||||
|
||||
From the repository root:
|
||||
|
||||
```bash
|
||||
cd components/mdns/tests/host_unit_test
|
||||
```
|
||||
|
||||
Run `idf.py reconfigure` once before building. This generates `build/config/` headers used by the host build.
|
||||
|
||||
## Unit tests
|
||||
|
||||
Available test suites (pass one to `-DUNIT_TESTS=`):
|
||||
|
||||
| Suite | Description |
|
||||
|-------|-------------|
|
||||
| `test_receiver` | Packet receive / parse path |
|
||||
| `test_sender` | Packet send path |
|
||||
| `test_browse` | Browse / TXT comparison regressions |
|
||||
|
||||
Example — build and run the receiver tests:
|
||||
|
||||
```bash
|
||||
. $IDF_PATH/export.sh
|
||||
idf.py reconfigure
|
||||
|
||||
mkdir -p build2 && cd build2
|
||||
cmake -DUNIT_TESTS=test_receiver ..
|
||||
cmake --build .
|
||||
ctest --extra-verbose
|
||||
```
|
||||
|
||||
Or run the binary directly:
|
||||
|
||||
```bash
|
||||
./mdns_host_unit_test --test
|
||||
```
|
||||
|
||||
Repeat with `-DUNIT_TESTS=test_sender` or `-DUNIT_TESTS=test_browse` in a separate build directory.
|
||||
|
||||
## Fuzzer tests
|
||||
|
||||
Build the AFL-instrumented harness (no `-DUNIT_TESTS`; uses `main.c`):
|
||||
|
||||
```bash
|
||||
export IDF_PATH=/path/to/esp-idf # required in the fuzz container
|
||||
|
||||
cd input && python generate_cases.py && cd ..
|
||||
|
||||
cmake -B build2 -S . -G Ninja -DCMAKE_C_COMPILER=afl-cc
|
||||
cmake --build build2
|
||||
|
||||
afl-fuzz -i input -o out -- build2/mdns_host_unit_test
|
||||
```
|
||||
|
||||
The harness reads packets from stdin and exercises IPv4/IPv6 and port 5353/53 combinations. Crashes are written to `out/default/crashes/`.
|
||||
|
||||
### Reproducing a crash
|
||||
|
||||
Build the non-unit-test binary with a normal compiler, then pass a crash file:
|
||||
|
||||
```bash
|
||||
cmake -B build2 -S .
|
||||
cmake --build build2
|
||||
./build2/mdns_host_unit_test out/default/crashes/id_000000,...
|
||||
```
|
||||
|
||||
With sanitizers enabled, ASan/UBSan report buffer overruns and undefined behaviour directly during unit tests and fuzzing.
|
||||
@@ -3,4 +3,8 @@
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#if __has_include("esp_assert.h")
|
||||
#include_next "esp_assert.h"
|
||||
#else
|
||||
#define ESP_STATIC_ASSERT _Static_assert
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "unity_main.h"
|
||||
#include "mock_mdns_pcb.h"
|
||||
#include "mock_mdns_send.h"
|
||||
#include "create_test_packet.h"
|
||||
#include "mdns_private.h"
|
||||
|
||||
static void test_mdns_hostname_queries(void)
|
||||
{
|
||||
@@ -61,6 +61,27 @@ static void test_mdns_with_answers(void)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Regression test for fa84ee6: packets shorter than MDNS_HEAD_LEN (12) must
|
||||
* be rejected before reading the additional RR count at offset 10.
|
||||
* An 11-byte AFL input (id_000005) previously passed the old check and read
|
||||
* one byte past the RX buffer.
|
||||
*/
|
||||
static void test_mdns_reject_short_packet(void)
|
||||
{
|
||||
static const uint8_t eleven_byte_packet[] = {
|
||||
0x00, 0xc0, 0x32, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x54, 0x01
|
||||
};
|
||||
|
||||
for (size_t len = 0; len < MDNS_HEAD_LEN; len++) {
|
||||
const uint8_t *data = eleven_byte_packet;
|
||||
send_packet(true, true, (uint8_t *)data, len);
|
||||
send_packet(true, false, (uint8_t *)data, len);
|
||||
send_packet(false, true, (uint8_t *)data, len);
|
||||
send_packet(false, false, (uint8_t *)data, len);
|
||||
}
|
||||
}
|
||||
|
||||
static void mdns_priv_create_answer_from_parsed_packet_Callback(mdns_parsed_packet_t* parsed_packet, int cmock_num_calls)
|
||||
{
|
||||
printf("callback\n");
|
||||
@@ -89,5 +110,7 @@ void run_unity_tests(void)
|
||||
// Run test with answers
|
||||
RUN_TEST(test_mdns_with_answers);
|
||||
|
||||
RUN_TEST(test_mdns_reject_short_packet);
|
||||
|
||||
UNITY_END();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user