XDC2012: Graphics stack security

LWN.net needs you! Without subscribers, LWN would simply not exist. Please consider signing up for a subscription and helping to keep LWN publishing

Martin Peres and Timothée Ravier's session on day one of XDC2012 looked at security in the graphics stack. They considered user expectations around security in the graphical user interface (GUI), reviewed these expectations against the implementations in X11 and Weston (the reference compositing window manager for Wayland), and covered some other ground as well. Martin began their presentation by noting that they had done quite a bit of research on the topic, and although they are Linux security engineers rather than X developers, he expected that they would nevertheless have useful things to tell the audience.

User security expectations and the X server

Martin began with a review of security on the X server that focused on the three classical areas: confidentiality, integrity, and availability. In each case, he described security weaknesses in the X server.

Starting with confidentiality issues, Martin used the example of a user entering a credit card number while shopping online. In this case, the credit card number could be stolen if a key logger was running on the machine, or another program was taking screen shots periodically. This violates the user's expectations of the GUI: applications should not be able to spy on each other's input events or output buffers. From the user's point of view, the only time that arbitrary applications should obtain information from one another is under explicit user control (for example, cut-and-paste). However, under X11, any application that can provide the magic cookie generated by the X server has full access to other applications' input and output. In other words, X11 provides isolation only between users, not between applications run by the same user. Thus, any application that is launched by the user has the potential to break confidentiality in the manner of the credit card example.

Martin's second example concerned application integrity. A user visits a bank web site, and, being a sophisticated user, carefully checks that the URL shown in the browser's address bar shows "https" plus the correct domain. However, the user is unaware that they are visiting a fake domain, and that the browser's address bar has been redrawn by a malicious application. Consequently, the user's bank information is passed to a third party. This can happen under X11's Digital Rendering Infrastructure (DRI) version 1. (This problem is addressed in DRI2, which has been the default for a few years now.) In addition, virtual keyboards can inject input to the X server; since the X server broadcasts input events, the virtual-keyboard input can reach any application (just like a real keyboard).

Martin's third point was that applications should not be able to make other applications or the entire system unavailable. Under X11, applications can, however, act as screen lockers, denying access to the system. In addition, in the past, a virtual keyboard was able to kill other applications using the XF86ClearGrab feature that was introduced in X server 1.11 (a feature that led to a high-profile security flaw that made it possible to break into a screen-locked system by typing a particular key combination).

Mitigating X server security issues

At this point, Timothée took the lead to discuss techniques that have been developed to mitigate these security problems. The first of the approaches that he described was XSELinux. XSELinux provides finer-grained control within the X server, allowing control over features such as drag-and-drop or access to the mouse. However, the level of control provided by XSELinux is still too coarse-grained to be useful: it allows per-application control of access to X features, but cannot (for example) restrict input to the currently selected application. Consequently, it is either not provided, or disabled, in most distributions. A sometimes recommended alternative for confining applications that use the X server is Xephyr, which implements sandboxing by launching an X server inside another X server. Although this provides a good degree of isolation between applications in different sandboxes, a sandboxing solution has problems of its own: it becomes complicated to share information between applications in different sandboxes.

Timothée went on to describe two projects that have tried, in different ways, to bring greater security to the X server: QubesOS and PIGA-OS. Both of these projects aim to confine applications, control which applications can access input buffers of other applications, and so on.

QubesOS groups applications into "domains" that have similar levels of security. Each domain runs its X server in a separate Xen virtual machine. For example, surfing the web in a browser would be conducted in a low-security domain, while reading corporate email is done in a separate, higher-security domain. Functionality such as cut-and-paste and drag-and-drop between domains is provided by means of a daemon that runs in the privileged dom0 virtual machine that implements mandatory access control. QubesOS provides a high degree of isolation between applications.

However, Timothée described a number of drawbacks to QubesOS. It requires many virtual machines, which results in slow performance on desktop and laptop systems. It is not feasible on mobile systems, because of heavy resource-usage requirements and the almost-mandatory requirement for hardware-assisted virtualization in order to achieve satisfactory performance. Furthermore, one can't be sure that Xen can isolate virtual machines, so there might be ways to access buffers in other virtual machines.

PIGA-OS [PDF], a system that Martin and Timothée have worked on, takes a different approach from QuebesOS. Each application is placed in a separate SELinux domain and XSELinux is used to provide confinement in the X server. SELinux plus XSELinux provide many of the pieces needed for a secure X server, but some pieces are still missing. Therefore, PIGA-OS adds a daemon, PIGA-SYSTRANS, that grants rights to applications and prompts users when they switch between different domains as a consequence of their activities.

PIGA-OS has some notable advantages. It does not require virtual machines. It dynamically adjusts (under user control) the permissions of applications according to the user's activity. However, a significant downside of the PIGA-OS approach is that it requires quite some effort to set up the global SELinux policy that governs applications and activities. (This is a one-time effort, but the policy must be updated if an application acquires new features that require new types of privileged access.)

Wayland and Weston

Timothée then turned to the subject of the Wayland, the display server protocol posited as a replacement for X11, and Weston, the reference implementation of the compositing window manager for Wayland. His goal was to look at how Wayland and Weston have fixed some of the problems of the X server described above and outline the problems that remain.

Timothée divided up the discussion of security somewhat differently in this part of the presentation, beginning by talking about the security of input in Wayland/Weston. On this front, the new system is in good shape. Because Weston knows where applications are on the screen, it is able to decide which application should receive input events (this differs from the X server). This defeats key logging applications. Regarding integrity of input, the kernel limits access to the two main sources ( /dev/input and /dev/uinput ) to the root user only. Because Wayland/Weston does not (yet) support virtual keyboards it is not (yet) possible to forge input. (The topic of virtual keyboards was revisited later in the talk.)

On the output side, Timothée observed that Weston does have some problems with confidentiality and integrity. Weston uses the Graphics Execution Manager (GEM) to share application buffers between the compositor and applications. The problem is that GEM buffers are referenced using handles that are 32-bit integers. These handles can be guessed (or brute-forced), which means that one application can easily access GEM buffers belonging to other applications. Martin noted that this problem would be resolved if and when Weston moved to the use of DMABUF (DMA buffer sharing).

Timothée then considered how Weston should deal with applications that need exceptional handling with respect to security. The first of these that he covered was virtual keyboards, which are pseudo-devices that are permitted to send input events to the compositor. He made the general point that virtual keyboards should be "included" in the compositor, so that the compositor knows that it can trust the input they provide. Peter Hutterer raised a potential problem: each natural language (with a unique character set) requires its own virtual keyboard, and it seems that every few months someone starts a new virtual keyboard project for another language, with the result that adding keyboards to the compositor would be a never-ending task. In response, Timothée and Martin refined what they meant by "include". The compositor must not trust just any application to be a virtual keyboard. Rather, since the compositor knows which applications it is launching, it can choose which applications it will trust as virtual keyboards. Peter agreed with this approach but noted that there may be some (solvable) complexities, since, when dealing with a multilingual user, a switch from one language to another may involve not only a switch of virtual keyboards, but also a switch of the background framework that generates input events.

Weston does not yet support screen-shot applications, but when that support is added, some care will be needed to avoid confidentiality issues. Timothée's proposal was similar to that for virtual keyboards: the compositor would allow only trusted applications that it has launched to make screen shots. Again, there must be a method for specifying which applications the compositor should trust for this task.

Global keyboard shortcuts present a further problem. For example, media players commonly use keyboard shortcuts to provide functionality such as pausing or skipping to the next track. Typically, media players are not visible on the screen, and so do not receive input events directly. Therefore the compositor needs a way of registering special keystroke combinations and passing these to applications that have registered them. The problem is that this sort of functionality can allow the implementation of a different kind of key logger: a malicious application could register itself for many or all keystroke combinations. Again, there needs to be a way of specify which applications are allowed to register global keyboard shortcuts, and perhaps which keystroke combinations they may register. Further complicating the problem is the fact that the user may change the global keyboard shortcuts that an application uses. Timothée said they had no solution to offer for this problem.

Peter Hutterer suggested what he called a "semantic approach" to the problem, but noted that it would require a lot more code. Instead of allowing applications to register keystroke combinations, the compositor would maintain a global registry where applications would register to say that they want to be notified for events such as "undo" or "cancel", and the compositor would control the key that is assigned to the event. This has the potential advantage that shortcuts could be consistent across applications. On the other hand, there will likely be conflicts between applications over deciding which events are which. Peter noted that the GTK project is currently doing some work in this area, and it may be worth contacting people working on that project.

The situation with screen-locking applications is similar to screen-shot applications. Currently, Weston does not support screen locking, but when that support is added, there should be the notion of having a restricted set of applications that the compositor permits to lock the screen. Indeed, since the screen-locking code is typically small, and the requirements are fairly narrow (so that there is no need for multiple different implementations), it may be sensible to implement that functionality directly inside the compositor.

Timothée summarized the proposals for controlling application security in Wayland and Weston. There should be a mandatory access control (MAC) framework as in the X Access Control Extension (XACE). Suitable hooks should be placed in the code to allow control of which applications can interact with one another and interact with Wayland to perform operations such as receiving input. The MAC framework should be implemented as a library, so that access control is unified across all Wayland compositors.

Rootless Weston

Traditionally, the X server has had to run with root privileges. Because the X window system is a large body of complex—and, in many cases, ancient—code, the fact that that code must run as root creates a window for attacks on a system. For this reason, it has long been a goal to rework the system to the point where root privilege is no longer need to run the X server. Although some progress has been made toward that goal , there is as yet no general solution the problem, and the X server still normally requires root privileges to run. The question then is how to avoid repeating this situation going forward, so that Weston does not require root privileges.

Timothée ran through some of the factors blocking rootless Weston. One problem is that Weston needs access to /dev/input , which is accessible only to root. Root privilege is also required to send output to the screen and to support hot plugging of keyboards and screens. The solution he proposed was to isolate the code that requires root privileges into a separate small executable that is run with root privileges. In the case where Weston needed access to a privileged file, the small executable would then open the required file and pass a file descriptor via a UNIX domain socket to Weston. There was little comment on this proposal, which may signify that it seemed reasonable to everyone present.

Hardware and driver security

Martin returned to the microphone to talk about hardware and driver security. He began with the simple observation that graphics drivers and hardware should not allow privilege escalation (allowing a user to gain root access) and should not allow one user to read or write graphics buffers belonging to another user. Various platforms and drivers don't live up to these requirements. For example, on the Tegra 2 platform, the GPU permits shader routines to have full read and write access to all of the video RAM or all of the graphics-hosting RAM. Another example is the NVIDIA driver, which provides unprivileged users with access to nearly all of the GPU registers.

Martin emphasized the need for a sane kernel API that isolates GPU users and doesn't expose GPU registers to unprivileged users. GPU access to RAM also needs to be restricted, in order to prevent the GPU from accessing kernel data structures. (The lack of such a restriction was the source of the recent vulnerability in the NVIDIA driver that allowed root privilege escalation.)

One approach to isolating GPU users would be to apply a virtual-memory model to video memory, so that applications cannot touch each other's memory. This approach provides the best security, but the problem is that it is not supported by all graphics hardware. In addition, implementing this approach increases context-switching times; this is a problem for DRI2, which does a lot of context switching, and for Qt5, where all applications that use QML (which is the recommended approach) have an OpenGL context. The Nouveau driver currently takes this approach, and some other modern GPUs are also capable of doing so.

An alternative approach for isolating GPU users is for the kernel to validate the user commands submitted to the GPU, in order to ensure that they touch only memory that belongs to the user. This approach has the advantage that it can be implemented for any graphics hardware and context-switching costs are lower. However, it imposes a higher CPU overhead. Currently the Radeon and Intel drivers take this approach.

Moving to another topic, Martin observed that a GPU buffer is not zeroed when it is allocated, meaning that the previous user's data is visible to the new user. This could create a confidentiality issue. The problem is that zeroing buffers has a heavy performance impact. He suggested two strategies for dealing with this: zeroing deallocated buffers when the CPU is idle and using the GPU to perform zeroing of buffers. Lucas Stach pointed out that even if one of these strategies was employed, on embedded devices the memory bandwidth required for zeroing buffers was simply too great. Martin accepted the point, and noted that the goal was to allow the user to choose the trade-off between security and performance.

The final topic of the presentation concerned plug-ins. Since the compositor has full access to input events and application output buffers, this means that compositor plug-ins potentially have the same access, so that a (possibly malicious) plug-in could cause a security vulnerability. Martin said that they didn't have too many concrete proposals on how to deal with this, beyond noting that, whenever possible, plug-ins should not have access to user inputs and output buffers. He suggested that address-space layout randomization inside the GPU virtual memory may help, along with killing applications that access invalid virtual addresses.

In some concluding discussion at the end of the session, Matthieu Herrb remarked that most X11 applications are not ready to handle errors from failed requests to the X server, and that if the graphics server is going to implement finer-grained access control, then it's important that applications have a good strategy for handling the various errors that may occur. Martin agreed, adding "We don't want to fix X; it's not possible. We can't ask people to rewrite [applications]. But with Wayland being new, we can do things better from day one."

Summary

From the various comments made during the presentation, it's clear that the X developers are well aware of the security problems in X11. It's equally clear that they are keen to avoid making the same mistakes in Wayland and Weston.

The X.Org wiki has pointers to the slides and video for this presentation, as well as pointers to the slides and video for a follow-on security-related presentation (entitled "DRM2").

