Skip to content

Introduction

Prerequisites

This document is targeted to programmers who are writing security extensions for X. It is assumed that the reader is familiar with the C programming language. It is assumed that the reader understands the general workings of the X protocol and X server.

Purpose

XACE makes it easier to implement new security models for X by providing a set of pluggable hooks that extension writers can use. The idea is to provide an abstraction layer between security extensions and the core DIX/OS code of the X server. This prevents security extensions writers from having to understand the inner workings of the X server and it prevents X server maintainers from having to deal with multiple security subsystems, each with its own intrusive code.

For example, consider the X.Org X server's resource subsystem, which is used to track different types of server objects using ID numbers. The act of looking up an object by its ID number is a security-relevant operation which security extension writers would likely wish to control. For one or two security extensions it may be acceptable to simply insert the extension's code directly into the resource manager code, bracketed by ifdef's. However for more extensions this approach leads to a tangle of code, particularly when results need to be logically combined, as in if statement conditions. Additionally, different extension writers might place their resource checking code in different places in the server, leading to difficulty in tracking down where exactly a particular lookup operation is being blocked. Finally, this approach may lead to unexpected interactions between the code of different extensions, since there is no collaboration between extension writers.

The solution employed by the X Access Control Extension is to place hooks (calls into XACE) at security-relevant places, such as the resource subsystem mentioned above. Other extensions, typically in their initialization routines, can register callback functions on these hooks. When the hook is called from the server code, each callback function registered on it is called in turn. The callback function is provided with necessary arguments needed to make a security decision, including a return value argument which can be set to indicate the result. XACE itself does not make security decisions, or even know or care how such decisions are made. XACE merely enforces the result of the decision, such as by returning a BadAccess error to the requesting client.

This separation between the decision-making logic and the enforcement logic is advantageous because it allows a great variety of security models to be developed without resorting to intrusive modifications to the core systems being secured. The challenge is to ensure that the hook framework itself provides hooks everywhere they need to be provided. Once created, however, a hook can be used by everyone, leading to less duplication of effort.

Prior Work

Security Extension

XACE was initially based on the SECURITY extension. This extension introduced the concept of "trusted" and "untrusted" client connections, with the trust level established by the authorization token used in the initial client connection. Untrusted clients are restricted in several areas, notably in the use of background "None" windows, access to server resources owned by trusted clients, and certain keyboard input operations. Server extensions are also declared "trusted" or "untrusted," with only untrusted extensions being visible to untrusted client connections.

Solaris Trusted Extensions

Trusted Extensions for Solaris has an X extension (Xtsol) which adds security functionality. Some of the XACE hooks in the current set were derived from security checks made by the Xtsol code. In other places, where the Xtsol and SECURITY extensions both have checks, a single XACE hook replaces both.

Linux Security Modules

XACE is influenced by the Linux Security Modules project, which provides a similar framework of security hooks for the Linux kernel.

Version 2.0 Changes

Different Return-Value Semantics

The status value returned by security modules has been changed. Formerly, security modules were expected to set the "rval" field of the input structure to "False" if access was to be denied. In version 2.0, this field has been removed in all hooks. Security modules must now set the "status" field to an X error code to describe the error. Typically, BadAccess will be returned, but this change allows security modules to return BadAlloc to report memory allocation failure and BadMatch to report a polyinstantiated object lookup failure (the section called “Polyinstantiation”).

DevPrivates Mechanism

The devPrivates mechanism in the X server was substantially revised to better support security extensions. The interface for using devPrivates has been unified across the different structures that support private data. Private space allocation is now independent of whether objects have already been created, and the private indexes are now global rather than being structure specific. Callbacks are available to initialize newly allocated space and to clean up before it is freed. Finally, there is a mechanism for looking up the offset of the private pointer field in a structure, given the structure's resource type.

New Access Modes

In the previous version, there were four possible modes for the "access_mode" field: read, write, create, and destroy. In version 2.0, many new modes have been introduced to better describe X operations, particularly on window objects. The access_mode field has also been added to additional hooks as described in the individual hook changes.

Polyinstantiation

XACE now supports polyinstantiation of selections and window properties. the section called “Property Access” and the section called “Selection Access” describe the details, but the basic idea is that the property and selection access hooks may be used to not only change the return value of a lookup operation but also to modify the lookup result. This allows more than one property or selection with the same atom name to be maintained.

Removed Hooks

The "drawable," "map," "window init", and "background" hooks have been removed. They have been folded into the resource access hook using new access modes. The "hostlist" hook has been removed and replaced by a new server access hook (see the section called “Server Access”). The "site policy" and "declare extension security" hooks have been removed as the SECURITY extension has been revised to no longer require them.

New Hooks

New "send" and "receive" hooks have been added to allow basic control over event delivery. "Client" and "server" access hooks have been added to control access by clients to other clients (for example, through the KillClient call) and to the server (for example when changing the host access list or changing the font path). "Screen" and "screen saver" hooks have been added to control access to screens and screen saver requests. A "selection" hook has been added to control access to selections.

Changes to Existing Hooks

  • The resource access hook structure now has additional fields to describe a "parent" object. They are set only when a resource with a defined parent (such as a Window object) is being created, in which case the access mode will include DixCreateAccess.

  • The device access hook structure has had the "fromRequest" field removed and an access mode field added.

  • The property access hook structure has had the "propertyName" field removed and a "ppProp" field added, which contains a pointer to a pointer to the property structure itself. The extra level of indirection supports polyinstantiation (see the section called “Polyinstantiation”). Note that the property structure contains the property name.

  • The extension dispatch/access hook structure now has an access mode field.

Future Work

Security Hooks

It is anticipated that the set of security hooks provided by XACE will change with time. Some hooks may become deprecated. More hooks will likely be added as well, as more portions of the X server are subjected to security analysis. Existing hooks may be added in more places in the code, particularly protocol extensions. Currently, the only method XACE provides for restricting access to some protocol extensions is to deny access to them entirely.

It should be noted that XACE includes hooks in the protocol dispatch table, which allow a security extension to examine any incoming protocol request (core or extension) and terminate the request before it is handled by the server. This functionality can be used as a stopgap measure for security checks that are not supported by the other XACE hooks. The end goal, however, is to have hooks integrated into the server proper.

Core X Server

The set of extensions supported by X.org needs to be re-examined. Many of them are essentially unused and removing them would be easier than attempting to secure them. The GLX extension and the direct rendering kernel interfaces need to be secured.

The server's routines for event delivery need to be reworked to allow greater control by XACE modules. In particular, security extensions need to be able to associate private data with each event at the time of its generation based on the context and then have that data available at a decision point just before the event is delivered to the client. This would allow event delivery to be better controlled on a per-client basis, and would potentially allow additional security extension functionality such as piggyback events.