zl程序教程

您现在的位置是:首页 >  其他

当前栏目

猿友福音:使用AddressSanitizer排查程序错误

错误程序 排查 福音 使用
2023-09-14 09:10:46 时间

AddressSanitizer(ASan)已经在Visual Studio 2019 v16.9中正式发布了。最近,我们使用了这项功能找到了MSVC编译器中的一个Bug。为了进一步验证ASan确实为开发者带来了实实在在的益处,我们还将其用在了一些被广泛使用的开源项目中,在开源项目Boost,Azure IoT C SDK和OpenSSL中,我们同样发现了一些Bug。 在本文中,我们通过描述发现的错误的类型以及它们在这些项目中的表现方式来介绍我们的发现。 如果你不了解ASan是什么,以及如何使用它,则可以在研究本文之前先阅读一下ASan的开发文档。

Boost和快速迭代器

快速迭代器是指向容器边界之外的元素然后被取消引用的迭代器。下面的代码演示了这种错误的内存访问模式:

 

有时候,快速迭代器可能会错误地出现在更复杂的循环中,例如Boost的UTF-8转换实现中的do_length函数,如下所示:

 

在上面的代码中,当后者指向UTF-8字符边界时,使用小于或等于运算符将from_next正确设置为from_end。 但是,这也会导致最终迭代器被取消引用的错误。使用ASan编译此代码并在Visual Studio中对其进行调试会导致ASan在预期位置中断,如下图所示:

 

对于这个问题,我们已经通知了Boost开发团队,他们已经修复了这个问题。

Azure IoT C SDK

当使用常量来跟踪数组的长度但长度不正确时,就会发生数组与其长度常量之间的分歧。 当在内存复制操作中使用长度常量时,这可能会导致内存访问错误。 下面的简单示例说明了这个问题:

 

我们在Azure IoT C SDK中发现了此错误的一个实例,其中字符串的长度常量与实际长度不匹配,如下图所示:

 


TWIN_REPORTED_PROPERTIES_LENGTH常数的值为117,而TWIN_REPORTED_PROPERTIES字符串的实际大小为107,使用memcpy复制该字符串时会导致全局缓冲区溢出。 在名为CONSTBUFFER_Create_Internal的深层内部函数中,使用ASan构建此代码并使用Visual Studio进行调试会在调用memcpy时显示错误:

 

这并没有立即告诉我们错误的根源是什么,但是由于Visual Studio中的ASan集成,可以使用“调用堆栈”窗口来遍历堆栈并查找传递了错误大小值的函数:

 

这种情况下的罪魁祸首是send_one_report_patch函数,该函数将TWIN_REPORTED_PROPERTIES和
TWIN_REPORTED_PROPERTIES_LENGTH传递给间接调用CONSTBUFFER_Create_Internal的函数:

 

通过使用sizeof运算符将长度常量设置为始终反映字符串实际大小的值,我们解决了此问题。

OpenSSL

当类型的大小根据预处理程序的定义而变化时,就会产生变形类型。 如果假定该类型具有特定大小,则可能会发生内存访问错误。 一个简单的示例如下所示:

 

如果定义了BIGGER_INT,则由于myBuffer假定MyInt的大小与int相同,因此由于localBuffer变量,memcpy操作可能会触发堆栈缓冲区溢出。 在test_param_time_t OpenSSL测试中找到了此错误的一个实例:

 

在这里,size_t被假定为与time_t相同的类型,但这并非总是如此,这取决于要为其编译的体系结构。 使用le_copy函数复制到cmp时,复制操作的大小为sizeof(time_t),但cmp缓冲区已使用size_t大小初始化。 使用ASan构建OpenSSL测试并使用Visual Studio进行调试时,调试器会在le_copy中出现ASan错误,从而导致调试失败:

 

再次感谢VS中的ASan集成,我们能够使用调用堆栈窗口来查找错误的实际来源:test_param_time_t函数:

 

我们将此发现告诉了OpenSSL开发团队,他们已经修复了此问题。

总结

在本文中,我们分享了如何使用AddressSanitizer查找各种开源项目中的错误。 我们希望这会激发你在自己的代码库中使用此功能。

最后

Microsoft Visual C++团队的博客是我非常喜欢的博客之一,里面有很多关于Visual C++的知识和最新的开发进展。大浪淘沙,如果你对Visual C++这门古老的技术还是那么感兴趣,则可以经常去他们那(或者我这)逛逛。
本文来自:《Finding Bugs with AddressSanitizer: Patterns from Open Source Projects》

最近我写了个东西

正如你们所知道的,拓扑梅尔智慧办公平台(Topomel Box)是一款绿色软件,主要面向经常使用电脑的朋友。它提供了各种提升办公效率的小功能,同时操作上尽可能地简单方便。
我想:你值得拥有。