我应该如何对线程进行沙盒处理并执行简单的 IO?

我应该如何对线程进行沙盒处理并执行简单的 IO?

我有第三方编写的代码。它看起来不错,但我怀疑其中有漏洞,可能被利用。有什么方法可以将其与我的其他代码隔离开来吗?

我能想到的两种主要方法是

  1. 创建几个管道,然后调用 clone,CLONE_FILES|CLONE_THREAD这样除了管道之外什么都不会共享(由于 O_CLOEXEC,文件不会共享?我不确定 O_CLOEXEC 是否适用于克隆/线程)。然后使用读/写执行所有 IO

  2. 除了几 MB 的内存外,不共享任何内容。线程需要能够调用系统调用,futex以便主线程可以唤醒它/第三方代码可以休眠而不需要自旋锁。我已经有执行此操作的线程代码

我的问题是,我不确定如果我真的对线程进行沙盒处理会怎样(它会破坏我的内存吗?文件?我能阻止它接触文件系统吗?)。我不熟悉 newns、cgroup 等,我不确定我应该做什么

使用 x86-64 汇编没问题。我的主要代码是 C++ 的,还有一些是 C 的

答案1

clone() 参数仅阻止线程直接接触进程的内存(几乎使其成为一个新的过程而不是线程),但它们不会阻止线程进行外部库调用、系统调用、打开新的文件句柄等。这当然是开始,但如果线程被诱骗调用 open(“.ssh/id_rsa”) 或某些东西,它将无法拯救你。

为了真正限制子进程或线程对系统的操作,你需要安全计算。找出模块可以承受的最小系统调用集,使用 seccomp 仅允许这些调用并阻止其余调用。(虽然违规的默认操作是“终止进程”,但也可以让被阻止的调用返回虚假的错误代码。)您可以使用建立一个配置文件,而不是手动编写 BPF 字节码。

某些沙盒技术仅对 root 可用,例如将进程置于其自己的命名空间中CLONE_NEW*(这些技术有时使用 setuid 包装器实现,如 Chrome 和 Flatpak 的 bwrap 所做的那样)。挂载命名空间(如 chroots)可有效防止进程打开系统上的随机文件 - 但您必须是 root 才能设置它们。

如果您正在编写服务,并且可以重构它以将第三方代码放在完全独立的守护进程中(主服务通过 IPC 与之通信),那么这些技术(以及系统调用过滤)可以由服务管理器(如 systemd)应用。也就是说,您将拥有具有特权的主“foo.service”,以及使用 systemd 公开的选项(包括 chroots、命名空间和 seccomp)受到严格限制的附加“foo-worker.service”。

相关内容