From patchwork Thu Sep 4 13:04:34 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 215 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1756991121; bh=eL1FkqndabxutLqCyaYy6xSiYLBoculVNHJ02KLfyJc=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=ZSBIDb1yTi6P0PHfD2VXYN1wVyxpeYzksvBqgCmtCTWmQpSQMqAY5UsY1pVkLJIlE GdngnCSBl/8bjhtI5BrKzscxYik4QvURt3SWsOBykQt69xLJVJMkVTC0lHXQ0dEGZ0 TyZ3zq3ze7lmoKI0pXVtlmyncL/vy3y3G9avUBFYTZsOzHf9PFIw5BCIqIm7xR72l3 U/FcKFevTbRoeKH/oxpZvnEMCiGG3mfQzcitSC9Hmd6RgTejNiSH3KKltIo3TpNKKx W7FKlTdpIkH6PUXvh3dauab+vMEFOo6ZnRhVy9onMxCymJCKWIhldYPRhweL00U6qB Rw1rNIh6cBLFQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 76DC86795D for ; Thu, 4 Sep 2025 07:05:21 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id VzkD-oT90VKC for ; Thu, 4 Sep 2025 07:05:21 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1756991121; bh=eL1FkqndabxutLqCyaYy6xSiYLBoculVNHJ02KLfyJc=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=ZSBIDb1yTi6P0PHfD2VXYN1wVyxpeYzksvBqgCmtCTWmQpSQMqAY5UsY1pVkLJIlE GdngnCSBl/8bjhtI5BrKzscxYik4QvURt3SWsOBykQt69xLJVJMkVTC0lHXQ0dEGZ0 TyZ3zq3ze7lmoKI0pXVtlmyncL/vy3y3G9avUBFYTZsOzHf9PFIw5BCIqIm7xR72l3 U/FcKFevTbRoeKH/oxpZvnEMCiGG3mfQzcitSC9Hmd6RgTejNiSH3KKltIo3TpNKKx W7FKlTdpIkH6PUXvh3dauab+vMEFOo6ZnRhVy9onMxCymJCKWIhldYPRhweL00U6qB Rw1rNIh6cBLFQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 655046794A for ; Thu, 4 Sep 2025 07:05:21 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1756991120; bh=/zBXMvCwFNCErD/XcrCNIhLs9lb/k8wGSj0DAltCHmQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O5Swg7QcH13fqlHV8Fd6qM7duLxp+GrwEZxwZspoq7NAdip5lXSIdfMAIxhHUr6sp +8qxVsHv+v78vz2Y3Z64tSipcSZbmv9IBoRfsHIWe3KIGK7WWWN8dN9Gd5Baneq4QZ Qrs1AyKy38/mwnEaO6j52cJFrrEp0HgSfWIEIL8etxz1Br98Xde3w/wxDjjI/Vuy7z eE/JGU6Sn+rg+d5BlRONQpgUHeMJYtUB+vWYx9NHVcp667denZQhVYojh54udW/qJE F5KwaWv4O0oZYgC7n+lC/XK6I25mCxQV+rSO5z0xnp7EOCruR9PsiKU3e0Df9SLluZ JddT5R0Bxt3nA== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 1D29367886; Thu, 4 Sep 2025 07:05:20 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id x9bWPp-jUQrL; Thu, 4 Sep 2025 07:05:20 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1756991115; bh=Bz1I4fY9QjhDZVmm6qRYP7+u6EZR5SoHuVkeLrE58OQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KU7Sd0L8wmKmVhJPin+vwCnhEJTRFPgakypDYBZdIw7I0SE3qFqQr7V1raQCCS5h0 VE5aPO+RbpDEzCtH7cF17ry8k5Kag9WQFPoGPHRVTXBjfDJq+mcor7wlDXNjQUAoKl HUJx4qiWD4MJG/A9IerSS+hbEO6WNljn3bKPCIZc2qenmMkE8+tghGwoFO3EXnzfL9 RW48DDGMeSGM6hyupVmMGgE018ce1BfQYCyFtuHgPmpGF4PCe+QBtWA8U7BSsqmjha B1SKpxSOPYxmbKYXBGk0jaa8kIeNTuHHWFcpgW8XQgyWdK/RPIq+gK/kPjXEAoO2pj hdQPyDZOoe5Rw== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 8DA74678AB; Thu, 4 Sep 2025 07:05:15 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Thu, 4 Sep 2025 07:04:34 -0600 Message-ID: <20250904130459.848794-2-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250904130459.848794-1-sjg@u-boot.org> References: <20250904130459.848794-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: JWIF2L53NYH4CFZ3YR6J22POK2FNSJQ6 X-Message-ID-Hash: JWIF2L53NYH4CFZ3YR6J22POK2FNSJQ6 X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 01/18] doc: Add fuzzing build documentation List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add some docs for using fuzzing with U-Boot, including building, running tests, and adding new tests. Co-developed-by: Claude Signed-off-by: Simon Glass --- doc/build/fuzz.rst | 219 ++++++++++++++++++++++++++++++++++++++++++++ doc/build/index.rst | 1 + 2 files changed, 220 insertions(+) create mode 100644 doc/build/fuzz.rst diff --git a/doc/build/fuzz.rst b/doc/build/fuzz.rst new file mode 100644 index 00000000000..4c05df4dc21 --- /dev/null +++ b/doc/build/fuzz.rst @@ -0,0 +1,219 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Building U-Boot with Fuzzing Support +===================================== + +U-Boot supports fuzzing through libFuzzer when built for the sandbox +architecture. Fuzzing helps identify security vulnerabilities and crashes by +testing with randomly generated inputs. + +Prerequisites +------------- + +The following tools are required: + +* Clang compiler with fuzzing support +* libstdc++ development libraries + +On Ubuntu/Debian systems, install the required packages:: + + sudo apt install clang libstdc++-dev + +Building with Fuzzing +--------------------- + +The recommended approach is to use buildman, which handles the configuration +automatically: + +1. Build with buildman (recommended):: + + buildman --bo sandbox -a FUZZ=y -O clang -L -o /tmp/fuzz -w + +The buildman options: + +* ``--booard sandbox`` - Build for sandbox board only +* ``-a FUZZ=y`` - Enable fuzzing support via CONFIG_FUZZ=y +* ``-O clang`` - Use Clang compiler (required for fuzzing) +* ``-L`` - Disable LTO to avoid sanitizer coverage linker issues +* ``-o /tmp/fuzz`` - Output directory +* ``-w`` - Use the output directory as the work directory + +Alternative: Manual build +~~~~~~~~~~~~~~~~~~~~~~~~~ + +To build manually with make: + +1. Configure the build with fuzzing enabled:: + + make HOSTCC=clang CC=clang O=/tmp/fuzz LTO_ENABLE= sandbox_defconfig + scripts/config --file /tmp/fuzz/.config --enable FUZZ + +2. Build the fuzzing-enabled binary:: + + make HOSTCC=clang CC=clang O=/tmp/fuzz LTO_ENABLE= -j$(nproc) + +Build Output +------------ + +The fuzzing build produces: + +* ``u-boot`` - Main fuzzing binary with AddressSanitizer and fuzzer + instrumentation +* Significantly larger binary size due to instrumentation (typically 40-50MB) +* Debug symbols included for better crash analysis + +Fuzzing Architecture +-------------------- + +The U-Boot fuzzing implementation consists of: + +* **Fuzzing Engine**: Sandbox-specific driver that interfaces with libFuzzer +* **Threading Model**: Separate threads for fuzzing harness and U-Boot + execution +* **Input Handling**: ``LLVMFuzzerTestOneInput()`` entry point processes + fuzz inputs +* **Command Fuzzing**: Tests U-Boot commands with generated inputs via + ``fuzz`` command + +Key source files: + +* ``arch/sandbox/cpu/fuzz.c`` - Main fuzzing implementation +* ``drivers/fuzz/`` - Fuzzing engine drivers +* ``test/fuzz/`` - Fuzzing test cases +* ``include/fuzzing_engine.h`` - Fuzzing engine interface + +Running Fuzz Tests +------------------ + +To run fuzzing tests, set the test name via environment variable and run the +fuzzing binary from the build directory: + +1. Change to the build directory:: + + cd /tmp/fuzz + +2. Set the fuzz test to run:: + + export UBOOT_SB_FUZZ_TEST=fuzz_vring + +3. Run the fuzzer:: + + ./u-boot + +The fuzzer will start libFuzzer with coverage-guided input generation. You +should see output similar to:: + + INFO: Running with entropic power schedule (0xFF, 100). + INFO: Seed: 1626867009 + INFO: Loaded 1 modules (104150 inline 8-bit counters): ... + #2 INITED cov: 28 ft: 29 corp: 1/1b exec/s: 0 rss: 318Mb + #4 NEW cov: 29 ft: 30 corp: 2/3b lim: 4 exec/s: 0 rss: 319Mb + +Available fuzz tests include: + +* ``fuzz_vring`` - Tests VirtIO ring buffer handling + +To stop fuzzing, use Ctrl+C. The fuzzer will automatically save any crash- +inducing inputs for later analysis. + +Understanding Fuzzer Output +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The fuzzer output shows: + +* ``cov: N`` - Number of code coverage points reached +* ``ft: N`` - Number of features discovered +* ``corp: N/Mb`` - Corpus size (number of test cases / total bytes) +* ``exec/s: N`` - Executions per second (performance metric) +* ``rss: NMb`` - Memory usage + +Error messages from the target code (like VirtIO "out of range" errors) are +expected and indicate the fuzzer is finding edge cases. + +Adding New Fuzz Tests +--------------------- + +To create a new fuzz test, follow these steps: + +1. **Create the test file** in ``test/fuzz/`` directory:: + + /* SPDX-License-Identifier: GPL-2.0+ */ + #include + + static int fuzz_my_component(const uint8_t *data, size_t size) + { + /* Your fuzzing logic here */ + if (size < 4) + return 0; /* Not enough data */ + + /* Test your component with fuzzed data */ + my_component_function(data, size); + + return 0; + } + FUZZ_TEST(fuzz_my_component, 0); + +2. **Add to Makefile** in ``test/fuzz/Makefile``:: + + obj-$(CONFIG_MY_COMPONENT) += my_component.o + + Or for tests that should always be included:: + + obj-y += my_component.o + +3. **Test the new fuzzer**:: + + export UBOOT_SB_FUZZ_TEST=fuzz_my_component + ./u-boot + +**Best practices for fuzz tests:** + +* **Input validation**: Check minimum data size requirements +* **Error handling**: Handle invalid inputs gracefully, don't panic +* **Resource cleanup**: Free any allocated resources +* **Focused testing**: Target specific functions or code paths +* **Deterministic**: Same input should produce same behavior + +**Example patterns:** + +* Parse structured data (protocols, file formats) +* Test buffer handling with varying sizes +* Exercise error paths with malformed inputs +* Stress test with boundary conditions + +Troubleshooting +--------------- + +**Linker errors about missing libstdc++**: + Install libstdc++ development libraries as shown in Prerequisites. + +**Sanitizer coverage linker errors**: + Ensure LTO is disabled with ``LTO_ENABLE=`` in the make command. + +**Build fails with GCC**: + Fuzzing requires Clang. Ensure both CC and HOSTCC are set to clang. + +**Fuzzer exits with "fdtdec_setup() failed"**: + Run the fuzzer from the build directory where u-boot.dtb is located. + The sandbox requires access to its device tree file. + +Security Considerations +----------------------- + +Fuzzing builds include: + +* **AddressSanitizer**: Detects buffer overflows, use-after-free, and other + memory errors +* **Fuzzer Coverage**: Instruments code for coverage-guided fuzzing +* **Debug Information**: Retained for crash analysis and debugging + +These features significantly increase binary size and runtime overhead, making +fuzzing builds unsuitable for production use. + +Further Reading +--------------- + +* :doc:`/arch/sandbox/sandbox` - General sandbox architecture documentation +* libFuzzer documentation: https://llvm.org/docs/LibFuzzer.html +* AddressSanitizer documentation: + https://clang.llvm.org/docs/AddressSanitizer.html diff --git a/doc/build/index.rst b/doc/build/index.rst index 7a4507b5746..bd380a5e6c2 100644 --- a/doc/build/index.rst +++ b/doc/build/index.rst @@ -9,6 +9,7 @@ Build U-Boot source gcc clang + fuzz reproducible docker tools