安全关键型软件:每个开发人员都应该知道的 15 件事
尽管安全关键型软件无处不在,但普通开发人员却很少关注它们。但最近安全关键型软件系统的故障,却让其中一家公司及其软件开发实践引起了公众的关注。我指的是波音公司的两起 737 Max 坠机事故、随后所有 737 Max 飞机的停飞,以及其Starliner 试飞失败。
如此杰出的公司怎么会犯下如此严重的错误?安全关键系统的安全标准和认证流程不是应该防止此类事件发生吗?Max 认证的时候,美国联邦航空管理局(FAA)在哪里?这些问题激起了我的好奇心,让我决定探究软件开发这个专业领域到底是什么。
在这篇文章中,我将分享我对安全关键型软件开发的了解,以及它对像你我这样的“普通”程序员有何用处。
1.什么是安全关键系统?
安全关键系统是指那些其故障可能导致生命损失、重大财产损失或环境破坏的系统。
飞机、汽车、武器系统、医疗设备和核电站是安全关键软件系统的传统例子。
但还有其他类型的安全关键系统:
- 代码库、编译器、模拟器、测试台、需求可追溯性工具以及其他用于管理和构建我们传统上认为是安全关键系统的工具本身也是安全关键的
- 为安全关键型系统提供决策数据的软件很可能是安全关键型的。例如,一款计算商用飞机燃油量的应用程序就是安全关键型的,因为该应用程序的错误结果可能会导致危及生命的情况。
- 与安全关键软件在同一系统上运行的其他软件如果可能对安全关键系统的安全功能产生不利影响(通过阻塞 I/O、中断或 CPU、耗尽 RAM、覆盖内存等),也可能被归类为安全关键软件。
2. 安全关键型软件项目是什么样的?
安全关键型软件开发是一个非常专业、昂贵、有条理、缓慢、流程驱动的软件开发领域。
安全关键型软件系统通常是嵌入式分布式系统
通常,软件使用各种传感器监视其环境,并通过控制执行器(例如阀门、液压装置、螺线管、电机等)来操纵该环境,无论是否有人工操作员的协助。
这些系统通常是嵌入式的,因为它们通常有不容错过的截止日期。此外,这些系统的创建者无论是否由他们创建,都要对系统中硬件、软件和电子设备的各个方面负责。因此,他们在系统中放入的东西越多,公司获得认证的难度和成本就越高。
安全关键型软件系统通常是分布式系统,因为:
- 它们通常很大
- 子系统可能由不同的团队或公司开发
- 许多此类系统需要冗余和/或将安全关键代码与非安全关键代码分离
所有这些因素都推动系统设计走向多个协作处理器/子系统。
安全关键型软件的数量比你想象的要多
这类软件有很多,但它们受到的关注远不及面向消费者的软件。例如,《军事与航空航天电子》杂志几乎每篇文章都会讨论包含安全关键型软件的系统。
开发安全关键型软件既困难又昂贵
整合跨职能的专业知识来开发、认证、销售和支持如此复杂且昂贵的系统需要大量的资源和资金。因此,虽然少数小公司可能会生产小型的安全关键型软件系统,但更常见的情况是,这些系统是由大型公司生产的。
3. 无论规模和复杂程度如何,安全关键型软件几乎肯定是世界上最可靠的软件
开发并认证为安全关键型的软件几乎肯定是世界上最可靠的软件。最关键的系统允许的故障率极低。
这些数字是针对整个系统(硬件和软件合计)的。因此,任何给定 SIL 等级的软件允许故障率甚至更低!
在SIL 4 级别(大致相当于 NASA 的“最高”级别)下,我们指的是每十亿小时连续运行不到一次故障。也就是 114,000 年!
换个角度来看,如果你的智能手机是按照这样的标准制造的,你或你的家人朋友就不太可能遇到危险的故障(手机死机、摄像头损坏、随机重启、恶意软件、数据泄露、数据丢失、连接中断等等),你也指望一辈子都不会遇到这样的故障!这个标准高得惊人。这也充分表明了这类产品和软件开发与你我日常接触的有多么不同。
以下是我对安全关键型软件在软件质量领域中应处于的位置的印象:
安全关键软件经过设计、构建和测试,以确保其具有超低的缺陷率和超高的可靠性。
没有什么能比航天飞机软件的质量更好
航天飞机软件或许是NASA 软件开发中最佳的典范。在撰写本文(链接见上文)时,航天飞机软件代码量达 42 万行,并且在最近的三个版本中每个版本都只有一个错误。这比普通的软件项目缺陷数量要少得多。如果你想了解如何编写世界上缺陷率最低的软件,请阅读本文。
4. 重点是安全,而不是功能或速度
(在本文的其余部分,我将使用NASA 软件安全指南作为示例安全标准。)
在大多数公司中,软件开发人员主要关注的是让软件“运行”,然后加快运行速度、提供更多功能并创造更多价值。但参与创建安全关键型系统的软件开发人员必须主要关注创建安全的系统。这是一项截然不同的任务。
他们必须找到系统可能造成危害的所有现实途径,然后制定减轻危害的方法。他们还需要确保系统在构建后能够按规定运行。在产品获得认证之前,他们必须让自己和审核员确信,他们已经充分构建了一个安全的系统。
我们所做的远不止单元测试、代码审查和填写表格那么简单。我们谈论的是艰苦的检查和复查、强制性流程、多轮分析以及大量的文档。
构建它就像你知道你会被起诉一样
当我阅读NASA的《软件安全指南》时,我脑海中浮现的画面是,你必须克服所有这些障碍,就像你正在为未来的一场官司做准备一样,你的产品已经造成了多人死亡。你的公司和你个人将被起诉,索赔数千万美元。你需要能够手按圣经,宣誓你和所有参与你项目的人:
- 经过适当的培训
- 遵循您所遵循的安全标准中规定的最佳实践
- 尽可能降低与产品相关的损害风险
- 认真努力,让您的产品获得权威认证机构的认证,符合您选择的安全标准
然后你需要能够指出一堆装满你的文件的盒子作为证据,证明你所说的是真的,同时要知道原告的专家和律师会试图将你驳斥。
如果您觉得自己可能无法赢得那场假设的诉讼,那么您的产品就不应该发布。
5. 安全和危害缓解要求将大大增加产品的复杂性(而且数量会很多)
除了与为普通产品创建软件相关的软件工程任务外,您还会面临许多与安全和风险缓解相关的额外需求。众所周知,随着需求的互动,代码量和复杂性会急剧上升。例如,我们知道,需求数量翻倍,完成大多数项目所需的工作量也会翻倍以上。
此外,安全和风险缓解要求通常难以实施,因为它们并非软件开发人员的“常规”工作,而且本身就很困难。让我们来看一个例子。
故障安全设计
您的系统必须能够安全地进行故障处理。这是安全关键系统设计的基本原则之一。这意味着,在任何合理的情况下,只要系统按照操作说明使用,一旦发生故障,就不能造成危险情况。
对于许多系统来说,这意味着停止所有执行器并报告错误。例如,如果我在食品加工机旋转时取下盖子,里面的刀片就会立即停止工作。这是一个简单的案例,但对于其他系统来说,仅仅弄清楚如何安全地进行故障处理就非常困难。
心脏搭桥机示例
在心脏搭桥机的语境下,“安全故障”是什么意思?断电后,系统不能自动关闭,因为那样会导致病人死亡。
电池备份?
所以,它可能需要一块备用电池,以便在医院发电机启动之前维持运行。还需要一个充电子系统来保持电池充电。还需要一个电池健康监测子系统,用于在电池无法继续充电时提醒系统维护人员。此外,代码中可能还应该包含一个条件,当电池出现故障、缺失或耗尽时,旁路机将无法启动。此外,还需要对显示屏进行某种更改,以便操作员能够了解机器的电源状态。
顺便说一句,在安全关键系统中添加锂离子电池并不像你想象的那么简单。即使经过大量测试,波音787在实际使用中仍然出现了电池问题,这需要进行广泛的调查并修改系统设计。
多个备份?
实际上,仔细研究了相关要求后,我们发现单靠备用电池是不够的,因为该系统需要在发生两次故障的情况下继续运行。所以,我们可能需要两个独立的电池系统吗?嗯……我们是否需要从不同的供应商处采购每个系统,以免一个电池系统发生故障导致两个系统同时瘫痪?
或者我们应该安装一个手摇曲柄,让护士转动发电机,以便在电源断电、电池耗尽或电池耗尽时为心脏搭桥机供电?我们还需要一个子系统来确保发电机正常工作,并产生足够的电力来运行心脏搭桥机。但即使是新的发电机,也无法产生足够的电力来运行心脏搭桥机的所有功能。所以,我们或许需要一种低功耗模式,让心脏搭桥机只运行必要的功能?或者,我们需要重新设计整个系统以降低功耗?等等。
因此,一项安全要求(“断电时病人不能死亡”)变成了几项明确的要求和一系列问题。
需要考虑的其他故障模式?
这只是其中一种故障模式。我们需要涵盖所有实际的故障模式。那么:
- 功率波动?
- 电源没电了?
- RAM 损坏?
- 内存损坏错误?
- 突然出现异常?
- 传感器故障?
- 传感器不一致?
- 硬盘故障?
- 手术期间随机硬关机?
- 泵故障?
- 显示故障?
- 操作员尝试输入适合大象而不是人类的设置的情况?
- 操作员意外关闭机器的情况?
- 其中一块电路板上的电容器烧坏了?
- 和...和...和...
很容易看出,在一个安全关键型系统中,安全需求的数量很容易超过功能需求。而且,这些需求的实现会大幅增加系统硬件和软件的复杂性。
6. 有些系统非常危险,因此被禁止建造
令我惊讶的是,只要你采取适当的预防措施并获得认证,NASA 就不会允许你建造任何你想要的东西(第 27 至 28 页)。
无论您愿意采取多少软件预防措施,NASA 都禁止构建以下类型的系统:
- 具有灾难性危险的系统,其发生可能或很可能
- 存在严重危险的系统,且可能发生
在哪里:
- 灾难性的定义是:人员伤亡或永久性残疾;整个系统损失;地面设施损失;严重的环境破坏
- 严重定义为:严重伤害或暂时残疾;重大系统或环境损害
- 可能性定义为:事件发生的频率,例如 10 次中有 1 次以上
- 可能性的定义是:事件在物品的生命周期内会发生多次
禁止系统示例
如果航天器推进系统没有计算机持续调整以保持系统稳定,就会炸毁航天器,这种系统几乎肯定会被美国宇航局拒绝,因为太危险了。
即使系统设计人员相信该软件可以将机组人员遇难的风险降低到每 5,000 个飞行年发生 1 起事故,该系统也可能会被归类为“禁止”,因为 NASA 知道软件永远不会完美。
7. 安全关键型软件与敏捷的距离几乎是无比遥远的
虽然有人讨论使用敏捷方法进行安全关键型软件开发,以提高速度并降低成本,但我认为敏捷方法在安全关键型领域取得长足进展的想法并不现实。《敏捷宣言》定义了4条开发价值观和12条开发原则,其中大多数都与安全关键型软件开发的要求截然相反。
“即使在开发后期也要接受需求变更”在安全关键型软件开发的背景下,这似乎是一个特别成问题的敏捷原则。一个需求变更就可能引发对整个项目的彻底重新分析。如果变更引入了新的风险,则必须对其进行调查、分析,并可能采取缓解措施。缓解措施可能会导致多项设计变更。设计变更(硬件和/或软件)可能会导致文档、安全手册、用户手册、操作员培训要求、测试用例、测试环境、模拟器、测试设备和代码的变更。代码变更需要围绕变更进行有针对性的重新测试。此外,所有与安全相关的测试都应该针对每次代码变更重新运行。最后,您还必须重新认证产品。
这只是一个简单的例子。想象一下,如果您的需求发生变化,导致软件安全级别提升到更高的水平(比如,NASA 项目的安全级别从“最低”升至“中等”,IEC 61508 项目的安全级别从 SIL 2 升至 SIL 3),会发生什么情况?现在,您必须使用适合新安全级别的规定流程重新执行项目!
瀑布式或螺旋式开发模式占据行业主导地位
大多数安全关键型软件似乎都是使用瀑布式或螺旋式开发模型开发的。NASA 特别建议不要对软件的安全关键元素使用敏捷方法(第 87 页)。
我见过很多例子,其中V 模型被提及为瀑布模型的特化版本,适用于安全关键型软件开发。在 V 模型中,同一水平层级上的步骤是松散关联的。因此,例如,在进行详细设计时,您应该考虑单元测试和集成测试。有些资料甚至建议在详细设计期间(编码开始之前)编写单元测试和集成测试。
8.“普通”软件有时用于安全关键目的
关于什么应该被视为安全关键,存在相当大的争议。如果一位医生使用智能手机上的计算器应用程序来计算一位正在服用非常危险药物的患者的静脉注射剂量,那么这个应用程序是否安全关键?计算器使用的数学库又如何?手机的操作系统以及手机上所有其他软件又如何?答案尚不清楚。
医生是否应该被迫使用经过认证的计算器来确定静脉注射药物的剂量?市面上真的有经过认证可用于安全关键应用的计算器吗?我知道这听起来像是在吹毛求疵;计算器显然能正常工作,对吧?实际上,并非如此。Harold Thimbleby 毕生致力于研究与技术相关的医疗错误。我发现这段他演示普通计算器各种错误操作的视频令人深感不安。出错的计算器不止一两台。他把这些计算器都称为“垃圾”。
但我们不仅要担心计算器。有多少电子表格包含着对安全至关重要的数据和计算?
从外部来看,当局似乎并不太关心将普通软件用于安全关键功能。然而,作为一名“普通”开发者,你可能需要意识到你的软件可能会被这样使用。除非你鼓励这种用途,否则从法律责任的角度来看,你可能没有问题,但从伦理道德的角度来看,这可能是另一回事。
9. 不安全的软件不能被视为安全
许多人批评安全标准在安全保障方面做得很差(请参阅下文的批评部分)。因此,安全研究人员发现许多安全关键产品存在明显的安全漏洞,您也应该不会感到惊讶。
因为您的整个安全案例依赖于您的软件完全按照规定运行,所以如果有人能使您的系统行为异常,您就会遇到大麻烦。
10. 没有灵丹妙药
我希望我对安全关键型软件开发的研究能让我了解到一些快速、高质量软件开发的秘诀,超越我已知的知识。我一直在寻找一些工具或技巧,让我在日常工作中脱颖而出。但我什么也没找到。
安全关键型软件开发的成功,很大程度上源于投入大量资金和人力来解决质量问题。我认为“一次把事情做好”的原则绝对适用于所有追求高质量的软件开发工作,但这其中并没有什么神奇之处。大多数情况下,关键在于流程、流程、再流程。
我发现最接近“魔法”的东西是从模拟模型自动生成代码,以及通过构造技术实现正确性。但对于从事非安全关键项目的普通开发人员来说,这两种方法都不会带来好处。
11. 安全关键型软件系统的开发应该如何进行
目前有很多安全标准。如果您正在开发自己的系统,您使用的标准可能由您所在行业决定。或者,在某些情况下,您可以选择您想要满足的标准。然后,您可以组建一支有能力的团队,制造您的产品,并尝试让您的产品获得认证机构的认证,或者,如果您所在的行业允许,您也可以选择自行声明您的产品符合标准。
如果您为他人开发产品,他们可能会在合同中规定您必须满足的标准。如果您的客户是 NASA,那么您需要遵循NASA 的软件安全指南进行软件开发(也可能遵循其他指南,具体取决于您的系统性质)。
确定你的安全级别
规则非常复杂,但基本思想是,您必须评估您的产品有多危险、危险可能发生的概率以及您的软件预计减轻这种危险的程度(而不是硬件控制或人工干预)。
确保家用高压锅不会超压爆炸的软件的认证级别会比自主控制核电站安全功能的软件低。因此,你必须遵循更严格的流程,并投入更多工作来认证核电站的软件。
NASA 对安全关键软件的认证分为四个级别:“完全”、“中等”、“最低”和“无”(第 28 页)。NASA软件安全指南将帮助您确定您计划的系统处于哪个级别。
也可能存在混合级别的系统。例如,一个子系统可能处于“完整”级别,而另一个子系统可能处于“最低”级别。
采用所需的流程、分析和文档
一旦您了解了产品的级别,就可以查找需要遵循、执行和创建哪些流程、分析和文档才能达到该级别。每个开发阶段都有一个表格,告诉您需要做什么(其他标准也有类似的表格)。
(我认为这些表格足够有趣,所以我在下面的NASA 软件安全指南中附上了每个开发阶段的表格。但您不必阅读它们也能理解这篇文章的其余部分。)
概念(需求之前的阶段,定义您需要什么样的系统)(第 102 页):
要求(第 107 页):
设计(第 136 页):
实现(编码)(第 167 页):
测试概述(第 181 页):
操作和维护(第 199 页):
正如您所见,即使在“最低”安全级别,NASA 也希望您做很多很多大多数软件项目永远不会做的事情。
你需要竭尽全力确保你的软件是安全的
让我们仔细看看动态测试表来说明我的观点。即使你已经对非安全关键项目的代码进行了例行单元测试,我敢打赌你肯定没那么彻底。也许你会跳过那些特别难测试的部分,要么根本不测试,要么“某种程度上”手动测试?嗯,这对于安全关键型软件来说还不够好。而且达到“足够好”所需的时间可能比所有简单测试加起来还要长。
美国宇航局希望对以下物品进行“最低”安全级别测试:
- 典型传感器值
- 输入的极值
- 每个传感器的所有模式
- 执行的每个语句、分支和路径
- 每个测试的谓词
- 每个循环执行 0、1、多次、最多 -1 次、最多次和最多 + 1 次
如果您尝试严格遵循这些测试要求,您无需太多想象力就能意识到将会发生一些事情:
- 您需要编写所有生产代码以实现可测试性,这将对代码的其他属性产生负面影响
- 测试代码的数量将比生产代码的数量大(可能差距很大)
- 编写测试用例时,很难将每个用例追溯到它所涵盖的动态测试类别以及它所满足的特定要求
- 您将更难以知道是否已创建足够的测试用例来满足代码库中每个子程序的动态测试要求
- 因为你在系统中进行了如此深入的测试(不仅仅是像大多数单元测试人员为非安全关键系统推荐的那样只测试公共 API),你会发现几乎不可能在不引起测试套件混乱的情况下重构代码
- 如果 QA 发现你的产品有问题,那么修改代码和测试用例而不犯任何错误将是一场噩梦
获得产品认证
这里有两条路可以走。
自我声明你符合标准
在某些行业,您可以简单地声明您的产品符合某些标准的所有要求,可能还需要独立公司的协助来确认该声明。
虽然这看起来像是一条更简单的认证途径,但你的客户可能不会接受。另外,我实际上并不清楚何时或何种情况下你可以自行声明你的产品符合特定标准。NASA 不允许这样做。而且,根据我所读到的信息,FAA 和 FDA 似乎也不太可能允许这样做。但其他行业可能有所不同?如果你知道自行声明是如何运作的,请在这篇文章下留言。
让您的产品获得认证机构的认证
另一种方法是聘请认证机构对您的产品进行独立评估,并在产品符合您所要求的标准后颁发认证证书。这是两种方法中更为严格的一种。
如果您打算与外部公司合作,协助认证您的产品,则应在项目生命周期的早期阶段尽可能早地将其纳入开发流程。由于开发初期出现错误,整个产品开发完成后未能获得认证的情况并不少见。在产品构建完成后,再添加缺失的需求、流程或文档几乎是不可能的。
认证并非保证。本文指出,只有25%寻求认证的公司最终获得认证。我确信认证的严格程度因行业和SIL而异,但据我所知,认证在任何地方都是一个严肃的流程。
独立验证和确认
如果您正在参与一个风险或价值极高的 NASA 项目,NASA 可能会为您的项目指派一个独立验证和确认 (IV&V) 团队(第 102 页)。该团队的任务是确保您的项目按计划交付安全且成功的系统/任务所需的质量和功能。IV&V 团队所做的工作超越了您为项目所做的所有工作,而不是替代项目。IV&V 团队还可以作为资源,解答您的问题,并帮助您根据项目风险适当地调整工作。
跟踪产品运行情况
您有责任跟踪产品在现场运行过程中的使用情况和缺陷。此活动的范围取决于您所生产的产品类型,但目标是收集数据以证明您的系统在实际使用中的可靠性。
例如,劳斯莱斯的喷气发动机利用卫星通信技术,通过遥测技术“回传”信息。劳斯莱斯收集发动机的使用小时数以及各种性能、故障和失效数据。你或许找不到比这更好的追踪方法了。
另一方面,像汽车安全气囊这样的装置,可能依赖于对触发事件的估计以及消费者的故障报告。这比劳斯莱斯收集的跟踪数据质量要低得多,但总比没有强。
13. 安全关键型软件系统的开发实际是如何进行的
我描述了安全关键型软件系统应该如何构建。但实际情况似乎大相径庭。我很快就意识到,一些公司在进行安全关键型软件开发时,很少考虑标准,也很少考虑系统故障可能造成的严重后果。
Barr Group 2017 年嵌入式安全与安保调查
Barr Group 对世界各地的嵌入式开发人员进行了调查,发现安全关键项目严重缺乏最佳实践。
28% 的受访者从事安全关键项目。
只有 67% 的安全关键子集符合安全标准!
在我的电商工作中,编码规范、代码审查和静态分析都是强制性的,因为它们是经济高效、行之有效的质量提升方法。但很大一部分安全关键型人员并没有这样做。
情况还在恶化。只有 59% 的安全关键子集进行了回归测试!进行系统级测试的还不到 100%!
这些数字让我头疼!
这项调查还有很多值得关注的地方。我鼓励大家观看 Barr Group 首席执行官在YouTube 上的演讲,了解这项调查的结果。
无论如何,如果您查看这些结果并将它们与我从NASA 软件安全指南中复制的所有表格进行比较,您就会很容易想象现实世界中有多少其他任务没有在安全关键项目中完成。
丰田意外加速调查
如果你还没听说过丰田的意外加速问题,我建议你去维基百科上读一下简要概述,了解一下情况。这绝对是一个安全至关重要的软件系统,而且它一团糟。
我们先把硬件和安全文化问题放在一边,只看电子油门控制系统(ETC)的一些软件发现。该系统负责读取油门踏板位置并控制发动机油门设置:
- 超过 250 KLOC 的 C 代码(不包括注释)
- 2,272 个全局变量
- 64 个相同全局变量的多个声明实例
- 333 转换改变值
- 22个未初始化的变量
- 67 个函数,复杂度超过 50
- 一个函数的复杂度为 146。它包含 1,300 行代码,并且没有单元测试
- 可能导致意外加速的错误
- 油门故障保险装置存在缝隙和缺陷
- 发现黑匣子记录了不正确的信息
- 堆栈溢出和可能导致内存损坏的缺陷
- 以及更多...
任何读过这篇文章的人都知道,这不是你想在安全关键系统中看到的那种代码。
更多详情,请观看Philip Koopman 的演讲,他指出了丰田硬件、软件和安全文化的诸多问题(幻灯片)。这真是一次令人大开眼界的演讲。
患者破解胰岛素泵并在网上发布计划
几年前,我看过一段视频,其中一位非程序员描述了他如何将一堆技术粘合在一起,以使他的连续血糖监测设备能够向胰岛素泵发送命令,自动调整输送到身体的胰岛素量来控制糖尿病。
作为一名专业的软件开发者,我深知编写正确的软件有多么困难,因此我对这家伙的做法感到非常震惊。他几乎对编程一无所知。他根据教程构建了这个系统,并与其他利用业余时间参与该项目的非程序员交流信息。我相信这确实是他编写的第一个程序,而且它绝对关乎安全——胰岛素过量或过少都可能致命。
现在,如果你想把自己的人生掌握在自己手中,自己动手做一个这样的装置供自己使用,我建议你尽管去做。但这些人把设计和代码分享在网站上,让任何人都可以使用,在我看来,这很不酷。美国食品药品监督管理局(FDA)在旁观了好几年之后,公开警告不要自己动手做“DIY”胰腺。
无论如何,这是理论与安全关键软件开发的现实截然不同的另一个例子。
波音 737 Max 和 Starliner 软件问题
两架波音 737 Max 坠毁事故和一次Starliner 试飞失败促使我写了这篇文章。但随着我对安全关键型软件开发,尤其是波音公司安全关键型软件开发的研究越来越深入,我意识到这个话题值得写一篇单独的文章。发布后我会在这里提供该文章的链接。
14. 安全标准受到广泛批评
这些标准是由委员会设计和批准的。它们基于起草者可能获得批准的内容,而不是最合适的或有证据支持的内容。虽然人们普遍认为编码标准、设计评审、代码评审、单元测试等都是好东西,但这些标准在具体的实践和方法上存在分歧。
行业不想被告知该做什么
我读到过一篇批评文章,称行业希望最大限度地减少标准规定的工作量,因此游说反对在标准中增加更多规定。在某些情况下,这是因为他们希望最大限度地减少产品认证所需的工作量。在其他情况下,这样做是为了能够在最有效的技术面世时立即采用,而不是仅仅因为标准规定他们必须这样做,就被迫去做一些他们知道与现有技术相比效率低下的事情。
几乎没有证据表明遵循标准可以生产出安全的软件
实际上,几乎没有证据表明,遵循规定的活动就能达到现场预期的质量/故障率。我认为NASA的《软件安全指南》第12页很好地描述了这种情况:
关于某些技术的有效性,人们的看法大相径庭,本指南试图在不预先判断其有效性的情况下阐述这些观点。在大多数情况下,目前几乎没有或根本没有指标可以对这些技术进行定量评估或比较。
安全被忽视
其他人批评这些标准,因为它们大多对安全性保持沉默。我认为这是合理的担忧。如果你的产品不安全,就很难说它是安全的。
这是 Barr Group 2017 年嵌入式安全与安保调查的另一张幻灯片。它显示,在从事与互联网相关的安全关键型项目的受访者中,只有 78% 的人将安全作为一项要求。甚至有 22% 的项目根本不考虑安全!那么,在这 78% 有安全需求的受访者中,你认为有多少人的安全措施做得好呢?
以下是安全关键型和联网型子集的编码标准合规性、代码审查和静态分析情况。这些比率与我之前在这篇文章中展示的仅安全关键型子集大致相同。如果您不遵循编码标准、不进行代码审查或使用静态分析,我很难相信您能以某种方式为您的联网安全关键型产品编写出超安全的代码。
这些标准并未解决组件交互故障等问题
Nancy Leveson列举了许多例子,证明仅仅遵循标准是不够的。正如我们承认所有软件都存在缺陷并据此制定计划一样,我们也应该承认我们的软件也可能包含/经历过以下情况:
- 组件交互失败
- 需求错误
- 意料之外的人类行为
- 系统设计错误
- 组件或系统之间的非线性或间接相互作用
- ETC。
Leveson 认为,我们需要构建能够应对这些因素的安全关键系统。她建议使用STAMP作为提升系统安全性的补充方法,以应对此类问题。她在 YouTube 上有一个精彩的演讲,涵盖了相关基础知识。
顺便说一句,她可不是那种在场边胡说八道的怪人。她是麻省理工学院的航空航天学教授,与国防部、美国国家航空航天局等机构合作研究安全关键系统。
15. 对安全关键软件开发未来的思考
以下是我对安全关键型软件开发的发展方向以及我们在实现这一目标过程中将面临的一些挑战的一些想法。
我预计以下领域对此类软件的需求将会猛增:
- 自动驾驶汽车和驾驶辅助功能
- 物联网(包括工业物联网)
- 机器人和工业自动化
- 军事系统
- 医疗设备和医疗保健相关应用
- 太空应用
挑战:
- 对更大、更复杂系统的需求超出了我们按照此类软件所需的质量标准构建它们的能力
- 我们需要一种方法来大幅减少生产此类软件所需的成本和时间
- 我们如何将人工智能和机器学习融入安全关键型系统?
- 我们如何允许安全关键系统相互通信以及与非安全关键系统通信而不降低安全性?
- 安全问题将继续成为我们的眼中钉
- 越来越多的软件将用于安全关键用途,但其设计和构建并未遵循安全关键标准(例如医生在智能手机上计算静脉注射药物剂量)
- 我们如何吸引足够数量的优秀软件开发人员来从事安全关键项目?
资源
- NASA软件安全指南(pdf)
- 安全关键系统简介(pdf)
- Martyn Thomas 谈论安全关键系统和对标准的批评(视频)
- Martyn Thomas 谈论通过构造技术实现正确性(视频)
总结
我希望你从中得到什么?
安全关键软件的数量和复杂性正在快速增长
安全关键型软件在我们周围随处可见,随着我们让更多的世界连接到互联网、让“愚蠢”的设备变得“智能”、发明全新的产品来让我们的生活更加美好,我们对安全关键型软件的期望只会越来越高。
开发这种软件很困难
安全关键型软件系统的开发人员比大多数软件开发人员更能感受到软件工程领域缺乏成熟度带来的痛苦。令我失望的是,他们似乎并没有掌握任何神奇的工具或技巧来解决我们在开发复杂产品时遇到的问题。除了比一般项目进行更多的前期规划外,他们就像我们其他人一样,只是把资金和流程投入到解决问题中。
一些安全关键型软件的开发完全无视最佳实践
安全关键型软件系统的开发和认证方式与实际情况之间存在巨大差距。令我震惊的是,许多安全关键型项目根本不使用编码标准、静态分析、代码审查、自动化测试,甚至根本不遵循任何安全标准!
如果你发现自己正在从事这样的项目,或许应该花点时间考虑一下你正在做的事情可能带来的后果。对于优秀的开发人员来说,有很多工作不需要你去危及他人的生命。
大多数安全关键软件都是相对安全的
尽管安全关键型软件开发面临诸多挑战,但大多数安全关键型软件系统似乎或多或少都足够安全,足以满足其预期用途。这并不意味着它没有错误,甚至不意味着它不会造成人员伤亡(因为几乎可以肯定它会造成人员伤亡)。我的意思是,大多数安全关键型软件都足够值得信赖,可以用于其预期用途,这一点从公众愿意乘坐飞机、居住在核电站附近以及在体内植入医疗设备就可以看出。
在波音公司最近出现 737 Max 问题之前,导致死亡的安全关键软件错误最典型的例子就是Therac-25 放射治疗机的故障。调查显示,这些机器几乎从上到下都是一场灾难。1985 年至 1987 年间,少数人受到了 Therac-25 机器的有害辐射剂量,导致数人死亡。
Therac-25 是安全关键软件故障导致人员死亡的典型案例,这在一定程度上说明了这些系统在现实世界中的表现有多么出色。毕竟,安全关键软件控制着核电站、医疗设备、轨道交通、电梯、飞机、交通信号灯、航天器、武器系统、汽车安全功能等等。但你上次听说软件错误导致安全关键系统故障并造成人员死亡是什么时候(除了波音 737 Max 和特斯拉自动驾驶仪的致命事故)?
有任何评论、问题或故事想分享吗?请在评论区留言。
喜欢这篇文章吗?请在下方点赞。
鏂囩珷鏉ユ簮锛�https://dev.to/bosepchuk/safety-ritic-software-15-things-every-developer-should-know-1kdh