MISRA C vs CERT C 是两种广泛使用的 C 语言编码规范对比介绍
在另外一篇文章中对几种c语言的安全编码规范进行了汇总介绍,这里详细介绍misra c和cert c两种。
MISRA C 和 CERT C 是两种广泛使用的 C 语言编码规范,均以提高代码的安全性和可靠性为目标,但它们的侧重点、应用场景和规则设计存在显著差异。以下是两者的详细对比:
1. 背景与目标
规范 | MISRA C | CERT C |
---|---|---|
制定机构 | 汽车工业软件可靠性协会 (MISRA) | 美国计算机应急响应小组 (CERT) |
主要目标 | 提高嵌入式系统(尤其是汽车电子)的可靠性和安全性 | 防止软件漏洞,提升代码安全性(通用领域) |
适用领域 | 汽车电子、航空航天、工业控制等嵌入式系统 | 通用软件开发(尤其是安全敏感系统) |
2. 规则分类与严格性
规范 | 规则分类 | 严格性 |
---|---|---|
MISRA C | 分为三类: - 强制 (Mandatory) - 必需 (Required) - 咨询 (Advisory) | 规则严格,部分规则允许例外(需记录原因),但通常要求完全遵守。 |
CERT C | 分为两类: - 建议 (Recommendations) - 规则 (Rules) | 规则灵活,允许根据风险分析选择性遵守,更关注安全漏洞的预防。 |
3. 核心规则对比
(1) 内存管理
规范 | 规则示例 | 解释 |
---|---|---|
MISRA C | 禁止动态内存分配(如 malloc /free )。(规则 21.1) | 避免内存泄漏和碎片化,适用于资源受限的嵌入式系统。 |
CERT C | 允许动态内存,但需安全使用(如检查分配结果、避免释放后使用)。 (规则 MEM30-C) | 关注内存操作的漏洞(如缓冲区溢出、释放后使用)。 |
(2) 类型安全
规范 | 规则示例 | 解释 |
---|---|---|
MISRA C | 禁止隐式类型转换(如 int 到 unsigned )。(规则 10.1) | 避免因类型转换导致的数据丢失或逻辑错误。 |
CERT C | 要求显式处理类型转换(如使用 static_cast )。(规则 EXP36-C) | 防止因类型不匹配引发的未定义行为。 |
(3) 未定义行为
规范 | 规则示例 | 解释 |
---|---|---|
MISRA C | 禁止使用未定义行为(如修改字符串字面量)。 (规则 22.1) | 确保代码的可移植性和确定性。 |
CERT C | 禁止依赖未定义行为(如除零操作)。 (规则 INT33-C) | 防止因未定义行为导致的安全漏洞。 |
(4) 代码结构
规范 | 规则示例 | 解释 |
---|---|---|
MISRA C | 禁止使用 goto 和递归。(规则 15.1、16.2) | 简化代码逻辑,提高可维护性。 |
CERT C | 允许 goto ,但需避免复杂跳转逻辑。(规则 MSC20-C) | 更关注代码的可读性和漏洞风险,而非完全禁止特定语法。 |
4. 典型场景对比
示例 1:动态内存分配
// MISRA C 禁止以下代码:
int* ptr = (int*)malloc(sizeof(int)); // 违反规则 21.1
// CERT C 允许但要求安全检查:
int* ptr = (int*)malloc(sizeof(int));
if (ptr == NULL) { /* 处理错误 */ } // 符合 MEM30-C
示例 2:隐式类型转换
// MISRA C 禁止隐式转换:
unsigned int a = 10;
int b = -5;
if (a > b) { /* 违反规则 10.1 */ }
// CERT C 要求显式处理:
if (a > (unsigned int)b) { /* 符合 EXP36-C */ }
5. 工具支持
规范 | 工具链 |
---|---|
MISRA C | Polyspace、LDRA、Coverity、Parasoft 等,通常集成在嵌入式开发工具链中。 |
CERT C | Clang Static Analyzer、CodeSonar、Coverity 等,更通用且支持开源工具。 |
6. 总结:异同对比
维度 | MISRA C | CERT C | 共同点 |
---|---|---|---|
核心目标 | 嵌入式系统的可靠性和确定性 | 通用软件的安全性和漏洞预防 | 均关注代码安全性和可维护性 |
规则严格性 | 严格,部分规则不可豁免 | 灵活,允许基于风险的选择性遵守 | 均要求静态分析工具支持 |
适用领域 | 汽车电子、工业控制等嵌入式系统 | 金融、医疗、网络等安全敏感系统 | 均适用于高可靠性要求的场景 |
典型规则 | 禁用动态内存、goto 、递归 | 安全使用内存、输入验证、并发安全 | 禁止未定义行为和危险操作 |
7. 如何选择?
- 选择 MISRA C:
适用于汽车电子、航空航天等嵌入式系统,需满足行业强制合规性要求(如 ISO 26262)。 - 选择 CERT C:
适用于通用软件开发(如金融、医疗),需防范安全漏洞(如 CWE/SANS Top 25)。 - 结合使用:
在安全关键系统中,可同时遵守 MISRA C(可靠性)和 CERT C(安全性),例如自动驾驶系统。
通过理解两者的差异,开发者可以根据项目需求选择合适的规范,或结合两者以实现更高的代码质量。