Safe Haskell有多安全?

17

我在思考Safe Haskell,并且我想知道我可以信任它多少?


一些虚构场景:

  1. 我是一个小黑客,正在编写一个可编程游戏(类似Robocode),我允许其他人编写自己的实体来竞争。大多数时候,用户会在私人计算机上运行一些不受信任的程序。在运行之前,这些不受信任的代码可能会被检查。

  2. 我是一个应用程序的程序员,该应用程序由几个客户使用。我提供api,以便他们扩展功能,并鼓励我的用户分享插件。用户社区很小,大多数时候有相互信任,但偶尔会有人在进行机密客户项目,任何数据泄漏都将造成灾难性后果。

  3. 我是...谷歌(或Facebook、Yahoo等),想要允许我的客户“脚本”他们的电子邮件帐户。脚本被上传并在我的服务器上运行。任何访问违规都将是致命的。


针对这些场景:

  • Safe Haskell是否适合用于确保沙箱和访问限制?
  • 在给定的情况下,有人应该相信所作的承诺吗?
2个回答

8
作为一个经验法则,我会说安全的 Haskell 试图达到 C# 的安全子集的大致程度。针对你的情况:
  1. 你可以使用安全的 Haskell 来检查代码。
  2. 如果仅仅使用安全的 Haskell 是无法避免灾难性的数据泄漏的。
  3. 我不建议 Google 或 Yahoo 仅仅依靠安全的 Haskell 运行不受信任的代码。首先,它无法管理过度的资源消耗(CPU、内存、磁盘)或底部(未定义或 while true)。对于这种情况,请使用操作系统沙箱。
关于未定义的说明:在操作上,它通过引发异常来阻止函数返回值,就像 error 函数一样。在含义上,它被认为是“底部”值。即使安全的 Haskell 禁止了 undefined 和 error,函数仍然可能由于无限循环而无法返回。而无限循环也是底部。因此安全的 Haskell 只能保证类型和内存的安全,但不能保证函数终止。当然,安全的 Haskell 是图灵完备的,因此通常不能证明终止性。此外,由于内存不足会引发异常,因此函数可能以异常结束。最后,模式匹配错误会引发异常。因此,安全的 Haskell 不能消除任何底部,并且可以允许显式地使用 undefined 和 error。

你能详细说明一下“仅使用安全 Haskell”的说法吗?我的理解是,如果我使用安全的 Haskell ,我可能还会使用某种沙盒来限制不受信任的代码运行时间和/或类似自由单子 DSL 的东西,以将用户限制在 Haskell 的子集中。 - fho
6
Safe Haskell 更多地是从类型系统的角度来防止人们使用不安全的函数,而不是从“沙箱”角度来防止。如果你想要这样的功能,你应该编写一个可以解释的 DSL。考虑查看 free monads,它们非常适合构建这种目的的 DSL。 - bheklilr
原因(3)尤其令人信服。 - Andrew Thaddeus Martin
在谷歌的情况下,他们拥有一个Python引擎,其中(3)同样重要,所以我想他们使用某种资源监控...所以仅仅因为这种语言不支持它,并不意味着它是不可能完成的。 - Karoly Horvath
@bheklilr 自由��:没错,就�我之�在评论中说的一样😉�际上,我写了一篇关�如何使用自由��为一些我之�使用过的大�机器编译�制程�的文章。这将在(完�并且)得到那家生产这些机器的公�批准�宣布😊 - fho
刚刚重新阅读了你的回答。Safe Haskell不能处理undefined?这背后的原因是什么?它肯定不能防止任何人将undefined传递给它...但它肯定可以防止在安全代码中出现undefined吧? - fho

-6
据我所知,安全的Haskell并不安全。有人可以在一个包中使用unsafePerformIO并手动覆盖“不安全”的因素。如果没有这样做,任何依赖于C程序或系统库的软件包都不能被标记为安全。(想想几乎每个人的Haskell基础包都链接到的libgmp.so。为了使基础包标记为安全,必须以某种方式明确将其标记为安全,即使它使用unsafePerformIO)。

9
Safe Haskell 应该移除 unsafePerformIO 和其他不安全的函数。必须将包标记为可信才能导入。 - Johannes Kuhn
3
我支持@JohannesKuhn的观点。据我所知,unsafePerformIOSafe Haskell存在的原因之一。 - fho
4
在使用Safe编译模块时,无法导入System.IO.Unsafe。虽然可以将模块标记为“可信”,但在加载外部文件时不允许这样做。 - Cubic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接