Week 4 - Slub Allocator
本文章涵蓋基礎 Slub Allocator 的運作流程。
slub allocator 是基於 buddy system 上,進行更精細物件分配的機制。
buddy system 分配時皆以 2^n 個 page 為單位,但一般情況不需要這麼大的記憶體。
若我們只想要 192 bytes 的空間,卻得到一個 page,將造成不小的 fragmentation。而且空間被 free 掉後,就會馬上被合併。兩者使 buddy system 在時間和空間上,都不適合小量頻繁操作。
因此 slub allocator 將一塊連續記憶體由一個 slab
控管。底下包含多個 object,類似 glibc 的 chunk,代表固定大小要分配的區塊。
而 slab
由 kmem_cache
, kmem_cache_node
, kmem_cache_cpu
控管。
常用結構
slab
在較早的 linux,slab 內嵌在 page 結構,畢竟一個 slab 由多個 page 組成,page 管好底下的 object 就好。
後來統一用 slab 結構管理。
1 | struct slab { |
slab_cache
slab 屬於的 kmem_cachefreelist
slab 上的 free object 組成一個 linked list,freelist 指向第一个 free objectslab_list
串連多個 slabinuse
目前多少 object 正被使用objects
此 slab 上的 object 數量frozen
是否被凍結,也就是屬於特定的 CPU
counters 和 inuse
, objects
, frozen
組成 union,後續對 counter 做操作,等同修改他們的值。
slab 的管理範圍,基本上是負責的連續記憶體,及其擁有的 free object。
kmem_cache
1 | struct kmem_cache { |
cpu_slab
當前 CPU 使用的kmem_cache_cpu
結構min_partial
partial list 上 slab 的最大數量cpu_partial
每個 CPU 的 partial list 的最大 object 數量cpu_partial_slabs
每個 CPU 的 partial list 的最大 slab 數量size
一個 object 包含 alignment 的大小object_size
一個 object 實際大小offset
slab 的 freelist 指向 object 上的偏移oo
一個 int- 低 16 位:一個 slab 的 object 數量
- 高 16 位:一個 slab 的大小
min
一個 slab 的最少 object 數量allocflags
向 buddy system 索取 page 所用的 gfp flagctor
分配 object 後調用 constructorrandom_seq
用於 CONFIG_SLAB_FREELIST_RANDOM 打亂 freelist 順序- CONFIG_HARDENED_USERCOPY 相關
useroffset
user space 能讀寫的 offsetusersize
user space 能讀寫的 size
node
包含多個kmem_cache_node
kmem_cache
負責控管全局資訊,包含 size, metadata,底下的 node 和 per cpu 等。一個 kmem_cache
只負責一個 size 的 object,與其他 cache 組成 double linked list。
kmem_cache_cpu
1 | struct kmem_cache_cpu { |
freelist
指向下一個 free objectslab
當前用來分配的 slab(只有一個),若要 allocate 時已滿,或是 free 時已完全空閒,可能換成其他 slabpartial
包含擁有 free object 的 slab 列表
kmem_cache_cpu
統合所有 slab,包含已經無 freelist 的 slab,操作時爲避免 context switch 造成 race condition,對 list 操作前常使用 lock。slab->freelist
僅當在 partial 時有用,若它是當前 CPU 使用的 slab,則 freelist 會移到 kmem_cache_cpu->freelist
。
kmem_cache_node
1 | struct kmem_cache_node { |
list_lock
保護 partial 和 full 的 locknr_partial
partial slab 的数量partial
包含擁有 free object 的 slabnr_slabs
partial + full 的 slab 数量total_objects
object 數量總和full
包含無 free object 的 slab
object
object 並無一個固定的 struct,它的結構依 object 大小和設定調整。
1 | Debug off: |
free pointer 位置在某些情況會存 object 正中間。
slab 只紀錄 free object,正被使用的 object 不會有 pointer 指向下一個 free object。
參考資料
- https://www.cnblogs.com/binlovetech/p/17373667.html
- https://ctf-wiki.org/pwn/linux/kernel-mode/exploitation/heap/heap_overview/#_3
- https://arttnba3.cn/2023/02/24/OS-0X04-LINUX-KERNEL-MEMORY-6.2-PART-III/
- https://blog.csdn.net/weixin_45337360/article/details/122921716
- https://zhuanlan.zhihu.com/p/490588193