防止进程覆盖文件

防止进程覆盖文件

那个设定

假设我有一个可执行文件,我们称之为program,其源代码不可用(可能是专有/遗留)。

每次执行该程序时,它都会生成一个文件,我们将其称为file.txt,始终具有相同的名称并且始终位于同一目录,具体取决于传递给 的命令行参数program

问题

我想program同时执行多个实例。这可能发生program在服务器正在侦听program来自客户端的执行请求的上下文中。

问题是,这似乎是不可能的,只要两个实例都会写入同一个file.txt,因此该文件最终可能会被损坏。

可能的解决方案想法

  • 我可以以某种方式将program的输出重定向到具有唯一名称的文件(请记住源已丢失)吗?
  • 我可以以某种方式“沙箱”program使它的行为就像在单独的文件系统上执行一样(开销可以忽略不计)吗?
  • 我听说过LD_PRELOAD,但我不知道它是否只适用于重写 C 标准库函数,或者它是否也适用于一般的重写 Linux 系统调用。

任何想法?

答案1

每次执行该程序时,它都会生成一个文件,我们将其称为“file.txt”,始终具有相同的名称并且始终位于同一目录中,该文件根据传递给程序的命令行参数而有所不同。

如果程序是动态可执行文件,您可以通过以下方式使用函数插入LD_PRELOAD使其将文件写入不同的位置(例如,由环境变量指定的位置)。这意味着拦截对 的调用open,检查该open调用是否针对file.txt,然后运行适当的替代方案。

如果程序作为 systemd 服务启动,则可以使用PrivateMounts选项在自己的挂载命名空间中运行它,并挂载一个可以在其中写入file.txt.

正如 @glennjackman 在评论中建议的那样,您还可以安排在容器中运行该进程:这实际上与之前的解决方案相同,但您使用的是 Docker 或 Podman 等容器运行时来设置,而不是 systemd挂载命名空间。


在上述选项中,在容器内运行它可能是操作上最简单的。


我听说过“LD_PRELOAD”,但我不知道它是否只适用于覆盖 C 标准库函数,或者它是否也适用于一般的覆盖 Linux 系统调用。

函数插入viaLD_PRELOAD仅允许您拦截函数调用,而不是系统调用。但这通常很好:当您的代码调用 时open,它并不是直接调用系统调用open;而是调用 syscall 。它调用一个 glibc 包装函数,该函数又调用系统调用。

相关内容