kfree源码分析2(slab何时被buddy-system回收)


kfree机制

1是快路径,其余的2、3、4、5都是慢路径的不同情况;

源码解析

slub中有如下成员:

counters是inuse、objects、frozen的联合体,便于一次性将三个值一起赋值、拷贝;

inuse表示slub中已经分割出去的对象的数目;

frozen是一个状态位表示slub是否在当前cpu的partial链表中;

do_slab_free源码如下:https://elixir.bootlin.com/linux/v5.10/source/mm/slub.c#L3090

首先通过page == c->page来判断是不是当前cpu的slab,如果是,则直接插入;如果不是,就走__slab_free:https://elixir.bootlin.com/linux/v5.10/source/mm/slub.c#L2961

一个do-while循环:

可以看到free的时候是要inuse-=cnt减去释放的数量的;

!new.inuse表示这个slub已经变成empty了,!prior是指freelist为NULL,也就是说slub是full的,这两种情况下,都有可能(还有看是不是在cpu的partial中)要进行移动,所以紧接着用!was_frozen表示不在当前cpu->partial的链表中,因此要分情况讨论移动;第一种情况kmem_cache_has_cpu_partial表示当前cpu有partial链表,并且slub是full,那就将其移动进来;否则就是往node中移动的情况:

cross_cache

可以看到,如果我们存在一个double-free漏洞,将漏洞结构体释放两次,则可以让slab的inuse减少两次,那么就存在某一个同cache的结构体没有释放的情况下使inuse达到0,然后经过一系列的操作让这个slab被buddy-system回收,最终造成这个未释放结构体的cross-cache-uaf;

参考

https://www.cnblogs.com/binlovetech/p/17434311.html


文章作者: q1ming
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 q1ming !
  目录