test(fuzz): extend csi_serialize fuzz harness for ADR-110 byte 18-19
The libFuzzer harness was compiled without CONFIG_CSI_FRAME_HE_TAGGING,
so the new byte 18/19 path in csi_collector.c was zero-filled at compile
time and never fuzzed. Three changes to fix that:
1. test/stubs/esp_stubs.h: wifi_pkt_rx_ctrl_t gains both branch families
- HE branch (CONFIG_SOC_WIFI_HE_SUPPORT path): cur_bb_format, second
- Legacy branch (S3 / pre-HE chips): sig_mode, cwb, stbc
A single stub compiles for either branch; the Makefile picks which
one is active via -D flags. Both sets are declared so a build for
the unselected branch still compiles cleanly.
2. test/Makefile: CFLAGS now defines CONFIG_CSI_FRAME_HE_TAGGING=1 so
the new code path is reachable. CONFIG_SOC_WIFI_HE_SUPPORT stays
UNSET (default — exercises the legacy S3 branch). Add it to CFLAGS
for a parallel HE-stub run if you want coverage of the C6 branch.
3. test/fuzz_csi_serialize.c: parses 3 more control bytes from fuzz
input (he_inputs[2] + legacy_inputs) and writes them through
info.rx_ctrl.{cur_bb_format,second,sig_mode,cwb,stbc} so the
serializer's PpduType switch and Adr018Flags computation are
reached on every iteration.
Result: the existing libFuzzer corpus + ASAN/UBSAN now covers the
ADR-110 wire encoding paths on every run. No more zero-fill silent skip.
Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
parent
89972c0917
commit
fc75a8a5c8
|
|
@ -20,6 +20,11 @@
|
|||
# FUZZ_JOBS=4 # Parallel fuzzing jobs
|
||||
|
||||
CC = clang
|
||||
# ADR-110: -DCONFIG_CSI_FRAME_HE_TAGGING=1 enables the byte-18/19 HE path
|
||||
# in csi_collector.c so the fuzzer exercises that code as well as the
|
||||
# legacy zero-fill path. CONFIG_SOC_WIFI_HE_SUPPORT is left UNSET to
|
||||
# exercise the legacy S3 branch (sig_mode/cwb/stbc). Add it to CFLAGS for
|
||||
# a parallel HE-stub build if you want fuzz coverage of the C6 branch.
|
||||
CFLAGS = -fsanitize=fuzzer,address,undefined -g -O1 \
|
||||
-Istubs -I../main \
|
||||
-DCONFIG_CSI_NODE_ID=1 \
|
||||
|
|
@ -28,6 +33,7 @@ CFLAGS = -fsanitize=fuzzer,address,undefined -g -O1 \
|
|||
-DCONFIG_CSI_TARGET_IP=\"192.168.1.1\" \
|
||||
-DCONFIG_CSI_TARGET_PORT=5500 \
|
||||
-DCONFIG_ESP_WIFI_CSI_ENABLED=1 \
|
||||
-DCONFIG_CSI_FRAME_HE_TAGGING=1 \
|
||||
-Wno-unused-function
|
||||
|
||||
STUBS_SRC = stubs/esp_stubs.c
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
|||
uint8_t channel;
|
||||
int8_t noise_floor;
|
||||
uint8_t out_buf_scale; /* Controls output buffer size: 0-255. */
|
||||
/* ADR-110: fuzz the new HE-branch + legacy-branch input fields too so
|
||||
* the byte 18/19 encoding code path is exercised. */
|
||||
uint8_t he_inputs[2] = {0}; /* cur_bb_format (4 bits) + second (4 bits) packed */
|
||||
uint8_t legacy_inputs = 0; /* sig_mode (2) + cwb (1) + stbc (1) packed */
|
||||
|
||||
fuzz_read(&cursor, &remaining, &test_case, 1);
|
||||
fuzz_read(&cursor, &remaining, &iq_len_raw, 2);
|
||||
|
|
@ -67,6 +71,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
|||
fuzz_read(&cursor, &remaining, &channel, 1);
|
||||
fuzz_read(&cursor, &remaining, &noise_floor, 1);
|
||||
fuzz_read(&cursor, &remaining, &out_buf_scale, 1);
|
||||
fuzz_read(&cursor, &remaining, he_inputs, 2);
|
||||
fuzz_read(&cursor, &remaining, &legacy_inputs, 1);
|
||||
|
||||
/* --- Test case 0: Normal operation with fuzz-controlled values --- */
|
||||
|
||||
|
|
@ -75,6 +81,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
|||
info.rx_ctrl.rssi = rssi;
|
||||
info.rx_ctrl.channel = channel & 0x0F; /* 4-bit field */
|
||||
info.rx_ctrl.noise_floor = noise_floor;
|
||||
/* ADR-110: feed both branch families. Only the active branch (chosen
|
||||
* at compile time by CONFIG_SOC_WIFI_HE_SUPPORT) will read its fields;
|
||||
* the other set is set-but-not-read. Both must be assignable without
|
||||
* triggering UBSAN bitfield-overflow. */
|
||||
info.rx_ctrl.cur_bb_format = he_inputs[0] & 0x0F; /* 0..15 valid input space */
|
||||
info.rx_ctrl.second = he_inputs[1] & 0x0F;
|
||||
info.rx_ctrl.sig_mode = legacy_inputs & 0x03;
|
||||
info.rx_ctrl.cwb = (legacy_inputs >> 2) & 0x01;
|
||||
info.rx_ctrl.stbc = (legacy_inputs >> 3) & 0x01;
|
||||
|
||||
/* Use remaining fuzz data as I/Q buffer content. */
|
||||
uint16_t iq_len;
|
||||
|
|
|
|||
|
|
@ -62,14 +62,28 @@ static inline esp_err_t esp_timer_delete(esp_timer_handle_t h) { (void)h; return
|
|||
|
||||
/* ---- esp_wifi_types.h ---- */
|
||||
|
||||
/** Minimal rx_ctrl fields needed by csi_serialize_frame. */
|
||||
/** Minimal rx_ctrl fields needed by csi_serialize_frame.
|
||||
*
|
||||
* ADR-110: the HE-tagging path in csi_collector.c references either
|
||||
* (CONFIG_SOC_WIFI_HE_SUPPORT branch) cur_bb_format, second
|
||||
* (legacy / S3 branch) sig_mode, cwb, stbc
|
||||
*
|
||||
* Both sets are unconditionally declared here so a single stub builds
|
||||
* for either branch — the Makefile picks which side via -D flags. */
|
||||
typedef struct {
|
||||
signed rssi : 8;
|
||||
unsigned channel : 4;
|
||||
unsigned noise_floor : 8;
|
||||
unsigned rx_ant : 2;
|
||||
/* Padding to fill out the struct so it compiles. */
|
||||
unsigned _pad : 10;
|
||||
signed rssi : 8;
|
||||
unsigned channel : 4;
|
||||
unsigned noise_floor : 8;
|
||||
unsigned rx_ant : 2;
|
||||
/* ADR-110 HE-branch fields (CONFIG_SOC_WIFI_HE_SUPPORT path) */
|
||||
unsigned cur_bb_format : 4; /**< 0=11b 1=11g/a 2=HT 3=VHT 4=HE-SU 5=HE-MU 6=HE-ER-SU 7=HE-TB */
|
||||
unsigned second : 4; /**< secondary 40 MHz channel offset */
|
||||
/* ADR-110 legacy-branch fields (pre-HE chips) */
|
||||
unsigned sig_mode : 2; /**< 0=non-HT 1=HT 3=VHT */
|
||||
unsigned cwb : 1; /**< 0=20 MHz 1=40 MHz */
|
||||
unsigned stbc : 1; /**< STBC flag */
|
||||
/* Padding to keep alignment predictable. */
|
||||
unsigned _pad : 18;
|
||||
} wifi_pkt_rx_ctrl_t;
|
||||
|
||||
/** Minimal wifi_csi_info_t needed by csi_serialize_frame. */
|
||||
|
|
|
|||
Loading…
Reference in New Issue