🤖 AI Summary
Existing formal methods struggle to effectively verify non-functional requirements—such as interface-level control-flow and data-flow constraints—in embedded automotive C code, particularly when untrusted code introduces safety risks. This work proposes an interface contract language tailored for C modules, extending ACSL functional contracts, and implements a dedicated verification plugin within the Frama-C framework to enable static verification of non-functional properties, including function call validity and variable initialization. The approach innovatively establishes a rule set focused on module interactions, addressing limitations of conventional standards like MISRA-C in capturing interface constraints. The methodology has been successfully applied to two safety-critical codebases from Scania trucks, demonstrating end-to-end translation of system-level requirements into verifiable contracts and their automated validation.
📝 Abstract
Code contracts provide a robust way to specify functional requirements of safety-critical software in embedded systems. For example, the ANSI/ISO C Specification Language (ACSL) can be used to specify the functional behavior of C code that is then formally verified by the Frama-C framework's Wp plugin. However, non-functional requirements, such as restrictions on control flow and data flow, are also important for embedded systems safety. Untrusted code developed by subcontractors, junior developers, or generated by large language models, can be verified by Wp but may nevertheless call unsafe functions or use uninitialized program variables. To address this problem, we constructed a set of general rules concerning non-functional requirements of C code in safety-critical embedded systems. Our rules are orthogonal to popular C rulesets such as MISRA-C and center on modules and their interaction through interfaces. To enable checking our rules, we propose an interface specification contract language for C modules. We implemented a checker for our rules as a Frama-C plugin, which takes as input a C module and its contract and checks control flow and data flow properties, ensuring, e.g., that only permitted functions are called by the module. We integrated our checker in a toolchain to enable specification and verification of module contracts and ACSL contracts for untrusted code. We report on two case studies on safety-critical C code using software in Scania trucks, where we defined module contracts and ACSL function contracts based on informal system requirements and verified them using our toolchain.