Writing Secure C++ Software for Automotive using AUTOSAR C++ Guidelines
Our previous blog discussed MISRA guidelines for automotive applications, with a focus on the C++ language. This blog explores the AUTOSAR C++ 14 guidelines and compares them with MISRA C++.
There has been a resurgence of interest in the C++ language in recent years. At the OpenCpp 2016 conference, the designer of C++ Bjarne Stroustrup attributed this newfound interest to the stagnation of CPU speed, which left developers looking for new ways to optimize performance. It also coincided with the C++ 11 standard, which was a major progression from the previous C++ 03 standard.
These standards maintain the basic principle of C++, offering a highly efficient language that controls hardware. Based on the C language with its basic data types and instructions, in the future the language is expected to be able to better use the novel hardware (caches, multicore, GPUs, FPGA, etc.). Another important principle of C++ is zero-overhead abstraction, i.e. maintaining the benefits of Object Oriented Programming (OOP) features with no overhead. Going forward, there are plans to add even better concurrency handling and improved type and resource safety.
The figure below illustrates the history of the C++ language and shows when the various standards were released. The diagram shows when the automotive C++ guidelines (MISRA and AUTOSAR) were released as well.
The first official C++ standard, which is sometimes referred to as C++98 was published in 1998 (C++ ISO/IEC 14882:1998). In 2003 the standard was revised based on reported problems with the 1998 standard. The changed standard was dubbed C++03. C++03 primarily fixes bugs with the previous standard and created only one new language feature: value initialization.
In 2011 C++11 was published, bringing a few additions to the core language in areas such as multithreading support, generic programming support, uniform initialization, and performance. With C++11, significant changes were also made to the C++ Standard Library. One of the design goals of C++ is to prefer changes to the libraries over changes to the core language. That’s why more than 50% of the standard is the standard library.
In 2014 a new standard (called C++14) was released, which includes a small extension over C++11, featuring mainly bug fixes and small improvements.
At the end of 2017 a new standard was approved (C++17). It introduced many new language features and additions to the standard library.
C++ in Automotive
C++98 (C++ 03) is still widely used, especially in the automotive industry. This is due in part to the longer cycles for CPU development in automotive as well as the corresponding compiler technologies. The MISRA C++:2008 standard covers only C++03 features. The AUTOSAR C++ guidelines discussed in this blog covers the C++14 standard.
The previous blog about MISRA discussed some of the drawbacks of C++ that come from its complexity and are often misunderstood, even by experienced developers. New language standards try to overcome this.
On the other hand, using the latest compiler and language feature might not always be correct, especially considering that many of these features are not proven and might have unknown security risks. For example, it will probably take a few years before C++17 standard is adopted by the automotive industry and any coding guidelines are created.
AUTOSAR C++ Guidelines
In early 2017 the AUTOSAR (AUTomotive Open System ARchitecture) consortium released C++ coding guidelines called “Guidelines for the use of the C++14 language in critical and safety-related systems” and referred to here as AUTOSAR guidelines. These guidelines are intended to fill in the gap created by the lack of appropriate coding standards for C++14 or C++11 in critical and safety-related software, and specifically as an extension of the MISRA C++ guidelines.
The guidelines are available here: https://www.autosar.org/fileadmin/user_upload/standards/adaptive/17-03/AUTOSAR_RS_CPP14Guidelines.pdf
The original MISRA C++ document completely disallowed dynamic memory and did not cover standard libraries and security. The new AUTOSAR document defines how to use dynamic memory, exceptions, templates, inheritance and virtual functions.
The AUTOSAR document is defined as an update of MISRA C++ (2008) guidelines. As a result, some of the rules are adopted from MISRA C++ without modifications and are not described in the AUTOSAR guidelines themselves. This requires the reader of the AUTOSAR guidelines to be familiar with and have access to the MISRA C++:2008 guidelines to understand the full rationale for non-modified rules.
The AUOTSAR standard specifies 342 rules, from which:
- 154 rules are adopted without modifications from MISRA C++:2008.
- 131 rules are derived/based on existing C++ standards
- 57 rules are based on research or other literature or resources.
The rule set for C++ standard libraries is only partially covered and not complete.
Like the MISRA C++ guidelines, the rules in the AUTOSAR guidelines are divided into “Required” and “Advisory” categories. Required rules are mandatory and advisory rules should be followed where reasonably practical.
Dynamic Memory Allocation Rules
The previous blog discussed the requirement of not using dynamic memory imposed by MISRA C++ standard via Rule 18-4-1. AUTOSAR relaxes this requirement, acknowledging that dynamic memory allocation is needed for the standard libraries, but imposes restrictions on the software to ensure that memory allocations are deterministic in the worst-case scenarios, there is no memory fragmentation and the application does not run out of memory.
The dynamic memory related rules can be found under section A18-5-x of the AUTOSAR guidelines. Specifically, rule A18-5-5 prescribes using custom memory management functions to address the main problems related to dynamic memory management:
- Non-deterministic worst-case execution time of allocation and deallocation
- Invalid memory access
- Mismatched allocations and deallocations
- Memory fragmentation
- Running out of memory
For example, to prevent running out of memory the application needs to pre-allocate enough memory during startup, based on its maximal memory needs.
Also, the memory management functions need to be executed without context switch and without syscalls to guarantee the worst-case execution time.
When external C++ libraries which use dynamic memory operations are used, the memory management module needs to provide custom implementation of C++ new and delete operators, as well as implementation of malloc and free operations. This way, it can replace the incorrect dynamic memory allocation/deallocation in the linked libraries.
Furthermore, rule A18-5-6 mandates that an analysis shall be performed to analyze the failure modes of dynamic memory management, i.e. for each of the dynamic memory allocation problems listed above. As some of the standard C++ library implementations violate one or more of the above requirements, the dynamic memory management module needs to provide custom memory allocators in those cases.
With Rule 18-5-7, AUTOSAR allows implementation of non-real-time dynamic memory management functions, during the non-real-time program phases.
The AUTOSAR C++ guidelines document does not specifically list how an organization can claim compliance. However, as it claims to be an extension of the MISRA C++:2008 standard, one can assume that it has the same compliance requirements.
According to the guidelines, MISRA C++ compliance can be claimed for a given product (and not for an organization) by stating that evidence exists to show:
- There is a compliance matrix showing how compliance has been enforced.
- All the C++ code in the product is compliant with the rules from the MISRA C++ guidelines or are subject to documented deviations.
- There is a list of instances where the rules have not been followed with an appropriately signed-off deviation for each instance.
- There are well documented software development practices that include training, style guide, compiler selection and validation, checking tool validation, metrics and test coverage.
The MISRA guidelines recognize that there may be instances where it is necessary to deviate from the rules in the document. A formal procedure therefore must be created that gives authorization to deviate from the rules rather than allowing individual programmers to deviate at will. The guidelines prescribe a sign-off procedure for each deviation, or class of deviations. The deviation must be justified and well documented. A good practice is to structure the code in such way that that modules with deviations are separate from the rest of the code and are clearly documented.
Most of the rules in the AUTOSAR C++ guidelines are automatically enforceable by static analysis. Some are partially enforceable or even non-enforceable and need to be enforced by a manual code review.
Although the AUTOSAR C++ guidelines are relatively new, many of the commercial static analysis tool providers already offer modules that check compliance.
As covered in the previous blog, MISRA C/C++ is the de facto coding standard for automotive systems. However, it does not cover some of the later C++ language improvements nor reflect knowledge from some of the more recent security breaches and vulnerabilities. The new AUTOSAR C++ 14 guidelines extends the previous MISRA standard in those areas. Because it comes from an automotive consortium and it is supported by tool vendors, it is likely to become the next automotive C++ guidelines standard and replace MISRA C++:2008.