【问题标题】:Static and Dynamic Linking Sandbox静态和动态链接沙箱
【发布时间】:2013-02-01 19:15:24
【问题描述】:

我试图在我的项目中使用libsandbox。我能够在这个沙箱中完美地运行 c/c++ 程序。 为了运行 c/c++ 程序,首先我必须将代码编译为:

g++  -lm  --static  <filename>  2> err.txt

然后我必须用上面的编译代码运行sample sandbox program

请注意我上面使用的标志 --static 非常重要。--static 的重要性体现在以下两个stackoverflow答案Link1Link2

现在,我想将这个沙箱用于 java 和 python。 但我不知道 python 和 java 的 gcc/g++ --static 等价物。

以下是否有效?

  javac --static    <filename>  2> err.txt 

  python  --static  <filename>  2>err.txt

我再说一遍,我很困惑,因为我不知道 java 或 python 中的 --static 等价物。

谢谢!

【问题讨论】:

  • 作为一种解释性语言,Python 不做任何静态链接或其他链接。
  • Java 也没有。所有此类绑定都在运行时。你能解释一下你想要做什么以及为什么吗?
  • @PeterLawrey:先生,我刚刚编辑了我的问题以反映 --static 的重要性。
  • @ritesh_nitw 但是你为什么要这样做?
  • @peter Lawrey:被沙盒化的二进制可执行文件最好静态链接,因为加载共享库涉及默认禁止的系统调用,如 SYS_open()。

标签: java python sandbox static-linking dynamic-linking


【解决方案1】:

可以使用libsandbox 对 Python 解释器进行沙箱处理。您需要处理一些系统调用,例如加载共享库和导入默认 python 模块。可以在 Richard Lobb 的 CodeRunner 项目中找到 pysandbox 在 Python3 解释器上的工作示例,

https://github.com/trampgeek/CodeRunner

Java 有自己的安全机制。因此没有必要将 Java VM 包装在沙箱中。

免责声明:我是libsandbox 的作者。

【讨论】:

  • @ritesh_nitw:它们是编译器标志,用于将警告转化为错误并显示所有错误。你可以在这里阅读它gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
  • 嗨,在沙箱中运行 python 对我来说仍然是个问题。运行 C/C++ 很简单,我只需要编写 'python Sample2.py a.out' ,其中 a.out 是可执行文件文件。但是在python中没有可执行文件。当我在命令行中输入'python Sample2.py python userscript.py'时,沙箱不起作用。userscript.py是我想在沙箱中运行的用户程序。没有用于在沙箱中运行用户 python 程序的适当文档。谢谢!
  • @ritesh_nitw,只是让您知道,有一个使用 CodeRunner 的策略对python3 脚本进行沙盒处理的工作示例,gist.github.com/liuyu81/5034438
  • @liuyu:谢谢你的回复。上面链接中的示例适用于 64 位 linux 操作系统。我试图更改我的 32 位机器的代码。当我运行沙箱时,结果:BP trace> SYSCALL {'mem_info': (3016, 3016, 8, 8, 108, 0), 'elapsed': 2, ' cpu_info': (0, 0, 0, 0L), 'signal_info': (0, 0), 'syscall_info': (45, 0), 'exitcode': 0} 我运行了以下命令:/python pytrace.py helloworld.py 其中 DIR 是我保存沙箱 pytrace.py 和其他所需文件(如 which.py​​、sandboxpolicy.py 等)的目录,而 helloworld.py 是我想在沙箱中运行的 python 脚本.
  • @ritesh_nitw, BP 表示bad policy - 表示您修改后的政策版本有错误。确保您可以在 python 的交互式控制台中成功import sandboxpolicy。我已经对 gist repo 进行了一些修改,py3trace.py 现在可以在i686 系统上运行。但是您仍然需要破解sandboxpolicy.py(将适当的系统调用号添加到sc_safe['i686'])以使策略在i686 系统上起作用。
【解决方案2】:

我认为你混淆了两件事。在libsandbox 所说的意义上,您的 Python 程序不是可执行文件。可执行文件是 Python 解释器。

因此,您不能使用libsandbox 对 Python 脚本进行沙箱处理。

但是,您可以对 Python 解释器进行沙箱处理。执行此操作的方式与对任何其他可执行文件进行沙箱处理相同。要么:

  • 创建 Python 解释器的静态构建(包含您需要编译的任何 C 扩展模块),并在沙箱中运行它。这并不容易,但可行,而且 Python 源代码树和其他地方的信息可能会有所帮助。
  • 使用更宽松的沙箱,允许标准解释器做它需要的一切(可能包括动态加载扩展模块,取决于您是否需要),但仅此而已。

无论哪种方式,您都需要反复试验来确定您可以禁止什么和不能禁止什么,以及如何将不同的 Python 代码位映射到系统调用,等等。并且有些事情是您无法阻止脚本执行的,因为您不希望 Python 代码执行的相同系统调用对于解释器本身来说是必需的。

Java 也是如此。 JVM 是可执行文件,而不是您的程序。而且你真的不能静态链接JVM,所以你只有第二种选择。

当然,除非您使用gcj 将Java 代码编译为本机代码而不是JVM 代码。在这种情况下,您实际上使用与gccg++ 相同的后端,并且您只需使用--static 来确保libgcj 和其他所有内容都得到静态链接。你可能仍然会遇到问题,因为libgcjlibc 在幕后做的更多……但概念与 C 代码相同。

(JVM 本身有自己的访问模型,您可能可以使用类加载器中的反射构建一些东西,以在 Java API 级别而不是 linux 系统调用 API 上沙箱 Java 程序。我不知道这样的东西已经存在了。)


每当我尝试在没有“--static”的情况下编译程序(我想在沙箱中运行)时,沙箱都不起作用。所以,再次 --static 非常关键,这超出了我的知识范围.

您的实际代码很可能不会打开任何文件,因此您使用的是禁止打开文件的默认沙盒设置。但是如果你动态链接你的程序,它必须打开 .so 文件来链接它们——这是行不通的,因为你的沙箱被配置为禁止它。

如果你静态链接同一个程序,问题就消失了,因为它不再需要打开任何.sos 来运行。简而言之,这就是沙盒静态链接的重点。你甚至在对你的问题的评论中解释了这一点,所以我无法想象你是怎么理解它的,除非你甚至不明白你为什么要禁止 SYS_open 以及这样做意味着什么。

(a)对于 java 和 python,如果我编译 w/o "--static",沙箱是否可以工作

是的,沙盒可以正常工作。这意味着,如果您使用默认配置,它将禁止您打开文件。这意味着您的 Java 或 Python 程序将失败,因为 VM/解释器必须打开(除其他外)您的程序才能运行它。

即使静态链接解释器或 JVM 也无济于事。您必须将程序的实际字节码静态链接到可执行文件中。并非不可能,但可能远远超出您此时想要考虑的任何事情。

正确的做法是弄清楚您要禁止哪些系统调用,以及为什么要禁止,并适当地配置沙盒。默认配置不适合你。

(b)同一个开发者openjudge.net/~liuyu/Project/LibSandbox有一个叫pysandbox的沙盒

pysandbox 只是配置和启动沙箱的一种更简单的方法。您不会在沙盒代码中使用它。 (有一个不同的 pysandbox 由另一位开发人员在 Python 级别对您的代码进行沙箱处理。这可能对您有用,但它与系统调用沙箱不同。)


在这一点上,我不确定你是否知道你想要做什么。为什么要首先对代码进行沙箱化?你知道你的代码需要什么样的访问权限才能完成它需要做的事情吗?如果您知道自己要做什么,您确定系统调用级别的沙箱是执行它的正确级别,而不是像RestrictedPython 这样的东西吗?在不知道您的实际用例的情况下,我什至无法猜测这些问题的答案。但是,如果您没有立即解决所有问题,那么您将无法完成任何有用的事情。

【讨论】:

  • 在向您征求一些建议之前,让我先说几句。每当我尝试在没有“--static”的情况下编译程序(我想在沙箱中运行)时,沙箱都不起作用。所以,再次 --static 非常关键,,这超出了我的知识。我有两个问题:(a)对于 java 和 python,如果我在没有“--static”的情况下编译,沙箱是否可以工作(b)同一开发人员 openjudge.net/~liuyu/Project/LibSandbox 有一个名为 pysandbox 的沙箱。那么,对于在沙箱中运行 python 代码,pysandbox 更容易吗?谢谢!
  • ...如果你不明白为什么需要--static 开头,也许你应该先弄清楚。
  • @kindall:是的,我同意。但老实说,我已经提到过,我对 --static 没有明确的想法。我已经在 stackoverflow 中发布了这两个链接,从中我了解到它在沙箱中的重要性。
  • @ritesh_nitw:让我编辑帖子,因为这在 cmets 中解释得太多了。
  • 最后一个问题的答案:我正在使用沙箱来确保我的“在线法官”安全。有大量的开源沙盒库可供使用。我发现 libsandbox 非常友好、安全且易于使用。并且以在线法官运行的沙盒程序而闻名。
【解决方案3】:

对于 Java,您唯一的选择似乎是使用静态绑定到它的 JNI 包装器。可能已经有这样的包装器,但如果你能写一个。

【讨论】:

  • 静态绑定到什么?你没有链接到libsandbox。 OP 询问静态链接的原因是,当您排除任何动态代码加载时,您可以使用更简单、更干净的沙箱,这对于 C 和 C++ 代码意味着您必须静态链接所有库而不是共享库。
  • @abarnert 要使用 JNI,您必须提供 DLL 或 SO。这可以有其他库静态绑定到它。
  • 是的,但是让其他库静态绑定到它有什么意义呢?将静态链接与沙盒可执行文件一起使用的全部原因是您可以将SYS_open 之类的东西列入黑名单。但是如果你这样做,JNI 就无法工作(JVM 本身也不会)。
猜你喜欢
  • 2010-09-15
  • 2012-05-14
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 2018-01-23
  • 2010-12-31
相关资源
最近更新 更多