In this post, we will compare the MISRA C 2012 standard with C2, and guide you through the journey of switching to the new standard. We will explain why MISRA's compliance is necessary to build secure embedded systems.
At Secure Code Warrior, we are always looking to expand our training coverage. To empower embedded developers and security managers to build secure embedded systems, we are tapping into the world of embedded systems security. In this post, we will talk about the MISRA C 2012 standard, and why its compliance is necessary to build secure embedded systems.
While writing code in C, it’s very easy to implement things that seemingly look right, but are inherently wrong. Your code may compile just fine, and even run well for a certain period of time. But the same code could crash, or exhibit undefined behavior, if your input size and/or memory grows. For example, a particular input number causing an integer to overflow, or a particular sequence of characters causing an array to go out-of-bounds.
This is where the MISRA C coding standard can help. The rules, guidelines, and best practices laid out by the standard, enable developers to write safe and reliable C code for embedded development.
MISRA C 2012, the latest version of the standard, adds new rules, enhances existing ones, and addresses some discrepancies. If you are still using an older version, now would be a great time to switch.
The MISRA C standard includes code safety, portability, and reliability guidelines for the C programming language. The first set of guidelines was released in 1998, which were specific to the C language.
However, since then, the MISRA Consortium also develops coding standards for C++. Every MISRA C document contains a set of rules, non-compliant examples, and detailed sections on the background information that contributed to the development of said rules.
C and C++ are the most widely used languages to develop embedded software. One of the main reasons is that they are fast, having only 1 or 2 levels of abstraction over machine language. But this also means that writing safe code, particularly in C, is difficult, and prone-to-error. For example, in most high-level languages like Java and C#, you don’t have to worry about trivial things like garbage collection or dynamic typing.
However, in C, there’s no predefined way to collect garbage, i.e. if you allocate a piece of memory for a data structure, you have to manually free it yourself, once you are done using it. If you don’t, C, unlike other languages, will not free the memory for you, which will lead to a memory leak.
MISRA C: 2012, also known as C3, was first released in April 2013. Drawing knowledge from the works of thousands of people and organizations, C3 adds new rules, enhances the explanation and backgrounds of some existing rules, and closes some loopholes.
C3 supports the C99 version of the language, while also maintaining rules for the older ISO C90. The main focus area in C3 was to reduce the usual costs of rule enforcement, while also making the use of the C language safer in critical systems. All this makes it prudent to switch to the new standard, if you haven’t already.
Overall, here’s a list of the most significant changes:
Enough talk, now it’s time to get hands-on with some MISRA C rules, with examples of how they apply.
The standard library functions memcpy, memmove, and memcmp perform byte-by-byte move or comparison of the specified number of bytes. The Rule 21.15 of MISRA C 2012 standard dictates that the two function parameters should be pointers to the same type. A function call with incompatible pointer types could indicate a mistake.
Consider the following image, taken from the official MISRA compliance document. The rule is required, decidable, and applies to both C90 and C99.
An example follows the rule description.
As you can see, since the objects are of different types (uint8_t and uint16_t), this is a non-compliant solution.
String handling functions from <string.h> that don’t take the length as an input, shouldn’t result in out-of-bound access. The relevant functions are: strcat, strchr, strcmp, strcoll, strcpy, strcspn, strlen, strpbrk, strrchr, strspn, strrstr, and strtok. The rule is mandatory, meaning it can never be breached, under any circumstances. It applies to both C90 and C99, and is undecidable.
The corresponding example is:
As you can see, strcpy in function f1, will copy beyond the length of the string, which can only hold 5 characters. We also have a compliant and safe use of strcpy, where the string will only get copied, if the contents of “str” will fit.
Dir 4.14 recommends checking the validity of data received from “external” sources. External input can be:
This directive falls in the required category, and is applicable to both C90 and C99. The rationale for this is that a program has no control over data received from external sources, which means that this data can be invalid or malicious. E.g. a program expects a user to input a number, but the user enters a string. Before processing the input, the program must verify that it’s indeed a number.
Switching to MISRA C 2012 will require an update in your coding guidelines document. If you don’t use one, and instead rely on a static analysis tool (which is the recommended choice), you may have to get a newer version of the tool. Here are three tools that check for MISRA C 2012 compliance:
There are also a few compilers that can test for MISRA compliance. In case a rule violation is detected, warnings or exceptions are raised accordingly. E.g. Green Hills Software provides compilers with support for all MISRA standards, for both 32-bit and 64-bit architectures.
Secure Code Warrior's flagship product - learning platform - has numerous interactive challenges, courses, and assessments that can help train developers to write secure C/C++ code. The content on the platform is framework-specific and highly engaging. Our C/C++:Embed coding challenges took inspirations from both MISRA C, AUTOSAR C++ (MISRA C++), and IEC.
Developers can embark on personalized learning journeys, where they identify C/C++-specific vulnerabilities and more importantly learn to fix those bugs. In this process, developers can keep track of their progress to identify their weaknesses, and even enjoy a friendly coding competitions with their peers. Find out more about how we help automotive and transportation industries with our solutions.
Want to find out how interactive and embed-focus our challenges are? Try some C/C++:Embed challenges on the learning platform today!