You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

-D_FORTIFY_SOURCE=1编译无效果?咨询生效条件及相关问题

关于-D_FORTIFY_SOURCE的常见问题解答

为什么编译后checksec显示FORTIFY为No、加固函数数量为0?

可能存在以下几个原因:

  • 目标缓冲区大小无法被编译器确定:如果你的strcpy调用中,目标是动态分配的内存(比如malloc返回的指针)、或者是未指定大小的指针,编译器无法在编译期获取缓冲区的准确大小,也就无法将strcpy替换为加固版本__strcpy_chk。比如下面的代码就无法被加固:
    char *dest = malloc(10);
    strcpy(dest, "long string that overflows");
    
    而如果目标是固定大小的数组,编译器就能识别并替换:
    char dest[10];
    strcpy(dest, "long string that overflows");
    
  • 编译选项或环境问题:确保没有使用禁用Fortify的选项(比如-fno-fortify-source),同时确认你的gcc版本和系统libc支持Fortify(RedHat系系统默认的glibc版本通常满足要求)。另外,部分旧版本的checksec可能存在检测逻辑的局限性,可通过查看二进制符号表(用nm ftest | grep chk)确认是否存在加固函数。
  • 优化等级未达标:Fortify依赖编译器的数据流分析,必须开启-O1及以上的优化等级(你用了-O2是符合要求的,但如果编译时不小心覆盖了优化等级也会失效)。

-D_FORTIFY_SOURCE=1何时生效?

满足以下条件时,该选项才会起作用:

  • 开启优化等级-O1及以上:无优化时,编译器无法完成缓冲区大小的静态分析,也就无法替换加固函数。
  • 编译器能确定缓冲区大小:目标函数(如strcpy、memcpy)的源/目标缓冲区大小必须在编译期可被编译器推导,比如固定大小的栈数组、全局数组,或者通过sizeof能明确获取大小的对象。
  • 使用支持Fortify的C标准库:比如glibc 2.3及以上版本,RedHat系发行版默认提供的libc均支持该特性。

代码中无目标函数时,gcc会尝试加固吗?

不会。Fortify的核心逻辑是扫描代码中特定的不安全函数调用,在满足条件的情况下将其替换为对应的加固版本。如果代码中没有strcpy、memcpy等目标函数,编译器不会执行任何Fortify相关的处理,也不会在二进制中生成加固相关的符号或逻辑。

内容的提问来源于stack exchange,提问作者Kiran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:20:34