美国白宫、C++ 之父……深入解析这场关于 C++ 内存安全的全球辩论

从历史来看,这场关于 C++ 内存安全的各方辩论。

原文链接:https://johnfarrier.com/looking-for-pointers-the-c-memory-safety-debate/

作者 | John E. Farrier

翻译 | 郑丽媛

随着权威机构最近的评估,围绕 C++ 和内存安全的讨论变得更加激烈。不久前白宫发出强烈呼吁,建议开发者转向内存安全的编程语言。总体来说,这一立场基于与内存安全问题相关的网络漏洞历史,它曾对国家安全和更广泛的数字生态系统的完整性产生了影响。

这场辩论发生在历史先例、技术演变和重新评估编程语言安全标准的背景下,也强调了在 C++ 中对内存安全进行细致理解的必要性。

C++ 中的内存安全挑战

内存安全问题仍是软件开发中的关键挑战,而 C++ 经常成为讨论焦点。内存安全问题通常会导致严重漏洞,例如缓冲区溢出和未管理的指针,这可能会导致未经授权的访问、数据损坏或系统崩溃。从历史上看,像 C++ 这样允许直接内存管理的编程语言很容易受到这类错误的影响,导致灾难性的网络安全漏洞。

然而,将 C++ 简单地视为本身就不安全的说法过于片面。C++ 语言经历了实质性的演变,现代版本强调了更安全的内存实践,同时又不损害核心原则——效率和控制。现代 C++ 引入了智能指针、自动资源管理和更严格的类型检查等功能,以减少常见的内存安全隐患。

尽管取得了这些进步,但人们仍然认为 C++ 存在内存安全风险,高调的安全漏洞和手动管理内存的固有复杂性更是助长了这种看法。白宫的报告强调了这一点,直接将内存安全与国家网络安全联系起来,督促人们过渡到固有内存安全机制的语言。

然而,这种观点并未完全承认现代 C++ 所取得的进步。C++ 开发社区持续解决内存安全问题,努力通过默认使安全性更易于实现,同时保持其效率。通过社区主导的计划和不断发展的标准,C++ 希望在保持其基础优势的同时,降低它在内存安全方面一直以来有损其声誉的风险。

总之,关于 C++ 内存安全的争论并非非黑即白。它包含了一系列技术、历史和文化因素,这些因素促成了关于开发安全高效软件最佳实践的持续辩论。

白宫和美国国家安全局对 C++ 内存安全的立场

在编程语言内存安全问题上,白宫已经明确表态,特别指出了像 C 和 C++ 这样的语言所带来的漏洞。最近,国家网络主任办公室(ONCD)强调了技术社区采用内存安全编程语言的必要性。这一举措不仅涉及编码实践的转变,更代表了网络安全政策的重大转变。其目标是通过消除自 20 世纪 80 年代以来一直存在的漏洞类别,从根本上减少网络安全威胁。

这项新政策的重点是通过解决最常见的切入点之一:内存安全漏洞,来显著减少网络攻击面。提倡向内存安全语言转变,不仅是为了增强软件的安全性,也是为了将网络安全的责任从个人和小型实体分配给大型组织和技术制造商,他们更有能力管理这些不断变化的威胁。

知名科技领袖和学者都支持白宫的行动号召,理解这一转变会如何影响国家的网络安全基础设施。ONCD 强调了过去发生的事件,如 Morris Worm 和 Heartbleed 漏洞,这些都是内存安全问题导致重大安全漏洞的典型案例。这些历史参考资料说明了这些漏洞的反复性,以及必须在基础层面上加以解决的必要性。

白宫的方法很全面,敦促工程师和管理人员在其议事日程中优先考虑内存安全。他们所倡导的变革是广泛的,并且承认了转向内存安全编程所固有的挑战。人们认识到,这种过渡可能会持续数十年,尤其是对于代码庞大的大型企业而言。然而,总体信息是明确的:采用内存安全的编程语言对于国家数字基础设施的长期安全至关重要。

此外,这一倡议是更广泛战略的一部分,与拜登总统关于网络安全的行政命令和随后旨在加强美国网络安全态势的国家战略相一致。它是对网络安全和基础设施安全局(CISA)和国家安全局(NSA)等机构现有努力的补充,加强了从软件开发的最初阶段就纳入安全问题的呼吁。

白宫和美国国家安全局对内存安全编程语言的推动是解决长期存在的网络安全漏洞的重要一步。通过倡导从 C 和 C++ 等语言向内存更安全的替代语言转变,美国政府旨在加强数字生态系统的基础元素,抵御数十年来一直困扰着数字生态系统的各类风险。这一政策转变强调了在更广泛的国家和全球网络安全环境中,内存安全的关键性。

Bjarne Stroustrup 为现代 C++ 内存安全的辩护

C++ 创始人 Bjarne Stroustrup 积极参与了围绕 C++ 内存安全的讨论。他强调了 C++ 在安全编码实践方面的能力,并回应了白宫和美国国家安全局等机构提出的担忧。

Stroustrup 指出,对 C++ 的批评往往忽视了其演进以及为增强类型和内存安全而采取的措施。他坚称,现代 C++ 可以在不违反类型系统、避免资源泄露和防止内存损坏的情况下编写,同时保持语言的高性能和表现力。

Stroustrup 主张的方法包括定义 C++ 在不同应用场景中的“安全”含义,这一定义对于建立适应不同应用需求的安全标准至关重要。他建议,通过安全配置文件,C++ 可以为各种领域(如嵌入式系统、汽车或医疗应用)提供定制的安全机制。这些配置文件将强制执行特定的安全功能,同时允许代码保持其性能和功能性。

Stroustrup 提出的一个重要建议是消除常见问题,如悬空指针和范围错误。通过解决这些问题,Stroustrup 的目标是让 C++ 在关键应用中达到经过验证的安全标准。这种方法并不完全依赖于运行时检查,而是鼓励在编译时使用抽象来执行安全性,这可以减少性能开销并提高代码质量。

Stroustrup 强调,现代 C++ 的设计旨在平衡安全性、效率和可用性。他认为,对安全性的持续关注是完善和实现该语言核心目标的契机,在应对现实世界编码挑战的同时,还能保持 C++ 的基础优势。Stroustrup 鼓励 C++ 社区及其批评者在评估和讨论中,也要考虑这些发展和语言不断演变的安全特性。

通过这些努力,Stroustrup 帮助人们深入了解了 C++ 的功能及其在现代软件开发中的作用,特别是在需要严格的安全性和可靠性标准的环境下。

历史背景:Ada 与国防编程政策

这并不是美国政府第一次对其技术实施进行微调。20 世纪 70 年代,美国国防部(DoD)采用 Ada 作为武器系统的唯一编程语言。这一决定源于统一当时使用的大量编程语言的需求,这些语言导致了效率低下和兼容性问题。Ada 通过竞争性程序开发而成,因其强大的类型系统、模块化编程机制和并发功能而被选中,主要用于实时嵌入式系统。这种语言以 Ada Lovelace 的名字命名,旨在取代美国国防部当时使用的 450 多种编程语言,以简化流程并增强关键任务软件的开发。

然而,随着软件开发环境和技术进步的不断演变,国防部对 Ada 的坚定政策面临挑战。最初,Ada 可能成为一种主导商业领域的编程语言,推动软件实践。但随着时间的推移,新软件的出现,主要是非 Ada 商用现成产品(COTS),以及国防部在软件开发中的角色变化改变了局面。尽管在高可靠性、实时性应用方面,Ada 仍保持着强大的优势,但它逐渐成为了一种小众解决方案。

失落的十年

从 20 世纪 80 年代到 90 年代,,美国国防部(DoD)在软件语言上进行了长达十年的斗争,凸显了在技术实施过程中硬性规定的危险性。国防部坚持在实时、关键任务系统中使用 Ada 编程语言,虽然最初的初衷是好的,但最终却被证明是有害的,既浪费了金钱,还可能危及国家安全。

使用 Ada 的规定始于 1983 年,旨在强制执行系统化的软件工程实践,简化代码更新,并减少军事系统中其他编程语言的扩散。Ada 具有强大的功能和可靠性,似乎是一个明智的选择。然而,随着时间的推移,行业的进步超过了 Ada 的能力,使其与 C 和 C++ 等替代语言相比竞争力大打折扣。

硬性要求用 Ada 的规定引起了软件工程师们的普遍不满,他们认为这是政府对他们决策过程的干涉。尽管国防部试图施加这一命令,但在行业内并未获得全面支持。此外,商业现成设备(COTS)的出现进一步削弱了规定的相关性,一些人将其解读为放弃 Ada 程序的信号。

国防部的计算机主管 Emmett Paige Jr. 支持取消使用 Ada 的决定,这反映出人们已经意识到,强制使用特定技术会扼杀创新、阻碍进步。他的建议与国家研究委员会(National Research Council)的一份报告的结论相吻合,该报告建议在军事项目中选择编程语言时采取更灵活的方法。这一转变承认了行业专业知识的重要性,以及迅速拥抱技术进步的必要性。

毫无根据的担忧

然而,放弃 Ada 规定的举措虽然标志着向灵活性迈出了一大步,但也引起了人们对潜在后果的担忧。批评者认为,如果没有强有力的语言政策,国防部就有可能重新回到“软件无政府”的状态,不禁让人让人联想到 20 世纪 70 年代的混乱做法。

“不制定强有力的 DoD 语言政策是一个错误。事实上,没有比 Ada 更适合完成国防任务的语言了,采用 Ada 的全部原因就是为了消除支持数百种不同语言和方言的需求。当我们放弃单一的语言政策时,如果我们没有一些强有力的语言,我们就会回到 70 年代的软件无政府状态。”

——Ralph Crafts,位于弗吉尼亚州费尔法克斯的 Ada 供应商“OC Systems Inc.”的销售和营销副总裁

此外,由于行业偏好和不断发展的技术,没有强制规定并不能保证 Ada 得到广泛采用。

事实证明,这些担忧是毫无根据的。

国防部应注重成果而非实施方式

国防部内的 Ada 事例对各行业的组织都具有警示作用。为了标准化技术采用的规定可能会带来短期利益,但在快速的技术创新面前很快就会过时。相反,培育一种合作、持续评估和适应的文化对于应对现代技术领域的复杂性至关重要。

展望未来,国防部必须吸取 Ada 任务失败的教训。采用更加灵活、更具包容性的方法来实施技术,利用行业专业知识,将创新置于硬性规定之上,这对于加强国家安全并走在新兴威胁前面至关重要。

现代 C++:内存安全与效率

现代 C++ 引入了多项提高内存安全性的功能,解决了历史上一直困扰该语言的问题。

智能指针与内存管理

智能指针,如 unique_ptr、shared_ptr 和 weak_ptr,在自动内存管理中起着关键作用,减少了内存泄漏和悬空指针等常见问题。这些指针可确保资源在不需要时被适当释放,从而使代码更安全、更简洁。例如,unique_ptr 提供了对动态分配内存的独占所有权,防止在释放后未经授权的访问,而 shared_ptr 则通过引用计数管理共享资源所有权。

移动语义与资源管理

C++11 引入了移动语义,以提高资源管理和效率。通过使用右值引用和移动构造函数,C++ 允许从临时对象中转移资源,无需复制大型数据集的开销。这不仅优化了内存使用,还加快了执行速度,特别是在嵌入式系统等内存受限的环境中。

Noexcept 与异常安全

noexcept 指定符是 C++11 的另一个特性,它有助于开发更安全、更可预测的代码。通过将函数标记为 noexcept,开发人员可以通知编译器这些函数不会抛出异常,从而优化生成的代码并减少运行时开销——在对稳定性和性能要求极高的嵌入式系统中,这一特性尤为重要。

解决空间和时间内存安全问题

空间内存安全问题,如缓冲区溢出和越界访问,可以通过 std::span 等构造来缓解,它提供了对对象序列的边界检查访问。时间安全问题,即防止“空闲后使用”错误,可以通过规范使用智能指针和谨慎管理资源所有权来解决。

并发和数据竞争

现代 C++ 也面临着多线程和并发带来的挑战。我们可以通过使用原子操作和锁来缓解数据竞争和同步问题。不过,要确保线程安全,就必须谨慎编程并遵守最佳实践,因为语言的内存模型要求开发者明确管理对共享资源的访问。

现代构造和安全编程实践

尽管现代 C++ 功能对内存安全性有很大贡献,但它们的有效性取决于程序员的规范使用和理解。如果使用不当,C++ 仍有可能出现不安全的问题。因此,在利用这些功能生成安全且高效的代码方面,在利用这些功能生成安全且高效的代码方面,教育、代码审查和静态分析至关重要。

尽管现代 C++ 在内存安全方面已经取得了长足进步,但仍需要开发人员共同努力才能有效利用这些功能。通过将现代语言构造与严格的软件开发实践结合起来,C++ 可以安全地用于各种应用,包括那些具有严格安全要求的应用。然而,C++ 代码的最终安全性和效率在于开发人员,取决于他们对内存管理和错误处理方面遵循最佳实践的程度。

C++ ISO 标准化的重要性

国际标准化组织(ISO)对 C++ 的标准化强调了 C++ 在全球范围内的认可度,并致力于维护一套通用规范,以确保它在不同平台和行业中的一致性、可靠性和质量。当前的 ISO C++ 标准,即 ISO/IEC 14882:2020(E),代表了国际专家为完善该语言的定义、功能和最佳实践而做出的共同努力。

与非标准化语言相比的优势

与未获正式认可的语言相比,ISO 标准化语言具有多项优势:

(1)互操作性:确保用 C++ 编写的代码可以在不同的环境和编译器中理解、编译和执行,减少特定平台的错误和不一致性。

(2)质量保证:严格的 ISO 标准化过程包括细致的审查和测试,从而提高代码的质量和稳定性。

(3)面向未来:标准的定期更新和修订预测并纳入了技术的进步,使 C++ 保持了相关性和高效性。

(4)全球合作:标准化过程汇集了来自不同背景的专家来分享知识,确保语言能够满足广泛的需求和应用。

与国防部推荐的其他语言相比的重要性

虽然 C# 和 Rust 等语言正受到越来越多的关注,特别是在优先考虑内存安全的领域,但它们缺乏像 C++ 那样通过 ISO 所具备的正式标准化。这可能会导致不一致性和碎片化,特别是在适应不同的国际市场或参与大规模跨国项目时。C++ 的 ISO 标准化提供了非标准化语言无法保证的稳定性和可靠性。

与缺乏正式标准化带来的挑战

没有正式 ISO 标准化的语言(如 Python)面临着各种挑战,诸如版本不兼容和实现分歧等,这可能会阻碍全球合作和代码的可移植性。虽然强大的社区标准在一定程度上可以缓解这些问题,但它们无法提供与 ISO 标准化相同水平的保证和全球认可。

C++ 的 ISO 标准化不仅仅是一种官僚式的荣誉,它还证明了该语言在快速发展的软件开发领域中的稳健性、通用性和持久相关性。虽然 DoD 在探索其他语言以满足特定用例,但 C++ 的正式标准化突显了它在从嵌入式系统到大规模高性能计算项目等广泛应用中的持续重要性。

通过促进全球合作和遵守公认的标准,C++ 仍然是商业和国防领域的关键语言,在系统编程及更广泛的领域中保持着领先地位。

现代 C++ 内存安全及其在满足现代计算需求方面的演变

关于 C++ 和内存安全性的持续辩论已成为焦点,重要人物如 C++ 创始人 Bjarne Stroustrup 也积极参与讨论,以推进语言的安全特性。美国国家安全局(NSA)等机构建议在可能的情况下使用内存安全语言而不是 C++,在这些机构日益增长的担忧中,人们正齐心协力推动 C++ 的发展,使其满足现代计算需求,同时又不影响其核心效率和功能。 

Stroustrup 对 C++ 演进的愿景

Stroustrup 一直坚持不放弃 C++,强调以渐进和演进式的方法来增强安全特性。他认为,虽然内存安全性至关重要,但它并不是唯一的安全问题,并建议从整体上看待语言安全,包括解决资源泄露、内存损坏和并发错误等问题。Stroustrup 建议通过新的工具和方法来增强 C++,将安全性直接集成到语言及其库中,而不是颠覆现有的 C++ 代码库来促进更安全的编码环境。

解决 C++ 内存安全问题,同时保留传统代码库

Stroustrup 的一个关键观点是,维护和升级现有 C++ 系统的实用性和必要性。他反对用多种新语言替换 C++ 的观点,这可能会带来互操作性挑战和巨大的转换成本。相反,Stroustrup 主张通过内部改进 C++,利用现代语言特性和最佳实践来增强内存安全性和整体安全性,同时保持 C++ 的高性能。

渐进式方法:配置文件和指南

Stroustrup 建议采用“安全配置文件”,使开发人员能根据特定的应用要求(如嵌入式系统、汽车或医疗应用)采用不同级别的安全措施。这一概念符合在语言框架内使安全性具有适应性和可执行性的想法,允许根据项目需求对安全功能进行更细致的应用。

此外,Stroustrup 还强调了正在进行的 C++ 核心指南工作,以提供静态保证类型安全和资源安全的编码实践。这一举措体现了各方的共同努力,为开发人员提供了一个路线图,使他们能用更安全的 C++ 代码构建技术资本,解决新老安全问题,同时又不忽视庞大的现有代码库和围绕它们建立的开发人员社区。

指明前进方向

让 C++ 成为更安全语言的道路复杂而充满挑战。然而,由 Stroustrup 主导并得到广大 C++ 社区支持的讨论和建议,为我们指明了一条既尊重 C++ 语言传统,又能满足现代计算迫切需求的前进道路。通过在安全性需求与现有基础设施现实之间取得平衡,C++ 将继续发挥其作为当代软件开发强大工具的作用,满足安全性、效率和互操作性不断发展的需求。

本文文字及图片出自 CSDN

你也许感兴趣的:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注