Sourcebrella Pinpoint令MySQL漏洞无处藏身

MySQL 是目前最流行的开源关系型数据库管理系统,据统计,其流行程度在2016年及2017年在数百种数据库管理系统中以微弱的差距排名第二[1],其历史悠久,至今已有573个发行版本以及众多直接与间接贡献者[2]。任何一个其中的软件漏洞都将影响数亿甚至更多人的生命财产安全。

Use-after-Free/Double Free是众所周知的高危漏洞,根据研究者对CVE中Chromium browser漏洞统计,该种类型的漏洞数量远远超过堆栈溢出,并比其它漏洞类型更为危险:88%的Use-after-Free/Double Free被标记为极为关键和重要的安全漏洞[3]。然而,由于该类漏洞的复杂性,学术界与工业界对其没有有效的(即精确又高效的)自动化检测方法[4]。

当世界最流行的开源关系型数据库管理系统遇到如此危险的高危漏洞,又缺乏有效检测工具时,其危险程度可想而知。况且,MySQL包含超过200万行的C/C++代码,精确的自动化分析困难:或分析及慢,远远超过一次nightly building的时间;或分析结果不精确,产生大量的误报。我们的自动化检测工具突破了困难,在1.5小时内完成了对MySQL Server的扫描,精准定位了其中两个Use-after-Free/Double Free漏洞,并获得了开发者的确认。

相关链接:

Bug#87200

mysql1

如上图所示,该bug的产生是由于开发者在第2750行调用my_free(buf)后,未重置buf为null造成的,这个释放后的内存的指针,将从该函数返回,从而影响系统安全。

在于开发者讨论过程中,开发者认为其在my_free函数中,对buf进行了特殊的操作,因此即使使用my_free(buf)后,buf的使用也是安全的。然而,MySQL提供了两套my_free函数,分别针对不同的运行环境,其中一个my_free函数如下将会直接调用my_raw_free函数,my_raw_free函数直接调用free函数,没有任何保护操作,因此开发者最终确认是一个真实的问题。

相关链接:

Bug#87203

相比上一个bug,该bug要复杂许多,其存在于一个长约1000行的函数之中,该bug也跨越了500余行,数个复杂的循环结构。

2.jpg

如上图所示,一个nonnull指针被释放以后,由goto语句跳转到write_buffers标记处,如下图所示:

3.jpg

write_buffers处是一个loop循环,其中有多个异常处理代码片段,会直接跳转到func_exit标记处,其中将对再次对nonnull指针进行free操作。

mysql4

该bug的复杂程度不仅可以从其跨越的代码行数看出,从开发者的回复中也可见一斑,开发者如是说 “We did a lot of analysis…this remains as Not a Bug”。可想而知,即使在拥有精准的检测工具的情形下,开发者仍然很难确认bug,难以想象,如果没有这样的检测工具,这样的漏洞会影响我们多久。当然,在与开发者交流的过程中,我们也发现了很多可以改进的地方,比如增加bug报告的可读性,让开发者更加相信自动化检测工具的结果,实实在在的接受自动化检测工具,而不是在第一时间否定bug的真实性。




[1] https://db-engines.com/en/ranking

[2] https://github.com/mysql/mysql-server

[3] Lee B, Song C, Jang Y, et al. Preventing Use-after-free with Dangling Pointers Nullification[C]//NDSS. 2015.

[4] 同上