jww*_*jww 5 linux shared-libraries dlopen
我想打开一个共享对象作为数据文件并对其执行验证检查。验证是签名检查,我对共享对象进行签名。如果验证成功,我想将当前打开的共享对象加载为正确的共享对象。
第一个问题:是否可以dlopen
在签名检查期间将共享对象作为数据文件调用和加载,从而不执行代码?根据手册页,我不相信,因为我没有看到类似于RTLD_DATA
.
由于我将共享对象作为数据文件打开,因此我有可用的描述符。验证成功后,我想将描述符传递给dlopen
动态加载程序以正确加载共享对象。我不想关闭文件然后通过重新打开它,dlopen
因为它可能会引入竞争条件(其中验证的文件与打开和执行的文件不同)。
第二个问题:如何将打开的文件传递给dlopen
使用文件描述符,以便dlopen
执行共享对象的习惯初始化?
在 Linux 上,您可能可以使用dlopen
一些/proc/self/fd/15
文件(对于文件描述符 15)。
RTLD_DATA
似乎不存在。所以如果你想要它,你必须修补你自己的动态加载器。也许在MUSL Libc 中这样做可能不那么困难。我还是不明白你为什么需要它。
你必须以dlopen
某种方式信任-ed 插件(它会在dlopen
时间运行它的构造函数)。
您可以在dlopen
使用一些ELF解析库(可能是libelf或libbfd
(来自binutils))之前分析共享对象插件;但我仍然不明白你想要进行什么样的分析(你真的应该解释一下;特别是如果插件间接链接到一些行为不良的软件会发生什么)。换句话说,您应该更多地解释您的验证步骤。请注意,共享对象可能会覆盖自身....
或者,不要dlopen
只使用mmap
您的文件(您需要解析一些ELF和进程重定位;有关详细信息,请参阅elf(5)和 Levine 的链接器和加载器,并查看您的源代码ld.so
,例如在GNU glibc 中) .
也许使用一些JIT 生成技术可能会很有用(您可以从一些经过验证的数据JIT 生成代码),例如使用GCCJIT、LLVM或libjit或asmjit(甚至LuaJit或SBCL)等...
如果你有两个文件描述符指向同一个共享对象,你可能不会有任何竞争条件。
一种选择是构建您的临时静态 C 或 C++ 源代码分析器(可能使用您提供的某些GCC 插件)。该插件可能(经过数月或数年的开发工作)检查用户 C++ 代码的某些属性。当心莱斯定理(限制每个静态源代码分析器的属性)。然后你的程序可能(就像我的manydl.c那样,或者像RefPerSys很快会在 2020 年中期做的那样,或者像几年前过时的GCC MELT那样)将用户 C++ 代码作为输入,对该 C++ 运行一些静态分析代码(例如使用您的 GCC 插件),将该 C++ 代码编译为一个临时共享对象,以及dlopen
该共享对象。所以阅读 Drepper 的论文如何编写共享库。