使用C语言子集进行语法检查

4
我希望建立一个基于Web的服务,让用户输入一些C代码,服务器将编译并运行该代码,然后返回结果。我知道,这是安全方面的噩梦。因此,也许我可以采用chroot或lxc等方法。在stackoverflow上有很多关于这些的好帖子。另一个选择是使用编程竞赛软件。
不过,我所做的并不是为了一般的编程目的。用户只能向几个存根函数添加代码,除此之外不能使用指针、数组或字符串。他们不应该能够打开/关闭/读取/写入文件、套接字或共享内存。他们甚至不能创建自己的函数。他们只能执行以下操作:
// style comments
/* */ style comments
declare variables of type int, double, float, int64_t, int32_t, uint64_t, uint32_t
for, while, do
+, -, *, /, % arithmetic operators ( * as dereference is NOT allowed )
( )
+, - unary operators
++, -- operators
math functions like sin, cos, abs, fabs, etc
a bunch of API functions that will exist
switch, case, break
{ }
if, else, ==, !=
=, +=, -=, *=, /=, etc

有没有一个工具可以用来检查给定的一段C代码,以确保它仅包含那些元素?

如果我找不到现有解决方案,我可以使用Antlr或类似的工具来自己设计。


你可能根本不想编译: https://dev59.com/rXRB5IYBdhLWcg3wkH9N - msw
2
另一方面,如果您的迷你语言受到限制,为什么要让用户使用35年前由极客设计、强调硬件级别(非)抽象和词汇简洁性的语法呢?这似乎是残忍的。 - msw
我同意C语言可能不是最佳选择。你有没有其他语言推荐,可以轻松设置这些限制?我认为C语言并不可怕,因为大多数用户只会输入数学表达式,但如果他们想要更多的灵活性,C语言可以让他们做更多的事情。 - Ginger Snaps
2
Python已成为大学计算机科学课程中事实上的初学者语言。它还可以通过简单地删除例如os模块来轻松地限制访问。 - msw
2
@msw:它是否可以防止 [t for t in (1).__class__.__bases__[-1].__subclasses__() if t.__name__ == 'file'][0]('/etc/passwd').read() 正常工作? - Joker_vD
显示剩余3条评论
1个回答

1

如果想要一个运行用户代码的实际网络服务的例子,可以看看持续集成服务Travis CI。开源项目使用它以集中的方式运行其单元测试。Travis的过程大致如下:

  • 从已知的良好配置启动全新的虚拟机。
  • 加载和编译用户代码。
  • 运行测试并显示结果。
  • 丢弃虚拟机。

有一个时间限制(我记得是10分钟),以防止人们在系统上运行僵尸网络,但除此之外,虚拟机完全功能并连接到互联网。不需要受限语法或其他人为限制。

需要记住的是,无论你如何限制用户,你都永远无法使服务器免受用户代码的威胁。另一种选择是假设服务器一旦被用户代码接触就完全毁了,然后将其丢弃,这正是Travis所做的。VM软件通常具有快照功能来帮助此类事情。


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