1

一种现代 Linux 安全强化策略是使用选项编译和链接代码-Wl,-z-noexecstack,这将 DLL 或二进制文件标记为不需要可执行堆栈。可以使用readelf或其他方式检查这种情况。

我一直在使用 uClibc 并注意到它会生成没有设置此标志的对象(.so 文件)。然而 uClibc 有一个配置选项UCLIBC_BUILD_NOEXECSTACK,根据帮助意味着:

  Mark all assembler files as noexecstack, which will mark uClibc
  as not requiring an executable stack.  (This doesn't prevent other
  files you link against from claiming to need an executable stack, it
  just won't cause uClibc to request it unnecessarily.)

  This is a security thing to make buffer overflows harder to exploit.
  ...etc...

在深入研究 Makefile 时,这是正确的 - 该标志仅适用于汇编程序。

因为标志只传递给汇编器,这是否意味着 uClibc 开发人员错过了一个重要的强化标志?还有其他选项,例如UCLIBC_BUILD_RELRO确实会导致将等效标志添加到链接器(as -Wl,-z,relro

然而,一个不经意的观察者很容易误读这一点,并假设,正如我最初所做的那样,这UCLIBC_BUILD_NOEXECSTACK实际上是在标记 .so 文件,而实际上并非如此。例如,OpenWRT 确保在构建 uClibc 时设置该标志。

为什么 uClibc 不会以“通常”的方式做事?我在这里想念什么?这些库(例如 librt.so、libpthread.so 等)实际上不是 NX 吗?

编辑 我能够使用 Makefiles 并通过使用-Wl,-z,noexecstack参数获得 noexecstack 位。那么他们为什么不使用它呢?

4

1 回答 1

1

好的,经过列表对话和进一步研究后发现:

  • GNU 链接器根据“最低公分母”设置 DLL / 可执行堆栈状态,即如果任何链接或引用的部分具有 exec 堆栈,则整个对象都以这种方式设置

  • 解决此问题的“正确”方法实际上是在不需要时查找并修复使用 exec 堆栈的程序集/目标文件。

如果您无法以其他方式解决根本原因,则使用链接器“修复”问题是一种解决方法。

所以对于 uClibc 的解决方案是提交一个错误,以便修复底层对象。否则任何与静态库链接的东西都不会得到非执行堆栈。

对于我自己的问题,如果构建不使用任何静态库的自定义固件,使用链接器标志可能就足够了。

参考:

于 2014-08-27T07:52:50.317 回答