本页目录
内核加固
覆盖: KASLR → stack protector → KPTI → KASAN/KMSAN/UBSAN → FORTIFY_SOURCE → lockdown → seccomp → SLAB_FREELIST_RANDOM → init_on_free 内核版本: 2.6 ~ 6.x
地址空间随机化: KASLR
启动时随机化内核代码/数据/模块的基址:
→ ROP/JOP 攻击需要知道 gadget 地址 → 不知道基址 → 更难
实现: arch/x86/boot/compressed/kaslr.c
在 bootloader 阶段选随机基址 → 解压 relocated 内核
kptr_restrict: 限制 /proc/kallsyms 泄露内核地址
/proc/sys/kernel/kptr_restrict = 2 → 非 root 看全是 0
Stack Protector
// CONFIG_STACKPROTECTOR: 编译器在每个函数的栈帧插入 canary
// gcc: -fstack-protector-strong
// → 保护: 函数中有局部数组或取地址的操作
// canary 被改写 → 栈溢出 → __stack_chk_fail() → panic
// kernel/stackleak.c (可选): 更彻底的栈清理
// 每次 syscall 返回前擦除已用栈空间
// → 防止栈信息泄露 (如未初始化的局部变量)
KPTI: Meltdown 防御
2018 Meltdown 漏洞:
CPU 在推测执行中不检查页表 U/S bit → 用户态读内核内存
KPTI (Kernel Page Table Isolation):
每个进程有两个页表:
内核态: 完整映射 (user + kernel)
用户态: 最小 (user + trampoline)
→ 用户态时无法推测访问内核内存
性能代价: ~5%~30% (syscall 密集型), PCID 部分缓解
现代 CPU (Cascade Lake+, Zen2+): 硬件修复, KPTI 自动禁用
Sanitizers: 运行时错误检测
// KASAN (Kernel Address Sanitizer):
// 检测: out-of-bounds, use-after-free, double-free
// 基于影子内存 (编译时 instrumentation)
// 开销: ~1.5-2x 慢, 仅调试内核
// KMSAN (Kernel Memory Sanitizer):
// 检测: 未初始化内存使用
// 比 KASAN 更重 (~3x), 仅开发用途
// UBSAN (Undefined Behavior Sanitizer):
// 检测: 整数溢出, 移位越界, 空指针解引用
// 开销低, 可在生产环境中启用 (CONFIG_UBSAN_BOUNDS)
FORTIFY_SOURCE
// 编译时替换 memcpy/strcpy/sprintf:
// 有边界信息 → 生成带检查的调用
// 编译时已知越界 → 编译失败
// 运行时越界 → BUG() (不是返回错误)
//
// 与用户态 FORTIFY_SOURCE 类似, 但覆盖更多函数
Kernel Lockdown
UEFI Secure Boot 启用后:
→ kernel lockdown 自动激活 (integrity 模式)
→ 禁止:
- /dev/mem, /dev/kmem (内存读写)
- ioport 访问
- kexec (加载未签名内核)
- BPF 写内核内存
- ACPI table 覆盖
/proc/sys/kernel/lockdown:
none / integrity / confidentiality
seccomp
// prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)
// 限制进程能调用的系统调用 (不可逆)
// BPF 过滤器:
// 检查 syscall number + 参数 → ALLOW / DENY / KILL / TRAP
// Chromium, Docker, systemd 都使用
// SECCOMP_RET_USER_NOTIF (5.0+):
// 不在内核中做决定 → 通知用户态监督进程
// 如: 容器管理器批准/拒绝某些 syscall
其他加固选项
# 释放时清零:
CONFIG_INIT_ON_FREE_DEFAULT_ON=y # 释放的 slab 对象 → 清零 (防 UAF 信息泄露)
# slab freelist 随机化:
CONFIG_SLAB_FREELIST_RANDOM=y # slab freelist 指针随机排序 (防 heap exploit)
# 硬化的用户内存复制:
CONFIG_HARDENED_USERCOPY=y # 验证 usercopy 源/目标在合法 heap/slab 区域内
# 栈随机化 (已有, per-process):
参考
- 源码:
security/lockdown/,kernel/seccomp.c,mm/kasan/,lib/ubsan.c - 内核文档:
Documentation/admin-guide/kernel-parameters.txt - LWN: "Kernel address space layout randomization", "The kernel lockdown patches"
关键词: KASLR, stack protector, KPTI, KASAN, FORTIFY_SOURCE, lockdown, seccomp, init_on_free