网易首页 > 网易号 > 正文 申请入驻

Redis 客户端隐藏的内存漏洞,被一个不稳定测试无意间揪出

0
分享至

绕了一圈的弯路转折点:double free第三位主角登场ASAN 终结技几点启示

你有没有遇到过这种情况——测试用例偶尔挂,重跑一次又好了,谁也没当回事?

这几乎是每个后端团队的日常。但Buildkite团队最近遇到的一个"随机挂"的测试,最终揪出了一个藏在 Redis 客户端库深处的 use-after-free 漏洞。整个过程堪称教科书级的线上排障案例,值得每个写代码的人看看。

事情是这样的。Buildkite 的某个工程师在周五下午顺手升级了一下 Redis gem 的版本——看起来就是个常规操作,CI 全绿,谁也没多想。

然后到了下周二,工程经理 David 发现自己的构建挂了。挂的方式很奇怪——不是每次都挂,而是"偶尔挂"。一看 Test Engine 面板,三个测试用例的 reliability 从接近 100% 一夜之间掉到了惨不忍睹。

团队很快拉了 Andon Cord。因为这些测试太不稳定了,直接堵住了 master 分支的部署。先临时排除,再慢慢查。

这时候有个细节值得注意。David 多看了一眼测试可靠性的趋势图,发现三个最严重的"捣蛋鬼"是在 2-4 天前突然变不稳定的——正好和周五下午那个 Redis 升级的时间点吻合。

排查问题的第一步从来不是看代码,而是看变化。谁改了什么、什么时候改的,这些信息往往比代码本身更能帮你缩小范围。

团队起初走了一条很自然的弯路。因为这些测试是 feature test,跑的是一整套环境——RSpec + Selenium 无头浏览器 + Web/API 服务器 + 数据库 + Redis 服务器。在这种多组件环境下,竞态条件(race condition)是导致测试不稳定的常见元凶。

有人提议:"在 test setup 和 assertion 之间加个 sleep 试试?"

这其实不是一个解决方案,而是一个诊断手段——如果加 sleep 后问题消失,说明是 WebSocket 消息延迟导致的竞态。但问题是,就算确认了是竞态,你也不知道具体是哪一段代码的什么问题。

到了周一,更多测试开始随机挂。Patrick(就是升级 Redis 的那位工程师)和另一个前端同事一起,花了三天时间试图复现。他们最终搞出了一个稳定的复现方案,但跑一次要 30 分钟才出问题。

30 分钟才能复现一次——这意味着你在调试循环里,每改一行代码就要等半小时才知道结果。做过排障的人都懂这有多折磨。

第三天晚上,Patrick 精疲力尽,准备收工。就在这时,他看到了一个极不寻常的错误信息:

ruby(29632,0x2a9f1f000) malloc: Double free of object 0x2a9bb6740ruby(29632,0x2a9f1f000) malloc: *** set a breakpoint in malloc_error_break to debug

Double free。这意味着同一块内存被释放了两次。在 C 层面,这种错误会直接损坏内存管理器的内部数据结构,后续的任何 malloc/free 都可能触发不可预测的行为——包括 Segfault、数据损坏、或者表面上什么事也没有(这才是最可怕的)。

但团队当时还没有足够的信息把 double free 和测试失败联系起来。

又过了一天,一个构建触发了 segmentation fault,并且附带了 core dump。

这里有个小插曲:core dump 能自动上传,是因为有个开发之前为了调试另一个问题,写了一个 Buildkite 插件,专门检查构建产物里有没有 core dump,有的话就自动上传。这个"顺手为之"的插件,成了破案的关键。

这时,第三位主角 Rian 登场了。这位老兄在 Buildkite 以修复各种诡异 bug 闻名。通过分析 core dump,他发现崩溃发生在 hiredis 的 C 扩展代码里。具体来说,是 memmove 函数被调用时,size 参数传了一个 0x00a0ffffffffffb6——换算成十进制,大约 45 PB。

一个 memmove 要搬 45 PB 的数据。不用说,这肯定是内存被写坏了。

巧合的是,Rian 年初刚参加过一个关于用 ASAN(Address Sanitizer)排查 C 语言内存安全问题的技术会议。ASAN 是 Google 开发的一款内存错误检测工具,能精确捕获 use-after-free、buffer overflow 这类问题。

Rian 花了几个小时,用 ASAN 编译的 Ruby 跑通了复现脚本。30 分钟内,ASAN 就报告了一个heap use-after-free

问题出在 hiredis 的并发设计上。为了支持并发执行,hiredis 为每个连接起了两个线程——一个负责读,一个负责写。在某些特定场景下,读线程会释放写线程正在使用的缓冲区。读线程以为这块内存不用了,就 free 掉了,但写线程还在用它——经典的 use-after-free。

修复本身倒是很直接:临时禁用 C 扩展连接,然后向上游提交了 issue。

复盘整个事件,有几个点我觉得特别值得说:

1. 好工具 = 放大器。如果没有 Test Engine 的可靠性趋势图,David 可能根本不会把测试失败和 Redis 升级联系起来。没有 core dump 自动上传插件,崩溃发生一万次也传不上来。写工具就是在给未来的自己铺路。

2. 竞态条件是最容易背锅的。在多线程/多进程环境下,任何偶发的失败都容易被归因于"竞态"。这确实是常见原因,但如果你一开始就默认是竞态,可能错过真正的根因。

3. 内存错误很难排查,但工具箱在变好。Use-after-free、double free 这类问题,在纯 C 代码里排查曾经是噩梦。但随着 ASAN、Valgrind、核心转储分析等工具的普及,很多曾经要花数周的问题,现在可以在几小时内解决。

4. 运气 = 准备 + 机会。Rian 年初去听了那个 ASAN 的分享,纯属巧合。但如果他没去,或者去了没记住,这个机会就浪费了。你永远不知道哪一天,你读过的某篇文章、参加过的某个分享会帮你省下一周的时间。

你在项目里遇到过最诡异的 bug 是什么?评论区聊聊。

声明:内容由AI生成

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
你见过最冷门的姓氏是什么?网友:五十多了第一次见

你见过最冷门的姓氏是什么?网友:五十多了第一次见

夜深爱杂谈
2026-07-25 22:43:45
一位17年的高中班主任,提醒家长:一定要让孩子远离"伥鬼"朋友…

一位17年的高中班主任,提醒家长:一定要让孩子远离"伥鬼"朋友…

育儿教育日记
2026-07-24 07:29:06
金价将重现历史?要有心理准备,下月,金价可能将复刻2015年历史

金价将重现历史?要有心理准备,下月,金价可能将复刻2015年历史

亿通电子游戏
2026-07-27 01:15:09
中国足球小将蓝队主教练徐亮:“我们一定会争取创造奇迹,争取跟小将红队决赛会师。”

中国足球小将蓝队主教练徐亮:“我们一定会争取创造奇迹,争取跟小将红队决赛会师。”

刘哥谈体育
2026-07-27 03:24:56
罗永浩痛批电视厂家长辈模式难用:不毁灭没天理

罗永浩痛批电视厂家长辈模式难用:不毁灭没天理

鞭牛士
2026-07-26 08:38:05
讲话千万不要有奴才之相。

讲话千万不要有奴才之相。

人间清醒柒奶奶
2026-06-30 12:55:50
姑娘下次自拍的时候整理一下房间吧,你的秘密都被大家发现啦

姑娘下次自拍的时候整理一下房间吧,你的秘密都被大家发现啦

舞指飞扬
2026-07-25 10:25:18
骑士压湖人领跑库明加争夺战! 交易筹码出炉:斯特鲁斯+两次轮

骑士压湖人领跑库明加争夺战! 交易筹码出炉:斯特鲁斯+两次轮

醉卧浮生
2026-07-27 06:57:50
《侠探杰克》第四季首曝预告:地铁命案牵出权力黑幕,李奇遭遇最强危机

《侠探杰克》第四季首曝预告:地铁命案牵出权力黑幕,李奇遭遇最强危机

菜但瘾大第一名
2026-07-26 07:56:45
随着土耳其3-1巴西 女排总决赛冠军诞生 奖金分配出炉:中国队122万

随着土耳其3-1巴西 女排总决赛冠军诞生 奖金分配出炉:中国队122万

侃球熊弟
2026-07-26 22:05:31
新职本,迎党委书记、校长!

新职本,迎党委书记、校长!

EOL教育在线
2026-07-26 14:20:23
巨亏22亿、儿子跑路、本人失联!曾经的中国巴菲特,风光不再

巨亏22亿、儿子跑路、本人失联!曾经的中国巴菲特,风光不再

徐醇老表哥
2026-07-26 13:23:54
男子每天用刀片割癌症晚期患者肿瘤,称是“气功治病”收取家属360万元治疗费:无行医资格,证书全是买的

男子每天用刀片割癌症晚期患者肿瘤,称是“气功治病”收取家属360万元治疗费:无行医资格,证书全是买的

深圳晚报
2026-07-25 19:14:51
尘埃落定!瓦尔加斯当之无愧,斩获MVP,惠若琪新职位露面!

尘埃落定!瓦尔加斯当之无愧,斩获MVP,惠若琪新职位露面!

天光破云来
2026-07-27 10:11:30
沙利文曾亲口认错:佩洛西2022年窜台,是一次重大战略失误

沙利文曾亲口认错:佩洛西2022年窜台,是一次重大战略失误

桑启红原
2026-07-22 10:28:57
你见过最惊为天人的发型是什么样子?网友:震撼

你见过最惊为天人的发型是什么样子?网友:震撼

夜深爱杂谈
2026-07-08 21:42:51
苏提达粉裙新亮相,全场黑脸冷对泰王,欧拉弄娘家被封赏打脸王后

苏提达粉裙新亮相,全场黑脸冷对泰王,欧拉弄娘家被封赏打脸王后

可乐谈情感
2026-07-27 05:18:07
清华、北理工、北邮!贵州三胞胎学霸被北京三所高校录取,父亲:填志愿时优先考虑专业,在一个城市有照应

清华、北理工、北邮!贵州三胞胎学霸被北京三所高校录取,父亲:填志愿时优先考虑专业,在一个城市有照应

极目新闻
2026-07-25 12:06:59
痛批民进党是台湾的敌人,侯汉廷呛赖清德:吃狗粮比关心食安还快

痛批民进党是台湾的敌人,侯汉廷呛赖清德:吃狗粮比关心食安还快

海峡导报社
2026-07-26 10:06:38
美以终于意识到自己闯了大祸:可以轰炸伊朗,但不该斩首哈梅内伊

美以终于意识到自己闯了大祸:可以轰炸伊朗,但不该斩首哈梅内伊

小叨娱乐
2026-07-25 07:39:00
2026-07-27 11:27:00
千纸鹤安安
千纸鹤安安
大自然的搬运工
50文章数 1关注度
往期回顾 全部

科技要闻

长鑫市值登顶A股,盘中市值约等于2个茅台

头条要闻

长鑫科技老员工:上市和普通员工关系不大 更关心工资

头条要闻

长鑫科技老员工:上市和普通员工关系不大 更关心工资

体育要闻

詹姆斯的最后一集,依旧最艰难的路?

娱乐要闻

佟丽娅离婚不离家,绝非恋爱脑

财经要闻

不肯裁员的善人:西安商人严鹏之死

汽车要闻

轿跑姿态+大空间/标配655km续航 奇瑞风云A9置换价10.68万起

态度原创

房产
教育
艺术
时尚
本地

房产要闻

37人抢1套房…海棠湾资产拍卖,爆了!

教育要闻

“As Easy as Pie” 做派明明难到哭,凭什么叫“小菜一碟”?揭秘19世纪美国人的“躺平哲学”

艺术要闻

739米!深圳差点就拥有“中国第一高楼”

从小萌娃变大女王,她就是“天选之女”吧

本地新闻

跟着影视去旅行:西游篇

无障碍浏览 进入关怀版