我知道有几个问题和我的问题相似,但是我的问题有点不同,我还没有找到一个合适的答案。
我知道运行来自不可信源代码的一个简单方法是创建一个容器,一个资源有限的监狱,然后等待超时;但我希望有不同的解决方案。2我需要结果是确定性的,也就是说,这段代码不能有任何副作用,即使是在隔离的环境中也不行。3代码将接收一个输入,并且必须总是基于该输入返回相同的输出。
我认为最自然的方式是要求代码 * 纯功能性 *,没有副作用。我想到了Haskell语言。是否有可能以某种方式禁用Haskell(单子)中的副作用,并运行纯功能性代码?我如何在Haskell中执行代码,禁用任何可能的副作用和所有类型的I/O?
一开始我并不介意代码进入无限循环并使用大量内存,但如果可以限制执行时间和内存使用,这将是一个更好的选择。
1条答案
按热度按时间jxct1oxe1#
开箱即用的Haskell并没有给你提供你所寻找的那种安全性。
unsafePerformIO
是一个明显的安全漏洞(但也有其他漏洞)。unsafePerformIO
接受IO a
类型的值,并将其转换为a
类型的值;正是你不应该用IO
做的!它通过“欺骗”来做;如果运行时系统需要结果值(a
类型),则挂钩运行时系统以实际执行IO操作(IO a
类型)。因为它允许你使用类型系统,给一个计算一个非IO类型,这个计算实际上会执行任意的副作用,但有时候在高级用法中你可以围绕内部使用杂质的东西构建纯接口,这就是它的用途。“礼貌”的Haskell没有使用
unsafePerformIO
来将重要的副作用1带入纯计算中,所以我们在推理纯代码时确实忽略了它。你不能相信它是“有礼貌的”。使用unsafePerformIO
将副作用带入纯函数中,这正是对手为了越狱而在代码中放入的东西。所以你不能忽视它(也不能忽视其他不安全的函数;由GHC提供的已知不安全的程序将在名称中具有unsafe
)。基本上,在这方面,Haskell并不固有地比C更安全(实际上,有人可以使用FFI从Haskell调用任意C并称其为pure!);它将纯粹性作为一种语言特性来帮助开发人员编写代码,而不是作为一种安全特性来限制不信任的代码。编译时代码(例如使用TemplateHaskell
)可以执行任意副作用!您可能对Safe Haskell感兴趣;这是GHC中的一个选择加入系统(通过语言扩展),它试图锁定Haskell的“后门”特性,以便(在其他保证中)您可以相信纯计算(没有
IO
类型)实际上是纯的。***警告:我从来没有尝试过使用安全Haskell,我不能说它是否适合您的目的。我的理解是,您不能简单地打开
LANGUAGE Safe
并编译和运行任何旧代码。它不是那么安全。它是一个加强Haskell的类型系统保证的工具,以便您可以将这些保证作为但是我不相信Haskell的类型系统保证本身就足够了。如果你想使用Safe Haskell来实现这个目的,你一定要做进一步的研究。1当然,哪些副作用“重要”是一个品味和上下文依赖性的问题,上游代码可能并不总是同意你的观点。