Targeted Fuzzing for Unsafe Rust Code: Leveraging Selective Instrumentation
David Paaßen, Jens-Rene Giesen, Lucas Davi
TL;DR
This work addresses the persistence of memory-safety vulnerabilities in Rust, which are concentrated in unsafe code. It introduces FourFuzz, a targeted fuzzing approach that uses partial instrumentation to focus coverage feedback on code paths that can reach unsafe blocks, implemented by patching the Rust/LLVMtoolchain to generate a block list from a compiled call graph and an unsafe-function map. The method achieves faster discovery of unsafe-code locations and finds more such locations across real-world Rust projects, while incurring no overhead during fuzzing and requiring only about 20% of the program functions to be instrumented. A compiler extension and a path-finder module enable accurate unsafe-code detection across dependencies, though the approach depends on reliable call-graph data, as demonstrated by a Naga case study. Overall, FourFuzz demonstrates that selective instrumentation is a viable and effective strategy for enhancing Rust fuzzing performance and security coverage with practical deployment considerations.
Abstract
Rust is a promising programming language that focuses on concurrency, usability, and security. It is used in production code by major industry players and got recommended by government bodies. Rust provides strong security guarantees achieved by design utilizing the concepts of ownership and borrowing. However, Rust allows programmers to write unsafe code which is not subject to the strict Rust security policy. Empirical studies show that security issues in practice always involve code written in unsafe Rust. In this paper, we present the first approach that utilizes selective code coverage feedback to focus the fuzzing efforts on unsafe Rust code. Our approach significantly improves the efficiency when fuzzing Rust programs and does not require additional computational resources while fuzz testing the target. To quantify the impact of partial code instrumentation, we implement our approach by extending the capabilities of the Rust compiler toolchain. We present an automated approach to detect unsafe and safe code components to decide which parts of the program a fuzzer should focus on when running a fuzzing campaign to find vulnerabilities in Rust programs. Our approach is fully compatible with existing fuzzing implementations and does not require complex manual work, thus retaining the existing high usability standard. Focusing on unsafe code, our implementation allows us to generate inputs that trigger more unsafe code locations with statistical significance and therefore is able to detect potential vulnerabilities in a shorter time span while imposing no performance overhead during fuzzing itself.
