【问题标题】:Enable LD_PRELOAD just for BASh after system startup系统启动后仅为 BAsh 启用 LD_PRELOAD
【发布时间】:2016-10-17 18:54:50
【问题描述】:

有没有办法为新会话注入/启用 LD_PRELOAD(即:BASh)?

我有一个语法高亮库,我想自动启用它(即:突出显示某些用户的警告),并且只需要为BASh 而不是所有进程加载它。如果我把它放在/etc/ld.so.preload 中,它会破坏所有系统服务和其他不需要它运行的程序,包装系统调用(主要是printfexec)。

有没有一种简单的方法可以做到这一点?

【问题讨论】:

  • bash在非交互模式下运行时是否在意库是否预加载?
  • @JohnBollinger 我希望库始终运行,无论交互/非交互模式如何。谢谢,顺便说一句>

标签: c linux bash pam ld-preload


【解决方案1】:

最简单的解决方案可能是将bash 替换为执行LD_PRELOAD 逻辑的shell 脚本,然后调用实际的(重命名的)bash 二进制文件。

即把/bin/bash移动到/bin/bash.original,然后创建一个脚本/bin/bash,内容如下:

#!/bin/sh

LD_PRELOAD=/path/to/my/library.so
export LD_PRELOAD
exec /bin/bash.original "$@"

如果您只想在连接到交互式会话时执行LD_PRELOAD,您可以在此处包含逻辑(例如,“is stdout a tty”)。在 bash 未连接到 tty 时尝试执行任何类型的终端操作可能会产生奇怪的结果。

【讨论】:

  • 我自己正在按照这些思路制定解决方案。但是请注意,就目前而言,此解决方案不符合 OP 的要求,即避免为 bash 以外的二进制文件预加载他的库,因为 shell 环境中的 LD_PRELOAD 变量将被它产生的进程继承。跨度>
  • 没有什么好的办法,因为进程总是继承父进程的环境。 LD_PRELOAD 设置在 bash 的环境(及其子环境)中,或者不是。可能您可以修改 /etc/bashrc/etc/profile 或类似的内容,以显式取消设置 LD_PRELOAD 环境变量。
  • @JohnBollinger 也许我可以使用procfs 检查库中的进程映像,这样它就不会为子进程启用某些功能?我最大的担忧是防止库被系统守护进程/服务加载,破坏它们。这个问题在 CentOS 上尤其明显,如果我只用一个非常简约的库设置 /etc/ld.so.preload,它似乎会中断(无法正常启动)。
  • @JohnBollinger 在library.so 的启动代码中,清除LD_PRELOAD 环境变量。请注意,将LD_PRELOAD 设置为通过其完整路径指向库将破坏任何不同架构的二进制文件 - 例如,如果/path/to/my/library.so 是一个 32 位库,则大多数使用该 envval 集运行的 64 位进程将失败(像 setuid 二进制文件这样忽略 LD_PRELOAD 的二进制文件可能会起作用)。
  • 对,如果/bin/sh 是符号链接,您将需要使用#!/bin/bash.original。这取决于分布(在许多情况下,/bin/sh 不是bash 的符号链接)。
猜你喜欢
  • 2018-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-23
  • 2020-11-10
  • 2018-05-16
  • 1970-01-01
相关资源
最近更新 更多