Securing low-level code with minimal developer efforts: from preventing type confusion by design to automated library fuzzing
Software is pervasive in our daily lives. From remote-controlled traffic lights that orchestrate traffic flows to applications reminding us to take medications, it increasingly governs safety-critical systems. To ensure correct and continuous execution, bugs have to be detected before the software is rolled out in production. Low-level codeâ used in performance-critical or resource constrained environmentâ is often written in languages with limited security guarantees. Specifically, C and C++ lack type- and memory-safety, making them prone to bugs. As manual efforts do not scale to the size of contemporary codebases, this thesis addresses the challenge of securing system code through techniques requiring minimal manual effort. We tackle this challenge along three dimensions: a language-level protection against derived type confusions, a detector for all type confusions during testing, and lastly a novel approach to automate fuzzing of software libraries. Our first contribution addresses illegal type conversions in C++ programs. Casting objects through an inheritance hierarchy, a common operation in C++, may lead to exploitable type confusion vulnerabilities. We propose type++, a novel C++ dialect that prohibits derived type confusions by design. By inlining type information in all objects involved in derived casts, type checks are performed at runtime for all casts, ensuring type safety. The change in object layout requires minimal patching and incurs minimal runtime overheadâ less than 1% overhead on the SPEC CPU benchmarks, allowing type++ to discover 14 new vulnerabilities. Our second contribution is Sourcerer, a comprehensive type confusion sanitizer. By instrument- ing objects involved in unrelated casts on top of type++, Sourcerer detects all type confusions. Through a specialized type information initializer, RTTIInit, we reduce the porting effort and the performance impact. Sourcerer supports complex idioms such as unions, which were problematic for previous tools. With a performance overhead of only 5%, Sourcerer verifies twice as many unrelated casts as type++ on the SPEC CPU benchmarks. Notably, Sourcerer is the first sanitizer used for a fuzzing campaign specifically aimed at type confusions. Instrumenting OpenCV, we discover six new type confusions using seven fuzz drivers. Lastly, we present libErator, a novel consumer-agnostic fuzz driver generator. Fuzzing relies on executing the code which is not directly possible for software libraries. Through static analysis and rapid feedback, libErator generates valid C drivers, exercising diverse and complex library functions. This addresses the limited development resources available for driver creation. Our evaluation shows that libErator achieves higher coverage in most libraries compared to the state-of-the-art and matches the coverage of manually written drivers. Notably, libErator discovers bugs in extensively tested libraries where other approaches fail. Finally, we characterize the trade-off between generating and testing drivers, a balance that libErator is first to fully explore. This thesis demonstrates how novel approaches enhance the security of system code with minimal developer effort. By preventing most type confusions and detecting the rest, we offer a comprehensive solution to address the lack of type safety in C++. For C libraries, libErator improves the testing workflow and scales to the numerous libraries underpinning todayâ s software ecosystem.
EPFL_TH10776.pdf
Main Document
Not Applicable (or Unknown)
openaccess
N/A
11.15 MB
Adobe PDF
1208f2cb38bd5879bc6e4da5d0621bdc