A secure coding standard for embedded software

The CERT® C and CERT C++ coding standards are secure coding practices for the C and C++ languages. Security vulnerabilities in embedded software increase chances of attacks from malicious actors. These attacks inject malware, steal information, or perform other unauthorized tasks. Secure coding practices plug these vulnerabilities and effectively reduce the surface of attack.

Why Is CERT C Important for Embedded Systems?

Embedded systems use handwritten or generated code in programming languages such as C. Although this language allows low-level operations such as direct memory access, the associated security risks are also higher. If an attacker gains control of a system, the consequences can be catastrophic.

Certain code constructs in the C language introduce security vulnerabilities. Malicious actors can exploit these vulnerabilities and perform operations such as code injection, buffer overflow, and arc injection.

For example, take this very simple case:

#define SIZE100 100
extern int tab[SIZE100];
int lookup(int n, int aFlag) 
{
    if(!aFlag &&  n < SIZE100)
      return tab[n];    
    else 
      return -1;
}

The lookup function has an obvious vulnerability to a buffer overflow since the parameter n is not checked for negative values before use as array index. Negative values can cause an out-of-bounds array index, expose restricted information, or allow modification of the contents of a restricted memory location. The buffer overflow can also risk introduction of malicious code that changes the course of execution and adversely affects the functional safety of the system.

CERT C rules and recommendations help reduce such risks by eliminating certain vulnerable code constructs from embedded software. CERT C is especially focused on secure coding in the C language, but organizations also use CWE, ISO/IEC TS 17961, MISRA® C:2012 Amendment 1, and other standards, or develop their own standards for secure coding. The CERT C standard was developed following a community-based development process managed by the Software Engineering Institute (SEI) affiliated with Carnegie Mellon University. The CERT C guidelines are available on the CERT Secure Coding wiki. A similar standard, CERT C++, was developed for the C++ language.

How Do I Ensure Compliance with CERT C?

CERT C guidelines are written in the form of rules and recommendations. A guideline is labeled as a:

  • Rule if a violation is most likely to cause a defect and if conformance can be established through automatic or manual inspection of the code alone without requiring additional assumptions. For instance, ARR30-C (“Do not form or use out-of-bounds pointers or array subscripts”) is a rule.
  • Recommendation if conformance improves the safety and security of software systems but a violation does not necessarily result in a defect. For instance, ARR02-C (“Explicitly specify array bounds, even if implicitly defined by an initializer”) is a recommendation.

The CERT C rules can be checked manually, but looking at hundreds of thousands, sometimes millions, of lines of code for rule violations is often not practical. Therefore, CERT C recommends use of static code analysis tools to ensure compliance.

Typically, a static code analysis tool checks for security-related defects, such as tainted data, along with underlying software weaknesses, such as static and dynamic memory defects, numerical defects, and data flow defects. Many of these defects come from violations of CERT C rules. Static analysis tools can thus automatically check for CERT C rule violations.

Checking CERT C Compliance with Polyspace® Static Code Analysis Tools

Polyspace Bug Finder™ is a static code analysis tool that supports the CERT C Secure Coding Standard out of the box. Using Polyspace Bug Finder, a developer or quality engineer can simply choose to check all or select CERT C rules and find violations without performing any additional configuration.

For instance, in the code snippet shown earlier, Polyspace Bug Finder finds a violation of CERT C Rule ARR30-C (“Do not form or use out-of-bounds pointers or array subscripts”) by detecting the array access out-of-bounds or buffer overflow defect. This violation is reported with rule information, location in code, and possible risks and fixes.

Detecting CERT C violations using Polyspace Bug Finder.

In addition to supporting almost all CERT C rules and many CERT C recommendations, Polyspace Bug Finder also supports related coding standards such as CWE, ISO/IEC TS 17961, MISRA C:2012 Amendment 1, and a significant portion of the CERT C++ Coding Standard.

With Polyspace Code Prover™, an additional layer of checking is available. When Polyspace Bug Finder reports a violation, you could run Polyspace Code Prover to exhaustively check for the absence of other such violations in the software. For example, suppose you fix the previous violation by checking the array index for negative values like this:

#define SIZE100 100
extern int tab[SIZE100];
int lookup(int n, int aFlag) 
{
    if(aFlag &&  (n<0 || n >= SIZE100))
      return -1;
    return tab[n];
}

Did that fix the issue? You can run Polyspace Bug Finder and see that rule ARR30-C is still violated. To get further insight, you can run Polyspace Code Prover. With the deeper analysis, you see that depending on the value of aFlag, the value of n might not be constrained at all and there is still the possibility of the out-of-bounds array index. You can then rework the code until Polyspace Code Prover proves the absence of the out-of-bounds index, as indicated by a green check mark.

Out-of-bounds array index checking using Polyspace Code Prover.

In summary, you can automate checking of almost all CERT C rules and a significant number of CERT C recommendations with Polyspace Bug Finder. You can gain further insight into issues with Polyspace Code Prover and, for specific rules, exhaustively check your code and prove the absence of those issues.

To learn more about the embedded security capabilities of Polyspace products, contact the expert.

See also: static analysis, verification, embedded systems, software quality objectives, software QA

7 façons de sécuriser les logiciels embarqués