本页目录

内核加固

覆盖: 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):
/proc/sys/kernel/randomize_va_space = 2  # ASLR fully enabled

参考

  • 源码⁠: 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