HIS,Hersteller Initiative Software, 制造商软件倡议,由一批德国汽车制造商联合发起的一个工作组,旨在在汽车软件供应链上,统一和标准化对软件质量的要求,特别是针对ECU的软件组件。
HIS的核心目标是:
- 标准化:为所有成员厂商建立一个统一的软件质量评估标准;
- 提高效率:减少供应商和制造商之间的沟通成本和重复劳动;
- 保证质量:通过一套统一且严格的标准,确保嵌入到汽车中的软件组件具备高可靠性和高质量。
HIS标准中,最具影响力、最被广泛实施的部分也是其对静态代码分析、代码度量和测试覆盖率提出的量化目标,这些目标通常被称为"HIS Metrics"。
HIS是元标准,它规定了在静态代码分析、测试覆盖率、代码度量等方面应达到什么目标,并引用MISRA等作为具体的技术标准作为衡量工具。
1. 静态代码分析
使用静态代码分析工具(如QAC, Coverity,Parasoft,Axivion等)对代码进行分析,代码必须遵守相应的编码标准。
常用使用的规范有:
- MISRA C:2012
- MISRA C++:2008
- AUTOSAR C++ R19_03
- CERT
注:具体的规则项一般根据由项目或团队约定,允许存在偏差项。
2. 代码覆盖率
对软件进行单元测试和集成测试,并测量代码覆盖率。
常见要求:
语句覆盖率:达到100%。
分支覆盖率:达到100%。
MC/DC覆盖率:对于最高安全等级(如ASIL D)的软件,通常要求达到100%。
3. 代码度量
对代码的结构复杂性进行度量,以确保软件的可维护性。
常见目标:
圈复杂度:每个函数的圈复杂度通常要求 ≤15,甚至更低(如 ≤10)。
嵌套深度:代码块的嵌套深度通常要求 ≤4。
一、编码规则
1、MISRA C规则:工业界的基石,定义了嵌入式C安全编码的范式
https://misra.org.uk/(需要购买)
- MISRA C:1998
- 初版
- MISRA C:2004
- 第一个成熟且被广泛使用的版本
- MISRA C:2012
- 增加了新语言标准(C99)的支持
- 对规则进行了大量的重新编号、重组和分类
- MISRA C:2023
- 完善了规则,提供了对C11/C18的官方支持
- MISRA C:2025
- 完全包含了MISRA C:2023的核心规则集
- 增加了5条新规则,规则总数从221条增至225条
- 对现有规则的分类和描述进行了优化,引入了新的规则管理类别
2、MISRA C++规则:C++安全领域的开拓者(但其严格和保守也受到了争议)
https://misra.org.uk/(需要购买)
- MISRA C++:2008
- 初版,被广泛认知使用
- 基于C++03,包含228条规则
- MISRA C++:2023
- 基于现代C++,支持C++14和C++17,包含了228条规则
- 淘汰了过于琐碎或过时的规则,并增加了针对现代C++特性和编程范式的、更核心价值的规则
3、AUTOSAR C++14编码规则:实现语言安全性和可靠性
https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_RS_CPP14Guidelines.pdf
- 基于现代C++(C++14)标准,为在AUTOSAR架构下开发安全相关软件而制定的C++编程指南
- 它吸取了MISRA C++的经验,并针对现代C++语言和AUTOSAR平台的特点进行了全面升级
目前R19-03是最新的版本,最后修订日期:2019-03-29.
4、CERT:Secure Coding Standard,安全编码标准
- 针对具体编程语言(C\C++等),具体的编码规则和建议
- 旨在消除可能导致安全漏洞的编码错误,实现防御性编程(防止外部攻击者利用代码缺陷进行攻击)
- CERT标准是CWE分类法的具体实践和实现,一条CERT规则可能旨在防止一个或多个CWE弱点
5、CWE:通用弱点枚举
https://cwe.mitre.org/index.html
- 通用的、社区驱动的"软件弱点字典"和"分类法"
注:CWE、CAPEC、CVE均由MITRE公司进行运营和维护。CAPEC是攻击手法词典,描述攻击者如何利用这些弱点实施攻击的方法、步骤和模式;CVE是具体的漏洞事件。
二、测试覆盖率
测试覆盖率是一个多维度的概念,从不同粒度衡量测试的完备性。最常见的是白盒测试覆盖率,主要包含以下几项(从弱到强):
- 语句覆盖率(Statement Coverage):编程语言中的语句,较弱的覆盖,要求每个语句执行一遍
- 分支覆盖率(Branch Coverage):每一个判定的分支至少都要被执行一遍
- 条件覆盖率(Condition Coverage):每个判断条件中的每个子表达式(原子条件)的真假值是否被测试过
- 条件/分支覆盖率(Conddition/Decision Coverage):同时满足上述的条件/分支覆盖率。(条件覆盖率关注原子条件的取值,分支覆盖率关注代码执行流。)
- 修正条件/判定(MC/DC)覆盖率:比条件/分支覆盖率更强的标准。要求每个条件都要能独立地影响整个判定的结果。
- 路径覆盖:验证程序所有可能执行路径。覆盖最强,但可行性最低,所需测试用例数随条件数会呈指数级增长(2^N)
其他覆盖率类型: - 函数覆盖率(Function Coverage):每个函数需要被测试调用
- 行覆盖率(Line Coverage):源代码中行被执行的覆盖率(100%行覆盖率不等于100%语句覆盖率)
- 区域覆概率(Region Coverage):一段没有控制流转移的连续代码,衡量测试对代码基本块的覆盖情况,本质上等同于语句覆盖率(Clang/LLVM的覆盖率实现机制,比简单代码行更精细的代码单元,其他覆盖率都是从区域覆盖率中派生出来的)。
三、METRIC:软件度量学,测量和评估代码质量属性的标准
- 圈复杂度:衡量函数中独立路径的数量。值越高,函数越复杂,越难测试和维护
- 嵌套深度:衡量代码块(如if、for、while)的嵌套层数
- 认知复杂度:不只计算路径,更关注代码对人脑的理解难度,弥补圈复杂度的不足
- 面向对象的度量:
- 继承深度:从类到继承树最顶层根类的层数
- 类的响应集:一个类的方法集合,以及被这些方法调用的其他方法的总数
- 类之间的耦合度:一个类引用其他类的数量
- 可维护性度量:
- 代码行数:函数、文件或类的代码行数
- 注释密度:代码中注释所占比例
- 可维护性指数:一个综合了圈复杂度、代码行数和注释率的计算公式得出的指数(通常是0-100)