«
编程规范 之 MISRA C/C++

时间:2021-10-26    作者:阅镜报告    分类:


随着软件在安全攸关(Safety Critical)系统中的广泛使用。这些软件自身代码的安全性便成了使用者和开发者共同关注的焦点。

为了给这些关键代码的安全性提供基础保障,相关领域的研究者和开发者在近三十年一直致力于代码安全编程规范的研究和制订。

MISRA C 和 C++ 安全编程规范的制订开始较早,也是目前该领域成果的典范。

—— 01 ——
MISRA 组织简介
MISRA全称为Motor Industry Software Reliability Association,即汽车工业软件可靠性联合会。该组织最早起源于英国政府发起的“SafeIT”项目。该组织从成立至今,一直致力于为车载电子系统中的嵌入式软件制订开发指导方针。

MISRA组织在1994年11月出版了《面向车载软件的开发指南(Development guidelines for vehicle based software)》。该文件是汽车行业在功能安全领域的第一份指导性文件,代表了当时汽车行业嵌入式开发人员对安全开发的共识。

在英国政府资助项目结束后,MISRA以独立非盈利实体的形式继续运作,出版了MISRA C、MISRA C++和MISRA安全论证指南等具有里程碑意义的标准及规范。

—— 02 ——
MISRA C/C++ 编程规范发展
MISRA C 起源于《面向车载软件的开发指南》中确定的“标准化编程语言的限制性子集”这一要求。考虑到 C 语言当时已被大量应用在汽车行业的嵌入式开发中,MISRA组织便组织编写了MISRA C 安全编程规范。由于后来受到其它领域从业人员的关注与使用,在其随后的修订中涉及了来自除汽车以外相关嵌入式开发行业的场景和需求。发展到今天,MISRA C 已经成为高安全性嵌入式开发领域中 C 语言开发的事实标准。

1998年,第一版C语言安全编程规范(MISRA C:1998)发布。该规范完整英文名称为“Guidelines for the use of the C language in critical systems”。由于当时缺乏针对 C 语言的相关安全编程指导,该规范发布之后,包括轨道交通、航空航天、医疗设备和军事等领域的嵌入式研发人员都开始借鉴和使用该标准。

2004年,第二版C语言安全编程规范(MISRA C:2004)发布。该版本广泛采纳了相关领域研究和开发者的反馈意见,主要针对以下几个部分进行了修改:
● 保证规范与标准语言的一致性
● 针对标准语言中未定义行为,用特定规则替换第一版中的广义规则
● 确定“一个规则解决一个问题”的原则,将原有的复杂规则拆解为原子规则
● 添加并改进代码示例
● 删除无法使用工具的选项

2007年,相关组织发布了MISRA C 编程规范示例测试集。该测试集涵盖了MISRA C 中大多数规则的示例代码,包括符合示例代码和不符合示例代码。

2007年,MISRA C:2004 技术勘误发布。该勘误主要针对一些使用中常见问题进行了修改。

2008年,MISRA组织发布了针对C++语言的安全编程规范(MISRA C++:2008)。该规范针对符合C++ 03标准的代码,共有228条编码规则。

2013年,第三版C语言安全编程规范(MISRA C:2012)发布。该版本扩展了对C99标准的支持,在规则上比第二版增加了约10%。同时根据使用者反馈在以下几个方面进行了改进:
● 针对方针增加了理由说明
● 为每条规则增加更加准确的描述
● 增加可以由静态分析工具识别的规则
● 为使用自动生成的代码提供指导
同时,该版本还增加了针对ISO 26262的交叉参考。

2016年,MISRA组织发布了MISRA C的第一修正案“MISRA C:2012 - Amendment 1: Additional Security Guidelines”。该文档增加了40条安全(Security)相关的规范。

2019年,MISRA组织宣布C++ 编程规范将在未来和AutoSar C++编程规范进行合并。这样做的目的旨在为业界提供一个统一的C++编程最佳实践。未来这个统一的C++安全编程规范将覆盖汽车、航空航天、医疗设备和军事等行业。

2020年,MISRA组织发布了MISRA C 的第二修正案“MISRA C:2012 - Amendment 2: Updates for ISO/IEC 9899:2011/18 Core functionality”。该修正案针对C11和C18标准进行了修改。

—— 03 ——
MISRA C 编程规范内容介绍
在最新的MISRA C:2012中,其前半部分整体介绍编程规范的的相关内容,包括编程规范的定位、MISRA C的背景、开发及检测工具选择和MISRA C的使用方法;后半部分描述编程规范的具体内容,包括规范内容介绍、分类和每条规范的详细解释。

根据规范的重要性,规范条目可分为强制规范(Mandatory guidelines),要求规范(Required guidelines)和建议规范(Advisory guidelines)。

指令与规则

根据规范的可检测性,可以分为指令(Directives)和规则(Rules)两类。

指令是一种描述性的指导规范,它无法提供执行符合性检查所需的完整描述。为了能够进行检查,需要给评测人员提供额外的信息,如设计文件或需求说明。
指令部分主要分为:实现、编译与构建、要求追踪、代码设计四个部分,共16条规范。

规则可以对相关要求提供完整的描述,评测人员或静态分析工具可以在不需要额外信息的情况下检查源代码是否符合对应规则。
规则部分是整个编程规范的核心,共分为22个部分,共142条规则。

所有规则根据重要性分类统计如下表:
类型名称 强制 要求 建议
标准C环境 0 2 1
未使用代码 0 2 5
注释 0 2 0
字符集和词法约定 0 1 1
标识符用法 0 8 1
类型用法 0 2 0
字符和常量用法 0 4 0
声明和定义 0 10 4
初始化 1 4 0
基本数据类型 0 7 1
指针转化规则 0 7 2
表达式 0 1 2
副作用 1 3 2
控制语句 0 4 0
控制流 0 4 3
Switch语句 0 7 0

函数 3 3 2
指针和数组 0 6 2
重叠存储 1 0 1
预处理指令 0 11 3
标准库 0 11 1
资源管理 4 2 0

10  101 31

强制规则
强制性规则是MISRA C 规范中重要性最高的规则,共10条,具体内容如下:

自动存储期的对象在读取前必须被赋值

sizeof操作中的操作数不应该有任何副作用

函数不应被隐式声明

在非void返回值类型的函数中,每个返回语句都应有对应的显式表达式

在声明数组时,中括号内不应含有 “static” 关键字。

对象在赋值或复制时不应有重叠

只有通过系统函数库分配的内存块才可以用free函数释放

针对以只读方式打开的流文件,不应尝试进行写操作。

指向FILE对象的指针不应被解引用

当文件被关闭后,指向该文件FILE对象的指针不应被再次使用

(以上译文都是小编自己尝试翻译的,如有问题还请大家斧正)

参考文献:
https://www.misra.org.uk/
Guidelines for the use of the C language in vehicle based software
Guidelines for the use of the C language in critical systems
MISRA C:2 012 Guidelines for the use of the C language in critical systems
MISRA C:2012 - Amendment 1: Additional Security Guidelines
MISRA C:2012 - Amendment 2: Updates for ISO/IEC 9899:2011/18 Core functionality
MISRA C++: A Subset of C++ for the Development of High-Integrity Systems

文章首发在【缺陷捕手】微信公众号


评论:

阅镜报告 2021-10-26 23:29
微信公众号【缺陷捕手】