基于Linux的OJ系统的设计与开发(一)

最近在研究基于linux的OJ系统,然后想自己写一系列文章记录自己这段时间的学习成果。

首先,从原理上讲,OJ功能实现并不难,最主要解决的是安全性问题。总结一下,而安全性方面问题主要是用户可能提交恶意不友好的代码。关于如何过滤这些不安全的代码,我从网上收集整理了许多资料,大体上思路如下:

  先说错误的做法:

1.所有的字符串过滤都是不靠谱儿的,坑人坑自己,C语言强大的宏几乎没有绕不过的字符串过滤,而且误伤也是很常见的,比如,你在程序里要是不小心定义一个叫做fork的变量,那么你的程序别指望可以AC了,因为字符串过滤会把你的fork想成创建子进程的那个fork,而这是不被允许的。

2.手工审计头文件,去掉某些头文件或者注释掉一部分是辛苦的且无用的;做了这样的工作之后你就几乎不再想去升级编译器及头文件了,更可怕的是这个工作需要你对语言,编译器,连接器有一定程度的了解,而我认为拥有足够了解的人都会明白这样做是毫无道理可言的:就算没有头文件,没有了函数原型,调用系统调用的方法还是有一大把,而且也都不是很麻烦。

再说说准备工作:

1.熟悉你的目标系统(windows or linux):必须要了解这个平台下的原生系统调用API是怎么使用的(不然你怎么屏蔽),最好可以了解到汇编层面。必须要了解这个平台下的用户系统,权限控制,资源限制。最好了解一下进程跟踪,调试,监控工具或者系统调用,例如Linux下的ptrace。最好要了解目标系统提供的各种沙盒限制功能。

2.了解你的编程语言及工具链:必须要了解你的目标语言的特性,及其在一般的OI/ACM比赛中的规定和限制。必须要了解你的工具链的功能及各种参数。

3.拥有足够的编程功底,对于这样的小的程序,应严格杜绝缓冲区溢出之类的BUG。

最后说说我的做法:我的目标平台是Linux,目标语言是C/C++,Java,Python。

1.操作系统层面:

a.时间资源的限制。

内存:我使用了rlimit进行控制,同时也是方便在运行结束后获得内存使用情况的数据,不过有一个缺点就是如果声明了超大的空间但是从未访问过就会不被统计进来,但是观察到很多ACM或者OI比赛也都是这样处理的,所有这也不算是一个问题。

时间:首先同样也是使用rlimit进行CPU时间控制,注意它只能控制CPU时间,不能控制实际运行时间,所以像是sleep或者IO阻塞之类的情况是没有办法的,所以还在额外添加了一个alarm来进行实际的限制。按照大部分比赛的管理,最终统计的时间是 CPU 时间。

  文件句柄:同样可以通过 rlimit 来实现,以保证程序不要打开太多文件。不过其实文件这一块问题是比较多的,如果可行的话最好还是使用 stdio 然后管道重定向,完全禁止程序的文件 IO 操作。

  b.访问控制:

  利用低权限用户nobody ,将程序限制在指定目录中运行。由于是比赛程序,使用的动态链接库很有限,所以直接静态编译,从而使得运行目录中连 .so 都不需要。

  进行必要的权限控制,例如将输入文件和程序文件本身设置为程序的运行用户只读不可写。

  c.权限控制:

  监控程序使用 root 权限运行, 完成必要准备后 fork 并切换为受限用户(比如 nobody )来运行程序。

  rlimit 设置的都是 hard limit ,非 root 无法修改。

  正确设置运行用户之后,nobody 受限用户是无法逃出的。

  d.系统调用控制:
  上面这些(尤其是第一步)是有很大问题,就算不是 root ,也还能做到很多事情。且不说 fork 之类的,光是那个
alarm ,就可以很轻松的把计时器取消了或者干脆主动接收这个信号。所以最根本的还是需要使用 ptrace
之类的调试器附着上程序,监控所有的系统调用,进行白名单 + 计数器(比如 exec 和 open
)过滤。这一步其实是最麻烦的(不同平台的系统调用号不一样,我们使用的是 strace 项目里头整理的调用号)。

  e.更进一步:
  如果你对操作系统更熟悉,那么还有一些更有趣的事情可以做。比如 Linux 下的 seccomp 功能(seccomp - Wikipedia , Chrome Linux 版就在沙盒中使用了这个技术 ),尤其是后期加入了 seccomp-bpf 之后变得更加易用。还比如 SELinux 也可以作为 defend-by-depth 的一环。另外, cgroup 其实也可以用得上。

  2.编译层面:

  a.很多编译工具都提供了强大的参数控制,允许你进行包括禁用内嵌 ASM 、限制连接路径之类的一些操作。通读一遍 manpage 肯定会有帮助的。

  b.算法竞赛的程序推荐静态编译,之后控制起来少了动态链接库会方便许多。

  c.小 心编译期间的一些“高级功能”,比如 C 的 include 其实是有很多巧妙的用法,试试看在 Linux 下 #include "/dev/random" 或者 #include "/dev/tty" 之类的(这两个东西会把网络上不少二流 OJ 直接卡死……)。

  d.不要使用 root 用户编译,越复杂的程序越容易有 bug ,万一哪天出个编译器的 0day ……

  e.考虑给编译过程同样进行时间、资源限制以作为额外防护手段。

  3.架构层面:

  a.运行在虚拟机/容器中

  b.快照

  c.心跳检测

时间: 08-02

基于Linux的OJ系统的设计与开发(一)的相关文章

基于Linux的智能家居的设计(2)

1  系统整体设计方案 智能家居系统的是一个实时查询家庭的温湿度.照明控制.自己主动控制的设定.集家庭娱乐.智能安防为一体,大量数据快处理.可靠的系统,因此在硬件和软件上都有非常大的要求,因此在这里进行了多方面的考虑有下面两个实现方案: 方案一:利用STM32单片机作为手持终端的控制器,使用按键和12864液晶屏作为人机交互的接口.利用51单片机作为房子内部的电灯.空调.门禁等家电的控制器,利用串口实现STM32单片机和51单片机作为传输数据的通道.这个能够实现.可是.机械按键和12864在智能

基于Linux的智能家居的设计(1)

写在前面:做了半年的毕业设计,找到的工作与这个完全无关,发现自己现在有写不甘心,但是我还是在关注这方面的发展,自己的摸索和前人的帮助我完成了智能家居的一部分,希望这个能够给一些初学者 能够一些便利,毕竟技术是一个开放的,不属于某一个人的. 摘要 本课题主要目的是设计和实现一个基于Linux开发平台的智能家居系统.本系统主要使用PVC板做成的家居模型.本系统硬件使用基于ARM架构的samsung S3C6410芯片做成的OK6410开发板为手持终端,利用Zigbee实现网络通讯,并结合各种电子元器

基于Linux的智能家居的设计(3)

2  硬件设计 本课题的硬件设计包括主控制器.数据传输设计.数据采集设计.控制驱动设计.显示设计,门禁设计. 2.1  主控制器 根据方案三选择S3C6410主控芯片,S3C6410是由Samsung公司推出的一款低功耗.高性价比的RSIC处理器 ,基于ARM11内核,内置强大的硬件加速,显示处理和缩放,运动视频处理,音频处理[9].这个作为智能家居的处理器是不二之选,硬件性能上完全可以实现.本设计选用的基于S3C6410的OK6410开发板.开发板上拥有如下特征[10]: (1)  12MHz

基于Linux的智能家居的设计(4)

3  开发环境的搭建 本次课题使用的开发环境比较特殊,没有一个现成的集成开发环境,需要自己一步一步的搭建开发环境,开发环境的搭建的过程十分复杂,而且如果没有这个开发环境本次课题就无法进行.因此,在进行设计时,必须要进行开发环境的搭建. 3.1  虚拟机安装和系统安装 在PC机上安装VMware workstation 10.0虚拟机,将虚拟网络改为桥接模式,在虚拟机中安装Ubuntu12.04的系统,然后安装VM-tools. 在windows下面的创建共享目录G:/share,实现window

基于J2EE新闻发布系统的设计与实现——论文随笔(十四)

一.基本信息 标题:基于J2EE新闻发布系统的设计与实现 时间:2010-10 出版源:南昌大学 领域分类:系统架构和设计 二.研究背景 问题定义:很多企业都没重视前期的市场调查 , 导致许多低质量或者说是不符合要求的新闻发布系统出现 , 因此在建新闻发布系统前进行市场分析就显得更重要了 , 只有了解好企业所在的市场才能结合自身现状建设出高水准的新闻发布系统来 . 相关工作:本文提出开发一个新闻发布系统的想法 ,基于J2EE设计方法设计. 三.创新方法 1.all in one 的J2EE的设计

Linux下日志系统的设计

简介:通过日志系统的设计,将多台主机上的日志统一发送到一台服                                器,日志服务器自动将日志记录到mysql数据库,远程通过web方式调用数据库查看日志(使用loganalyzer解决方案,基于php). 在linux系统下,使用apache做web客户端,mysql数据库,php为web及后台数据的调用,统称为lamp. 日志的种类:/var/log/secure 身份验证有关信息的日志 /var/log/maillog 邮件相关的日志

基于JavaEE的网上书店的设计与开发

获取项目源文件,技术交流与指导联系Q:1225467431 摘  要 在正常运营中,一个现代化网上书店需要对进书.售书.库存.统计信息以及个人信息进行管理,这些信息数量非常巨大并且处理起来十分复杂.如果使用传统的管理方法,既浪费了人力物力,而且存在着很多的漏洞,一旦出现错误,造成的损失将是不可估量的.因此,一个信息化.系统化.智能化的网上书店是十分必要的. 本系统是基于B/S(Browser/Server)结构的网上书店,它使用了目前最流行的Java语言编写,用到了先进的JSP技术,用户界面友好

linux下播放器的设计和开发

本文根据DawnLightPlayer的开发经验写成.DawnLithtPlayer是今天3月份开始,和maddrone一起在业余时间开发的一个跨平台,多线程的播放器,主要是在Linux下面开发的,文中所用示例代码均截自其中.DawnLightPlayer目前可以运行在Linux和Windows系统上,并使用VC和Python开发了GUI,支持大部分的音视频文件格式和网络流,另外新增对CMMB协议的支持,不支持 RMVB, SWF 等尚未公开协议的视频文件格式. 目录:一. 播放器的流程   1

基于Linux的智能家居的设计(5)

4  软件设计 软件设计部分主要包括uboot移植.内核编译.系统移植.设备驱动编程.应用程序编程(QT编程.mysql数据库编程.控制系统编程).各个模块的功能函数(部分是在windows下面的IAR中实现). 软件部分的结构框图如图4-1所示: 图4-1  软件结构框图 4.1  U-boot移植 由于每个操作系统在运行前必须要运行一段小程序,这个就是通常说的Bootloader,类似windows的BIOS的固件程序[15].通过这段程序可以初始化硬件设备.建立内存空间映射图,从而将系统引