【问题标题】:PyO3 - prevent user submitted code from looping and blocking server threadPyO3 - 防止用户提交的代码循环和阻塞服务器线程
【发布时间】:2021-11-28 10:53:32
【问题描述】:

我正在用 Rust 编写一个游戏,每个玩家都可以向服务器提交一些 python 脚本,以便自动执行游戏中的各种任务。我打算使用pyo3 从 rust 中运行 python。

但是,如果玩家提交这样的脚本,我会看到一个问题:

def on_event(e):
    while True:
        pass

现在,当服务器调用函数(使用类似PyAny::call1())时,线程将在到达无限循环时挂起。

我的第一个想法是让pyo3 一次执行一条python 语句,因此如果脚本运行超过某个阈值就可以退出,但我认为pyo3 不支持这一点。

我的下一个想法是让每个玩家都有自己的线程来运行他们自己的脚本,这样如果他们的一个脚本卡住了,只会影响他们的游戏玩法。但是,当线程陷入无限循环时,我仍然遇到无法杀死线程的问题 - 如果很多玩家提交刚刚循环的脚本,大量线程将开始使用大量 CPU 时间。

我所需要的只是以某种方式执行 python 脚本,如果其中一个确实循环,它根本不会影响服务器的性能。

谢谢:)

【问题讨论】:

  • 请注意,让用户在服务器上运行不受信任的 Python 代码可能比让服务器挂起更糟糕:通常对可以运行的代码没有限制,因此用户可以轻松地做更多事情恶意的东西,例如修改服务器文件或在您的服务器上安装恶意软件或加密矿工软件。
  • python 代码无法访问任何标准的 python 库函数或模块——所以我认为这意味着攻击基本上是不可能的。如果我错了,请纠正我
  • 我个人认为这还不够。例如,快速的 Google 搜索将我引导至 this page,其中充满了解决此类限制的技巧。安全地运行不受信任的用户代码通常是一个非常困难的问题。

标签: multithreading rust pyo3


【解决方案1】:

一种解决方案是限制您为每个用户脚本运行的时间。

您可以通过PyThreadState_SetAsyncExc 进行操作,请参阅here 获取一些代码。它使用解释器的 C 调用,您可能可以在 Rust 中访问它(使用 PyO3 FFI 魔法)。

另一种方法是在操作系统级别执行此操作:如果您为用户脚本生成一个进程,然后在它运行时间过长时将其终止。如果您限制进程可以访问的内容(通过一些操作系统调用),这可能会更安全,但需要一些样板来在主机之间进行通信。

【讨论】:

    猜你喜欢
    • 2012-12-30
    • 2017-11-15
    • 2015-11-25
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多