Linux内核堆栈溢出防护需启用多层加固机制:启用CONFIG_STACKPROTECTOR/STRONG插入栈金丝雀;开启STRICT_KERNEL/MODULE_RWX实现内存权限隔离;禁用KPROBES、KGDB、BPF_JIT等危险调试功能;配合SMAP/SMEP阻断利用链。

Linux内核堆栈溢出漏洞主要源于函数调用时局部变量或返回地址被恶意覆盖,进而劫持控制流。Kernel-hardening(内核加固)参数本身不直接“修复”某类溢出,而是通过限制攻击者利用溢出的能力,大幅提高 exploit 难度。关键在于启用并正确配置一系列内存保护与执行控制机制,而非单靠某个开关。
启用栈保护(STACKPROTECTOR)
这是防范堆栈溢出最基础且有效的编译期防护:
- CONFIG_STACKPROTECTOR:启用基础栈保护,插入 canary 值校验函数返回前的栈完整性;建议始终开启
- CONFIG_STACKPROTECTOR_STRONG:更强策略,对更多函数(含含数组、alloca、内联汇编等)插入 canary;推荐在生产环境启用
- 注意:该选项需内核编译时设定,运行时不可动态开启;检查当前是否生效可执行:
zcat /proc/config.gz | grep STACKPROTECTOR(若未启用 CONFIG_IKCONFIG_PROC,则需查编译配置文件)
强制只读/不可执行内存(RWX Protection)
即使栈被溢出,若无法跳转到恶意 shellcode 或篡改关键指针,攻击即失效:
- CONFIG_STRICT_KERNEL_RWX:确保内核代码段(.text)和只读数据段(.rodata)不可写、不可执行(对数据段);默认已启用,禁用会显著削弱防护
- CONFIG_STRICT_MODULE_RWX:同理约束内核模块内存权限;加载恶意模块时若此选项关闭,攻击者可直接 patch 模块函数指针
- 两者共同防止“ROP/JOP”类绕过——因为 gadget 地址所在区域被标记为不可执行,或关键函数指针所在结构体(如 file_operations)被设为只读
禁用危险调试与动态修改功能
某些本用于开发的功能,在生产环境中反而扩大攻击面:
- CONFIG_KPROBES 和 CONFIG_KGDB:允许运行时动态修改内核指令或内存;若非必要,应禁用;否则攻击者可借其绕过 RWX 保护(临时开写权限)
- CONFIG_BPF_JIT_DISABLE:设为 y 可禁用 eBPF JIT 编译器,避免 JIT 内存成为可执行喷射目标(尤其对旧版内核重要)
- CONFIG_DEBUG_SET_MODULE_RONX:虽非必需,但配合 STRICT_MODULE_RWX 可进一步锁定模块只读属性
辅助缓解:SMAP/SMEP 与 UAPI 限制
这些不直接防栈溢出,但能阻断常见利用链:
- CONFIG_X86_SMAP(x86_64):阻止内核态直接访问用户空间内存,使“ret2user”类攻击失效
- CONFIG_X86_SMEP:禁止内核执行用户空间代码,同样封堵 shellcode 直接执行路径
- 精简 CONFIG_COMPAT、关闭未用子系统(如 CONFIG_NETFILTER 若无防火墙需求),可缩小内核攻击面,降低溢出点暴露概率


















