intel cet 的 shadow stack 是硬件强制的只写独立栈,专存返回地址,cpu 执行 ret 时校验主栈与 shadow stack 顶部地址一致性,不一致则触发 #cp 异常;它仅防护函数返回路径,不防 jmp/call/间接跳转、堆 rop 或 jit spray。

Intel CET 的 shadow stack 是什么,它真能拦住 ROP?
它不是万能盾牌,但确实是目前 x86_64 上最实用的 ROP 缓解机制之一。CET 的 shadow stack(影子栈)通过硬件强制维护一个只写、只用于存返回地址的独立栈,让攻击者无法用常规栈溢出篡改 ret 指令要跳转的目标——因为 CPU 在执行 ret 时会同时校验主栈和 shadow stack 顶部的地址是否一致,不一致就触发 #CP 异常。
注意:它只保护「函数返回」这一跳转路径,对 jmp、call、间接跳转(如 jmp rax)完全不设防;也不防堆上构造的 ROP 链或 JIT spray。所以别把它当成“开了就安全”的开关。
启用 CET shadow stack 需要哪些编译+链接步骤?
必须全链路配合:源码编译、链接、运行时加载都得支持,缺一不可。常见漏掉的是链接器没加 --shstk 或没启用 -fcf-protection=full。
- 编译时加
-fcf-protection=full(GCC/Clang),这会插入endbr64指令并为每个函数生成 shadow stack 同步逻辑 - 链接时加
-Wl,-z,shstk(告诉链接器生成含 CET 元数据的 ELF) - 可选但推荐:加
-mshstk(显式启用 shadow stack 指令支持,避免某些旧 binutils 报错) - 运行前确认内核支持:
cat /proc/cpuinfo | grep cet_report有输出,且sysctl kernel.unprivileged_userfaultfd不影响 CET(它不依赖 userfaultfd)
为什么开了 CET 还 crash 在 __cet_report_failure?
这不是 bug,是 CET 正常拦截到非法返回行为后调用的终止函数。常见原因有三类:
- 手写汇编里用了
ret但没同步更新 shadow stack(比如 inline asm 中直接pop %rax; ret) - 异常处理流程绕过了编译器生成的 shadow stack 恢复逻辑(如 longjmp、setjmp 跨 CET 编译模块时未统一启用)
- 第三方库(尤其闭源或静态链接的老库)没编译 CET 支持,它的函数返回时 shadow stack 和主栈不匹配
查问题最快方式:用 gdb 断在 __cet_report_failure,看 $rsp 和 $r15(shadow stack pointer,默认由内核设为 0x7ffffffff000 附近)的值差异,再回溯调用栈里哪个函数没走编译器生成的 shstk 入口/出口序列。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
C++ 对象生命周期和异常会不会破坏 shadow stack?
标准 C++ 异常机制本身不破坏 shadow stack,但前提是整个调用链(包括 libstdc++ 或 libc++)都用 -fcf-protection=full 编译。否则 throw/catch 过程中某一层调用的 runtime 函数(如 __cxa_throw)若没 CET 支持,就会导致 shadow stack 失步。
更隐蔽的问题是 RAII + 栈展开混合场景:如果析构函数里调用了未启用 CET 的回调函数(比如通过 std::function 绑定的裸函数指针),而该函数又执行了 ret,那它不会做 shadow stack 同步——因为编译器不知道这个函数需要保护。
建议:所有参与异常传播路径的代码(包括 STL 实现、自定义分配器、回调注册点)统一开启 CET;避免在析构函数里调用不可控的外部 C 接口。
复杂点在于,CET 的 shadow stack 是 per-thread 的,且由内核在 clone 时初始化。如果你用 pthread_create 创建线程但没链接 -lpthread(或用 musl libc),某些场景下 shadow stack pointer 可能没被正确设置,导致线程一执行 ret 就崩——这种问题只能靠 strace -e clone,arch_prctl 观察系统调用流来定位。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!








