APP下载

如何保持C语言程序的安全※

2014-06-25IARSystemsAndersHolmberg

单片机与嵌入式系统应用 2014年4期
关键词:编程语言子集C语言

IAR Systems Anders Holmberg

姜桥 胡文婷 译

引 言

本文关注的是使用C语言对安全功能有高度要求的安全关键系统(Safety-Critical System)进行开发的过程中涉及到的一些问题。尽管这种语言充满不确定行为、依赖硬件以及其他陷阱,但它仍然是在安全关键开发领域使用的最为广泛和流行的语言。而我们可以通过事先考虑和规划,把这些潜在的问题变成了优势。

1 移动你的脚步

早在1991年,《开发者的洞察力》杂志发表了一篇标题为《如何搬起石头砸自己的脚》的文章,其开头说:“随着现代编程语言的大量扩散(彼此之间借鉴了大量类似的功能特点),有时您要弄清楚目前正在使用的是哪种编程语言都是很困难的。本指南所提供的内容可视作一项公共服务,以帮助程序员在困境中发现自我。”

由C开始的语言列表和其简单的状态:

◆C——搬起石头砸了自己的脚

这个判断可能显得有点苛刻,但还是有些道理的。然而,即使替代编程语言可能没有如类型安全和不确定的行为等方面的问题,但它们往往缺乏编程控制硬件功能。如果坚持用C语言,我们就需要在其优点以及明显或不那么明显的缺陷之间找一个平衡点。我们可以从两个不同的角度观察C语言在安全关键功能编程开发中的应用:

◆在安全关键的项目中有哪些外部需求,怎样选择编程语言?

◆可以做些什么来弥补一些明显的C语言的缺陷呢?特别是针对现有的代码。

2 标准答案

如果您的产品涉及到如汽车、工业控制、医疗设备、铁路等领域,这些产品一般来说都有正式的功能安全要求。这种要求可以归结为一个非常具体的产品容错率要求,或产品中某些特定功能的允许故障发生的概率。它也可以是按照IEC61508(电气和电子可编程器件)、ISO26262(汽车),或EN50126x(铁路)等通用功能安全标准开发的产品。至少10年以来,一个明显的趋势是安全功能的实施正在离开纯机械或PLC自动化控制,从而进入单片机的世界,因此这种要求也延伸到了软件领域。

由于各种标准的软件要求的意图是类似的,我们使用IEC61508标准作为一个例子。该标准规定了许多特定行业标准的基础要求,符合IEC61508标准的产品很大程度上也是符合ISO26262标准的。

这些标准将严重影响你的工作方式和工作文档:从收集需求,到计划你的产品如何在客户现场部署和退役。你和你的项目利益相关方并不能单方面决定项目是否已经成功达成所选标准的规定,还必须说服来自认证机构的第三方评估员,或者是在组织中扮演类似角色的人员,获得他们的认可。

这些标准大部分使用的是安全完整性等级概念的变种。所以根据产品的分类,在具体运用合适的标准时将会有一些变化。

3 标准适用吗?

先来说一个有趣的问题:这与我所选择的编程语言有什么关系呢?关系可大了,接下来就开始说明这个问题。表1给出了如何根据应用程序或者安全功能所需要达到的安全完整性水平来选择一个合适的编程语言的相关建议。

表1 软件设计和开发—支持工具与编程语言

HR是Highly Recommended的缩写,这意味着对于标有HR标志的项目,应当尽量遵守该建议,如果不能遵守,也请给出一个100%合理的理由。

正如在表1中看到的,使用合适的编程语言是被强烈推荐的,但是究竟为何要被推荐,我们并没有多大感觉,对吗?不过,表中引用的C附录给出了一个关于合适的编程语言的定义:语言的定义应该是充分且明确的。语言应该是面向用户或问题的,而不是面向处理器/平台的。与专用语言相比,应当优先选择广泛使用的语言或它们的子集。语言应鼓励使用小且方便管理的软件模块;应当限制对在特定的软件模块中的数据、变量子范围定义,以及任何其他类型错误限制结构的访问。

让我们看看C语言是否均能满足上述各个部分的定义:

① 语言应充分明确定义:这取决于你如何考虑,可以说C99包含至少190未定义行为。

② 语言应该是面向用户或问题的,而不是面向处理器/平台的:最初创建C语言是为了成为PDP-11架构的系统开发语言;一个特定目标的C语言实现必然与另一个目标的实现是不同的,有时对相同目标的实现甚至都是不同的,我们真的很难认为C符合这部分定义……

③ 与专用语言相比,应当优先选择广泛使用的语言或它们的子集:终于,我们发现C语言是能够满足这条定义的!

④ 语言应该鼓励使用小且方便管理的软件模块,限制对在特定的软件模块中数据、变量子范围定义,以及任何其他类型错误限制结构的访问:虽然C没有明确禁止创建符合这些条件的抽象概念,但是坦率地说,我们认为正好相反,C语言本身绝对没有对此类概念提供任何支持。

C语言并不完全符合这些标准的期望。然而,我们可以做些什么呢?其实,答案很简单,至少我们在读这些标准。如果继续读下去,会发现一个特定语言的判断表,以下是C语言相关描述:

9 C R-NR NR 10 C及其子集和代码编写标准,以及静态分析工具的使用HR HR HR HR

尽管并没有推荐使用C语言,但是,如果严格遵守代码编写标准并使用静态分析工具,带有一个适合子集的C语言是被强烈推荐的。但是,上文中提及的子集和代码编写标准怎么理解?

4 子标准

在此背景下,语言子集就是为了减少编程错误的概率,增加找到已经悄然潜伏在代码库中错误的可能性。对于C语言,这意味着尽可能杜绝使用未定义的行为,实现定义明确的行为。有很多这样的语言子集可供使用,其中最广为人知的可能是 MISRA-C。MISRA-C规则集开始是英国汽车工业软件可靠性协会的一项倡议,仅仅着眼于汽车软件。多年来,MISRA-C规则已经传播到世界各地,并扩展到其他细分行业,其规则集是现在嵌入式行业使用最广泛的C子集。

IEC61508中也涉及了很多代码编写标准的说明。下面是一些MISRA-C规则之外我们需要考虑的问题:

◆如何来保护共享资源,如全局变量的访问。

◆使用为对象分配的栈和堆的内存。

◆允许或不允许递归?

◆复杂性的限制,如限制函数的循环复杂度。

◆在某些不合适的情况下放弃遵循MISRA-C规则。

◆如何使用编译器的特定功能,如本征函数或语言扩展。

◆如何使用范围检查,断言和前置/后置条件以及类似的结构来捕获错误。

◆模块之间的接口组织和访问。

◆文档要求。

从本质上讲,一种代码编写标准应提供一些建议来指导如何处理影响到代码质量和完整性的问题,而不是由语言和其子集提供明确的建议。

5 总 结

总结出以下几个重点:

◆开始写代码之前,先熟悉相关标准定义的软件开发要求;

◆使用MISRA-C作为代码编写标准基础;

◆检查volatile关键字使用;

◆实施一个堆栈分配测试和分析策略。

本文为期刊缩略版,全文见本刊网站www.mesnet.com.cn。

猜你喜欢

编程语言子集C语言
由一道有关集合的子集个数题引发的思考
拓扑空间中紧致子集的性质研究
压力-体积转换在CFC编程语言中的实现解析
基于Visual Studio Code的C语言程序设计实践教学探索
关于奇数阶二元子集的分离序列
Java编程语言的特点与应用
基于C语言的计算机软件编程
浅谈不同编程语言对计算机软件开发的影响
高职高专院校C语言程序设计教学改革探索
面向对象Web开发编程语言的的评估方法