|  1c1c0cc791 
		
			Some checks are pending
		
		
	 CI / setup (check) (push) Waiting to run CI / setup (esp32) (push) Waiting to run CI / setup (esp32c3) (push) Waiting to run CI / setup (esp32c6) (push) Waiting to run CI / setup (esp32s3) (push) Waiting to run CI / setup (nrf52840) (push) Waiting to run CI / setup (rp2040) (push) Waiting to run CI / setup (rp2350) (push) Waiting to run CI / setup (stm32) (push) Waiting to run CI / version (push) Waiting to run CI / check (push) Blocked by required conditions CI / build-esp32 (push) Blocked by required conditions CI / build-esp32s3 (push) Blocked by required conditions CI / build-esp32c3 (push) Blocked by required conditions CI / build-esp32c6 (push) Blocked by required conditions CI / build-nrf52840 (push) Blocked by required conditions CI / build-rp2040 (push) Blocked by required conditions CI / build-rp2350 (push) Blocked by required conditions CI / build-stm32 (push) Blocked by required conditions CI / build-debian-src (push) Waiting to run CI / package-pio-deps-native-tft (push) Waiting to run CI / test-native (push) Waiting to run CI / docker-deb-amd64 (push) Waiting to run CI / docker-deb-amd64-tft (push) Waiting to run CI / docker-alp-amd64 (push) Waiting to run CI / docker-alp-amd64-tft (push) Waiting to run CI / docker-deb-arm64 (push) Waiting to run CI / docker-deb-armv7 (push) Waiting to run CI / gather-artifacts (esp32) (push) Blocked by required conditions CI / gather-artifacts (esp32c3) (push) Blocked by required conditions CI / gather-artifacts (esp32c6) (push) Blocked by required conditions CI / gather-artifacts (esp32s3) (push) Blocked by required conditions CI / gather-artifacts (nrf52840) (push) Blocked by required conditions CI / gather-artifacts (rp2040) (push) Blocked by required conditions CI / gather-artifacts (rp2350) (push) Blocked by required conditions CI / gather-artifacts (stm32) (push) Blocked by required conditions CI / release-artifacts (push) Blocked by required conditions CI / release-firmware (esp32) (push) Blocked by required conditions CI / release-firmware (esp32c3) (push) Blocked by required conditions CI / release-firmware (esp32c6) (push) Blocked by required conditions CI / release-firmware (esp32s3) (push) Blocked by required conditions CI / release-firmware (nrf52840) (push) Blocked by required conditions CI / release-firmware (rp2040) (push) Blocked by required conditions CI / release-firmware (rp2350) (push) Blocked by required conditions CI / release-firmware (stm32) (push) Blocked by required conditions CI / publish-firmware (push) Blocked by required conditions * Start portduino_config refactor * refactor GPIOs to new portduino_config * More portduino_config work * More conversion to portduino_config * Finish portduino_config transition * trunk * yaml output work * Simplify the GPIO config * Trunk | ||
|---|---|---|
| .. | ||
| build.sh | ||
| Dockerfile | ||
| platformio-clusterfuzzlite-post.py | ||
| platformio-clusterfuzzlite-pre.py | ||
| project.yaml | ||
| README.md | ||
| router_fuzzer_seed_corpus.py | ||
| router_fuzzer.cpp | ||
| router_fuzzer.options | ||
ClusterFuzzLite for Meshtastic
This directory contains the fuzzer implementation for Meshtastic using the ClusterFuzzLite framework. See the ClusterFuzzLite documentation for more details.
Running locally
ClusterFuzzLite uses the OSS-Fuzz toolchain. To build the fuzzer manually, first grab a copy of OSS-Fuzz.
git clone https://github.com/google/oss-fuzz.git
cd oss-fuzz
To build the fuzzer, run:
python3 infra/helper.py build_image --external $PATH_TO_MESHTASTIC_FIRMWARE_DIRECTORY
python3 infra/helper.py build_fuzzers --external $PATH_TO_MESHTASTIC_FIRMWARE_DIRECTORY --sanitizer address
To run the fuzzer, run:
python3 infra/helper.py run_fuzzer --external --corpus-dir=<path-to-temp-corpus-dir> $PATH_TO_MESHTASTIC_FIRMWARE_DIRECTORY router_fuzzer
More background on these commands can be found in the ClusterFuzzLite documentation.
router_fuzzer.cpp
This fuzzer submits MeshPacket protos to the Router::enqueueReceivedMessage method. It takes the binary
data from the fuzzer and decodes that data to a MeshPacket using nanopb. A few fields in
the MeshPacket are modified by the fuzzer.
- If the tofield is 0, it will be replaced with the NodeID of the running node.
- If the fromfield is 0, it will be replaced with the NodeID of the running node.
- If the idfield is 0, it will be replaced with an incrementing counter value.
- If the pki_encryptedfield is true, thepublic_keyfield will be populated with the first admin key.
The router_fuzzer_seed_corpus.py file contains a list of MeshPackets. It is run from inside build.sh and
writes the binary MeshPacket protos to files. These files are use used by the fuzzer as its initial seed data,
helping the fuzzer to start off with a few known inputs.
Interpreting a fuzzer crash
If the fuzzer crashes, it'll write the input bytes used for the test case to a file and notify about the location of that file. The contents of the file are a binary serialized MeshPacket protobuf. The following snippet of Python code can be used to parse the file into a human readable form.
from meshtastic.protobuf import mesh_pb2
mesh_pb2.MeshPacket.FromString(open("crash-XXXX-file", "rb").read())
Consider adding any such crash results to the router_fuzzer_seed_corpus.py file to ensure there a isn't
a future regression for that crash test case.