漏洞分析

漏洞1

题目类似实现了一个共享页面管理器,在简单逆向后可以发现,题目的d3kshrm_vm_ops回调仅实现了d3kshrm_vm_closed3kshrm_vm_fault,而并未实现vm_open的相关操作。

d3kshrm_vm_close中,销毁一个vma会对total_ref进行—操作,由于题目并未实现vma_open,我们实际可以通过mremapmunmap提前多次触发d3kshrm_vm_close,在仍有vmakshrm_slot有索引的情况下提前满足release条件,达成vmakshrm_slot的uaf。

image.png

image.png

但此时kshrm_slot->pages已被释放,在kmalloc-192中难以找到可以堆喷类似page** 的结构体,继续分析逻辑可以找到fault与free逻辑中存在race。

d3kshrm_vm_fault操作逻辑中只持slot锁

image.png

而ioctl中release逻辑在完全free pages之前就释放了slot锁

image.png

从而我们可以想到以下利用方式

1.再次申请slot,populate此时vma索引的slot,page的ref为1

2.利用free_pages到cache_free之间的time window,此时page已被释放回buddy system,但是并未被pages数组clear,slot此时也能访问到pages数组,从而可以fault一个位于free area的页,拿到page-uaf

thread1 therad2
free_page
fault
free_pages

笔者在成功fault一个位于free area的页后,在赛中并未成功通过堆喷重新将该页申请出来,后续赛中利用使用了漏洞2

漏洞2

注意到d3kshrm_vm_fault逻辑实际存在一个off_by_one,允许我们越界fault一个页。

虽然在d3kshrm_mmap的处理逻辑中限制了映射长度,但我们可以通过mremap bypass 限制。

image.png