在drivers/tty/n_hdlc.c中存在竞争条件, 同一个对象可以两次被加入到一个将被free的链表中, 然后导致double free.
- 在最开始的调试中, 发现kfree函数会改写被释放空间的首个unsigned long数据,
后来发现这个数据是用来记录前一个释放的空间的地址.
用如下模块测试
ptr0 = kmalloc(8192, ...); ptr1 = kmalloc(8192, ...); kfree(ptr0); *(unsigned long *)ptr0 = ptr0+0x4000; /* this value is not ptr1 */ kfree(ptr1); kmalloc(8192, ...); /* return ptr1 */ kmalloc(8192, ...); /* return ptr0+0x4000 */
- 在触发double free时,
prev = last rx_free_buf_list
buf0 = first tx_free_buf_list
buf1 = buf0->link
buf2 = buf1->link
buf3 = buf2
因为在释放的时候, 会把->link的数据改写为之前释放的空间地址, 释放的顺序为 prev buf0 buf1 buf2 buf2 buf1 buf0 prev 此时buf1和buf2的首个unsigned long数据均为buf2, 也就是说, 后续的 申请会得到两个对象指向同一个空间地址的情况 - double free 类型漏洞的利用