Android 8.1 上 memcpy 一点有趣的东西
前言
这几天一直在看 CVE-2020-0022 的东西,不清楚的同学可以参考:
https://insinuator.net/2020/02/critical-bluetooth-vulnerability-in-android-cve-2020-0022/
代码不长,具体逻辑我就不在这里分析了,总而言之问题就是
1 | diff --git a/hci/src/packet_fragmenter.cc b/hci/src/packet_fragmenter.cc |
当计算 packet->len = partial_packet->len - partial_packet->offset; 值的时候,可能计算出一个小的数,或者干脆是负数,导致在
后面拷贝的时候, 拷贝一个 负数长度的值,由于 memcpy 参数是无符号的,则导致拷贝一个大数
Android 8.1 memcpy 引起的一个小bug
在我和 @leommxj 测试的过程中,遇到一个坑,大致如图:
X0 是 dest ,X1是 src, X2是 size ,此时的size 明明是个负数,而且下溢后至少是一个很大的数,但是程序并没有崩溃。
引起 BUG 的原因
真的各种猜测不如看代码,所以我们把 libc.so 拿出来看了一下
重点在于:
此时 X0 是dest,Dest 取低位赋值给X9,然后
1 | ADD X2, X2 ,X9 |
而此时的 X2 是 len,导致他整型上溢出,变成一个小的数字,例如 0xa
当进入下图逻辑时
此时 X2 为 0xA,进行下面的指令的时候
1 | SUBS X2, X2, #0x90 |
由于此时 X2 为 0xA ,小于0x40,所以 此时条件为 小于
B. LS 则表示,当小于等于条件成立时候,为真,则跳转到 loc_1C8A8 处代码。
1 | loc_1C8A8 |
之后的代码逻辑直接就是 RET ,导致 并没有拷贝过长的内存,导致 crash。