5

我想将共享对象作为数据文件打开并对其执行验证检查。验证是签名检查,我对共享对象进行签名。如果验证成功,我想将当前打开的共享对象加载为正确的共享对象。

第一个问题:是否可以dlopen在签名检查期间调用共享对象并将其加载为数据文件,从而执行代码?根据手册页,我不这么认为,因为我没有看到类似于RTLD_DATA.

由于我将共享对象作为数据文件打开,因此我有可用的描述符。验证成功后,我想将描述符传递给dlopen动态加载器,以便正确加载共享对象。我不想关闭文件然后通过重新打开它,dlopen因为它可能会引入竞争条件(验证的文件与打开和执行的文件不同)。

第二个问题:如何将打开的文件传递给dlopen使用文件描述符,以便dlopen执行共享对象的常规初始化?

4

1 回答 1

5

在 Linux 上,您可能可以使用dlopen一些/proc/self/fd/15文件(对于文件描述符 15)。

RTLD_DATA似乎不存在。所以如果你想要它,你必须修补你自己的动态加载器。也许在MUSL Libc中这样做可能不那么困难。我还是不明白你为什么需要它。

你必须以dlopen某种方式信任 -ed 插件(并且它会运行它的构造函数dlopen)。

dlopen您可以在使用一些ELF解析库(可能是libelflibbfd(来自binutils ))之前分析共享对象插件;但我仍然不明白你想要进行什么样的分析(你真的应该解释一下;特别是如果插件间接链接到一些行为不良的软件会发生什么)。换句话说,您应该更多地解释您的验证步骤。请注意,共享对象可能会覆盖自身......

或者,不要dlopen只使用mmap您的文件(您需要解析一些ELF并处理重定位;有关详细信息,请参阅elf(5)和 Levine 的链接器和加载器,并查看您的源代码ld.so,例如在GNU glibc中) .

也许使用一些JIT 生成技术可能是有用的(你会从一些经过验证的数据中 JIT 生成代码),例如使用GCCJITLLVMlibjitasmjit(甚至是LuaJitSBCL)等......

如果你有两个文件描述符指向同一个共享对象,你可能不会有任何竞争条件。

一种选择是构建您的临时静态 C 或 C++ 源代码分析器(可能使用您提供的一些GCC 插件)。该插件可能(经过数月甚至数年的开发努力)检查用户 C++ 代码的某些属性。当心赖斯定理(限制每个静态源代码分析器的属性)。然后你的程序可能(就像我的manydl.c所做的那样,或者像RefPerSys将在 2020 年中期那样做,或者像几年前过时的GCC MELT所做的那样)将用户 C++ 代码作为输入,对该 C++ 运行一些静态分析代码(例如,使用您的 GCC 插件),将该 C++ 代码编译为临时共享对象,然后dlopen将该共享对象。所以阅读 Drepper 的论文如何编写共享库

于 2013-04-24T05:43:36.353 回答