Leveldb 中未定义的行为: 引用到 memcpy 读取 adding bytes 因为灵活的数组成员
作者: ubersandro创建于 2026年5月8日更新于 2026年5月8日
系统信息
- Oss-fuzz(git 承诺1282bc0ec18def62761c7e77d16d5003b72fcaa,分行主)
- 建筑和运行环境:脆弱平分版在Docker图像 Oss-fuzz 构建器中构建和运行,而不是跑道. 为了方便,我用建筑工在自定义的工作流程中模糊。 更具体地说,该容器基于Ubuntu 20.04.
根@b6ea40e79b1e:/sc/level#猫/etc/issues
Ubuntu 20.04.6 LTS平分版本:从多克文件的GitHub复制出尖端版本,git承诺7ee830d02b623e8ffe0b95d59a74db1e58da04c5,主分支.
编译器:Clang 21.1.0,基站git标记QQellvmorg-21.1.0```,自定义HWAsan来检查内对象错误. 目前我不能透露原型,因为它是一个正在进行的研究项目。 所有东西都是根据我的定制仪器和运行时间编成的
QQ 错误描述 使用“struct LRUHandle”中`key data'字段的灵活阵列成员。
// 一个条目是一个可变长度堆积分配结构. 条目
/ 保存在按访问时间排序的双链接循环列表中。
构建路汉德尔{
无效* 值;
无效( *deleter (const Slice&, 无效* 值);
LRUHandle * 下册;
下一个;
LRUHandle* 预科;
大小 t 充电; // TODO( opt): 只允许 uint32 t 吗 ?
大小 t 键 长度;
隐藏中布尔; // 条目是否在缓存中 。
uint32 t refs; // 参考文献,包括缓存引用,如果有的话.
uint32 t 散列; // hash 键 (); 用于快速硬化和比较
字符密钥 数据 [1]; // 密钥开头
剪切键 () const {
// 下一个当 LRU 控件为列表头时, 才等于此 。
// 空列表 。 列表头从来没有有意义的密钥.
profile( 下一个!=此);
返回 Slice( key data, key 长度);
{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
* ;
造成物体内溢出 引发我这种虫子的消毒器崩溃 一个memcpy在编译器插入的编码字节内写出. 这是使用灵活阵列成员造成的未定义行为的(经典)例子,我建议你考虑将"char key data [1]"改为"char key data[]",再将"cache.cc"中的行273和274改为:
a : 以美元计; LRUHandle* e = (中文(简体) ). 重新解释(malloc (LRUHandle) - 1 + 密钥. six () ) ;
b : (单位:千美元) LRUHandle* e = (中文(简体) ). 重新解释 cast < LRUHandle}(malloc (sizeof (LRUHandle) + key. signe ()) );
硬盘
root@10985de90b39:/src/leveldb#/out/fuzz db/crashes-fuzz db/* 维基语录链接:名人名言 - 文学作品 - 谚语 - 谚语 - 谚语 - 谚语 - 谚语
从/crashes-fuzz db/04e9ce2d296e542fcfda87adbd01f845a94b2e16读取262144字节.
[韩 地址 0x16007c4ff7260134: ptr 标签=b0b0b0bmem 标签=0b时检测到的标记不匹配.
===============================================================================================================================================================================================================================================================
0x7c4ff7260134标记时大小为8的WRITE: 0b/ff (ptr/mem) 在线程 T0中
以 1 为起点的无效访问
#0 0x555558d0a5 在SigTrap <( 花山: 错误行动)1, ( 花山: AccessType) 1>
. . . . . . .内容来源: google/leveldb