微软不是修改源代码来修复bug的?
微软不是修改源代码来修复bug的?当像微软这样的公司需要修复其中一个产品的安全漏洞时,这个过程通常很简单:确定 bug 的位置,更改程序的源代码来修复 bug,然后重新编译程序。但看起来该公司必须走出这一典型的过程来修复 bug。与修复源代码不同,该公司的开发人员似乎对 bug 程序的可执行文件进行了一系列仔细的修改。
漏洞 CVE-2017-11882 是 Office 自带的老旧公式编辑器中的缓冲区溢出。 公式编辑器分配固定大小的内存来保存字体名称,然后将公式文件中的字体名称复制到这段内存中。 但是,它不检查确保字体名称是否适合这段内存。 如果提供的字体名称太长,公式编辑器会溢出缓冲区,破坏自己的内存,攻击者可以使用它来执行任意的恶意代码。
正常情况下,解决这个问题是先确定字体名称的长度,并创建一个足够大的缓冲区容纳它。源代码中,这是一个很简单的更改。如果这是不可能的 - 偶尔会出现缓冲区不容易变大的情况 - 那么下一个最好的解决办法是限制复制到它的数据量,如果字体名太长而不适合,则截断字体名。同样,这也是在源代码中进行的简单更改。
但是微软似乎不是这样做的。
对微软补丁的分析表明公司根本没有修改源代码。相反,它似乎是通过非常仔细地修改公式编辑器可执行程序本身来修复的。通常当一个程序被修改并重新编译时,这个编译会产生连锁反应。编译后的代码的底层内容会稍微改变;重新编译的代码将使用稍微不同的寄存器,函数将被放置在内存中的不同位置,等等。但这些都不是证据。对固定程序和原始版本的并行比较表明,除了几个函数中的几个字节之外,它几乎完全没有改变。唯一可能发生的情况是直接在程序二进制文件上执行 bug 修复,而不是修改源代码。
这是很难完成的。固定版本包括一个额外的测试,以确保字体名称不太长,如果长的话,将它截断。做这个额外的测试意味着增加额外的指令给这个 buggy 函数,但是微软需要在不让函数更新更长的时间来保证其他的,相邻的函数没有被干扰的情况下进行修复。为了为新的长度检查留出空间,程序中复制字体名称的部分被稍微地进行了优化,用稍微慢一点的程序替换了一个较快的例程,并且在这个过程中释放了几个字节。
检查甚至表明,这不是微软第一次做出这样的修复;有几条指令被发现在原来的版本中被奇怪地复制了。如果先前的修改使程序的代码稍微短一些,这种事情就会发生。
看公式编辑器的嵌入式版本信息也可以得出为什么微软在一开始就采用这种方法。它是一个第三方工具,由一家名为 Design Science 的公司在 1990 年至 2000 年开发。该公司仍然存在,仍然在用生产方程式编辑软件,但是如果我们猜测,微软要么根本没有源代码,要么就没有权限来修复它。。
Word 现在有自己的内置公式编辑功能,但公式编辑器仍然支持向后兼容性,以确保嵌入方程的旧文档继续可用。不过,我们对微软修复它而不是完全删除它感到有点惊讶。这确实是另一个时代的遗迹,比微软在安全编码实践和利用缓解技术方面的投入要早得多。公式编辑器缺少微软近期对代码的所有保护,使得它的缺陷比 Word 或 Windows 更容易被利用。这使它成为一种安全责任,如果这个字体错误是最后一个被发现的,我们会很难以置信。