Proposal: Generalized Security Framework for X server

Eamon Walsh ewalsh@epoch.ncsc.mil
03 Mar 2004 19:19:38 -0500


--=-3jCRHILicid20yNGvlv4
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

xserver developers:

I have been working on a server extension which replaces the old
"Security" extension with a framework of callbacks and security state,
similar to the Linux Security Module in the Linux kernel.  The attached
proposal describes it in more detail, including code examples.

I work for the NSA Security-Enhanced Linux team, and this extension is
the foundation upon which we hope to implement SELinux support for X. 
However, it can be generally used to implement a wide variety of models
for access control and auditing.

I have been working from the xserver CVS head and am reaching the point
where I have usable-but-experimental code.  With list support, I would
like to post patches for review.

Comments on the proposal?

Eamon Walsh
National Security Agency


--=-3jCRHILicid20yNGvlv4
Content-Disposition: inline
Content-Description: Forwarded message - Re: FREENIX, X Server security
	extension, and Freedesktop.org
Content-Type: message/rfc822

Received: from jazzswing.ncsc.mil (jazzswing.ncsc.mil [144.51.68.65]) by
	epoch.ncsc.mil (8.12.8/8.12.8) with ESMTP id i23N8QjP002002 for
	<ewalsh@epoch.ncsc.mil>; Wed, 3 Mar 2004 18:08:26 -0500 (EST)
Received: from jazzswing.ncsc.mil (localhost [127.0.0.1]) by
	jazzswing.ncsc.mil  with ESMTP id i23N6j6Q018941 for
	<ewalsh@epoch.ncsc.mil>; Wed, 3 Mar 2004 23:06:46 GMT
Received: from home.keithp.com ([63.227.221.253]) by jazzswing.ncsc.mil 
	with ESMTP id i23N6j5t018938 for <ewalsh@epoch.ncsc.mil>; Wed, 3 Mar 2004
	23:06:45 GMT
Received: from sendmail (helo=evo.keithp.com) by home.keithp.com with
	local-esmtp (Exim 3.36 #1 (Debian)) id 1AyfTO-0002fN-01; Wed, 03 Mar 2004
	15:08:18 -0800
Received: from keithp (helo=evo.keithp.com) by evo.keithp.com with
	local-esmtp (Exim 3.36 #1 (Debian)) id 1AyfF7-0000G3-00; Wed, 03 Mar 2004
	14:53:33 -0800
X-Mailer: exmh version 2.3.1 11/28/2001 with nmh-1.1-RC1
To: Eamon Walsh <ewalsh@epoch.ncsc.mil>
Cc: keithp@keithp.com, bart@cs.pdx.edu
Subject: Re: FREENIX, X Server security extension, and Freedesktop.org 
From: Keith Packard <keithp@keithp.com>
In-Reply-To: Your message of "03 Mar 2004 14:52:11 EST." <1078343531.32358.67.camel@moss-tarheels.epoch.ncsc.mil> 
Mime-Version: 1.0
Content-Type: multipart/signed; boundary="==_Exmh_1641863826P"; micalg=pgp-sha1; protocol="application/pgp-signature"
Content-Transfer-Encoding: 7bit
Date: Wed, 03 Mar 2004 14:53:33 -0800
Message-Id: <E1AyfF7-0000G3-00@evo.keithp.com>
Sender: Mail Forwarding <sendmail@keithp.com>

--==_Exmh_1641863826P
Content-Type: text/plain; charset=us-ascii


Around 14 o'clock on Mar 3, Eamon Walsh wrote:

> Do you think the freedesktop X community would be interested in hosting
> this work on an experimental basis?  I have attached a proposal similar
> to the FREENIX abstract but with the SELinux/kernel stuff stripped out.

Freedesktop is pretty open to any project related to the open source 
desktop, which this obviously is.

Anything which generalizes the existing security bits and makes the 
resulting code look better would be welcome.

-keith



--==_Exmh_1641863826P
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Exmh version 2.3.1 11/28/2001

iD8DBQFARmHtQp8BWwlsTdMRAuxcAJ921jdcVAKsz3S9ldHiHgLtYa0tlwCgr4oi
tcRVZT1LQgwXTGEn8lLKA7Q=
=a5nf
-----END PGP SIGNATURE-----

--==_Exmh_1641863826P--

--=-3jCRHILicid20yNGvlv4
Content-Disposition: attachment; filename=XSMproposal.txt
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; name=XSMproposal.txt; charset=UTF-8

Proposal: Generalized Security Framework for X Server
Date: 3 March 2004

Author: Eamon Walsh <ewalsh@epoch.ncsc.mil>
Organization: NSA SELinux Team


Summary

In the Linux kernel, the Linux Security Module [3] provides the
ability to implement arbitrary kernel security extensions.  LSM does
this by providing hook functions which can be used to arbitrate access
at key points in the kernel.  LSM also provides space to store
security labels which are associated with kernel objects.

We've been working on a similar type of thing for the X Server,
implemented as an extension.  It is based on the current "Security"
extension [1].  The remainder of this paper describes how it works.
It is a general security framework, which could be used to make
extensions that do:

- What the original Security extension does
- Auditing
- Multi-level security (MLS)
- Jail-style restrictions (clients can see some resources, but not others)
- Trusted window labeling (requires trusted window manager)
- SELinux (type enforcement and role-based access control) support for X [2=
]

The extension is called the "X Security Module" right now but this
could be changed (there is also an "X Session Manager" which could
create confusion).

We are interested in having an X Server development project host this
work on an experimental basis, in the hope that it gains use as the
preferred X Server for use on trusted platforms (such as SELinux
kernel-based Linux distributions).


How It Works

The X server already has most of what is needed.  The Security
extension has code at key points in the dix and os layers.  It also
has fields in the Client and ExtensionEntry structures where it stores
some state (an authId, a trustLevel, and a callback function pointer
in the case of the client).

The X server also has a resource manager that assigns a resource ID to
most server objects.  The resource ID allows you to determine which
client owns the resource.  The current Security extension controls
access to resources (using its simple two-level trust model) via a
callback function that gets called on each resource access.

Basically, the X Security Framework replaces the simple two-level
trust model of the Security extension with a more general facility
that can be used by other extensions which provide their own callback
functions and security state (labeling).


Security State

The Security extension has these fields in the client structure:

#ifdef XCSECURITY
    XID         authId;
    unsigned int trustLevel;
    pointer (* CheckAccess)(
            ClientPtr /*pClient*/,
            XID /*id*/,
            RESTYPE /*classes*/,
            Mask /*access_mode*/,
            pointer /*resourceval*/
    );
#endif

The XSM replaces these with more general state pointers:

#ifdef XSM
    pointer securityState[NUM_SLOTS];
#endif

Extensions can register themselves at init time via a call to
XSMRegisterExtension(), which returns an index number into the
securityState array.  The extension can then allocate some memory and
store whatever it wants there, freeing the memory using a
ClientStateCallback when the client exits.  (The number of extensions
that can store security state is limited by the value of NUM_SLOTS).

The same type of securityState array replaces the "Bool secure" field
in the ExtensionEntry structure.  Extensions can use the same index
number and initialize the security state through a generalized
DeclareExtensionSecurity() callback.  This part of XSM is still under
development though; the DeclareExtensionSecure() call still only takes
a boolean secure/insecure value, and not all extensions call this
function.


Security Callbacks

Wherever the Security extension has code in the dix and os layers that
does a check, we can instead have code that simply marshals arguments
and calls a CallbackList.  For example, in ProcQueryExtension()
(dix/extension.c) right now we have:

        i =3D FindExtension((char *)&stuff[1], stuff->nbytes);
        if (i < 0
#ifdef XCSECURITY
            /* don't show insecure extensions to untrusted clients */
            || (client->trustLevel =3D=3D XSecurityClientUntrusted &&
                !extensions[i]->secure)
#endif
            )
            reply.present =3D xFalse;
        else
        {
            reply.present =3D xTrue;
	    ...


XSM replaces this with:


        i =3D FindExtension((char *)&stuff[1], stuff->nbytes);
        if (i < 0
#ifdef XSM
            /* call callbacks to find out whether to show extension */
            || !XSMHook(XSM_EXT_ACCESS, client, extensions[i])
#endif
            )
            reply.present =3D xFalse;
        else
        {
            reply.present =3D xTrue;
	    ...

The first argument to SecmodHook() is the type of security event.  XSM
maintains a CallbackList for each event type.  The remaining arguments
are marshalled into a structure along with a return value field that
is the return value of SecmodHook().  This structure gets passed to
the callback functions.

XSM provides a RegisterCallback() function that extensions can use to
add a callback function for a given event.  Each callback function can
examine the fields of the structure and set the result field based on
whether or not it wishes to allow access.  Where there are multiple
callbacks, each callback is supposed to honor the decisions of the
others (i.e. not set the return value to TRUE if it was previously
changed to FALSE by someone else).

Note that the callback function can make its decision based on the
security state it has stored in the Client and ExtensionEntry
structures.

Here is a description of all the security hooks currently in XSM.
Adding another one is a matter of adding another symbolic constant and
structure to XSM and placing a call to XSMHook() at the appropriate
place in the server code.

XSM_RESOURCE_ACCESS
	Arguments: client, resourceID, resourceType, accessMode, resourcePtr
	Arbitrates access to resources.
XSM_DEVICE_ACCESS
	Arguments: client, devicePtr, bool fromRequest
	Arbitrates access to devices.
XSM_PROPERTY_ACCESS
	Arguments: client, window, propertyName, accessMode
	Arbitrates access to properties.
XSM_DRAWABLE_ACCESS
	Arguments: client, drawablePtr
	Arbitrates access to drawable contents.
XSM_MAP_ACCESS
	Arguments: client, windowPtr
	Arbitrates ability to map windows.
XSM_BACKGRND_ACCESS
	Arguments: client, windowPtr
	Arbitrates ability to create background-None windows
XSM_EXT_ACCESS
	Arguments: client, extensionEntry
	Arbitrates access to server extensions
XSM_HOST_ACCESS
	Arguments: client
	Arbitrates ability to change host access list
XSM_SITE_POLICY
	Arguments: char *policyString
	Facility for indicating support of a certain site policy
XSM_DECLARE_EXT_SECURE
	Arguments: extensionEntry, bool secureflag
	Facility for extensions to indicate their secureness.
XSM_AUTH_AVAIL
	Arguments: client, authId
	Additional ClientStateCallback when the authId becomes available.

XSM_LBX_EXT_ACCESS
	Arguments: client, lbxExtensionEntry
	EXT_ACCESS equivalent for LBX
XSM_DECLARE_LBX_EXT_SECURE
	Arguments: lbxExtensionEntry, bool secureflag
	DECLARE_EXT_SECURE equivalent for LBX
XSM_LBX_PROXY_ACCESS
	Arguments: client, authID
	Checks the authorization of a client connecting through a LBX proxy.


Extension Files

In addition to the code in the dix and os layers which replaces the
XCSECURITY code, XSM has the usual extension files xsm.c xsm.h and
xsmstr.h which provide the interface used by other extensions.  It
does not currently have any client requests, events, or errors defined
(i.e. no changes to Xlib.)  It might be necessary to have at least the
standard QueryVersion request, however.


References

[1] David Wiggins, "Security Extension Specification."
www.xfree86.org/~herrb/security.pdf

[2] SELinux papers:  http://www.nsa.gov/selinux/docs.cfm

[3] Linux Security Module:  http://lsm.immunix.org

--=-3jCRHILicid20yNGvlv4--