一种现代 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 位。那么他们为什么不使用它呢?