当前位置: 首页 > 科技观察

C++之父做出决定:内部自救!

时间:2023-03-12 20:29:14 科技观察

作者|钱山严正评论|YunZhao进入2023年,技术圈关注着大洋彼岸的聊天机器ChatGPT,但对于编程圈来说,没有什么比内存安全更能引发热议了。近日,美国国家安全局(NSA)点名批评C++,建议使用Rust等内存安全语言,并立即将“编程语言的安全问题”摆上了桌面。那么,C++能否顶住这一波压力“活下来(安全)”呢?面对来自政府的压力,C++的创造者BjarneStroustrup终于低下了头。他一改以往激昂的说辞,不再大喊“谁不懂C++”、“我没看到C++这30年的进步”等等,而是开始倾向于“编程”的说辞语言也应该与时俱进”,并补充说其他核心贡献者明显感到惊讶,他们加入了改变编程语言本身以解决安全问题的行列。一、安全落伍的C++正在寻找对策C++社区一直存在安全争议,其内存安全漏洞引起了众多开发者的警惕。1月中旬,官方C++“指导小组”发布了一份声明,解决了对C++安全性的担忧。虽然许多语言现在都支持“基本类型安全”,确保变量只能访问由其数据类型明确定义的内存部分,但C++一直在努力提供类似的保证。由C++创始人BjarneStroustrup与人合着的新声明现在似乎呼吁对C++编程语言本身进行更改,以解决安全问题。“我们现在支持这样一种想法,即安全性的变化不仅需要在工具中可见,还需要在语言/编译器和库中可见。”“指导小组”还支持其长期以来首选的安全调试工具(以及“用于更全面分析以识别人类难以识别的安全问题的先进工具”)。但1月份的声明强调了其对C++内部结构的提议更改。具体来说,它建议“将几个特性打包成一个配置文件”(配置文件后来被定义为“定义要强制执行的属性的约束和要求的集合”,例如,通过触发自动分析。)这样,新的安全更改“应该是可见的,以便可以命名安全代码的部分(可能使用配置文件)并与正常代码混合。”这种新方法最终不仅带来了安全性,还带来了灵活性,其配置文件专门设计用于支持嵌入式计算、性能敏感型应用程序或高度特定的问题领域,例如汽车、航空航天、航空电子、核能或医疗应用程序。“例如,我们甚至可能有安全嵌入式、安全汽车、安全医疗、性能游戏、性能HPC和欧盟政府法规的安全配置文件,”指导小组还建议道。在文档的其他地方,它们更加简洁。“为了支持不止一种‘安全’概念,我们需要能够命名它们。”但拟议的改革呼应了去年12月与联邦政府摊牌时出现的想法。1月中旬的声明指出,一个特别重要的团体,即美国商务部具有影响力的国家标准与技术研究所,已经对C++的安全性提出了担忧。11月,国家安全局还在一份关于软件内存安全的信息表中调用了C++(作为其任务的一部分,以确定对各种联邦系统的威胁并“发布网络安全规范和缓解措施”)。也许正是这种来自高层的担忧最终播下了变革的种子……2.国家安全问题美国国家安全局引用了微软和谷歌的分析评估。微软在2019年的一次会议上透露,从2006年到2018年,它发现的漏洞中有70%是由内存安全问题引起的;谷歌估计,Chrome中也存在类似比例的内存安全漏洞,另外90%的Android系统漏洞也是内存安全问题。然后他们警告说,黑客可能会利用这些漏洞进行远程代码执行或其他不利影响,这通常会危及设备并成为大规模网络破坏的第一步。因此,无论是内存溢出、内存分配错误还是未初始化的变量,“所有这些内存问题都太常见了。”2019年Microsoft安全演示文稿发现,从2006年到2018年,70%的漏洞都涉及内存安全。显然,软件分析工具和“操作环境选项”可以发现很多问题,但NSA仍然建议“在可能的情况下”仅使用内存安全语言。为了澄清,他们将其定义为一种语言,通过运行时和编译时检查,内存“作为计算机语言的一部分自动管理;它不依赖程序员添加代码来实现内存保护。”NSA提供了C#、Go、Java、Ruby、Rust和Swift的示例。在美国国家安全局看来,C++等常用的编程语言在内存管理方面提供了很大的灵活性,但使用这种语言开发的应用程序的安全性在很大程度上取决于程序员的检测环节。但只要是程序员本身的一个疏忽,就有可能带来严重的内存安全隐患。虽然很多软件分析工具可以检测内存管理问题,运行环境选项也可以提供一定的保护,但是内存安全语言提供的内在保护可以规避或缓解大部分内存管理问题。12月,Stroustrup在开放标准网站上回应称,他认为“在我关心的使用范围内”这些语言并不优于C++。Stroustrup还反对NSA对安全的讨论“仅限于内存安全,忽略了语言可以(并且将)用于违反某种形式的安全和保障的十几种其他方式......'安全'不仅仅是一个定义,我们可以通过结合编程风格、支持库和静态分析实施来实现各种安全性。”顺带一提,Stroustrup还提出了第二个论点:在一些对性能至关重要的现实场景中,“并不是每个人都把‘安全’放在第一位”。因此Stroustrup认为,列出安全问题(包括未定义的行为)然后根据需要使用预执行调试工具(例如静态分析器)来寻找防止这些问题的方法是“明智的”。沿着这些思路,Stroustrup已经在为C++调用编译器选项和代码注释以请求类型安全(和资源安全),并表示这“让您仅在需要的地方应用安全保证,并使用您最喜欢的调优技术……”新提出的“配置文件”似乎是一种语言方式。3、理性看待C++的安全性Stroustrup也反对美国安全局文件中将C++和C混淆的说法。即使是现在,他指出,“C++核心指南致力于为那些需要它的人提供静态保证的类型安全和资源安全,而不会破坏可以在没有这种强大保证的情况下运行的代码库,也不会引入额外的工具链。”Microsoft的VisualStudio分析器(及其内存安全配置文件)以及许多静态分析器已经支持这些核心准则。根据Stroustrup的说法,这种方法允许C++“完全实现这些保证,而成本只是迁移到各种新颖的‘安全’语言的一小部分”。Stroustrup还引用了他在2021年写的另一篇论文,其中指出:“自1979年以来,完整的类型和资源安全一直是C++的理想(目标),并且可以通过语言规则和明智的编程技术的静态分析实现来强制执行。”(后来Stroustrup写道,解决方案是“一套精心设计的编程规则,由图书馆设施支持,并由静态分析强制执行。”)该论文承认,就其本身而言,“核心指南不提供完整的类型和默认情况下的资源安全”——但考虑通过执行附加规则来保证它(例如,“由MicrosoftVisualStudio发布的核心指南检查器实现”)。Stroustrup支持Rust基于编译器的类型检查,写道“编译器不是我们唯一的工具,而且从来都不是”,并提供了(预编译)静态分析可以执行的强大检查的具体示例。例如,静态分析可以:防止不安全的类型转换防止创建未初始化的对象确保没有内存引用指针“逃脱”超出其狭义定义的范围并错误地指向其他对象我们生活在一个“数十亿行C++代码”的世界不要神奇地消失,”Stroustrup写道,并补充说逐步采用这些安全规则(以及在适当的情况下,不同的安全规则)是很重要的。在某种程度上,美国国家安全局的文件似乎同意其中的一些观点。它的文档包括关于用非内存安全语言编写的“强化”代码的技巧,推荐用于静态分析(检查源代码)和动态分析(在代码执行时执行)的工具,以及简化结果的漏洞相关工具。“修复这些工具发现的问题可能需要大量工作,但会产生更健壮和安全的代码。”NSA文件确实提到了“相当大的保护”。(它还建议通过控制流保护、地址空间布局随机化和数据执行预防等安全功能加强编译和执行环境。)在一次新的采访中,72岁的Stroustrup回顾了他的学生时代。年轻时,他获得了数学和计算机科学硕士学位。他发现自己的数学并没有想象中的那么好,但是“机器体系结构真的很有趣”。当被问到,如果有时光机可以带他回到C++刚诞生的时候,他最想改变什么?Bjarne说,他现在比创建C++时更了解那个时代,他所做的任何更改都可能无法适应只有1MB内存的工作环境,也无法编译到早期的640MBWindows计算机。“关于编程语言设计的有趣之处在于,如果你成功了,你就会拥有几年和几十年前所做的一切,你必须忍受它。一旦你获得用户,你就有责任,其中一项责任就是不要”不要破坏他们的代码……有数千亿行C++代码,我们无法破坏它们。”Stroustrup强调了他对C++的信心。“我认为C++可以做任何Rust可以做的事情,我希望它更容易使用。”但他还在2020年的一次采访中表示,基本类型安全——确保变量只能访问其明确划分的内存块——是他最早的设计目标之一,也是他花了数十年时间努力实现的目标。5.没有时光机,一切都像刚开始。虽然这位年过七十的C++的创造者此时重拾了自信,但对于评论者的言论却有些伤感,“当我听到人们谈论C++时,这些人就像回到了1980年代和1990年代(指向)。”但正如前文所说,世界上没有时光机,C++的设计理念必须随着它所处的时代而演进。C++在诞生近四十年之后依然保持着强大的生命力,Stroustrup认为,保持它的稳定和追求渐进是必要的。“我从一开始就知道我不可能构建出理想的语言,所以我不得不以增量开发为目标:改进。老实说,我不相信完美语言的想法:它怎么可能是完美的呢?对谁(完美)?他补充说:“为了迎接不断变化的世界的挑战并融入新的想法,改进是必须的。”参考链接:https://thenewstack.io/can-c-be-saved-bjarne-stroustrup-on-ensuring-memory-safety/