我曾经问过一些关于在stackoverflow上开发一个在线评判的问题,我发现了很多很好的答案。我已经开始开发一个,我似乎遇到了我的代码中的一个主要缺陷。
用户提交的源代码将在服务器上编译。这是通过exec()在分叉进程中执行gcc来完成的。现在我设置CPU时间的资源限制,并且在超过该时间时,SIGXCPU信号被发送到进程。一切都很好,直到现在。但是假设某人编写了一个处理SIGXCPU代码本身的恶意代码,它将继续在服务器上运行,并可能为某人开启远程控制服务器的方式。
那我在这里错过了什么?必须有一些可以预防的。
编译模块的基本原型如下:
int main() { int pid; int rv; if (!( pid=fork() )) { struct rlimit limit; getrlimit(RLIMIT_CPU, &limit); limit.rlim_cur = 1; setrlimit(RLIMIT_CPU, &limit); //execl() with gcc and source file name } else if(pid) { wait(&rv); } else printf("Error forking\n"); return 0; }
如果源文件包含类似
的内容void handler(int signum) { if (signum == SIGXCPU) printf("Caught SIGXCPU signal\n"); } int main() { signal(SIGXCPU, handler); while(1); return 0; }
......这是大麻烦
答案 0 :(得分:1)
在Linux上,具体来说,用户可以做你说的话。 但是如果达到硬限制(而不是你设置的软限制),linux将向进程发送sigkill,这将终止进程。
(请记住,你真的需要在chrooted环境中运行你的东西)
答案 1 :(得分:1)
哇。在大约7分钟的时间里考虑过这项艰巨的任务,我提前为我即将说的任何愚蠢事件道歉。
这会是UVA Judge吗?
如果目标是允许相对简单的程序运行而不允许恶意用户破坏您的系统,那么您似乎需要比这更主动,否则您将修补漏洞直到时间结束。
至少我认为您需要删除用户头文件并替换包含最小功能的自己的头文件。禁止汇编。使用修改后的stdlib和/或内核,在任何尝试的系统调用()等操作上禁止或杀死进程。
这里有很多值得考虑的事情。