内存分配学习笔记1


kmem_cache

kmem_cache定义如下:https://elixir.bootlin.com/linux/v6.13.1/source/mm/slab.h#L258

cpu_slab

cpu_slab是一个__per_cpu变量,这意味着kmem_cache创建时会为每一个CPU创建一个__per_cpu变量,所以不同的CPU分配资源的时候就会从不同的slab上进行分配;

  • freelist:指向下一个空闲对象的指针
  • slab:当前用以进行内存分配的 slab
  • partial:percpu partial slab 链表,链表上为仍有一定空闲对象的 slab

slab 的 freelist 仅当其在 partial 链表上时有用,当一张 slab 为当前 CPU 正在使用的 slab 时,其 freelist 为 NULL,由 kmem_cache_cpu.freelist 指向第一个空闲对象:

kmem_cache_node

kmem_cache_node *node[]是一个 kmem_cache_node 数组,对应多个不同 node 的后备内存池,这里的node即内存三级结构”页-区-节点“中的节点

partial指向一个部分使用的slab的链表;

full则是指向一个完全使用的slab的链表;

slab

源码定义

slab再源码中的定义位置:https://elixir.bootlin.com/linux/v6.13.1/source/mm/slab.h#L52

  • inuse :已被使用的对象数量
  • objects:该 slab 上的对象总数
  • frozen:是否被冻结,即已经归属于特定的 CPU

所以在double-free漏洞中,释放vul-obj两次,会使inuse变量递减两次,从而导致在有一个obj尚且存活的情况下,使得该slab被判定为empty。

slab的object管理结构分析

再回过头来看一个kmem_cache的成员:

size是包含了上述object之外的“红区”等结构的size(当然可能这些空间压根不存在,取决于内核编译配置),object_size则是真正的obj的size,而offset成员则表示了freepointer指针在一个object中的偏移:

slab object的其他保护措施

CONFIG_SLAB_FREELIST_RANDOM

初始化slab的内存空间时,随机顺序选取free-object形成freelist链表;

CONFIG_SLAB_FREELIST_HARDENED

CONFIG_HARDENED_USERCOPY

分配&&释放

内存分配浅析

slab分配对象的过程大致如下:

内存回收浅析

快速释放:释放对象所在的 slab 刚好是 slab cache 在本地 cpu 缓存 kmem_cache_cpu->page 缓存的 slab

慢释放:

  1. 如果 slab 本来就在 slab cache 本地 cpu 缓存 kmem_cache_cpu->partial 链表中,那么对象在释放之后,slab 的位置不做任何改变;

  2. 如果 slab 不在 kmem_cache_cpu->partial 链表中,并且该 slab 由于对象的释放刚好由一个 full slab 变为了一个 partial slab,为了利用局部性的优势,内核需要将该 slab 插入到 kmem_cache_cpu->partial 链表中。

  3. 如果 slab 不在 kmem_cache_cpu->partial 链表中,并且该 slab 由于对象的释放刚好由一个 partial slab 变为了一个 empty slab,说明该 slab 并不是很活跃,内核会将该 slab 放入对应 NUMA 节点缓存 kmem_cache_node->partial 链表中,刀枪入库,马放南山。

    在将这个 empty slab 插入到 kmem_cache_node->partial 链表之前,同样需要检查当前 partial 链表中的容量 kmem_cache_node->nr_partial 不能超过 kmem_cache-> min_partial 的限制。如果超过限制了,直接将这个 empty slab 释放回伙伴系统中。

  4. 如果不符合第 2, 3 种场景,但是 slab 本来就在对应的 NUMA 节点缓存 kmem_cache_node->partial 链表中,那么对象在释放之后,slab 的位置不做任何改变。

参考

https://arttnba3.cn/2023/02/24/OS-0X04-LINUX-KERNEL-MEMORY-6.2-PART-III/

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

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

https://blog.csdn.net/Breeze_CAT/article/details/130015721


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