Aiur – ZelluX 的技术博客

Security, Kernel, Virtualization, Programming Languages

Archive for the ‘Computer System’ Category

跨站脚本攻击和BluePrint

8 views | without comments

Blueprint: Robust prevention of cross-site scripting attacks for existing browsers

这篇论文提出了一种防范是跨站脚本攻击(XSS)的新的方法,发在IEEE S&P 2009上,作者是UIUC的Mike Ter Louw。

所谓跨站脚本攻击,简单地说就是在网页中注入非法的脚本代码,从而达到攻击的效果。比较著名的例子有当年在MySpace上泛滥的Samy蠕虫,通过特殊的脚本注入手段,每一位访问Samy主页的用户,他们的主页都会被修改加上一段Samy is my hero文字,并且他们的主页也会被植入攻击代码,从而把这段脚本扩散给更多的用户。

通常防范跨站脚本攻击的方式有两种。一种做在服务器端,为每一段用户上传的内容做检查,并剔除恶意代码。但这种方式很难保证能过滤掉所有的恶意字符串,一方面攻击方法防不甚防,有兴趣的朋友可以参考下XSS Cheat Sheet,上面给出了很多一般人很难想到的攻击代码的组合方式。另一方面由于现在大多数论坛和博客都支持<b> <i>等修饰标签,所以简单的标签剔除或者重新编码都不可行。

另一种方法是做在浏览器端,但是由于浏览器无法区分某一段脚本到底是来源于不可信的用户还是可信的站点,所以这种方法实现起来也有很大的困难。

这里实现防范措施的一个难点在于,Web应用把生成HTML的返回给浏览器后,就不参与浏览器的HTML解析工作了。这样浏览器就不知道哪部分出现脚本是安全的,哪部分出现是不安全的。

BluePrint就着眼于这个点,提出了一种让Web应用“参与”HTML解析工作的设计。下面通过论文里面的一个例子,简单介绍下它的防范机制。

假如一位恶意的用户在一个博客上上传了这样一段含有恶意代码的留言:

<p>
Here is a page you might find
<b """><script>doEvil(. . .)</script>">very</b>
interesting:
<a href=" &#14; javasc&#x0A;ript:doEvil(. . .);">
Link</a>
</p><p style="nop:expres/*xss*/sion(doEvil(. . .))">
Respectfully,
Eve
</p>

可以看到,这段代码里包含了很多可能引发脚本执行的代码,而要在服务器端把这些所有隐藏的攻击可能找出来是一件比较困难的事。那么BluePrint是怎么在不知道这段代码是否含有恶意代码的前提下处理的呢?

首先,这种由用户上传的不可信的字符串会先在服务器端被解析成一棵树,就像HTML在浏览器中被解析一样,这棵HTML解析树可以用一些简单的DOM API来生成,例如appendChild, createElement等。这些描述如何生成HTML解析树的方法会和数据值(URL、标签属性等)一起,通过特殊的编码(Base64)传递给浏览器。例如上面这段代码,最后在浏览器接收到的HTML中,会变成这样:

<code style="display:none;" id="__bp1">
=Enk/sCkhlcmUgaXMgYSBwYWdlIHlvdSBta...
=SkKICAgICI+dmVyeQ===C/k/QIGhlbHBmd...
=ECg===C/Enk/gCiAgUmVzcGVjdGZ1bGx5L...
</code><script id="__bp1s">
__bp__.cxPCData("__bp1", "__bp1s");
</script>

在浏览器端,这段特殊的代码会被JS库解析成自定义的命令和数据格式,并由前面提到的DOM API动态生成这些HTML结点,从而达到和传统的方式一样的显示效果。当然可信的HTML代码,例如文章正文,还是按传统的方式传输的。

通过这种方式,BluePrint绕过了浏览器对不可信代码的解析,从而防止了不可信代码里内嵌的脚本的执行

此外还有一些细节的问题,例如为什么使用Base64编码来描述自定义的命令和数据,而不是常用的例如UTF-8呢?这是因为使用UTF-8的话攻击者就有可能通过构造一段特殊的字符串,而这段字符串对应的编码恰好能起到攻击作用。而使用Base64编码就不会有这个问题。

攻击例子中的第5行和第7行还分别包括了通过恶意URL和CSS风格实现的代码,前面提到的措施还不足以防范这两种类型的攻击。论文里面也提到了相应的解决方案,这里不再赘述,有兴趣的朋友可以搜索论文阅读相关部分。

把BluePrint整合到现有的应用程序里也不难,只要把包含不可信内容显示部分的代码重新加一层包装就行了,像这样:

// Code for trusted blog content
// appears untransformed aboveˆˆ.
<?php foreach ($comments as $comment): ?>
    <li>
        <?php
$model = Blueprint::cxPCData($comment);
echo($model);
        ?>
    </li>
<?php endforeach; ?>

在BluePrint的开销方面,包含25个用户评论的wordpress页面产生速度慢了55%,不过作者提到wordpress本身还有HTML解析和恶意代码检查过滤的功能,用了BluePrint后就不需要这些冗余的检查了,所以把这部分代码去掉会快不少。另外由于不可信内容都需要动态的被解码并创建相应的HTML结点,浏览器端的显示速度慢了很多,作者也解释到这种解析开销其实并不重要,因为通常看一篇博文的时候都是先看内容,由于文章内容本身是可信的,所以会以传统的方式传输并显示,若干秒后再显示评论也未必会对用户体验造成太大的影响。

这篇论文给我的感觉是思路很清晰,抓住了主要的难点后用了对应的方法绕过了浏览器的HTML解析。不过应用面上还有一些局限,只能防止不可信代码中脚本的执行,对于需要执行脚本的情形(例如Blogger上的Gadget)就不适用了。MIT去年发在EuroSys ‘09上的BFlow就是针对这样一种情形,通过类似于Flume的标签系统,使得不可信的脚本读取了隐私数据后就无法将它们传输给不可信的网站。

用beamer做了slides,在这里可以下载到: http://zellux-notes.googlecode.com/hg/slides/blueprint/

Written by zellux

March 3rd, 2010 at 11:47 pm

Posted in Computer System

Tagged with , , ,

Linear Page Table: 更方便地访问页表

18 views | with one comment

Linear page table又叫virtual page table,是一种方便虚拟机监控器(VMM)/操作系统(OS)/应用程序访问页表的技巧。Xen、64位Linux内核、JOS操作系统中都用到了这种技巧。这里以x86_32的虚拟内存管理为例,简单介绍一下它的实现和使用,如有错误敬请指出。

一般情况下,如果OS需要访问某个页表,需要将它映射到自己的虚拟空间中,然后再访问。这样带来两个问题,一是访问比较繁琐,需要临时的页映射;二是对于Exokernel这种fork等行为都是在用户态程序实现的系统,可能会增加一下安全上的问题。因为用户程序在fork的时候需要访问自己的页表,而这时候除非操作系统提供另一些权限控制更精确的系统调用,否则就很难让不可信的应用程序访问自己的页表且不做有害的改动。

Linear page table很好的解决了这两个问题。它的实现很简单,只需要在页目录中增加一项VPT,和一般的页目录项不同的是,这个VPT指向的是页目录本身

这样带来了什么好处呢?借用一下MIT 6.828课件上的图片来更好的说明这个问题

增加了VPT后,通常的物理地址->虚拟地址的转换还是没变。和之前唯一的不同在于虚拟地址的页目录索引号(PDX)为之前设置的VPT的时候。

举个例子来说,假如现在要访问的虚拟地址是(VPT << 22) | (VPT << 12),即这里的PDX和PTX都等于VPT的时候,整个转换过程是怎么样的呢(假设TLB miss的情况)?首先根据cr3中的物理地址,硬件开始查找页目录中的第VPT项,然后根据这一项中的物理地址,找到了下一级“页表”。注意这时候硬件以为自己得到的页表地址,实际上访问的还是页目录本身。同样,在这个“页表”中找到第VPT项指出去的最终页,得到了最终页的物理地址。因为PTX还是等于VPT,所以最后得到的物理地址还是页目录的。

也就是说,通常的页表访问的顺序是 CR3->页目录->页表->最终页,现在访问这个特殊地址的过程则成了 CR3->页目录->页目录->页目录,通过VPT这一项在页目录上绕了两圈后返回。

接下来,再来看看如何通过这个机制来访问某个页表,假如现在要访问第i个页目录项指向的页表上的第j项,那么我们应该构造这样一个特殊地址:

(VPT << 22) | (i << 12) | (j * 4)

即PDX=VPT, PTX=i, offset=j*4。通过这个地址就能得到需要的页表项了,另外由于(i << 12) | (j * 4) = (i * 1024 + j) * 4,定义vpn为虚拟页的编号,vpn = i * 1024 + j,则这个地址可以转换为

(VPT << 22) + vpn * 4

在JOS中,就是把vpt定义为一个uint32_t的数组,然后vpt[vpn]就是第vpn个虚拟页的页表项了。前面提到的另一个问题,如果要让用户以只读权限访问页表,又应该怎么做呢?很简单,在页目录中为用户设置另一个只读项,指向页目录自己就行了。

Written by zellux

February 9th, 2010 at 2:33 pm

基于函数调用栈的rootkit

111 views | without comments

好久没更新这个博客了,最近忙实验室项目,作息时间有点颠倒,以至于现在这会儿睡不着把以前扫过一篇paper拿出来看了下。

这篇题目为Return-Oriented Rootkits: Bypassing Kernel Code Integrity Protection Mechanisms的论文发在了今年的Usenix Security上,现在在Usenix网站上还不能下到这篇paper的pdf,可以去作者的主页上下。

现在有不少用来防止栈溢出攻击的技术,比如操作系统保证任何一个页不能同时为可写且可读(WinXP SP2、Win 2003、Exec Shield for Linux等都采用了这个策略),这个方法实现起来比较简单,但只能防范部分形式的攻击,如果攻击者事先准备一张含有恶意代码的用户态的只读页,然后跳转到这个页,就能绕开这种保护措施了;另外也有人提出在操作系统的下面再加一层虚拟层,让它来保证上层系统没有因为各种buffer overflow而执行恶意代码(NICKLE)。

而这里提到的return-oriented的攻击方法不同于传统的攻击机制,它所采用的攻击代码都是内核自身的代码,因此能绕过前面提到的各种保护手段。

所谓return-oriented programming,简单的说就是把原来已经存在的代码块拼接起来,拼接的方式是通过一个预先准备好的特殊的返回栈,里面包含了各条指令结束后下一条指令的地址。

例如现在函数A里面有这么一段指令
instruction A
ret

函数B里面有另外一段:
instruction B
ret

它们在正常的运行情况下没有任何关系,但是我发现如果把A和B拼起来就能达到我想要的结果,于是我构造了一个包含有A和B的地址的栈,先通过ret指令返回到instruction A处,之后再执行ret指令时,由于栈是精心构造的,因此接下来会执行到instruction B,这样就得到我想要的结果了。只要这个ret前的指令库足够大,就能实现几乎所有的程序。

这种攻击方式并非这篇paper的首创,最早是由Shacham提出的(http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.140.9210,http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.78.7135)

这篇paper的一大贡献在于实现了一个自动从libc和驱动、内核等代码中找到可用的指令,并拼接成所需程序的系统,这里面包括一个扫描可利用代码、并把它们结合起来的Constructor,一套专用的语言,以及把这套语言编译成对应代码片段之和的编译器,最后还有一个计算实际代码地址的Loader。

这套攻击机制在WinXP SP2/Sp3, Vista SP1等系统上都获得了成功,尽管查找代码并生成这个过程的overhead很大,但对于一次成功的rootkit攻击来说影响并不大。

Written by zellux

August 12th, 2009 at 2:35 am

Posted in Computer System

Tagged with , ,

Xen警告Time went backwards的暴力解决方法

193 views | with 3 comments

前几天给测试Xen用的虚拟机挂了,只能用VMware的snapshot返回到之前的镜像,然后似乎因为时间问题启动Xen的时候总是会定时打印出类似

571 Timer ISR/0: Time went backwards: delta=-11072481 delta_cpu=298927519 shadow=196807680595 off=288495093 processed=197107247546 cpu_processed=196797247546
572  0: 196797247546
573  1: 197107247546

的信息,google了下发现是时间同步的问题,用ntp协议同步时间即可解决这个问题。另外这里再给出一个最暴力的解决方法:在linux-xen源码的arch/i386/kernel/time-xen.c文件中找到Time went backwards,把这行打印语句以及后面的循环打印删除,然后重新编译内核。x86_64体系结构也是修改这个文件。方法很暴力,也没真正解决问题,但是至少不影响我看/var/log/messages的输出了。

Written by zellux

July 7th, 2009 at 11:08 am

Posted in Computer System

Tagged with

云计算

293 views | with one comment

某门课程的Open Topic,我的话题是关于云计算的,读了一篇Above the Clouds: A Berkeley View of Cloud Computing

http://www.eecs.berkeley.edu/Pubs/TechRpts/2009/EECS-2009-28.html

这是UCB的RAD(Reliable Adaptive Distributed)实验室花了六个月时间brainstorm总结出来的paper,介绍了云计算的概念、现状及未来展望。以下内容主要来自于我上交的文档,做了一些修改,欢迎大家指正。

虽然现在对云计算这个概念的炒作大于实际研究,以至于很多人听到云计算这个名词就想到忽悠,但这里面还是很多东西需要好好考虑和设计的。云计 算和以前的cluster computing等概念虽有相同之处,区别也有不少,它涉及了经济学、虚拟化技术、安全等诸多领域的内容。

何谓云计算?

云计算包含两方面内容,一是通过Internet提供的作为服务的应用程序,这些服务以前也被称为SaaS(Software as a Service);二是提供这些服务的在数据中心的硬件和系统软件,这部分也就是我们通常所称呼为“云”的东西。

云计算平台的优势

云计算带来了三个新颖的观点:
1.    提供了看起来没有上限的可用计算资源,用户不需要提前考虑设备的需求量;
2.    免去了云计算用户的前期投入,使得公司可以从一个规模较小的硬件资源起家,并根据自己的需要增加资源;
3.    细粒度的计费手段,例如按每小时使用处理器数或者每天使用的存储空间计算,并在暂时不需要机器和存储空间时即时减免费用。

关于云计算资源拥有很好的弹性,以Amazon EC2为例,用户可以在几分钟内完成硬件资源的增加或者减少操作,而这在传统的应用程序部署中是很难做到的。文中提到了Facebook上的一个应用Animoto,这个应用的资源需求在三天内从50台服务器上升到了3500台服务器,这在传统的部署中很难估计并完成。另外还有一个问题,当资源需求下降时,传统方式部署的服务器资源就被闲置了,而通过云计算部署的资源甚至可以在晚上访问量下降时减少占用的硬件资源从而减少支出费用。

平台分类

现在的云计算平台提供了不同粒度的API。Amazon EC2是一个底层的极端,它提供了类似物理硬件的接口,用户可以几乎控制从内核开始的整个软件栈。通过虚拟技术提供的CPU、块设备、IP级别的连通技术使得开发人员几乎可以做任何事情。高度的灵活性带来的是可控性的损失,在自动伸缩性(automatic scalability)和容错转移(failover)方面,服务商就力不从心了。而Google AppEngine则提供了比较高层的API,主要面向传统的web应用,在牺牲灵活性之后能很好的实现自动伸缩和转移,并对用户完全透明。而微软的Azure则介于这两者之间,提供了CLR接口,用户可以通过.Net的一系列语言和类库实现自己的应用程序。

不同的平台有不同的适用范围,不可能有一方压倒性的胜过另一方,这个问题就像Ruby和C语言孰优孰劣一样。

当前问题及解决方案

1.    服务的有效性
即如何保证服务总是可以访问

文中提出的方法是不同的公司能提供独立的软件栈,以保证某一个服务无法使用后能及时切换到另一个。但这个实现似乎会有不少阻力,至少现在的云计算服务平台各自的API都还大相径庭,要在不同的平台间转移应用不怎么可行。

至于DDoS攻击,云计算的弹性可以很好的化解这个问题。文章算了一笔账,从黑市租借50万个攻击机器人攻击一个EC2的实例会使得受害者遭受额外的每小时460美刀的支出,但由于租借这些机器人需要1.5万美刀的资金,要使得受害者的损失大于攻击者的支出,这样的攻击需要持续32小时,对于攻击者来说很不可取。

2.    数据被锁定
数据被锁在服务提供商的数据平台中,客户无法很简单的把数据从一个站点转移到另一个。这也是Stallman反对云计算的一个重要原因,客户可能因为数据锁在云计算平台中而不得不接收服务提供商的价格提升等要求。

文中提到的一个解决方案就是统一平台的API,使得数据能在不同的服务提供商之间转移。我觉得这个方案也不现实,就像有了GAppEngine后,应该不会有另一家服务商提供类似的Python或者Java的API支持了吧?

不过也许可以有一个第三方的库把不同的服务商的API再做一层抽象,让应用程序来使用这些平台无关的API,就像是OpenCL/Streamware之于GPU。

3.    数据机密性
这个问题我想不算难点,可信计算已经是研究的热门之一了,而用户自己也可以将机密数据加密后再保存到云中。而虚拟机监控器层也能提供相应的保障,例如CHAOS和VMware的OverShadow可以保护在不可信的操作系统中应用程序运行的安全性,这样即使攻击者能利用操作系统层的漏洞,也无法对操作系统上面的受保护的应用程序进行攻击。

4.    数据传输瓶颈
用户的数据要传输到云里面,消耗的时间和带宽都很高,怎么办呢?

一个简单和实用的方案就是直接通过快递公司邮递硬盘,几TB的数据不到一天就能传到数据中心了。

另一个手段是尽可能地把数据保留在云中。我觉得广义的来说这也是一种locality的优化吧,但是这样就又要考虑到前面提到的数据锁定的问题了。

此外,降低网络传输的费用也是一个研究方向,据估计三分之二的网络带宽费用都是用在高端的路由器上,而另外的三分之一才是用在传输介质中。如何减少路由器的耗费是一个需要深入研究的问题,另外如何更有效的设计云里面的网络的拓扑结构也值得探讨。

5.    性能的不稳定
我觉得相对其他问题,这个问题应该算是很难解决的了。由于客户使用的虚拟机往往和其他虚拟机共享了云中的硬件资源,在共用I/O设备的时候表现性能会有较大的起伏。

提高性能稳定性的最直接的途径自然是提高体系结构和操作系统虚拟中断及I/O通道时的效率了。另外文中还考虑了使用闪存来降低I/O干扰的可能,不过我认为闪存随机写的性能很差,代替硬盘后的性能未必会好,尤其在多个虚拟机同时访问的情况下,稳定性就很难说了。

另外,在调度虚拟机的时候,还要采用Gang Schedule,即对于一些必须几个线程同时运行的程序,要保证这些虚拟机能被同时调度运行。

6.    文章还提到了另外5个障碍,包括存储设备的可伸缩性,如何快速伸缩、大规模分布式系统中的bug问题,这可以通过开发相应的可伸缩存储系统、算法以及分布式调试器解决。另外还有声誉共享(一个客户的恶意行为被其他网站记录,可能影响到同一台物理机上的另一个无辜的客户),软件协议等问题。这些应该都不是难点,而软件协议方面,微软也已经推出Windows Server和Windows SQL Server的到期支付(pay as you go)的协议。

Written by zellux

June 9th, 2009 at 5:24 pm

Posted in Computer System

Tagged with ,

利用VMware的虚拟串口调试Xen

299 views | with one comment

VMware支持虚拟串口设备,对于调试内核或者虚拟机的帮助很大,具体设置如下(VMware Server 2, Xen 3.3):

1. VMware中为虚拟机增加串口设备
Add Hardware->Serial Port,然后在设置中将Connection模式设为File,指定相应的文件路径(如[standard] debian-xen/serial-port.log)

2. 修改虚拟机的grub启动参数,以我的/boot/menu/lst为例

title           Xen 3.3.0 / Debian GNU/Linux, kernel 2.6.18.8-xen
root            (hd0,0)
kernel          /boot/xen-3.3.0.gz com1=115200,8n1 loglvl=all guest_loglvl=all console_to_ring console=com1,vga sync_console
module          /boot/vmlinuz-2.6.18.8-xen root=/dev/sda1 ro console=tty0
savedefault

3. 重启虚拟机,即可在之前指定的文件中(Host机上的/opt/vmware/Virtual Machines/debian-xen/serial-port.log)中看到虚拟机的输出信息了。

Written by zellux

May 27th, 2009 at 2:31 pm

Posted in Computer System

Tagged with , ,

ISCA 09 – Multi-Execution

273 views | with 3 comments

Multi-Execution: Multicore Caching for Data-Similar Executions

这篇paper针对以multi-execution这种模式运行的程序提出了一种新的cache手段。

所谓multi-execution,指的是同时运行同一个程序的多个进程,而它们的输入数据又互不相同。这种模式在machine-learning领域比较常见,一些相对独立的learner可以以并行的方式被训练,而它们的结果可以通过一种叫做boosting的方式合并起来。给我的感觉似乎有点像mapreduce?

然后呢,作者们发现以这种方式运行的程序进程的数据有很大一部分是相同的,在合并cache数据上可以做一下文章,节省cache的使用。

于是这篇paper提出了一种叫做mergeable cache的架构,用于代替传统的L2 cache,L1 cache还是传统的cache架构。首先假设相同的数据的虚拟地址往往也是相同的(应该去掉了address space randomization的影响),以类似Page Coloring的策略进行物理页的分配,使得不同进程同一虚拟地址所对应的物理页都是相邻的。然后把虚拟地址的头9位作为cache tag,再为每个cache line记录一个bit vector用以表示某个processor的数据是否保存在这条cache line中。于是L2 cache hit当且仅当:
1. 虚拟地址的头9位等于cache line的tag
2. cache line中的bit vector的processor对应的位被置上

另外为了简化cache策略,L1和L2的数据内容是互斥的,或者说一段被cache的数据要么在L1,要么在L2,不可能同时存在于两者中。这样一来L2就只有从L1淘汰出来的数据了,而L2中的数据修改分三步完成:
1. 把数据从L2中标记为不存在(对应processor的bit vector位置0)
2. 数据进入L1
3. 修改数据

这就是这篇paper提出的cache架构的主要内容,后面的evaluation部分做的也很不错。从数据中可以看出合并的cache里面dirty cache占了比较大的比例,从而说明简单的copy-on-write策略的效果不会很好,因为copy-on-write只能合并clean cache。最后平均的speedup提升在2.5x左右,很不错。但是对于数据无关的并行程序运行,会产生一定的overhead,此时可以选择传统的L2 cache机制。

Written by zellux

May 12th, 2009 at 11:11 am

Posted in Computer System

Tagged with , ,

Page Coloring

103 views | without comments

Multi-Execution (ISCA ‘09)的时候看到的名词,中文叫做高速缓冲器页着色,有点拗口,还是用英文术语好了

早期的处理器缓存都是映射虚拟内存的,这样带来两个问题,一是进程切换等场合下需要清空缓存,二是由于多个虚拟地址可能指向同一个物理地址,因此会出现缓存中数据别名的问题(data aliasing)。

于是现代的处理器更多的通过物理地址进行数据缓存,这也引入了另一个问题,虚拟内存中看到的相邻的两块数据在缓存中很有可能是不相邻的,如果操作系统分配物理页时不考虑这点就会影响性能。

举例来说,假设CPU能缓存4个物理页,缓存策略是CSAPP中提到的最简单的方式,即第n号缓存只用于物理页号除4余数为n的物理页(n=0,1,2,3),比如第2号缓存对应于2,6,10,..号页面。现在用户为页面号为0的虚拟页申请空间,操作系统把第16号物理页分配给它;接下来用户又为页面号为1的虚拟页申请空间,而17-19号物理页已经用掉,此时操作系统就不应该分配20号物理页给它,因为20号物理页和16号物理页占用同一个缓存地区,假设用户程序的局部性(locality)很好的话这样的分配方式会产生比较严重的抖动(thrashing),影响系统缓存的性能。所以操作系统应该分配21号物理页给它,而保证这种分配策略的方式就是为每个页标记不同的颜色,并使得同一时间使用的页面颜色尽可能的不同。

参考资料
http://en.wikipedia.org/wiki/CPU_cache
http://www.freebsd.org/doc/en/articles/vm-design/page-coloring-optimizations.html

Written by zellux

May 11th, 2009 at 9:30 pm

Posted in Computer System

Tagged with

EuroSys 09 – Orchestra

156 views | without comments

吴总讲的一篇paper,题目是Orchestra: Intrusion Detection Using Parallel Execution and Monitoring of Program Variants in User-Space,发在EuroSys ‘09上,UCI的。

这篇paper提出了一种检测栈上buffer overflow攻击的方法。想法很有意思,它运行两个孪生进程,这两个进程的唯一的区别就是一个进程的栈往上长而另一个进程的栈往下长,这样在大多数情况下如果没有出现buffer overflow的问题的话那么两者的行为应该是一致的。

栈的增长行为是由编译器控制的,作者修改了gcc的代码使之生成的代码的栈增长方向相反,关于这个编译器他们之间发过一篇paper在一个叫CATARS的workshop上,题目是Reverse stack execution in a multi-variant execution environment。

“行为一致”的精确定义是两者的system call的调用方式、参数都一样,也就是说这里system call成了两个进程运行的synchronization point。如果某个点上两个进程调用的syscall不同或者调用参数不同就认为它已经被buffer overflow攻击了。

整个monitor都是跑在user态的,主要利用了ptrace,使两者的行为尽可能的一致。这里要做的事情很多,比如要保证进程调用getpid()的得到返回值一样才能使得后面的其他系统调用的参数相同,又比如一个进程调用write写入文件时不能影响到另一个进程,此外还要保证两个进程获得的file descriptor、随机数、时间、信号等信息都相同,甚至在进程创建子进行的时候也要保证所有子线程关系的同构。

用ptrace能够解决上面的大多数问题,但还有一些open problem以及false positive。如这篇paper无法解决进程用MAP_SHARED方式打开一个文件并修改的情况,尽管作者说这种mmap的用例很少见;此外由于两个进程的同步并不是原子性的,中间可能被第三方的程序干扰(比如进程A读入某个文件开头后,该文件被其他进程修改,进程B再读取就和进程A读到的不一样了),这就造成了false positive;另外由于无法截取rdtsc指令的使用,也就无法保证它们的返回值一样,也可能引起另一种false positive。

感觉这个东东想法不错,但是没什么实用性,工程量也很大。

Written by zellux

May 6th, 2009 at 11:17 am

Posted in Computer System

Tagged with , ,

Notes on Xen vcpu

95 views | without comments

1. 绑定vcpu和cpu
xm vcpu-pin <domain-id> <vcpu-id> <cpu-id>

2. 为domainU设置vcpu数
xm vcpu-set <domain-id> <vcpu-id>
注意这里的vcpu-id不能超过domainU配置中的vcpu数

3. xen中的不同domain的vcpu是独立的,或者说domain0的vcpu0和domainU的vcpu0不是同一个。在这个问题上犯过错,以至于设计接口语义的时候出问题了。

Written by zellux

April 27th, 2009 at 9:13 pm

Posted in Computer System

Tagged with

FireStats icon Powered by FireStatsBetter Tag Cloud