如何在python

时间:2017-02-11 05:50:41

标签: python linux subprocess stdout apparmor

我需要运行用户提交的应用程序。我的代码如下:

def run_app(app_path):
    inp = open("app.in", "r")
    otp = open("app.out", "w")

    return subprocess.call(app_path, stdout=otp, stdin=inp)

既然我无法控制用户提交的内容,我想限制应用程序输出的大小。其他诸如尝试访问未经授权的系统资源和滥用CPU周期等因素正受到apparmor规则实施的限制。允许运行的最长时间由父进程处理(在python中)。现在,一个流氓应用程序仍然可以尝试通过向stdout写入大量数据来充斥服务器系统,因为知道stdout正被保存到文件中。

我不想在stdout / stderr文件中使用AppArmors RLIMIT或内核模式的任何东西。能够使用标准库从python中完成它会很棒。

我目前正在考虑创建文件的子类,并在每次写入时检查已经向流写入了多少数据。或者创建一个设置了最大长度的内存映射文件。

但我觉得可能有一种更简单的方法来限制文件大小我还没有看到它。

1 个答案:

答案 0 :(得分:2)

子类化file或创建其他伪文件Python对象根本不起作用,因为该文件将在子进程中使用 - 因此它必须是O.S.文件,而不是Python类对象。子进程不会发送您的Python对象以供其他进程使用。

虽然Python对内存映射文件有本机和简单的支持,但通过mmap模块,内存映射并不适用于此:您可以指定镜像到内存的文件大小,但是这根本不限制写入文件:多余的数据将被简单地写入磁盘而不被映射。 (并且,再次,您将磁盘文件传递给子进程,而不是mmap对象)。可以在某个时刻创建一个带有sentinel值的文件,并保持一个线程检查是否覆盖了sentinel,此时它可以杀死子进程 - 但我怀疑这是否可靠。

然后,有磁盘活动监视工具,例如inotify:您可以使用pyinotify到主进程上的处理程序,只要访问该文件就会调用该处理程序。缺点:没有“文件写入”的事件。 - 只是'文件acessed' - 我不确定是否会通过增量写入文件触发任何可能的事件。而且,如果子进程在单个系统调用中完成所有写入操作,则无论如何都要通知得太晚。

所以,我能想到的就是:在人为有限的文件系统中创建一个文件。这样,当超过max-size时,操作系统将阻止写入。

在Linux下,您可以预先创建一个具有所需大小+一些开销的文件,在其上创建一个FS,然后使用" loop"接口 - 然后只需在该文件系统中创建stdout和sterr文件,并调用您的子进程。

您可以根据需要预先创建和预安装这样的文件系统池 - 或者,甚至可以动态创建它们 - 但这需要创建FS主机文件,创建文件系统的步骤它上面的结构(mkfs)和安装它 - 所有这些都可能是很多开销。

总而言之,也许您只需使用Apparmor自己的rlimit设置即可。