A practical guide to make your legacy codebase MISRA C 2012 compliant
Add bookmarkProblem Statement
Making legacy code fully compliant with MISRA C 2012[2] coding guidelines is a rather daunting task. The original MISRA principles were created to be applied as code being developed. Even the document itself has a warning "...a project that checks for MISRA C compliance late in its cycle is likely to spend a considerable amount of time re-coding, re-reviewing and re-testing. It's therefore expected that the software development process will require the early application of MISRA C principles.".[2]
In reality, many organizations still need to reuse their legacy codebases for business reasons, and satisfy regulatory requirements such as coding standards like MISRA C. The MISRA Consortium recognized this challenge and the "MISRA Compliance :2016" [3] guidance document was created in response to these challenges and clearly distinguishes between the native code that is developed in the scope of a current project from the "adopted" code, which was developed outside of the scope of a project.
Even with this delineation, the situation in many cases is not black and white. There are plenty of engineering houses that develop an initial prototype or even a fully functional product without following any MISRA guidelines, and then management realizes that MISRA compliance is a requirement for a derivative product. Typically, the legacy codebase was never developed with any coding guidelines in mind. It cannot be automatically classified as “adopted code” because it will be updated in a context of a new project. If this is a familiar situation, this paper is for you.
The Initial Shock
All too often, initial scans of the codebase via a static analysis tool with all MISRA C 2012 rules enabled, including the Amendment 1 [1], produces tens of thousands of violations. After the initial shock, teams begin to find creative ways of addressing the violations. It’s important for development teams not to be deterred – there is light at the end of the tunnel.
Over time, the author has collected and identified best practices and approaches that development teams have used to make the code compliant while not interfering with the ongoing development velocity. In this paper, some practical, balanced approaches to make existing codebases MISRA compliant are outlined.
Disclaimer: suggestions below are not official recommendation from Parasoft or the MISRA Consortium, but rather an overview of practical ways to approach an existing problem.
Use the MISRA Compliance:2016 framework
Before describing how to use the MISRA Compliance: 2016 document with legacy code compliance, let’s take a step back and reflect on the difference between the compliance framework and coding guidelines.
MISRA C 2012 is a set of coding guidelines for the C programming language. The focus of the standard is increasing safety of software by preemptively prevent programmers from making coding mistakes that can lead to runtime failures (and possible safety concerns) by avoiding known problem constructs in the C language. Over the years, many developers of embedded systems were (and still are) complaining that MISRA C is too stringent of a standard and that the cost of writing fully compliant code is not justified. What is interesting, however, is that those same developers do agree that some MISRA rules are practical and provide real value to protect the programmers from making mistakes when using undefined or unspecified programming language features or dealing with pointers, type system, and memory allocation. This paper doesn’t argue one way or another, but rather focuses on reasonable approaches that teams can apply to achieve compliance efficiently.
To summarize, development teams on one end of the spectrum are expressing that MISRA "is too stringent – the cost outweighs the benefits" and on the other end teams are aware that "there is a need for a coding standard to prevent errors ". Hence the truth is somewhere in the middle and the value of applying the standard to a project depends on factors such as
- Risk of a system malfunction because of a software failure
- Cost of a system failure to the business
- Development tools and target platform
- Level of developer's expertise
There is a need for a framework that allows programmers to find a practical middle ground that satisfies the spirit of the standard and still claim MISRA compliance without wasting effort on non-value-added activities.
In the document "MISRA Compliance: 2016" [3] the MISRA Consortium provides the response that was needed by the community. It provides reasonably well-defined framework of what the statement "MISRA Compliant" truly means. The document is helping organization to use a common language articulating the compliance requirements by defining the following artifacts:
- Guideline Enforcement Plan - demonstrates how each MISRA guideline is verified.
- Guideline Re-categorization Plan - communicates the agreed upon severity of individual rules in the guidelines as part of the vendor/client relationship.
- Deviations report - documents the violations of guidelines with appropriate rationale.
- Guidelines compliance summary - is the primary record of overall project compliance.
The focus on what to do with a legacy codebase, the key document is the Guideline Re-categorization plan. This document captures all directives and rules and identifies which categories have been recategorized. For example, the following diagram shows part of re-categorization plan:
First, for the “adopted” legacy code, the MISRA 2016: Compliance document suggests that all re-categorizations from a less stringent to a more stringent classification should not be applied. In other words, if the development team decides to re-classify some Required rules and directives as Mandatory, or Advisory rules as Required, then these re-categorizations don’t have to apply to the legacy codebase. In addition, it’s possible to dis-apply Advisory rules all together after reviewing the types of violations with the team.
The requirement to document deviations is only necessary for all Required rules. Any violations in adopted code should be reviewed and deviations need to clearly state that violation does not compromise safety and security. Note that If there is a finding that that shows that safety or security of the system can be compromised – the issue must be fixed. Also, keep in mind that blindly making changes to the legacy code may introduce other issues not clearly seen by the developer.
Begin with the end in mind
How does the development team demonstrate and prove compliance at the end of the project? This can be a contentious issue resulting in wasted time and effort if the evaluation criteria are based on subjective opinions from the various stakeholders.
A recommended approach to improving the evaluation of compliance readiness is to use existing templates for both the final compliance and tool qualification report (covered in the next section).
There is also a tendency to add more information into the reports than is required. If the information is not required by the standard, avoid embellishment. Only the necessary information needs to be included in the final reports. Adding extra information is not only a waste of time, but also introduces a risk of delaying an audit process.
The required information that should be included in the final report is already provided by the MISRA Compliance 2016 [3]:
- Guideline Enforcement Plan
- Guideline Compliance Summary
- Details of all Approved deviation permits
- Deviation records covering all violations of guidelines re-categorized as Required.
The example below shows an HTML format, with links to appropriate sections:
Establish the End Goal Early
In addition to the above recommendations, there are few other important points to consider:
- Has the GRP (Guideline Re-categorization Plan) been established at the beginning of the project?
- According to the MISRA standard negotiation with the acquirer is possible as is the creation of multiple GRP's for the adopted code that is used without any modifications and native code which are the files actively modified during the project. For every incremental change, is there visibility into how many items of work are remaining to get to full compliance? This helps to plan the work accordingly and set the right expectations with the management.
- Have the GPS (Guidelines Compliance Summary) report templates been reviewed with the acquirer at the beginning of the project and were they found acceptable and complete?
There are templates for those documents that commercial static analysis tool vendors provide to help organizations the MISRA 2016 Compliance framework, but it’s always possible to create custom tools and tracking software.
A Phased Approach: Divide and Conquer
As previously stated, the initial scan of existing code by a static analysis tool tends to produce thousands of violations. It's impractical and not recommended to stop new development effort to focus on fixing all these violations. In fact, the author has seen cases where regressions were introduced when significant changes to the codebase are made to fix the static analysis violations. Therefore, it's important to establish a workflow to fix the violations over time without disrupting the development process and degrading the quality of the software.
There are several practical approaches of addressing the static analysis violations over time. Some key recommendations when using static analysis tools for the first time in a project are stated below:
- Baselining. After the initial scan of the code, mark all the initial violations as “to be addressed later” and set as a baseline. From that point forward when updating existing code and/or developing new code, maintain a policy of "no new violations allowed". This policy can be enforced by the code review process or a Continuous Integration (CI) tool like Jenkins or Bamboo. When developers have a few hour or days to spare, they can resolve remaining violations marked from the baseline. Organizations can prioritize this approach based on current code under development, on code review findings or by relying on metrics (e.g. complexity) to suggest the next violation to resolve.
- Line in the sand. The development sets a date, “the line in the sand.” After this date, every translation unit (individual source file) modified must have all violations addressed. All unmodified translation units automatically fall under the true “adopted” code definition from the MISRA Compliance document. Note that this approach has a potential drawback if an individual modifies a large file and ends up owning hundreds of violations.
- Severity based prioritization. The developer fixes all mandatory findings for the module assigned to them. Over time, they address all Required violations as time permits based on a priority selected by the team lead.
For any of the approaches described above, it’s important for technical leads and management to constantly monitor the progress and project compliance status via a centralized dashboard. For example, a reporting hub provides the following pre-configured compliance status dashboard:
Tool Qualification
A less obvious component of MISRA compliance, often left till the end of the project, is the recognition that development tools used in the product need to be qualified (proven fit for purpose) for intended use. If a tool needs qualification what level of validation needs to be performed?
While in many instances tool qualification is required, the method which is used to perform tool qualification varies depending on the risk associated with the tool malfunction and the software criticality level. Parasoft provides a qualification kit and certifications for specific safety standards and their requirements. In the absence of this efficient kit, software teams must consider tool qualification costs when evaluating commercial, free, and open source tools.
Some standards like ISO 26262 and DO-178B/C provide reasonable guidance on tool qualification requirements. Regardless of the method, the goal of the tool qualification process is to state that “Tool is valid for intended use” and provide a proof and rationale of how the team came to this conclusion.
Here are some recommended steps to follow for a tool qualification process:
- Specify tool requirements for your intended use
- Identify a subset of features in the product that are used. Reduce the qualification process to only the features used
- Outline a qualification plan
- Outline the set of qualification steps (which may include tests performed by the team) that verify that the tool meets the requirements
- Automatically execute test cases which can be automated
- Provide a framework to input results of manual testing steps
- Report templates to reduce the amount of text needed to be entered by developers.
- Review the report with stakeholders and sign off.
Overlooking the tool qualification from the start might lead to project delays late in the cycle.
Staff Competency
The expertise and training of development staff is another key factor overlooked by software organizations and frequently being identified by auditors as number one issue when evaluating the readiness of a product.
According to MISRA Guidelines [3], staff competency is an important part of the MISRA compliance. It's best to conduct training in the beginning of the project and have a training date recorded with all the developers signed off that they received the training. At the end of the project the development team should be able to prove that:
- Staff that approved deviations understands and has been trained to recognized the risks associated with the violation
- Staff has been trained to properly configure and use the static analysis and development tools prior to use.
In practice, training for an experienced team is relatively short, but a few days invested in the beginning of the project saves weeks of rework after a project deadline has been missed.
Summary:
There is no silver bullet that makes achieving MISRA compliance of legacy code easy in safety critical projects. However, the introduction of the MISRA Compliance 2016 framework and using practical phased approach with a clearly defined end point in mind as outlined in this paper, software development teams can achieve compliance without significantly disrupting their development process. The bottom line is that there is still a fair amount of work to achieve compliance, but with intelligent planning and the right approach, a minimal and balanced set of tasks can be established to make both legacy and newly developed code safe and secure.
References:
- [1] MISRA C 2012: Amendment 1. “Additional security guidelines for MISRAC: 2012”. April 2016
- [2] MISRA C: 2012. “Guidelines for the use of the C language in critical systems”. March 2013
- [3] MISRA Compliance: 2016. “Achieving compliance with MISRA Coding Guidelines”. April 2016