天天看点

display: XDC2012: Graphics stack security

在XDC2012的第一天,Martin Peres和TimothéeRavier的会议探讨了图形堆栈中的安全性。他们考虑了用户对图形用户界面(GUI)中安全性的期望,并针对X11和Weston(Wayland的参考合成窗口管理器)中的实现回顾了这些期望,并涵盖了其他一些方面。 Martin在开始演讲时指出,他们已经对该主题进行了大量研究,尽管他们是Linux安全工程师而不是X开发人员,但他希望他们仍然可以向听众提供有用的信息。

User security expectations and the X server

Martin首先回顾了X服务器上的安全性,重点是三个经典领域:机密性,完整性和可用性。在每种情况下,他都描述了X服务器中的安全漏洞。

从机密性问题开始,马丁以用户在网上购物时输入信用卡号为例。在这种情况下,如果在计算机上运行按键记录器,或者另一个程序定期进行屏幕截图,则信用卡号可能会被盗。这违反了用户对GUI的期望:应用程序不应能够监视彼此的输入事件或输出缓冲区。从用户的角度来看,任意应用程序都应从彼此获取信息的唯一时间是在明确的用户控制下(例如,剪切和粘贴)。但是,在X11下,任何可以提供X服务器生成的魔术cookie的应用程序都可以完全访问其他应用程序的输入和输出。换句话说,X11仅提供用户之间的隔离,而不提供同一用户运行的应用程序之间的隔离。因此,用户启动的任何应用程序都可能以信用卡示例的方式破坏机密性。

Martin的第二个示例涉及应用程序完整性。用户访问银行网站,作为高级用户,请仔细检查浏览器地址栏中显示的URL是否显示“ https”以及正确的域。但是,用户不知道他们正在访问伪造的域,并且浏览器的地址栏已被恶意应用程序重绘。因此,用户的银行信息被传递给第三方。这可能在X11的数字渲染基础结构(DRI)版本1下发生。(此问题已在DRI2中得到解决,这已经是几年来的默认设置了。)此外,虚拟键盘可以将输入注入X服务器。由于X服务器广播输入事件,因此虚拟键盘输入可以到达任何应用程序(就像真实的键盘一样)。

Martin的第三点是,应用程序不应使其他应用程序或整个系统。但是,在X11下,应用程序可以充当屏幕locker,从而拒绝访问系统。此外,过去,虚拟键盘能够使用X服务器1.11中引入的XF86ClearGrab功能杀死其他应用程序(该功能导致引人注目的安全漏洞,使系统有可能进入锁屏状态,通过键入特定的组合键)。

Mitigating X server security issues

此时,蒂莫斯(Timothée)率先讨论了为缓解这些安全问题而开发的技术。他描述的第一种方法是XSELinux。 XSELinux在X服务器中提供了更细粒度的控制,从而可以控制诸如拖放或鼠标访问之类的功能。但是,XSELinux提供的控制级别仍然太粗糙而无法使用:它允许按应用程序控制对X功能的访问,但不能(例如)将输入限制为当前选定的应用程序。因此,在大多数发行版中都未提供或禁用它。对于限制使用X服务器的应用程序,有时推荐的替代方法是Xephyr,它通过在另一台X服务器内部启动X服务器来实现沙箱。尽管这提供了不同沙箱中的应用程序之间的高度隔离,但是沙箱解决方案有其自身的问题:在不同沙箱中的应用程序之间共享信息变得很复杂。

Timothée继续描述了两个尝试以不同方式为X服务器带来更高安全性的项目:QubesOS和PIGA-OS。这两个项目的目的都是限制应用程序,控制哪些应用程序可以访问其他应用程序的输入缓冲区,等等。

QubesOS将应用程序分组为具有相似安全级别的“域”。每个域都在单独的Xen虚拟机中运行其X服务器。例如,在浏览器中浏览网络将在低安全性域中进行,而读取公司电子邮件则在单独的更高安全性域中进行。通过在特权dom0虚拟机中运行的守护程序提供域之间的剪切和粘贴等功能,该守护程序在实现强制访问控制的特权dom0虚拟机中运行。 QubesOS在应用程序之间提供高度隔离。

但是,Timotheee描述了QubesOS的许多缺点。它需要许多虚拟机,这会导致台式机和笔记本电脑系统性能下降。在移动系统上这是不可行的,因为需要大量的资源使用,并且为了获得令人满意的性能而对硬件辅助虚拟化几乎是强制性的要求。此外,不能确定Xen是否可以隔离虚拟机,因此可能存在访问其他虚拟机中的缓冲区的方法。

Martin和Timothée研究的PIGA-OS [PDF]系统与QuebesOS采用的方法不同。每个应用程序都放置在单独的SELinux域中,并且XSELinux用于在X服务器中提供限制。 SELinux和XSELinux提供了安全的X服务器所需的许多组件,但是仍然缺少一些组件。因此,PIGA-OS添加了守护程序PIGA-SYSTRANS,该守护程序授予应用程序权限,并在用户由于其活动而在不同域之间切换时提示用户。

PIGA-OS具有一些显着的优势。它不需要虚拟机。它根据用户的活动动态调整(在用户控制下)应用程序的权限。但是,PIGA-OS方法的一个重大缺点是,它需要付出相当大的努力才能建立起管理应用程序和活动的全局SELinux策略。 (这是一次性的工作,但是如果应用程序获得需要新类型的特权访问的新功能,则必须更新策略。)

Wayland and Weston

然后,Timothée讨论了Wayland,Wayland是替代X11的显示服务器协议,而Weston是Wayland的组合窗口管理器的参考实现。他的目标是研究Wayland和Weston如何解决上述X服务器的一些问题,并概述仍然存在的问题。

Timothée在本部分的演讲中对安全性的讨论有所不同,首先讨论了Wayland / Weston中输入的安全性。在这一方面,新系统状况良好。因为Weston知道应用程序在屏幕上的位置,所以它能够决定哪个应用程序应该接收输入事件(这与X服务器不同)。这打败了关键的日志记录应用程序。关于输入的完整性,内核仅将两个主要源(/ dev / input和/ dev / uinput)的访问权限限制为root用户。由于Wayland / Weston目前尚不支持虚拟键盘,因此尚无法伪造输入。 (虚拟键盘的主题在稍后的讨论中进行了重新讨论。)

在输出方面,Timotheee注意到Weston确实在保密性和完整性方面存在一些问题。 Weston使用图形执行管理器(GEM)在合成器和应用程序之间共享应用程序缓冲区[weibi]。问题在于,使用32位整数的句柄来引用GEM缓冲区。这些handle句柄可以猜测(或强行使用),这意味着一个应用程序可以轻松访问属于其他应用程序的GEM缓冲区。马丁指出,如果韦斯顿转而使用DMABUF(DMA缓冲区共享),将可以解决此问题。

Timothée然后考虑了Weston应该如何处理需要对安全性进行特殊处理的应用程序。他介绍的第一个工具是虚拟键盘,这是伪设备,可以将输入事件发送到合成器。他指出,虚拟键盘应该“包含”在合成器中,这样合成器知道它可以信任它们提供的输入。 Peter Hutterer提出了一个潜在的问题:每种自然语言(具有唯一的字符集)都需要使用自己的虚拟键盘,而且似乎每隔几个月就会有人为另一种语言启动一个新的虚拟键盘项目,结果是将键盘添加到了合成器中将是一项永无止境的任务。对此,蒂莫斯(Timothyée)和马丁(Martin)完善了“包含”的含义。合成器不得仅将任何应用程序视为虚拟键盘。相反,由于该合成器知道它正在启动的应用程序,因此它可以选择它将作为虚拟键盘信任的应用程序。 Peter同意这种方法,但指出可能存在一些(可解决的)复杂性,因为在与多语言用户打交道时,从一种语言切换到另一种语言可能不仅涉及虚拟键盘的切换,而且还涉及背景的切换。生成输入事件的框架。

Weston尚不支持截屏应用程序,但是添加该支持后,将需要采取一些措施以避免机密性问题。 Timothée的提议类似于虚拟键盘的提议:该合成器将只允许它已启动的受信任应用程序进行屏幕截图。同样,必须有一种方法来指定合成器应为此任务信任的应用程序。

全局键盘快捷键提出了另一个问题。例如,媒体播放器通常使用键盘快捷键来提供功能,例如暂停或跳到下一首曲目。通常,媒体播放器在屏幕上不可见,因此不会直接接收输入事件。因此,合成器需要一种注册特殊按键组合并将其传递给已注册它们的应用程序的方式。问题在于这种功能可以允许实现其他类型的按键记录器:恶意应用程序可能会为许多或所有按键组合注册自身。同样,需要一种方法来指定允许哪些应用程序注册全局键盘快捷键,以及可能指定它们可以注册的按键组合。使问题进一步复杂化的是,用户可能会更改应用程序使用的全局键盘快捷键。蒂莫斯说,他们没有解决这个问题的办法。

彼得·哈特(Peter Hutterer)提出了他所谓的“语义方法”,但是指出这将需要更多的代码。代替允许应用程序注册击键组合,合成器将维护一个全局注册表,在该注册表中,应用程序将进行注册以说他们希望针对诸如“撤消”或“取消”之类的事件得到通知,并且合成器将控制分配的键参加活动。这具有潜在的优势,即快捷方式在各个应用程序之间可以保持一致。另一方面,在决定哪个事件是哪个事件之间,应用程序之间可能会发生冲突。彼得指出,GTK项目目前正在这方面做一些工作,可能值得联系从事该项目的人员。

屏幕锁定应用程序的情况类似于屏幕截图应用程序。当前,Weston不支持屏幕锁定,但是当添加该支持时,应该有一个概念,即合成器允许锁定屏幕的应用程序数量有限。确实,由于屏幕锁定代码通常很小,并且要求也很狭窄(因此不需要多种不同的实现方式),因此在合成器内部直接实现该功能可能是明智的。

Timothée总结了在Wayland和Weston中控制应用程序安全性的建议。应该像X访问控制扩展(XACE)中那样具有强制性的访问控制(MAC)框架。应该在代码中放置合适的钩子,以控制哪些应用程序可以相互交互并与Wayland交互以执行诸如接收输入之类的操作。 MAC框架应实现为一个库,以便所有Wayland合成器之间的访问控制是统一的。

Rootless Weston

传统上,X服务器必须以root特权运行。由于X窗口系统包含大量复杂的代码,并且在许多情况下是古老的代码,因此该代码必须以root用户身份运行这一事实为攻击系统提供了一个窗口。因此,将系统重做到不再需要root特权来运行X服务器的目的一直是一个目标。尽管已朝着该目标取得了一些进展,但该问题尚无一般解决方案,并且X服务器通常仍需要root特权才能运行。然后的问题是如何避免重复这种情况,以便Weston不需要root特权。 Timothée遇到了一些阻碍rootless weston的因素。一个问题是Weston需要访问/ dev / input,只有root可以访问。还需要Root特权才能将输出发送到屏幕,并支持键盘和屏幕的热插拔。他提出的解决方案是将需要root特权的代码隔离到一个单独的具有root特权运行的小型可执行文件中。如果Weston需要访问特权文件,则小型可执行文件将打开所需文件,并通过UNIX域套接字将文件描述符传递给Weston。对该提案几乎没有评论,这可能表明它对在场的每个人似乎都是合理的。

Hardware and driver security

马丁回到麦克风上谈论硬件和驱动程序安全性。他从简单的观察开始,图形驱动程序和硬件不应允许特权升级(允许用户获得root访问权限),并且不应允许一个用户读取或写入属于另一用户的图形缓冲区。各种平台和驱动程序都不符合这些要求。例如,在Tegra 2平台上,GPU允许着色器例程具有对所有视频RAM或所有图形托管RAM的完全读写访问权限。另一个示例是NVIDIA驱动程序,该驱动程序为非特权用户提供对几乎所有GPU寄存器的访问权限。 Martin强调了一个合理的内核API的需求,该API可以隔离GPU用户并且不向非特权用户公开GPU寄存器。为了防止GPU访问内核数据结构,也需要限制GPU对RAM的访问。 (缺少这样的限制是NVIDIA驱动程序中最近的漏洞的根源,该漏洞允许升级根权限。) 隔离GPU用户的一种方法是将虚拟内存模型应用于视频内存,以使应用程序无法相互访问对方的内存。这种方法提供了最佳的安全性,但是问题是并非所有图形硬件都支持它。此外,实施此方法会增加上下文切换时间;对于进行大量上下文切换的DRI2和对于Qt5(这是所有使用QML的应用程序(推荐的方法)都具有OpenGL上下文)的Qt5,这是一个问题。 Nouveau驱动程序当前采用这种方法,而其他一些现代GPU也可以这样做。 隔离GPU用户的另一种方法是让内核验证提交给GPU的用户命令,以确保它们仅接触属于该用户的内存。这种方法的优点是可以为任何图形硬件实现,并且上下文切换成本更低。但是,这会增加CPU开销。当前,Radeon和Intel驱动程序采用这种方法。 转到另一个主题,马丁观察到GPU缓冲区在分配时并未归零,这意味着新用户可以看到先前用户的数据。这可能会导致机密性问题。问题在于调零缓冲区会严重影响性能。他提出了两种解决方案:在CPU空闲时将已分配的缓冲区清零以及使用GPU对缓冲区进行清零。 Lucas Stach指出,即使采用了其中一种策略,在嵌入式设备上,将缓冲区清零所需的内存带宽也实在太大了。 Martin接受了这一点,并指出目标是允许用户在安全性和性能之间进行权衡取舍。 演示的最后一个主题是插件。由于合成器对输入事件和应用程序输出缓冲区具有完全访问权限,因此这意味着合成器插件可能具有相同的访问权限,因此(可能是恶意的)插件可能会导致安全漏洞。 Martin表示,关于如何处理此问题,他们没有太多具体建议,除了指出,只要有可能,插件就不应访问用户输入和输出缓冲区。他建议,GPU虚拟内存内部的地址空间布局随机化可能会有所帮助,同时还会杀死访问无效虚拟地址的应用程序。 在会议结束时的一些结论性讨论中,Matthieu Herrb指出,大多数X11应用程序都没有准备好处理来自失败请求到X服务器的错误,并且如果图形服务器要实现更细粒度的访问控制,那么它就可以了。重要的是应用程序必须具有良好的策略来处理可能发生的各种错误。马丁表示同意,并补充说:“我们不想修复X;这是不可能的。我们不能要求人们重写[应用程序]。但是随着Wayland的出现,我们可以从一开始就做得更好。”

继续阅读