如何修复“/usr/bin/ld:警告:trap.o:缺少 .note.GNU-stack 部分意味着可执行堆栈”?

问题描述 投票:0回答:2

我分别在wsl和我的主要使用的操作系统archLinux中的ubuntu20.04上编译了相同的项目。在 wsl 上,一切正常,而在 archlinux 上,会显示如下错误消息:

/usr/bin/ld: warning: trap.o: missing .note.GNU-stack section implies executable stack
/usr/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker

这似乎是由链接器ld引起的错误,它在我的linux操作系统上的版本消息是:

GNU ld (GNU Binutils) 2.39
Copyright (C) 2022 Free Software Foundation, Inc.

我的 wsl 上的它是:

GNU ld (GNU Binutils for Ubuntu) 2.34
Copyright (C) 2020 Free Software Foundation, Inc.

在 arch 上,gcc 的版本是 12.1.1,而在 wsl 上是 gcc 9.3.0

是新旧版本差异造成的吗? 我该如何解决它?

c linux gcc windows-subsystem-for-linux ld
2个回答

0
投票

这是 GNU bin-utils 版本 2.39 引入的新警告消息。

这里引用来自发布消息

如果堆栈被创建,ELF 链接器现在将生成警告消息 可执行的。同样,如果输出二进制文件包含 具有所有三个读、写和执行权限的段 位设置。这些警告旨在帮助开发人员识别 可能容易受到这些可执行文件攻击的程序 记忆区域。

话虽如此,很难说出为什么您的代码会生成可执行堆栈。以下是可能的原因和解决方案的列表:

  • 链接时(或同时编译和链接),将标志
    -z noexecstack
    传递给
    gcc
    clang
  • 如果您的项目包含原始 x86-64 汇编代码,您可能需要在汇编中添加以下行
    .section .note.GNU-stack,"",@progbits
    。这行告诉编译器不要使用可执行堆栈;
  • 如果您编写了显式使用可执行堆栈的汇编代码,则在链接时应传递标志
    -z execstack
    ;然而,可执行堆栈通常被认为是安全漏洞;
  • 最棘手的部分是,尽管您不希望有可执行堆栈,但编译器以某种方式认为它是必要的。一种可能的原因(以及许多其他原因)是嵌套函数和函数指针。很难发现这些事件;一种方法可能是将所有文件编译成程序集并定位为
    .section .note.GNU-stack,"x",@progbits
    ,这意味着使用可执行堆栈。在这种情况下,传递标志
    -z noexecstack
    是不够的。尽管警告被抑制并且编译和链接可能会成功,但可能会出现运行时错误。
© www.soinside.com 2019 - 2024. All rights reserved.