使用文件描述符调用 dlopen?

jww*_*jww 5 linux shared-libraries dlopen

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

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

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

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

Bas*_*tch 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 的论文如何编写共享库

  • 嗨,巴西勒。“你必须以某种方式信任 dlopen-ed 插件。” 实际上我们没有 :) 当我们没有有效的安全控制时,我们使用信任。在这种情况下,我至少有两个控件:(1)签名检查;或 (2) 自验证 URL。 (2认同)