acm-header
登录

ACM通信

研究突出了

原生客户端:可移植的、不受信任的X86原生代码的沙箱


克劳迪娅·马尔科维奇《障碍》的细节

来源:www.claudiampublications.com

本机客户机是一个用于不受信任的x86本机代码的沙箱。它的目标是在不影响安全性的前提下,为基于浏览器的应用程序提供本地应用程序的计算性能。本机客户端使用软件故障隔离和安全运行时,通过它控制的接口来指导系统交互和副作用。它进一步提供了二进制代码的操作系统可移植性,同时支持Web应用程序编程环境中通常缺乏的面向性能的特性,例如线程支持、指令集扩展(如SSE),以及使用编译器固有特性和手工编码的汇编器。我们在一个鼓励社区评审和第三方工具的开放架构中组合这些属性。

回到顶部

1.简介

作为一个应用程序平台,现代Web浏览器汇集了各种资源,包括对Internet资源的无缝访问、JavaScript等高效编程语言,以及用于图形表示和用户交互的丰富的文档对象模型(Document Object Model, DOM)。虽然这些优点使浏览器成为新应用程序开发的首要目标,但它在一个关键方面仍然受到限制:计算性能。多亏了摩尔定律和硬件社区对它的热情观察,许多有趣的应用程序在浏览器中获得了足够的性能,尽管存在这一缺陷。但是由于性能的限制,仍然有一组计算对于基于浏览器的应用程序来说是不可行的,例如,牛顿物理模拟、计算流体动力学和高分辨率场景渲染。目前的环境也倾向于禁止使用JavaScript以外的语言开发的大量高质量代码。

现代Web浏览器提供了扩展机制,比如ActiveX7和Netscape插件应用程序编程接口(NPAPI)19允许本地代码作为Web应用程序的一部分加载和运行。这样的体系结构允许插件绕过应用于Web内容的安全机制,同时允许它们访问完全的本机性能,这也许是次要的考虑因素。鉴于这种组织结构,并且缺乏有效的技术措施来约束这些插件,希望使用本机代码的浏览器应用程序必须依赖非技术措施来实现安全性,例如,通过弹出对话框手动建立信任关系或手动安装控制台应用程序。从历史上看,这些非技术措施不足以防止恶意本机代码的执行,从而导致了不便和经济损失。3.22因此,我们认为专家们对基于浏览器的应用程序的本地代码扩展存在偏见,而广大计算机用户对其不信任。

虽然承认将本地代码合并到Web应用程序中的当前系统是不安全的,但我们也观察到,没有根本原因说明本地代码应该是不安全的。在本机客户机中,我们将安全本机执行的问题与扩展信任的问题分离开来,允许分别进行独立管理。从概念上讲,本机客户机分为两部分:用于本机代码的受限执行环境,以防止意外的副作用,以及用于托管这些本机代码扩展的运行时,通过它可以安全地发生允许的副作用。

这项工作的主要贡献是

  • 用于操作系统和浏览器可移植的沙盒x86二进制模块的基础设施
  • 支持高级性能功能,如线程、SSE指令、编译器内部特性和手工编码的汇编器
  • 这是一个开放的系统,可以轻松地重新定位新的编译器和语言
  • CISC软件故障隔离的改进,使用x86段来提高简单性和减少开销

我们将这些特性组合在一个支持安全副作用和本地通信的基础设施中,同时防止任意的文件系统和网络访问。总的来说,Native Client提供了本地代码的沙箱执行和跨操作系统的可移植性,为浏览器提供本地代码性能。

本文的其余部分组织如下。第1.1节描述了我们的威胁模型。第二节介绍了NaCl的一些基本概念一个系统架构和编程模型。第3节给出了附加的实现细节,围绕主要的系统组件进行组织。第4节使用更现实的应用程序和应用组件对系统进行定量评估。在第5节中,我们讨论了这项工作的一些影响。第6节讨论了以前和现在的相关制度。第7节给出了我们的结论。

*1.1.威胁模型

本地客户端应该运行来自任何网站的不可信模块,其安全性可与JavaScript等系统媲美。当呈现给系统时,一个不可信的NaCl模块可能包含任意的代码和数据。结果是NaCl运行时必须能够确认模块符合我们的有效性规则(详细内容如下)。不符合这些规则的模块会被系统拒绝。

一旦符合条件的NaCl模块被接受执行,NaCl运行时必须约束其活动以防止意外的副作用,例如可能通过对本机操作系统的系统调用接口的无调节访问来实现。NaCl模块可以任意地组合NaCl执行环境允许的所有行为,试图破坏系统。它可以执行被验证的文本段中任何可到达的指令块。它可以使用NaCl应用程序二进制接口以任何方式访问运行时服务:传递无效参数等。它还可以通过模块间通信接口发送任意数据,通信的对等端负责验证输入。NaCl模块可以根据资源限制分配内存和生成线程。它可能试图利用竞争条件来颠覆系统。

下一节将详细介绍我们的架构和代码有效性规则如何创建一个有效包含NaCl模块的沙盒。

回到顶部

2.系统架构

NaCl应用程序由一组可信和不可信组件组成。图1展示了一个用于管理和共享照片的假想的基于nacl的应用程序的结构。它由两个组件组成:一个用户界面(使用JavaScript实现并在Web浏览器中执行)和一个图像处理库(imglib。nexe),作为NaCl模块实现。在这个假设的场景中,用户界面和图像处理库是应用程序的一部分,因此不受信任。浏览器组件受浏览器执行环境的约束,图像库受NaCl容器的约束。这两个组件都可以跨操作系统和浏览器移植,native Client支持本地代码可移植性。在运行照片应用程序之前,用户已经安装了Native Client作为浏览器插件。注意,NaCl浏览器插件本身是针对操作系统和浏览器的。还要注意,它是受信任的,也就是说,它拥有对OS系统调用接口的完全访问权,用户相信它不会被滥用。

当用户导航到承载照片应用程序的Web站点时,浏览器加载并执行应用程序JavaScript组件。JavaScript接着调用NaCl浏览器插件来将图像处理库加载到NaCl容器中。注意本机代码模块是无声加载的,没有弹出窗口请求权限。本地客户端负责约束不受信任模块的行为。

每个组件都在自己的私有地址空间中运行。组件间通信基于Native Client的可靠数据报服务IMC (Inter-Module Communications)。对于浏览器和NaCl模块之间的通信,Native Client提供了两种选择:简单远程过程调用(SRPC)和NPAPI,两者都是在IMC上实现的。IMC还提供共享内存段和共享同步对象,旨在避免大容量或高频通信的消息传递开销。

NaCl模块还可以访问“服务运行时”接口,提供内存管理操作、线程创建和其他系统服务。这个接口类似于传统操作系统的系统调用接口。

在本文中,我们使用“NaCl模块”来指代不可信的本地代码。但是请注意,应用程序可以使用多个NaCl模块,受信任和不受信任的组件都可以使用IMC。例如,照片应用程序的用户可以选择使用一个(假设的)可信NaCl服务来本地存储图像,如图所示图2.因为它可以访问本地磁盘,所以存储服务必须作为本地浏览器插件安装;它不能作为NaCl模块来实现。假设照片应用程序被设计为可选地使用稳定存储服务;用户界面将在初始化期间检查稳定存储插件。如果检测到存储服务插件,用户界面将与它建立IMC通信通道,并将通道描述符传递给图像库,使图像库和存储服务可以直接通过基于IMC的服务(SRPC、共享内存等)进行通信。在这种情况下,NaCl模块通常会静态链接到一个库上,该库提供了访问存储服务的过程化接口,隐藏了imc级通信的细节,比如它是否使用SRPC或是否使用共享内存。注意存储服务必须假设镜像库不受信任。服务负责确保它只服务与用户隐含契约一致的请求。例如,它可能对照片应用程序使用的磁盘总量进行限制,并可能进一步限制操作只能引用特定的目录。

Native Client架构被设计成支持纯计算。它不适用于需要进程创建、直接文件系统访问或不受限制地访问网络的模块。存储等受信任的设施通常应在Native Client之外实现,鼓励单个组件的简单性和健壮性,并对所有组件实施更严格的隔离和检查。这种设计选择呼应了微内核操作系统的设计。1412

有了这个例子,我们现在将更详细地描述NaCl系统关键组件的设计。

*2.1.内盒

本机客户机是围绕x86特定的进程内部“内部沙箱”构建的。我们相信内部的沙箱是稳健的;无论如何为了提供纵深防御58我们还开发了第二个“外部沙箱”,它在进程边界调解系统调用。外部沙盒与之前的结构基本相似1120.这里我们就不详细讨论了。

内部沙箱使用静态分析来检测不受信任的x86代码中的安全缺陷。以前,由于自修改代码和重叠指令等实践,这种分析对任意x86代码都具有挑战性。在Native Client中,我们通过一组对齐和结构规则来禁止这种做法,当观察到这些规则时,可以确保本机代码模块可以可靠地反汇编,这样在反汇编期间可以识别所有可到达的指令。通过可靠的拆卸作为工具,我们的验证器可以确保可执行文件只包含合法指令的子集,禁止不安全的机器指令。

内部的沙箱进一步使用x86分段内存来约束数据和指令内存引用。利用现有硬件来实现这些范围检查,极大地简化了约束内存引用所需的运行时检查,从而降低了安全机制对性能的影响。

这个内部沙箱用于在本地操作系统进程中创建安全子域。通过这种组织,我们可以将可信的服务运行时子系统与不可信的应用程序模块放置在同一进程中,并使用安全的蹦床/跳板机制来允许从受信任代码到不受信任代码的安全转移,反之亦然。虽然在某些情况下,进程边界可以有效地包含内存和系统调用的副作用,但我们相信内部沙箱可以提供更好的安全性,因为它有效地将本机系统调用接口与不受信任的代码隔离开来,从而将其从攻击面中移除。我们通常假设操作系统不是没有缺陷的,因此这个接口可能有可利用的缺陷。内部沙箱进一步隔离了本地操作系统可能有意映射到所有进程的任何资源,就像在Microsoft Windows中经常发生的那样。实际上,我们的内部沙箱不仅将系统与本机模块隔离开来,而且还有助于将本机模块与操作系统隔离开来。

*2.2.运行时设备

沙箱可以防止不必要的副作用,但是一些副作用通常是使本地模块有用所必需的。对于进程间通信,本地客户端提供了一个可靠的数据报抽象,即“模块间通信”服务或IMC。IMC允许受信任和不受信任模块发送/接收由无类型字节数组和可选的“NaCl资源描述符”组成的数据报,以促进文件共享、共享内存对象、通信通道等,跨进程边界。IMC可由受信任或不受信任的模块使用,它是两个更高级抽象的基础。其中第一个是SRPC功能,它为跨NaCl模块边界定义和使用子例程提供了方便的语法,包括从浏览器中的JavaScript调用NaCl代码。第二个是NPAPI,它提供了一个与浏览器状态交互的熟悉接口,包括打开url和访问DOM,这符合现有的内容安全约束。这两种机制都可以用于与传统浏览器内容的一般交互,包括内容修改、处理鼠标和键盘活动、获取额外的站点内容,基本上是JavaScript通常可用的所有资源。

如上所述,服务运行时负责提供容器,NaCl模块通过该容器与浏览器进行交互。服务运行时提供一组通常与应用程序编程环境关联的系统服务。它提供了sysbrk ()而且mmap ()系统调用时,支持原语malloc()和free ()接口或其他内存分配抽象。它提供了POSIX线程接口的一个子集,带有一些NaCl扩展,用于创建和销毁线程、条件变量、互斥量、信号量和线程本地存储。我们的线程支持已经足够完整,可以支持Intel的线程构建模块21原生客户端。服务运行时还提供公共POSIX文件I/O接口,用于对通信通道以及基于web的只读内容进行操作。由于这些接口无法访问本地文件系统的名称空间,因此不可能产生本地副作用。

为了防止意外的网络访问,网络系统调用如connect ()而且accept ()只是省略了。NaCl模块可以在浏览器中通过JavaScript访问网络。这种访问受到适用于其他JavaScript访问的相同限制,对网络安全没有实际影响。

NaCl开发环境主要基于Linux开放源码系统,大多数Linux和Unix开发人员都很熟悉。我们发现,移植现有的Linux库通常很简单,大型库通常不需要更改源代码。

*2.3.攻击表面

总的来说,我们认为以下是潜在攻击者可能试图利用的系统组件:

  • 浏览器集成接口
  • 内部沙箱:二进制验证
  • 外部沙箱:操作系统系统调用拦截
  • 服务运行时二进制模块加载器
  • 服务运行时蹦床接口
  • IMC通信接口
  • NPAPI接口

除了内部和外部的沙箱,系统设计还融入了CPU和内容黑名单。这些机制将允许我们基于对各种组件的健壮性的信心和对如何实现性能、灵活性和安全性之间的最佳平衡的理解来合并保护层。

在下一节中,我们将讨论这些设施的安全实现是可能的,并且在我们自己的实现中做出的特定选择是合理的。

回到顶部

3.本地客户端实现

*3.1.内盒

在本节中,我们解释NaCl如何实现软件故障隔离。该设计仅限于显式控制流,用机器码中的调用和跳转来表示。其他类型的控制流(例如异常)在NaCl服务运行时中管理,在不受信任的代码之外,如下文在NaCl运行时实现中所述。

我们的内部沙箱使用了一组可靠的反汇编规则、一个遵守这些规则的修改的编译工具链,以及一个确认遵守了这些规则的静态分析器。这种设计允许小型可信代码库(TCB),26使用TCB之外的编译工具,以及一个足够小的验证器,允许彻底的检查和测试。我们的验证器实现只需要不到600个C语句(分号),包括一个x86解码器和cpuid解码。这将编译成大约6000字节的可执行代码(Linux优化构建),其中大约900字节是cpuid实现,1700字节是解码器,3400字节是验证器逻辑。

为了消除副作用,验证器必须解决四个子问题:

  • 数据完整性:在数据沙箱之外没有加载或存储
  • 可靠的拆卸
  • 没有不安全的指令
  • 控制流的完整性

为了解决这些问题,NaCl建立在CISC故障隔离的基础上。我们的系统结合了80386段内存6使用以前的CISC软件故障隔离技术。15我们使用80386段来约束数据引用到虚拟32位地址空间的连续子范围。这使我们能够有效地实现数据沙箱,而不需要加载和存储指令的沙箱。VX3210以类似的方式实现其数据沙箱。注意,NaCl模块是32位的x86可执行文件。对最新的64位可执行模型的支持是我们正在开发的一个领域。

表1列出本机客户端对不受信任的二进制文件所要求的约束。约束C1和C6使拆卸可靠。以可靠的拆卸为工具,检测不安全的指令是直接的。本地客户端不允许的部分操作码列表包括:

  • 系统调用而且int。不受信任的代码不能直接调用操作系统。
  • 所有修改x86段状态的指令,包括摩门教、远呼等。
  • 后悔。返回使用一个以寄存器间接跳转结束的沙盒序列来实现。

除了方便控制沙箱之外,还包括受潮湿腐烂如果在堆栈上检查了返回地址,还可以防止由于竞争条件导致的漏洞。类似的论点要求我们在间接上不允许内存寻址模式无条件转移指令而且调用指令。本地客户端允许hlt指令。它永远不应该被正确的指令流执行,并且会导致模块被立即终止。出于卫生考虑,我们不允许所有其他特权/ring-0指令,因为在正确的用户模式指令流中永远不需要它们。我们还限制x86前缀的使用,只允许已知的有用指令。根据经验,我们发现这消除了与CPU勘误表相关的某些拒绝服务漏洞。

第四个问题是控制流的完整性,确保程序文本中的所有控制传输都指向拆解过程中识别的指令。对于每个直接分支,我们根据约束C6静态计算目标并确认它是一个有效指令。我们的间接分支技术结合了80386分段内存和简化的沙箱序列。根据约束C2和C4,我们使用CS段来约束可执行文本为一个从零开始的地址范围,大小为4KB的倍数。由于文本范围受分段内存限制,一个简单的常量掩码足以确保间接分支的目标对齐mod 32,根据约束C3和C5:

ins01.gif

我们将这个特殊的两个指令序列称为anacljmp.编码为3字节和2字节无条件转移指令它与CISC沙箱以前的实现相比有优势。1623如果没有分段内存或零基础文本,沙盒控制流通常需要两个6字节指令(一个而且和一个),总共14个字节。

注意,此分析只涉及显式的同步控制流。例外情况将在第3.2节中讨论。

如果验证器速度过慢,可能会阻止人们使用该系统。我们发现我们的验证器可以以大约30 MB/秒的速度检测代码(在使用MacOS 10.5、2.4 GHz Core 2 Duo CPU、温暖的文件系统缓存的MacBook Pro上测量,1.2秒内检测到35.7 MB)。在这种速度下,验证所需的计算时间通常比下载时间要短,因此不存在性能问题。

我们相信这个内部的沙箱需要非常健壮。我们使用随机指令生成以及有效x86指令的穷举来测试它的解码缺陷。我们还使用了“模糊”测试来随机修改测试可执行文件。最初,这些测试暴露了关键的实现缺陷,尽管随着测试的继续,最近没有发现任何缺陷。我们还在各种x86微处理器实现上进行了测试,担心处理器的勘误表可能会导致可利用的缺陷。14我们确实发现了CPU缺陷的证据,导致系统“挂起”,需要重新启动机器。这种情况发生在验证器的较早版本中,该版本允许相对不受约束地使用x86前缀字节,由于限制它只允许已知的有用前缀,所以我们无法重现这样的问题。

*3.2.异常

硬件异常(分段故障、浮点异常)和外部中断是不允许的,部分原因是Linux、MacOS和Windows中不同的和不兼容的异常模型。Linux和Windows都依赖于x86堆栈% esp用于交付这些事件。遗憾的是,由于NaCl修饰了%党卫军段寄存器,堆栈对操作系统来说似乎是无效的,这样它就不能交付事件,相应的进程立即被终止。使用x86分段进行数据沙箱可以有效地防止从这些类型的异常中恢复。因此,NaCl不可信模块对异常应用故障安全策略。为了隔离异常,每个NaCl模块运行在自己的OS进程中。NaCl模块不能使用异常处理来从硬件异常中恢复,并且必须正确处理此类错误条件,否则有突然终止的风险。在某种程度上,这很方便,因为在将这些事件安全交付给不受信任的代码时存在非常具有挑战性的安全问题。

虽然我们目前不能支持硬件异常,但Native Client确实支持c++异常。24因为它们是同步的,并且完全可以在用户级别实现,所以不存在实现问题。Windows结构化异常处理18需要不可移植的操作系统支持,因此不受支持。

*3.3.服务运行时

从概念上讲,服务运行时是承载Native Client模块的容器。在我们的研究系统中,服务运行时被实现为一个NPAPI插件,以及一个本机可执行文件,该可执行文件对应于不受信任模块的进程容器。它支持Windows、MacOS和Linux上的各种Web浏览器。它实现了动态强制,维护了内部沙箱的完整性,并提供了资源抽象,将NaCl应用程序与主机资源和操作系统接口隔离开来。它包含可信任的代码和数据,虽然与包含的NaCl模块共享一个进程,但只能通过一个受控接口访问。服务运行时通过结合x86内存段和页面保护来防止不受信任的代码受到不适当的内存访问。

当一个NaCl模块被加载时,它被放置在服务运行时地址空间内一个段隔离的256MB区域中。NaCl模块的前128KB地址空间(NaCl“用户”地址空间)被预留给服务运行时进行初始化。这个128KB区域的前64KB被读写保护,以检测NULL指针,并对意外的16位地址计算提供深度防御。剩下的64KB包含实现“蹦床”调用门和“跳板”返回门的可信代码。Untrusted NaCl模块文本在这个保留的128KB区域之后立即加载。的% c段被设置用来约束从基数为0到NaCl模块文本末尾的控制传输。设置其他段寄存器来约束对256MB NaCl模块地址空间的数据访问。

由于它起源于受信任的服务运行时并由其安装,因此允许蹦床和跳板代码包含在不受信任的可执行文本中被禁止的指令。这段代码在运行时补丁作为NaCl模块加载过程的一部分,使用段寄存器操作指令和目前电话指令,用于启用不受信任的用户代码和受信任的服务运行时代码之间的控制传输。由于每一个0 mod 32NaCl用户空间中第二个64KB的地址是一个潜在的计算控制流目标,这些是我们到系统调用trampolines表的入口点。其中一个入口被一个停止指令,以便将剩余空间用于只能从服务运行时调用的代码。这为跳板返回门提供了空间。

调用蹦床将控制从不受信任的代码转移到受信任的代码。蹦床序列重置% dsandthenusesa目前电话toresetthe% c段注册并将控制转移到受信任的服务处理程序,重新建立代码在服务运行时所期望的传统fat寻址模型。一旦超出了NaCl用户地址空间,它就会重置其他段寄存器,比如% fs% gs,%党卫军为了重新建立本机代码线程环境,完全禁用此线程的内部沙箱,并加载堆栈寄存器% esp使用服务运行时使用的受信任堆栈的位置。注意,每个线程的受信任堆栈驻留在不受信任的地址空间之外,以保护它免受不受信任的NaCl模块中其他线程的攻击。

就像蹦床允许从不受信任的代码跨越到受信任的代码一样,跳板允许从另一个方向跨越。这个跳板由可信运行时使用:

  • 将控制转移到任意一个不受信任的地址。
  • 启动一个新的posix样式的线程。
  • 启动主线程。

对齐确保不受信任的代码不能直接调用跳板。从服务调用返回时使用了跳转到任意不可信地址的能力。从trampoline调用返回需要从堆栈的顶部取出一个未使用的蹦床返回地址,恢复段寄存器,最后在NaCl模块中对齐并跳转到返回地址。

作为一个比较点,我们测量了一个“空”系统调用的开销。在相同的硬件上,156 ns的Linux开销略高于Linux 2.6 getpid的系统调用时间138 ns(通过vsycall表和使用sysenter指令)。我们注意到,在x86架构的生命周期中,用户/内核传输一直在不断发展。相比之下,在NaCl蹦床中使用的段寄存器操作和far调用就不那么常见了,而且在x86体系结构的历史中可能很少被考虑。

*3.4.通信

IMC是NaCl模块之间通信的基础。实现是建立在氯化钠的套接字,提供一种双向的、可靠的、有序的数据报服务,类似于Unix域套接字。13一个不受信任的NaCl模块在创建时接收到它的第一个NaCl套接字,可以通过创建它的DOM对象从JavaScript访问。JavaScript使用套接字向NaCl模块发送消息,也可以与其他NaCl模块共享。JavaScript还可以通过打开和共享NaCl套接字作为NaCl描述符来选择将模块连接到其他可用的服务。NaCl描述符也可以用来创建共享内存区域。

使用NaCl消息,Native Client的SRPC抽象完全在不受信任的代码中实现。SRPC提供了一种方便的语法,用于在JavaScript和NaCl模块之间或两个NaCl模块之间声明过程化接口,支持一些简单类型(例如int、float、char)、简单类型的数组和NaCl描述符。不支持指针。更高级的数据表示可以很容易地在IMC消息或SRPC上分层。

我们的NPAPI实现也建立在IMC之上,并支持公共NPAPI接口的一个子集。形成当前实现的特定需求是能够读取、修改和调用浏览器中脚本对象的属性和方法,支持简单的光栅图形,提供createArray ()方法以及像文件描述符一样打开和使用URL的能力。我们目前正在研究对NPAPI的一些额外改进,以提高可移植性、性能和安全性。b

*3.5.开发人员工具

构建NaCl模块:我们已经修改了标准的GNU工具链,使用gcc编译器集合的4.2.2版本c以及binutils的2.18版本d生成符合nacl的二进制文件。我们已经从newlib构建了一个引用二进制文件e使用产生的工具链,重新托管使用NaCl蹦床来实现系统服务(例如,Read (), brk(), gettimeofday(), imc_sendmsg()).本地客户端支持一种不安全的“调试”模式,该模式允许额外的文件系统交互,否则安全代码是不允许的。

我们通过更改函数条目的对齐方式来修改Native Client的gcc(-falign-functions)为32字节,并通过更改目标分支的对齐方式(-falign-jumps)32字节。我们也改变了gcc来使用nacljmp用于间接控制转移,包括间接呼叫和所有返回。我们对汇编器做了更重要的更改,以实现Native Client的块对齐要求。为了实现返回,汇编程序确保调用指令总是出现在32字节块的最后一个字节中。对汇编器进行了扩充,实现了间接控制传输序列nacljmp伪指令是正确对齐的连续字节块。为了方便测试,我们添加了使用更长时间的支持nacljmp序列,对齐文本库,并使用使用重定位作为蒙版的“和”和“或”。这允许通过在命令行上运行应用程序来测试应用程序,并且已经用于运行整个gcc C/ c++测试套件。我们还修改了链接器,按照NaCl加载器(今天128KB)的要求设置了图像的基址。

除了直接使用工具链之外,工具链还通过实例记录了如何修改现有的工具链以生成NaCl模块。在gcc和binutils中总共只使用了不到1000行代码来修补这些更改,这证明了将编译器移植到Native Client的简单性。

配置和调试: Native Client的开源版本包括一个简单的分析框架,以最小的性能开销捕获完整的调用跟踪。这种支持是基于gcc的-仪器-功能代码生成选项与rdtsc定时指令。该分析器是可移植的,完全作为不受信任的代码实现。根据我们的经验,在这个框架中分析的优化构建的性能介于两者之间-00年而且-02年构建。应用程序程序员可以选择使用类似的方法来注释分析器的输出printf,输出将出现在跟踪中而不是标准输出中。

我们的发行版还包括一个修改版的Linux上的gdb,用于本地客户端调试。调试器识别受信任和不受信任代码使用的不同地址域,以及两个域的独立符号表。即使有了这种支持,Native Client的额外复杂性也会干扰调试。因此,我们维护一组库,以方便构建项目的独立版本和本地客户端版本,通常首先调试独立版本。

回到顶部

4.经验

本节中的性能度量是在不使用Native Client外部沙箱的情况下进行的。外部的沙盒实现是平台相关的,通常使用标准的内核设施(例如Windows上的系统调用acl, Linux上的用户id),固有的增量开销很小。

*4.1.SPEC2000

本机客户机的主要目标是交付本机代码执行的所有性能。NaCl模块的性能受到对齐约束、间接控制流传输的额外指令以及NaCl通信抽象的增量成本的影响。

我们首先考虑使本机代码无副作用的开销。为了隔离NaCl二元约束的影响(表1),我们使用NaCl编译器构建了SPEC2000 CPU基准测试,并链接到作为标准的Linux二进制文件运行。NaCl开销的最坏情况是CPU绑定应用程序,因为它们有最高密度的对齐和沙盒开销。图3显示了NaCl编译一组SPEC2000基准测试的开销。最糟糕的情况下,性能开销约为12%,在所有基准测试中平均约为5%。硬件性能计数器测量表明,最大的性能下降是由于指令缓存丢失造成的。对于巧妙的操作,在NaCl构建中,指令获取单元在83%的周期内停止,而在默认构建中,这一比例为49%。Gcc和vortex也会受到指令缓存丢失的显著影响。

由于我们目前的对齐实现是保守的,对齐了一些不是间接控制流目标的指令,我们希望在细化实现的同时增量地改进代码大小。“NaCl32”测量使用静态链接的二进制文件、32字节对齐和nacljmp用于间接控制流传输的伪指令。为隔离间接控制流序的影响,图3还显示了仅针对静态链接和32字节对齐的“align32”结果。这些比较清楚地表明,在开销很大的某些情况下,对齐是一个因素。相比之下,静态链接和沙箱指令开销的影响很小。

在整个基准测试套件中,对齐的影响并不一致。在某些情况下,对齐似乎提高了性能,而在其他情况下,它似乎使事情变得更糟。我们假设将分支目标对齐到32字节边界有时会与缓存、指令预取缓冲区和处理器微架构的其他方面进行良好的交互。这些影响很奇怪,但还没有大到足以进行进一步的研究。如前所述,在对齐导致性能下降的情况下,一个可能的因素是代码大小。由于对齐,NaCl代码大小的增加可能高达50%,特别是在像gcc SPEC2000基准这样具有大量静态调用站点的程序中。类似地,具有大量控制流分支(例如,crafty, vortex)的基准测试,由于分支目标对齐,代码大小增长更快。随着沙盒的代码增量大小的增加nacljmp一直小。

总的来说,Native Client对这些基准测试的性能影响平均不到5%。在这个级别上,开销比不受信任的本机执行要好。

*4.2.h .解码器

我们移植了H.264视频解码的内部实现,以评估移植工作的难度。最初的应用程序将H.264视频转换成原始文件格式,在Linux上的标准GCC环境中使用大约11K行C语言实现。我们把它修改成播放视频。这个端口需要大约20行额外的C代码,其中一半以上用于错误检查。除了重写Makefile之外,不需要进行其他修改。这一经验与我们对Native Client的一般经验是一致的;传统的Linux库本身不需要网络和文件访问,通常只需极少的工作就可以进行移植。原始版本和NaCl版本的性能不相上下,但受到视频帧率的限制。

*4.3.地震

我们异形sdlquake-1.0.9f使用系统自带的“timedemo demo1”命令。《Quake》在Ubuntu Dapper Drake Linux系统上以640 × 480分辨率运行,并搭载2.4 GHz Intel Q6600四核CPU。视频系统的垂直同步(VSYNC)被禁用。Linux可执行文件使用gcc 4.0.3版本构建,Native Client版本使用nacl-gcc 4.2.2版本构建,两者都使用-02年优化。

在Quake中,Native Client和普通的可执行文件之间的区别实际上是不可区分的。看到表2的比较。我们观察到运行之间很少有不确定性。测试播放相同的事件序列不管帧率。由于操作系统的线程调度程序和来自其他进程的共享缓存的压力,仍然可能会出现轻微的帧速率差异。虽然Quake使用了软件渲染,但最终将位图传输到用户桌面的性能可能取决于视频设备的繁忙程度。

回到顶部

5.讨论

如上所述,本地客户端有内部和外部的沙箱,冗余的壁垒来保护本地操作系统接口。此外,还将部署CPU黑名单、NaCl模块黑名单等附加措施。

我们已经在Ubuntu Linux, MacOS和Microsoft Windows XP上开发和测试了本地客户端。总的来说,我们对Native Client与这些操作系统的交互很满意。也就是说,更好的操作系统支持会在某些领域有所帮助。例如,流行的操作系统要求所有线程都使用胖寻址模型,以便正确地交付异常。使用分段内存可以防止这些系统解释堆栈指针和其他基本线程状态。通过更好的操作系统段支持,我们可以解决这个问题,并在不受信任的代码中提供硬件异常支持。但是,请注意,由于我们的可移植性要求,我们不能对不受信任的模块启用异常支持,除非所有本地操作系统都支持它。这种最小公分母效应也出现在系统的其他部分,例如NaCl模块的256MB地址空间限制。

关于编程语言和语言实现,我们受到了Native Client和GNU工具链的最初经验的鼓舞,并正在考虑移植其他编译器。我们还移植了两个解释器,Lua和awk。虽然支持诸如Java这样的jit语言具有挑战性,但我们希望Native Client有一天能够允许开发人员在浏览器中使用他们所选择的语言,而不是局限于JavaScript。

回到顶部

6.相关工作

安全执行第三方代码的技术通常分为四类:系统请求审核、虚拟化、故障隔离和信任认证。

基于内核的机制,如基于用户id的访问控制、systrace20.和ptrace25是类unix系统上熟悉的设施。许多项目已经将这种机制应用于包含不可信代码,最近的一个是Android2从谷歌到Xax9从微软的研究。虽然它们可能非常有效,但这些方法需要依赖于本机操作系统。这些依赖关系反过来会影响可移植性,并暴露出更多的本机操作系统的攻击面。我们内部的沙盒设计很大程度上受到可移植性和操作系统独立性的影响。

许多研究和实际系统都采用抽象虚拟机来约束不可信代码。虽然它们通常支持ISA可移植性,但它们也往往会造成性能障碍,我们可以通过直接使用机器码来避免这种障碍。在机器代码中直接表示沙盒的另一个优点是它不依赖于可信的编译器或解释器。这大大减少了可信计算基础的规模,26在本地客户端中还有一个好处,就是将系统开放给第三方工具链。

本地客户端应用了在研究文献中广泛讨论的软件故障隔离概念。我们的数据完整性方案是在Intel 80386中实现的分段内存的直接应用。6我们的控制流完整性技术基于Wahbe、Lucco、Anderson和Graham的开创性工作,27也运用了McCamant和Morrisett所描述的技术。16

在Web内容中使用本地代码最普遍的方式可能是通过微软的ActiveX。7ActiveX控件依赖于一个信任模型来提供安全性,控件使用微软专有的Authenticode系统进行加密签名,17只有当用户表示他们信任发布者时才允许运行。这种依赖于用户做出谨慎的信任决策的做法通常被利用。ActiveX不保证受信任控件的安全。即使控件本身没有内在的恶意,也可以利用控件中的缺陷,通常允许执行任意代码。相反,Native Client被设计用来防止这种剥削,即使是有缺陷的NaCl模块。

回到顶部

7.结论

本文描述了Native Client,这是一个将不受信任的x86本机代码合并到运行在Web浏览器中的应用程序中的系统。除了创建防止不良副作用的屏障之外,Native Client还支持跨操作系统和跨Web浏览器移植的模块,并支持面向性能的特性,如线程和向向量化指令。我们认为NaCl内部沙盒是非常坚固的;无论如何,我们提供了额外的冗余机制来提供纵深防御。

根据我们的经验,我们发现将现有的Linux/ gcc代码移植到Native Client是很简单的,而且对沙箱的性能损失很小,特别是在系统设计为计算绑定的场景中。

通过在这里描述Native Client并将其作为开放源码提供,我们希望鼓励社区审查和贡献。我们相信,这些反馈加上我们持续的努力,将使我们能够创建一个比以前的本地代码Web技术更安全的系统。

回到顶部

致谢

许多人为Native Client的方向和发展做出了贡献;我们在这里感谢其中的一些人。该项目是基于Matt Papakipos的想法。Jeremy Lau、Brad Nelson、John Grabowski、Kathy Walrath和Geoff Pike为系统的实施和评估做出了有价值的贡献。还要感谢丹尼·柏林、克里斯·迪博纳和丽贝卡·沃德。Doug Evans负责我们的GDB实现。我们感谢Sundar Pichai和Henry Bridge对项目方向的塑造所发挥的作用。我们也要感谢Dick Sites对本文早期版本的周到反馈。

回到顶部

参考文献

1.Accetta, m.a., baron, R., Bolosky, W., Golub, D., Rashid, R., Tevanian, A., Young, M.。Mach: UNIX开发的新内核基础.1986年,93112年。

2.为android开发安全的移动应用程序。http://isecpartners.com/files/iSEC_Securing_Android_Apps.pdf, 2008年。

3.Campbell, K., Gordon, L., Loeb, M., Zhou, L.公开宣布的信息安全漏洞的经济成本:来自股票市场的经验证据。11 . c, 3(2003), 431448。

4.Cheriton, D.R. V分布式系统。Commun。ACM 31(1988), 314333。

5.科恩,联调局电脑病毒深度防御。Comp。安全内核。11, 6(1993), 565584。

6.克劳福德,J. Gelsinger, P。编程80386.认真Inc .(1991)。

7.丹宁,一个。ActiveX控件Inside Out.微软出版社(1997年5月)。

8.指挥、控制、通信和计算机系统理事会,美国国防部联合参谋部。通过纵深防御保障信息。技术报告,指挥、控制、通信和计算机系统理事会,美国国防部联合参谋部,2000年2月。

9.Douceur, J.R., Elson, J.R., Howell, J.R., Lorch, J.R.利用遗留代码在web上部署桌面应用程序。在2008年操作系统设计与实现研讨会论文集(2008年12月)。

10.Ford, B., Cox, R. Vx32: x86上的轻量级用户级沙箱。在2008 USENIX年度技术会议(2008年6月)。

11.Goldberg, I., Wagner, D., Thomas, R. brewer, E.A.为不受信任的助手应用程序提供的安全环境。在第六届USENIX安全研讨会论文集(1996)。

12.Golub, D., Dean, A., Forin, R., Rashid, R. UNIX作为应用程序。在1990年夏季USENIX会议记录(1990), 8795。

13.Joy, W., Cooper, E., Fabry, R., Leffler, S., McKusick, K., Mosher, D. 4.2 BSD系统手册。技术报告,计算机系统研究组,加州大学伯克利分校,1983年。

14.卡巴斯基,K., Chang, A.,通过英特尔CPU bug远程代码执行。在Hack In The Box (HITB) 2008马来西亚会议

15.McCamant, S., Morrisett, G. CISC架构的高效、可验证的二进制沙箱。技术报告MIT-CSAIL-TR-2005030, 2005。

16.McCamant, S., Morrisett, G.评估CISC架构的SFI。在第十五届USENIX安全研讨会(2006年8月)。

17.微软公司。使用Authenticode签名和检查代码。http://msdn.microsoft.com/en-us/library/ms537364 (VS.85) . aspx

18.微软公司。结构化异常处理。http://msdn.microsoft.com/en-us/library/ms680657 (VS.85) . aspx, 2008年。

19.网景公司。Gecko插件API参考。http://developer.mozilla.org/en/docs/Gecko_Plugin_API_Reference

20.N.通过系统调用策略提高主机安全性。在USENIX安全研讨会(2003年8月)。

21.Reinders, J。英特尔线程构建模块.奥莱利律师事务所,2007年。

22.今年计算机病毒的成本已经超过100亿美元。ChannelWeb2001年8月。

23.MiSFIT:用于构造安全的可扩展c++系统的工具。在第三届面向对象技术USENIX会议论文集(1997年6月)。

24.Stroustrup B。c++编程语言:第二版.addison - wesley, 1997年。

25.Tarreau, W. ptrace文件。http://www.linuxhq.com/kernel/v2.4/36rc1/Documentation/ptrace.txt, 2007年。

26.美国国防部计算机安全中心。可信计算机系统评价标准,1985年12月。

27.Wahbe, R., Lucco, S., Anderson, t.e., Graham, S.L.高效的基于软件的故障隔离。ACM SIGOPS打开。Sys。启27, 1993.12, 203216。

回到顶部

作者

伊班纳特,谷歌,Inc., Mountainview, CA

大卫Sehr,谷歌,Inc., Mountainview, CA

格里高利Dardyk,谷歌,Inc., Mountainview, CA

j·布拉德利陈,谷歌,Inc., Mountainview, CA

罗伯特Muth,谷歌,Inc., Mountainview, CA

Tavis听完,谷歌,Inc., Mountainview, CA

志贵Okasaka,谷歌,Inc., Mountainview, CA

Neha Narula,谷歌,Inc., Mountainview, CA

尼古拉斯Fullagar,谷歌,Inc., Mountainview, CA

回到顶部

脚注

a.我们使用“NaCl”作为本地客户端系统的形容词。

b。https://wiki.mozilla.org/Plugins:PlatformIndependentNPAPI

c。http://gcc.gnu.org

d。http://www.gnu.org/software/binutils/

e。http://sourceware.org/newlib/

从f。http://www.libsdl.org

这篇论文的前一个版本发表在2009年IEEE安全与隐私研讨会论文集, 2009年5月。

DOI: http://doi.acm.org/10.1145/1629175.1629203

回到顶部

数据

F1图1。假设NaCl-Based应用程序。不可信模块的背景是灰色的。

F2图2。图1中的假想应用程序带有一个受信任的存储服务。

F3图3。SPEC2000性能。“Align32”结果用于具有对齐的32字节指令块的二进制文件。“Nacl32”的结果是针对NaCl二进制的。相对于使用静态链接的标准编译,两者的性能都有所提高。

回到顶部

T1表1。Nacl二元化合物的约束条件。

T2表2。地震性能比较。数字以每秒帧数表示。

回到顶部


©2010 acm 0001-0782/10/0100 $10.00

允许制作本作品的全部或部分的数字或硬拷贝用于个人或课堂使用,但前提是该拷贝不是为了盈利或商业利益而制作或分发,并且该拷贝在第一页上带有本通知和完整引用。以其他方式复制、重新发布、在服务器上发布或重新分发到列表,需要事先获得特定的许可和/或付费。

数字图书馆是由计算机协会出版的。版权所有©2010 ACM有限公司


没有发现记录

Baidu
map