#微软故障##Crowdstrike是怎么让全球微软系统崩溃的#
昨天网络安全巨头Crowdstrike的一次软件更新引发了大规模的Windows系统崩溃,海外不少航班也不飞了,打工人也不用上班了。
技术专家Zach Vorhies在X上进行了深入分析,我补充了一些背景知识,做了个综述。没想到,是这么一个低级错误。但是貌似很多灾难性技术事故的背后,都是类似的失误。其实也说明,人是不可靠的。
Andrej Karpathy也发了一个推评论,“CrowdStrike 故障是一个系统性风险案例研究......错误的几个比特就能导致 10 亿台计算机瘫痪,并产生所有二阶、三阶效应。技术领域还存在哪些瞬时失效的单点故障?”
***
1、事件概述:
2024年7月,Crowdstrike推送了一个例行的软件更新。然而,这个看似普通的更新却包含了一个致命的编程错误,导致大量Windows用户遭遇了系统崩溃,俗称"蓝屏死机"(BSOD, Blue Screen of Death)。这不仅影响了普通用户,还可能对依赖Windows系统的企业和组织造成严重影响。
2、问题根源:
这个问题的根源在于C++编程语言中的一个"空指针"(Null Pointer)错误。C++是一种广泛用于系统级编程的语言,以其高效和灵活性著称,但同时也以其复杂性和潜在的内存管理问题而闻名。
深入理解计算机内存:
3、要理解这个问题,我们需要先了解计算机内存的工作原理:
*计算机内存可以想象成一个巨大的数组,每个位置都有一个唯一的地址。
*这些地址通常用十六进制表示,例如0x1A3B。
*在32位系统中,内存地址范围从0x00000000到0xFFFFFFFF。
*在64位系统中,这个范围更大,但原理相同。
4、空指针的概念:
在C++中,指针是一种存储内存地址的变量。"空指针"(通常表示为NULL或在现代C++中为nullptr)是一个特殊的值,表示指针没有指向任何有效的内存位置。它通常被赋予地址0或接近0的值。
5、关键的编程错误:
在Crowdstrike的代码中,程序员犯了一个常见但危险的错误:没有检查指针是否为空就试图使用它。这就像是在没有确认书本是否存在的情况下,就试图翻到某一页。
6、错误的具体表现:
让我们用更技术化的语言来解释这个错误:
假设程序试图访问一个对象的成员,该成员位于对象起始地址偏移0x9c(156字节)的位置。
正常情况下,如果对象位于内存地址0x10000000,那么访问这个成员就会读取地址0x1000009c的内容。
但如果对象指针为NULL(地址0),那么程序就会试图读取地址0x0000009c的内容。
地址0x0000009c位于系统保护的内存区域,尝试读取它会立即触发系统保护机制。
7、系统级软件的特殊性:
Crowdstrike的软件是一个系统驱动程序,运行在内核模式(Ring 0)。这意味着:
*它有最高级别的系统访问权限。
*它的错误可能直接影响整个操作系统的稳定性。
*普通应用程序的崩溃通常只会导致该程序被终止,而内核模式的崩溃会导致整个系统宕机。
8、正确的编程实践:
为了避免这种错误,程序员应该养成以下习惯:
*总是检查指针是否为空before使用它。
*使用现代C++特性,如智能指针(std::shared_ptr, std::unique_ptr),它们可以帮助管理内存和避免空指针错误。
*考虑使用静态代码分析工具,这些工具可以自动检测潜在的空指针问题。
9、行业反思和改进措施:
*微软需要改进其驱动程序认证过程,可能引入更严格的测试要求。
*考虑实施更灵活的更新回滚机制,以便快速应对类似事件。
*软件公司可能需要重新评估其质量保证(QA)流程,特别是对于系统级软件。
*加强对开发人员的培训,特别是在内存安全和系统编程方面。
10、编程语言的演进:
这个事件也引发了关于编程语言选择的讨论:
C++虽然强大,但容易出现内存相关的错误。
新兴的系统编程语言如Rust,通过其所有权系统和借用检查器,在编译时就能防止许多内存错误。
然而,转向新语言涉及大量的代码重写和再培训,是一个复杂的决策。
11、安全与效率的权衡:
这个事件突出了在系统编程中安全性和效率之间的永恒权衡:
C++提供了接近硬件的控制,但也带来了更高的风险。
更安全的语言或更严格的检查可能会带来性能开销。
在关键系统软件中,如何在保持高性能的同时确保安全性,仍是一个挑战。
