CERT C

什么是 CERT C?

CERT® C 和 CERT C++ 编码标准是针对 C 和 C++ 语言的安全编码实践。嵌入式软件中的安全漏洞会增加恶意行为者发动攻击的机会。这些攻击会注入恶意软件,窃取信息,或执行其他未经授权的任务。安全编码实践有助于修补这些漏洞,并有效地减少攻击面。

为什么 CERT C 对于嵌入式系统很重要?

嵌入式系统使用 C 语言等编程语言的手写或生成代码。尽管此类语言支持直接内存访问等底层操作,但相关联的安全风险也更高。如果攻击者获得了系统的控制权,则可能会造成灾难性的后果。

C 语言中的某些代码构造会引入安全漏洞。恶意攻击者可以利用这些漏洞,执行代码注入、缓冲区溢出和弧注入等操作。

下面是一个非常简单的例子:

#define SIZE100 100
extern int tab[SIZE100];
int lookup(int n, int aFlag) 
{
    if(!aFlag &&  n < SIZE100)
      return tab[n];    
    else 
      return -1;
}

lookup 函数存在明显的缓冲区溢出漏洞,因为在参数 n 用作数组索引之前没有检查它是否为负值。负值会导致数组索引越界,公开受限制的信息,或允许修改受限制内存位置的内容。缓冲区溢出还会带来引入恶意代码的风险,这些恶意代码会更改执行过程,对系统的功能安全产生负面影响。

借助 CERT C 规则和建议,可通过从嵌入式软件中消除某些易受攻击的代码构造来降低此类风险。CERT C 专注于 C 语言的安全编码,但各组织也使用 CWEISO/IEC TS 17961MISRA® C 和其他标准,或制定他们自己的安全编码标准。CERT C 标准是遵循基于社区的开发过程制定的,该过程由卡内基梅隆大学附属软件工程研究所 (SEI) 管理。CERT C 规范可在维基百科上的 CERT 安全编码中找到。与此类似,CERT C++ 标准是针对 C++ 语言制定的。

如何确保符合 CERT C?

CERT C 规范以规则和建议形式编写。规范属于规则还是建议视具体情况而定:

  • 规则。如果违规很可能导致缺陷,并且只需通过自动检查或手动检查代码即可确定合规性,而无需额外的假设,则规范属于规则。例如,ARR30-C(“不要形成或使用越界指针或数组下标”)就是一项规则。
  • 建议。如果合规可提高软件系统的安全性和可靠性,但违规不一定会导致缺陷,则规范属于建议。例如,ARR02-C(“显式指定数组边界,即使已由初始化器隐式定义”)就是一项建议。

CERT C 规则可以手动检查,但查看数十万行甚至数百万行代码是否违反规则往往是不切实际的。因此,CERT C 推荐使用静态代码分析工具来确保合规性。

通常,静态代码分析工具可检查与安全相关的缺陷,例如被污染的数据以及底层软件弱点,例如静态和动态内存缺陷、数值缺陷和数据流缺陷。其中许多缺陷源于违反了 CERT C 规则。因此,静态分析工具可以自动检查是否违反 CERT C 规则。

使用 Polyspace® 静态代码分析工具检查 CERT C 合规性

Polyspace Bug Finder™ 是一款静态代码分析工具,可以直接支持 CERT C 安全编码标准。使用 Polyspace Bug Finder,开发人员或质量工程师可以简单地选择检查所有或选定的 CERT C 规则来发现违规情况,而无需执行任何额外的配置。

例如,在上述代码片段中,Polyspace Bug Finder 可通过检测数组访问越界或缓冲区溢出缺陷,发现违反 CERT C 规则 ARR30-C(“不要形成或使用越界指针或数组下标”)的情况。此违规将与规则信息、在代码中的位置以及可能的风险和修复一起报告。

使用 Polyspace Bug Finder 检测 CERT C 违规。

使用 Polyspace Bug Finder 检测 CERT C 违规。

除了支持几乎所有 CERT C 规则和许多 CERT C 建议外,Polyspace Bug Finder 还支持相关的编码标准,如 CWE、ISO/IEC TS 17961、MISRA C:2012 修订版 1 和 CERT C++ 编码标准的大部分内容。

使用 Polyspace Code Prover™ 可以进行额外的检查。当 Polyspace Bug Finder 报告某项违规时,您可以运行 Polyspace Code Prover 来彻底检查软件中是否存在其他此类违规。例如,假设您通过检查数组索引中的负值来解决上述违规问题,如下所示:

#define SIZE100 100
extern int tab[SIZE100];
int lookup(int n, int aFlag) 
{
    if(aFlag &&  (n<0 || n >= SIZE100))
      return -1;
    return tab[n];
}

这样做是否解决了问题?您可以运行 Polyspace Bug Finder,看看是否还违反 ARR30-C 规则。要获得进一步的信息,您可以运行 Polyspace Code Prover。通过更深入的分析,您会发现,根据 aFlag 的值,n 的值可能根本不受约束,仍存在数组索引越界的可能性。然后,您可以重新编写代码,直到 Polyspace Code Prover 证明不存在索引越界的情况,如绿色对勾所示。

使用 Polyspace Code Prover 进行越界数组索引检查。

使用 Polyspace Code Prover 进行越界数组索引检查。

综上所述,您可以使用 Polyspace Bug Finder 自动检查几乎所有的 CERT C 规则和大量的 CERT C 建议。您还可以使用 Polyspace Code Prover 进一步深入了解问题,并针对特定规则彻底检查您的代码,证明不存在这些问题。

了解有关 Polyspace 产品嵌入式安全功能的更多信息。

另请参阅: 静态分析, 验证, 嵌入式系统, 软件质量目标, 软件质量保证