本文研究了内核编译选项 CONFIG_SLAB_MERGE_DEFAULT
对 kmem_cache
分配的影响.
以及开启该配置的时候, slab UAF 的一种利用方案 (方案来源, 本文内容基于 Linux-5.10.90).
阅读前, 需要对 slab/slub, buddy system 有基本的了解.
CONFIG_SLAB_MERGE_DEFAULT
配置对比测试Keywords: slab/slub | CONFIG_SLAB_MERGE_DEFAULT | Linux kernel exploit
创建 struct kmem_cache
的时候,有两种情况:
__kmem_cache_alias
create_cache
kmem_cache_create(..)
kmem_cache_create_usercopy(..)
if (!usersize) // usersize == 0
s = __kmem_cache_alias(name, size, align, flags, ctor); // s 为 NULL 才会创建新的 slab
if (s)
goto out_unlock;
create_cache()
// 进入 `__kmem_cache_alias` 看看
__kmem_cache_alias(..)
// 检查 CONFIG_SLAB_MERGE_DEFAULT 配置;
// 如果开启了,则通过 sysfs_slab_alias 找到已经创建的相同大小的 slab 作为替代
s = find_mergeable(..)
list_for_each_entry_reverse(s, &slab_caches, list) {
if (slab_unmergeable(s)) // slab_nomerge 为 true 时 return 1;
continue;
...
return s;
}
return NULL; // slab_nomerge 为 true 的时候返回 NULL
if(s)
...
sysfs_slab_alias(..)
return s;
// CONFIG_SLAB_MERGE_DEFAULT=y -> slab_nomerge == false
// CONFIG_SLAB_MERGE_DEFAULT=n -> slab_nomerge == true
static bool slab_nomerge = !IS_ENABLED(CONFIG_SLAB_MERGE_DEFAULT);
// <https://cateee.net/lkddb/web-lkddb/SLAB_MERGE_DEFAULT.html>
// CONFIG_SLAB_MERGE_DEFAULT: Allow slab caches to be merged
// For reduced kernel memory fragmentation, slab caches can be merged
// when they share the same size and other characteristics.
// This carries a risk of kernel heap overflows being able to
// overwrite objects from merged caches (and more easily control cache layout),
// which makes such heap attacks easier to exploit by attackers.
测试 CONFIG_SLAB_MERGE_DEFAULT
的影响
Host 主机(开启了配置):
└─[$] uname -r
5.15.0-52-generic
└─[$] cat /boot/config-$(uname -r) |grep CONFIG_SLAB_MERGE_DEFAULT
CONFIG_SLAB_MERGE_DEFAULT=y
VM (未开启配置):