online judge sandbox 设计思路(2)

This article is deprecated, please see here for more details. seccomp() seccomp 是 Linux 内核提供的一种应用程序沙箱机制,seccomp 通过只允许应用程序调用 exit(), sigreturn(), read() 和 write() 四种系统调用来达到沙箱的效果。如果应用程序调用了除了这四种之外的系统调用, kernel 会向进程发送 SIGKILL 信号。 seccomp 很难在实际中得到推广,因为限制实在是太多了,Linus 本人也对它的应用持怀疑的态度,直到出现了 seccomp-bpf。seccomp-bpf 是 seccomp 的一个扩展,它可以通过配置来允许应用程序调用其他的系统调用。chrome 中第一个应用 seccomp-bpf 的场景是把 Flash 放到了沙箱里运行(实在是不放心),后续也把 render 的过程放到了沙箱里。 我们仍然先通过限制 unlink() 来看一下 seccomp 是如何工作的: 删除失败了。 下面,我们写一个程序 b.out,让 seccomp 允许调用 unlink() ,但是不允许调用 fork(): 编译运行下: 我们的目的达到了。 seccomp-nurse … Continue reading "online judge sandbox 设计思路(2)"

Read More

online judge sandbox 设计思路(1)

This article is deprecated, please see here for more details. 实现 OJ 的 sandbox 主要有两种思路:ptrace 和 seccomp,下面我们分别讨论。 ptrace() ptrace 是类 Unix 系统上一个可以观察、控制其他进程内部状态的工具。它的用途有很多,例如程序调试(gdb、dbx等)、代码覆盖率检测、甚至可以用来做运行时补丁(想没想起来IDA和OllyDbg )。今天我们讨论的是如何通过对系统调用的限制来达到在沙箱(sandbox)中运行程序的效果。 我们先写一个程序,用来删除 /etc/hosts 文件: a.out 完成了它的使命,成功的删除了 hosts 文件。 现在,我们需要设计一个程序:通过 ptrace() 来限制 unlink() 删除文件系统中的文件。 首先,我们来看下手册上是怎么介绍 ptrace() 的: 其中,request 参数决定了 ptrace() 的行为,我们选几个用得到的选项介绍: PTRACE_TRACEME: 表明子进程(tracee)正在被父进程(tracer)所控制。注意:只有本选项适用于子进程(tracee); PTRACE_PEEKUSER: 可以从子进程中获取通用寄存器中的值,寄存器(orig_rax /orig_eax,取决于平台 )中保存的是最近一次的syscall number; PTRACE_SYSCALL: 可以将子进程从停止的状态唤醒并继续; 这样,我们就有思路了:每次程序调用系统调用,我们都去看看本次系统调用是不是 unlink(),如果是,杀掉子进程并退出即可: 当系统调用发生时,内核会把当前的 %eax/%rax … Continue reading "online judge sandbox 设计思路(1)"

Read More