MISRA C 2012与MISRA C2 - 如何进行转换

发表于2021年8月17日
由Secure Code Warrior
案例研究

MISRA C 2012与MISRA C2 - 如何进行转换

发表于2021年8月17日
由Secure Code Warrior
查看资源
查看资源

在Secure Code Warrior ,我们一直在寻求扩大我们的培训范围。为了使嵌入式开发人员和安全管理人员能够构建安全的嵌入式系统,我们正在挖掘嵌入式系统的安全世界。在这篇文章中,我们将谈论MISRA C 2012标准,以及为什么它的合规性对于构建安全的嵌入式系统是必要的。

在用C语言编写代码时,很容易实现一些看似正确,但本质上是错误的东西。你的代码可能编译得很好,甚至在一定时期内运行良好。但如果你的输入大小和/或内存增加,同样的代码可能会崩溃,或表现出未定义的行为。例如,一个特定的输入数字导致一个整数溢出,或者一个特定的字符序列导致一个数组越界。

这就是MISRA C编码标准可以帮助的地方。该标准规定的规则、准则和最佳实践,使开发人员能够为嵌入式开发编写安全和可靠的C代码。 

MISRA C 2012是该标准的最新版本,增加了新的规则,加强了现有规则,并解决了一些差异。如果你还在使用旧版本,现在是转换的好时机。 

什么是MISRA C编码标准?

MISRA C标准包括C编程语言的代码安全、可移植性和可靠性准则。第一套准则是在1998年发布的,是专门针对C语言的。 

然而,从那时起,MISRA联盟也制定了C++的编码标准。每一份MISRA C语言文件都包含一套规则、不符合要求的例子,以及有助于制定上述规则的背景信息的详细章节。

C和C++是开发嵌入式软件最广泛使用的语言。主要原因之一是它们速度快,只比机器语言有1到2级的抽象。但这也意味着编写安全的代码,特别是C语言,是困难的,而且容易出错。例如,在大多数高级语言如Java和C#中,你不必担心垃圾收集或动态类型等琐碎的事情。 

然而,在C语言中,没有预定义的方法来收集垃圾,也就是说,如果你为一个数据结构分配了一块内存,一旦你用完它,你必须自己手动释放它。如果你不这样做,C语言与其他语言不同,不会为你释放内存,这将导致内存泄漏。

MISRA C 2004 (C2) 与MISRA C 2012 (C3) - 有什么变化?

MISRA C: 2012,也被称为C3,于2013年4月首次发布。C3从数以千计的人和组织的工作中汲取知识,增加了新的规则,加强了对一些现有规则的解释和背景,并堵塞了一些漏洞。

C3支持C99版本的语言,同时也保留了旧版ISO C90的规则。C3的主要重点领域是减少规则执行的通常成本,同时也使C语言在关键系统中的使用更加安全。所有这些都使得如果你还没有转换到新的标准,那么就应该谨慎行事。

总体而言,这里列出了最重要的变化。

  • 纠正2004年版本中发现的问题。
  • 大幅增加可解码规则 的数量如果一个分析工具能够帮助你确定是否符合规则,那么这个规则就是可解的
  • 规则可分为 "必要"、"建议 "或 "强制"。强制性规则在任何情况下都不得违反。在特殊情况下可以违反 "规定 "和 "建议 "的规则,但要有正当理由。
  • 增加了关于如何对自动生成的代码应用规则的指导。这一点非常重要,因为人写的代码的相同准则,并不总是适用于工具生成的代码。
  • 删除那些过于笼统的规则,禁止合理的用户行为。例如,以前建议根本不要使用宏,因为它们会导致各种困难和混乱(不能调试宏,宏没有命名空间等)。这就阻止了宏的使用,即使在宏可以提供一个优雅、安全和方便的解决方案的情况下。在MISRA C: 2012中,引入了关于宏的新规则,允许人们在适用的情况下谨慎地使用它们。请看下面的摘录,摘自MISRA C的一份文件,其中推荐使用宏而不是函数。

MISRA C规则的实施

说得够多了,现在是时候亲身体验一下MISRA C的一些规则了,并举例说明它们的应用。

使用兼容类型作为memcpy、memmove和memcmp的指针参数

标准库函数memcpy、memmove memcmp 执行逐个字节的移动或指定字节数的比较。MISRA C 2012标准的规则21.15规定,两个函数参数应该是相同类型的指针。指针类型不兼容的函数调用可能表明存在错误。 

考虑一下下面的图片,它取自MISRA的官方合规文件。该规则是必需的,可解的, 并适用于C90和C99。

MISRA C规则21.15的屏幕截图

在规则描述后面有一个例子。

一个不符合规定的解决方案的截图。

正如你所看到的,由于对象的类型不同(uint8_t和uint16_t),这是一个不合规的解决方案。

不把长度作为输入的字符串处理函数不应导致越界访问

String handling functions from <string.h> that don’t take the length as an input, shouldn’t result in out-of-bound access. The relevant functions are: strcat, strchr, strcmp, strcoll, strcpy, strcspn, strlen, strpbrk, strrchr, strspn, strrstr, and strtok. The rule is mandatory, meaning it can never be breached, under any circumstances. It applies to both C90 and C99, and is undecidable.

MISRA C规则21.17的屏幕截图。

相应的例子是。

字符串处理功能的一个正确例子的截图

正如你所看到的,函数f1中的strcpy 会复制超过字符串的长度,因为它只能容纳5个字符。我们也有一个符合要求的安全使用strcpy的方法,即只有当 "str "的内容适合时,才会复制字符串。

验证外部接收的数据

Dir 4.14建议检查从 "外部 "来源收到的数据的有效性。外部输入可以是。

  • 从一个文件中读取。
  • 从一个环境变量中读取。
  • 任何用户的输入。
  • 通过通信渠道收到的任何东西。例如,通过TCP连接或HTTP API等。

该指令属于要求 类,对C90和C99都适用。这样做的理由是,程序无法控制从外部来源收到的数据,这意味着这些数据可能是无效的或恶意的。例如,一个程序期望用户输入一个数字,但用户却输入了一个字符串。在处理这个输入之前,程序必须验证它确实是一个数字。

应检查从外部来源获得的数值的有效性

如何切换到MISRA C 2012

转换到MISRA C 2012将需要更新你的编码指南文件。如果你没有使用,而是依靠静态分析工具(这是推荐的选择),你可能需要得到一个较新版本的工具。这里有三个工具可以检查MISRA C 2012的合规性。

  1. Cppcheck是一个开源的工具,可以检查MISRA规则,也可以检测各种bug。
  2. PC-lint Plus是一个付费工具,有30天的评估期。除了检查MISRA C的合规性外,它还可以帮助识别潜在的错误和漏洞。
  3. CodeSonar是另一个可以检查MISRA C和C++兼容性的工具。

也有一些编译器可以测试MISRA的合规性。如果检测到有违反规则的情况,就会相应地提出警告或异常。例如,Green Hills软件公司 提供支持所有MISRA标准的编译器,适用于32位和64位架构。

使用Secure Code Warrior ,以提高MISRA C的开发人员的技能。

Secure Code Warrior'的旗舰产品 -learning platform - 有许多互动挑战,courses ,和评估,可以帮助培训开发人员编写安全的C/C++代码。该平台上的内容是针对框架的,而且非常吸引人。我们的C/C++:嵌入编码挑战从MISRA C、AUTOSAR C++(MISRA C++)和IEC中获得灵感。

开发人员可以踏上个性化的学习之旅,在这里他们可以识别C/C++特有的漏洞,更重要的是学会修复这些错误。在这个过程中,开发人员可以跟踪他们的进展,以确定他们的弱点,甚至可以与他们的同行享受友好的编码比赛。了解更多关于我们如何用我们的解决方案帮助汽车和运输行业

想知道我们的挑战是如何互动和注重嵌入的吗?今天就在learning platform ,尝试一些C/C++:嵌入的挑战吧!

查看资源
查看资源

作者

Secure Code Warrior

Secure Code Warrior 通过向开发人员传授安全代码编写的技能,建立以安全为导向的开发人员文化。我们的旗舰产品敏捷Learning Platform 为开发人员提供了基于技能的相关途径、动手实践missions 以及上下文工具,帮助他们快速学习、构建和应用技能,从而快速编写安全代码。

想要更多吗?

在博客上深入了解我们最新的安全编码见解。

我们广泛的资源库旨在增强人类对安全编码技术提升的方法。

查看博客
想要更多吗?

获取关于开发者驱动的安全的最新研究

我们广泛的资源库充满了有用的资源,从白皮书到网络研讨会,让你开始使用开发者驱动的安全编码。现在就去探索它。

资源中心

MISRA C 2012与MISRA C2 - 如何进行转换

发表于2021年8月17日
通过Secure Code Warrior

在Secure Code Warrior ,我们一直在寻求扩大我们的培训范围。为了使嵌入式开发人员和安全管理人员能够构建安全的嵌入式系统,我们正在挖掘嵌入式系统的安全世界。在这篇文章中,我们将谈论MISRA C 2012标准,以及为什么它的合规性对于构建安全的嵌入式系统是必要的。

在用C语言编写代码时,很容易实现一些看似正确,但本质上是错误的东西。你的代码可能编译得很好,甚至在一定时期内运行良好。但如果你的输入大小和/或内存增加,同样的代码可能会崩溃,或表现出未定义的行为。例如,一个特定的输入数字导致一个整数溢出,或者一个特定的字符序列导致一个数组越界。

这就是MISRA C编码标准可以帮助的地方。该标准规定的规则、准则和最佳实践,使开发人员能够为嵌入式开发编写安全和可靠的C代码。 

MISRA C 2012是该标准的最新版本,增加了新的规则,加强了现有规则,并解决了一些差异。如果你还在使用旧版本,现在是转换的好时机。 

什么是MISRA C编码标准?

MISRA C标准包括C编程语言的代码安全、可移植性和可靠性准则。第一套准则是在1998年发布的,是专门针对C语言的。 

然而,从那时起,MISRA联盟也制定了C++的编码标准。每一份MISRA C语言文件都包含一套规则、不符合要求的例子,以及有助于制定上述规则的背景信息的详细章节。

C和C++是开发嵌入式软件最广泛使用的语言。主要原因之一是它们速度快,只比机器语言有1到2级的抽象。但这也意味着编写安全的代码,特别是C语言,是困难的,而且容易出错。例如,在大多数高级语言如Java和C#中,你不必担心垃圾收集或动态类型等琐碎的事情。 

然而,在C语言中,没有预定义的方法来收集垃圾,也就是说,如果你为一个数据结构分配了一块内存,一旦你用完它,你必须自己手动释放它。如果你不这样做,C语言与其他语言不同,不会为你释放内存,这将导致内存泄漏。

MISRA C 2004 (C2) 与MISRA C 2012 (C3) - 有什么变化?

MISRA C: 2012,也被称为C3,于2013年4月首次发布。C3从数以千计的人和组织的工作中汲取知识,增加了新的规则,加强了对一些现有规则的解释和背景,并堵塞了一些漏洞。

C3支持C99版本的语言,同时也保留了旧版ISO C90的规则。C3的主要重点领域是减少规则执行的通常成本,同时也使C语言在关键系统中的使用更加安全。所有这些都使得如果你还没有转换到新的标准,那么就应该谨慎行事。

总体而言,这里列出了最重要的变化。

  • 纠正2004年版本中发现的问题。
  • 大幅增加可解码规则 的数量如果一个分析工具能够帮助你确定是否符合规则,那么这个规则就是可解的
  • 规则可分为 "必要"、"建议 "或 "强制"。强制性规则在任何情况下都不得违反。在特殊情况下可以违反 "规定 "和 "建议 "的规则,但要有正当理由。
  • 增加了关于如何对自动生成的代码应用规则的指导。这一点非常重要,因为人写的代码的相同准则,并不总是适用于工具生成的代码。
  • 删除那些过于笼统的规则,禁止合理的用户行为。例如,以前建议根本不要使用宏,因为它们会导致各种困难和混乱(不能调试宏,宏没有命名空间等)。这就阻止了宏的使用,即使在宏可以提供一个优雅、安全和方便的解决方案的情况下。在MISRA C: 2012中,引入了关于宏的新规则,允许人们在适用的情况下谨慎地使用它们。请看下面的摘录,摘自MISRA C的一份文件,其中推荐使用宏而不是函数。

MISRA C规则的实施

说得够多了,现在是时候亲身体验一下MISRA C的一些规则了,并举例说明它们的应用。

使用兼容类型作为memcpy、memmove和memcmp的指针参数

标准库函数memcpy、memmove memcmp 执行逐个字节的移动或指定字节数的比较。MISRA C 2012标准的规则21.15规定,两个函数参数应该是相同类型的指针。指针类型不兼容的函数调用可能表明存在错误。 

考虑一下下面的图片,它取自MISRA的官方合规文件。该规则是必需的,可解的, 并适用于C90和C99。

MISRA C规则21.15的屏幕截图

在规则描述后面有一个例子。

一个不符合规定的解决方案的截图。

正如你所看到的,由于对象的类型不同(uint8_t和uint16_t),这是一个不合规的解决方案。

不把长度作为输入的字符串处理函数不应导致越界访问

String handling functions from <string.h> that don’t take the length as an input, shouldn’t result in out-of-bound access. The relevant functions are: strcat, strchr, strcmp, strcoll, strcpy, strcspn, strlen, strpbrk, strrchr, strspn, strrstr, and strtok. The rule is mandatory, meaning it can never be breached, under any circumstances. It applies to both C90 and C99, and is undecidable.

MISRA C规则21.17的屏幕截图。

相应的例子是。

字符串处理功能的一个正确例子的截图

正如你所看到的,函数f1中的strcpy 会复制超过字符串的长度,因为它只能容纳5个字符。我们也有一个符合要求的安全使用strcpy的方法,即只有当 "str "的内容适合时,才会复制字符串。

验证外部接收的数据

Dir 4.14建议检查从 "外部 "来源收到的数据的有效性。外部输入可以是。

  • 从一个文件中读取。
  • 从一个环境变量中读取。
  • 任何用户的输入。
  • 通过通信渠道收到的任何东西。例如,通过TCP连接或HTTP API等。

该指令属于要求 类,对C90和C99都适用。这样做的理由是,程序无法控制从外部来源收到的数据,这意味着这些数据可能是无效的或恶意的。例如,一个程序期望用户输入一个数字,但用户却输入了一个字符串。在处理这个输入之前,程序必须验证它确实是一个数字。

应检查从外部来源获得的数值的有效性

如何切换到MISRA C 2012

转换到MISRA C 2012将需要更新你的编码指南文件。如果你没有使用,而是依靠静态分析工具(这是推荐的选择),你可能需要得到一个较新版本的工具。这里有三个工具可以检查MISRA C 2012的合规性。

  1. Cppcheck是一个开源的工具,可以检查MISRA规则,也可以检测各种bug。
  2. PC-lint Plus是一个付费工具,有30天的评估期。除了检查MISRA C的合规性外,它还可以帮助识别潜在的错误和漏洞。
  3. CodeSonar是另一个可以检查MISRA C和C++兼容性的工具。

也有一些编译器可以测试MISRA的合规性。如果检测到有违反规则的情况,就会相应地提出警告或异常。例如,Green Hills软件公司 提供支持所有MISRA标准的编译器,适用于32位和64位架构。

使用Secure Code Warrior ,以提高MISRA C的开发人员的技能。

Secure Code Warrior'的旗舰产品 -learning platform - 有许多互动挑战,courses ,和评估,可以帮助培训开发人员编写安全的C/C++代码。该平台上的内容是针对框架的,而且非常吸引人。我们的C/C++:嵌入编码挑战从MISRA C、AUTOSAR C++(MISRA C++)和IEC中获得灵感。

开发人员可以踏上个性化的学习之旅,在这里他们可以识别C/C++特有的漏洞,更重要的是学会修复这些错误。在这个过程中,开发人员可以跟踪他们的进展,以确定他们的弱点,甚至可以与他们的同行享受友好的编码比赛。了解更多关于我们如何用我们的解决方案帮助汽车和运输行业

想知道我们的挑战是如何互动和注重嵌入的吗?今天就在learning platform ,尝试一些C/C++:嵌入的挑战吧!

我们希望得到您的许可,向您发送有关我们产品和/或相关安全编码主题的信息。我们将始终以最谨慎的态度对待您的个人资料,绝不会将其出售给其他公司用于营销目的。

提交
要提交表格,请启用 "分析 "cookies。完成后,请随时再次禁用它们。