linux - 使用文件描述符调用 dlopen?

标签 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 来分析它解析库,也许 libelflibbfd(来自 binutils);但我仍然不明白你想进行什么样的分析(你真的应该解释一下;特别是如果插件间接链接到一些不良行为软件会发生什么)。换句话说,您应该更多地解释您的验证步骤。请注意,共享对象可能会覆盖自身....

或者,不要使用 dlopen 而只使用 mmap 您的文件(您需要解析一些 ELF 并处理 relocations ;参见 elf(5)和莱文的 Linkers and Loaders 了解详细信息,并查看您的 ld.so 的源代码,例如 GNU glibc )。

也许使用了一些 JIT generation技术可能会有用(您可以通过 JIT 从一些验证数据生成代码),例如与 GCCJIT , LLVM , 或 libjitasmjit (甚至 LuaJitSBCL )等...

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

一个选项是构建您的临时静态 C 或 C++ 源代码分析器(可能使用您提供的一些 GCC plugin)。该插件可能(需要数月或数年的开发工作)检查用户 C++ 代码的某些属性。当心Rice's theorem (限制每个静态源代码分析器的属性)。然后你的程序可能(像我的 manydl.c 那样,或者像 RefPerSys 很快会在 2020 年年中那样,或者像过时的 GCC MELT 几年前那样)将用户 C++ 代码作为输入,运行一些静态分析在该 C++ 代码上(例如,使用您的 GCC 插件),将该 C++ 代码编译成一个临时共享对象,然后dlopen该共享对象。所以请阅读 Drepper 的论文 How to Write Shared Libraries .

关于linux - 使用文件描述符调用 dlopen?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16182774/

相关文章:

c - 加载另一个共享库的共享库

c - 从内核空间执行 ioctl

linux - 如何在 expect spawn 命令中使用 .bashrc 命令

c++ - 有没有办法将相对库路径添加到可执行文件以避免设置 LD_LIBRARY_PATH

c++ - CMakeLists.txt 有两个自己的 CMakeLists.txt 子项目只需要创建一个 .so 库,其中包含所有

c++ - 共享对象在主二进制文件中找不到符号,C++

c - Linux 字符设备驱动程序如何检测使用它的程序何时异常退出?

linux - 将接口(interface)名称获取到 linux shell 脚本变量中

c++ - 链接到动态库的静态库中的 undefined symbol

c++ - 如何查找使用 dlopen() 打开的库的覆盖率?