[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'upstream-experimental'



Rebased ref, commits from common ancestor:
commit 375908557fd11e37e8d686f1ff6a372aa2c239de
Author: Adam Jackson <ajax@redhat.com>
Date:   Thu Mar 6 00:19:09 2008 -0500

    xserver 1.4.99.901

diff --git a/configure.ac b/configure.ac
index 0f58f32..f3b238a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.4.99.900, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.4.99.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([dist-bzip2 foreign])
 AM_MAINTAINER_MODE

commit 2a47accff8dccded4dfe031f9366c028ba927824
Author: Adam Jackson <ajax@redhat.com>
Date:   Wed Mar 5 23:56:49 2008 -0500

    Fix distcheck.

diff --git a/GL/apple/Makefile.am b/GL/apple/Makefile.am
index 33ad157..c064c03 100644
--- a/GL/apple/Makefile.am
+++ b/GL/apple/Makefile.am
@@ -11,10 +11,10 @@ AM_CPPFLAGS = \
 if HAVE_AGL_FRAMEWORK
 noinst_LIBRARIES = libAGLcore.a 
 libAGLcore_a_SOURCES = aglGlx.c \
-		       $(top_srcdir)/hw/darwin/quartz/xpr/x-list.c \
-		       $(top_srcdir)/hw/darwin/quartz/xpr/x-list.h \
-		       $(top_srcdir)/hw/darwin/quartz/xpr/x-hash.c \
-		       $(top_srcdir)/hw/darwin/quartz/xpr/x-hash.h \
+		       $(top_srcdir)/hw/xquartz/xpr/x-list.c \
+		       $(top_srcdir)/hw/xquartz/xpr/x-list.h \
+		       $(top_srcdir)/hw/xquartz/xpr/x-hash.c \
+		       $(top_srcdir)/hw/xquartz/xpr/x-hash.h \
 		       $(top_srcdir)/hw/dmx/glxProxy/compsize.c
 endif
 
diff --git a/hw/xfree86/x86emu/Makefile.am b/hw/xfree86/x86emu/Makefile.am
index 9f9c87f..acd249c 100644
--- a/hw/xfree86/x86emu/Makefile.am
+++ b/hw/xfree86/x86emu/Makefile.am
@@ -21,6 +21,7 @@ EXTRA_DIST = validate.c \
              x86emu/ops.h \
              x86emu/prim_asm.h \
              x86emu/prim_ops.h \
+	     x86emu/prim_x86_gcc.h \
              x86emu/regs.h \
              x86emu/types.h \
              x86emu/x86emui.h
diff --git a/include/Makefile.am b/include/Makefile.am
index 0654b57..673a976 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -50,10 +50,10 @@ sdk_HEADERS =		\
 	validate.h	\
 	window.h	\
 	windowstr.h	\
-	xkbsrv.h	\
 	xorg-server.h
 endif
 
 AM_CFLAGS = $(DIX_CFLAGS)
 
-EXTRA_DIST = $(sdk_HEADERS) do-not-use-config.h dix-config.h xorg-config.h
+EXTRA_DIST = $(sdk_HEADERS) do-not-use-config.h dix-config.h xorg-config.h \
+	xkb-config.h xkbfile.h xkbsrv.h xkbstr.h
diff --git a/xkb/Makefile.am b/xkb/Makefile.am
index e750d60..5b594c1 100644
--- a/xkb/Makefile.am
+++ b/xkb/Makefile.am
@@ -47,7 +47,7 @@ libxkb_la_SOURCES = $(DDX_SRCS) $(DIX_SRCS) $(XI_SRCS) $(XKBFILE_SRCS) \
                     $(X11_SRCS)
 libxkbstubs_la_SOURCES = ddxVT.c ddxPrivate.c ddxKillSrv.c
 
-EXTRA_DIST = xkb.h xkbDflts.h
+EXTRA_DIST = xkbDflts.h xkbgeom.h xkb.h
 
 xkbcompileddir = $(XKB_COMPILED_DIR)
 dist_xkbcompiled_DATA = README.compiled

commit 9de621afee4c9ad0d58d71968ec2c32a7fcc7753
Author: Eamon Walsh <ewalsh@tycho.nsa.gov>
Date:   Tue Mar 4 22:39:41 2008 -0500

    xselinux: Implement polyinstantiation support and related protocol.
    
    (cherry picked from commit d4101140f4e569f18554cf0cbf43138d08bd1277)

diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index a7d3999..18c6526 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -60,31 +60,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * Globals
  */
 
-/* private state record */
+/* private state keys */
 static DevPrivateKey subjectKey = &subjectKey;
 static DevPrivateKey objectKey = &objectKey;
+static DevPrivateKey dataKey = &dataKey;
 
-/* This is what we store for security state */
+/* subject state (clients and devices only) */
 typedef struct {
     security_id_t sid;
+    security_id_t dev_create_sid;
+    security_id_t win_create_sid;
+    security_id_t sel_create_sid;
+    security_id_t prp_create_sid;
+    security_id_t sel_use_sid;
+    security_id_t prp_use_sid;
     struct avc_entry_ref aeref;
     char *command;
     int privileged;
 } SELinuxSubjectRec;
 
+/* object state */
 typedef struct {
     security_id_t sid;
     int poly;
 } SELinuxObjectRec;
 
-/* selection manager */
+/* selection and property atom cache */
 typedef struct {
-    Atom selection;
-    security_id_t sid;
-} SELinuxSelectionRec;
-
-static ClientPtr securityManager;
-static Window securityWindow;
+    SELinuxObjectRec prp;
+    SELinuxObjectRec sel;
+} SELinuxAtomRec;
 
 /* audit file descriptor */
 static int audit_fd;
@@ -123,9 +128,9 @@ static unsigned numKnownTypes;
 static security_id_t *knownEvents;
 static unsigned numKnownEvents;
 
-/* Array of selection SID structures */
-static SELinuxSelectionRec *knownSelections;
-static unsigned numKnownSelections;
+/* Array of property and selection SID structures */
+static SELinuxAtomRec *knownAtoms;
+static unsigned numKnownAtoms;
 
 /* dynamically allocated security classes and permissions */
 static struct security_class_mapping map[] = {
@@ -135,7 +140,7 @@ static struct security_class_mapping map[] = {
     { "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
     { "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }},
     { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "write", NULL }},
-    { "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }},
+    { "x_selection", { "read", "", "", "setattr", "getattr", "setattr", NULL }},
     { "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }},
     { "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }},
     { "x_device", { "read", "write", "", "", "getattr", "setattr", "", "", "", "getfocus", "setfocus", "", "", "", "", "", "", "grab", "freeze", "force_cursor", "", "", "", "", "use", "manage", "", "bell", NULL }},
@@ -159,48 +164,164 @@ static pointer truep = (pointer)1;
  */
 
 /*
- * Looks up the SID corresponding to the given selection atom
+ * Looks up a name in the selection or property mappings
  */
 static int
-SELinuxSelectionToSID(Atom selection, SELinuxObjectRec *sid_return)
+SELinuxAtomToSIDLookup(Atom atom, SELinuxObjectRec *obj, int map, int polymap)
 {
-    const char *name;
-    unsigned i, size;
+    const char *name = NameForAtom(atom);
+    security_context_t ctx;
+    int rc = Success;
 
-    for (i = 0; i < numKnownSelections; i++)
-	if (knownSelections[i].selection == selection) {
-	    sid_return->sid = knownSelections[i].sid;
-	    return Success;
-	}
+    obj->poly = 1;
 
-    /* Need to increase size of array */
-    i = numKnownSelections;
-    size = (i + 1) * sizeof(SELinuxSelectionRec);
-    knownSelections = xrealloc(knownSelections, size);
-    if (!knownSelections)
-	return BadAlloc;
-    knownSelections[i].selection = selection;
+    /* Look in the mappings of names to contexts */
+    if (selabel_lookup(label_hnd, &ctx, name, map) == 0) {
+	obj->poly = 0;
+    } else if (errno != ENOENT) {
+	ErrorF("SELinux: a property label lookup failed!\n");
+	return BadValue;
+    } else if (selabel_lookup(label_hnd, &ctx, name, polymap) < 0) {
+	ErrorF("SELinux: a property label lookup failed!\n");
+	return BadValue;
+    }
 
-    /* Look in the mappings of selection names to contexts */
-    name = NameForAtom(selection);
-    if (name) {
-	security_context_t con;
-	security_id_t sid;
+    /* Get a SID for context */
+    if (avc_context_to_sid(ctx, &obj->sid) < 0) {
+	ErrorF("SELinux: a context_to_SID call failed!\n");
+	rc = BadAlloc;
+    }
 
-	if (selabel_lookup(label_hnd, &con, name, SELABEL_X_SELN) < 0) {
-	    ErrorF("SELinux: a selection label lookup failed!\n");
-	    return BadValue;
-	}
-	/* Get a SID for context */
-	if (avc_context_to_sid(con, &sid) < 0) {
-	    ErrorF("SELinux: a context_to_SID call failed!\n");
+    freecon(ctx);
+    return rc;
+}
+
+/*
+ * Looks up the SID corresponding to the given property or selection atom
+ */
+static int
+SELinuxAtomToSID(Atom atom, int prop, SELinuxObjectRec **obj_rtn)
+{
+    SELinuxObjectRec *obj;
+    int rc, map, polymap;
+
+    if (atom >= numKnownAtoms) {
+	/* Need to increase size of atoms array */
+	unsigned size = sizeof(SELinuxAtomRec);
+	knownAtoms = xrealloc(knownAtoms, (atom + 1) * size);
+	if (!knownAtoms)
 	    return BadAlloc;
+	memset(knownAtoms + numKnownAtoms, 0,
+	       (atom - numKnownAtoms + 1) * size);
+	numKnownAtoms = atom + 1;
+    }
+
+    if (prop) {
+	obj = &knownAtoms[atom].prp;
+	map = SELABEL_X_PROP;
+	polymap = SELABEL_X_POLYPROP;
+    } else {
+	obj = &knownAtoms[atom].sel;
+	map = SELABEL_X_SELN;
+	polymap = SELABEL_X_POLYSELN;
+    }
+
+    if (!obj->sid) {
+	rc = SELinuxAtomToSIDLookup(atom, obj, map, polymap);
+	if (rc != Success)
+	    goto out;
+    }
+
+    *obj_rtn = obj;
+    rc = Success;
+out:
+    return rc;
+}
+
+/*
+ * Looks up a SID for a selection/subject pair
+ */
+static int
+SELinuxSelectionToSID(Atom selection, SELinuxSubjectRec *subj,
+		      security_id_t *sid_rtn, int *poly_rtn)
+{
+    int rc;
+    SELinuxObjectRec *obj;
+    security_id_t tsid;
+
+    /* Get the default context and polyinstantiation bit */
+    rc = SELinuxAtomToSID(selection, 0, &obj);
+    if (rc != Success)
+	return rc;
+
+    /* Check for an override context next */
+    if (subj->sel_use_sid) {
+	sidget(tsid = subj->sel_use_sid);
+	goto out;
+    }
+
+    sidget(tsid = obj->sid);
+
+    /* Polyinstantiate if necessary to obtain the final SID */
+    if (obj->poly) {
+	sidput(tsid);
+	if (avc_compute_member(subj->sid, obj->sid,
+			       SECCLASS_X_SELECTION, &tsid) < 0) {
+	    ErrorF("SELinux: a compute_member call failed!\n");
+	    return BadValue;
 	}
-	freecon(con);
-	knownSelections[i].sid = sid_return->sid = sid;
-    } else
-	knownSelections[i].sid = sid_return->sid = unlabeled_sid;
+    }
+out:
+    *sid_rtn = tsid;
+    if (poly_rtn)
+	*poly_rtn = obj->poly;
+    return Success;
+}
 
+/*
+ * Looks up a SID for a property/subject pair
+ */
+static int
+SELinuxPropertyToSID(Atom property, SELinuxSubjectRec *subj,
+		     security_id_t *sid_rtn, int *poly_rtn)
+{
+    int rc;
+    SELinuxObjectRec *obj;
+    security_id_t tsid, tsid2;
+
+    /* Get the default context and polyinstantiation bit */
+    rc = SELinuxAtomToSID(property, 1, &obj);
+    if (rc != Success)
+	return rc;
+
+    /* Check for an override context next */
+    if (subj->prp_use_sid) {
+	sidget(tsid = subj->prp_use_sid);
+	goto out;
+    }
+
+    /* Perform a transition */
+    if (avc_compute_create(subj->sid, obj->sid,
+			   SECCLASS_X_PROPERTY, &tsid) < 0) {
+	ErrorF("SELinux: a compute_create call failed!\n");
+	return BadValue;
+    }
+
+    /* Polyinstantiate if necessary to obtain the final SID */
+    if (obj->poly) {
+	tsid2 = tsid;
+	if (avc_compute_member(subj->sid, tsid2,
+			       SECCLASS_X_PROPERTY, &tsid) < 0) {
+	    ErrorF("SELinux: a compute_member call failed!\n");
+	    sidput(tsid2);
+	    return BadValue;
+	}
+	sidput(tsid2);
+    }
+out:
+    *sid_rtn = tsid;
+    if (poly_rtn)
+	*poly_rtn = obj->poly;
     return Success;
 }
 
@@ -383,8 +504,7 @@ finish:
 	FatalError("SELinux: client %d: context_to_sid(%s) failed\n",
 		   client->index, ctx);
 
-    sidget(subj->sid);
-    obj->sid = subj->sid;
+    sidget(obj->sid = subj->sid);
     freecon(ctx);
 }
 
@@ -415,8 +535,7 @@ SELinuxLabelInitial(void)
     if (avc_context_to_sid(ctx, &subj->sid) < 0)
 	FatalError("SELinux: serverClient: context_to_sid(%s) failed\n", ctx);
 
-    sidget(subj->sid);
-    obj->sid = subj->sid;
+    sidget(obj->sid = subj->sid);
     freecon(ctx);
 
     srec.client = serverClient;
@@ -434,6 +553,44 @@ SELinuxLabelInitial(void)
     }
 }
 
+/*
+ * Labels new resource objects.
+ */
+static int
+SELinuxLabelResource(XaceResourceAccessRec *rec, SELinuxSubjectRec *subj,
+		     SELinuxObjectRec *obj, security_class_t class)
+{
+    int offset;
+    security_id_t tsid;
+
+    /* Check for a create context */
+    if (rec->rtype == RT_WINDOW && subj->win_create_sid) {
+	sidget(obj->sid = subj->win_create_sid);
+	return Success;
+    }
+
+    if (rec->parent)
+	offset = dixLookupPrivateOffset(rec->ptype);
+
+    if (rec->parent && offset >= 0) {
+	/* Use the SID of the parent object in the labeling operation */
+	PrivateRec **privatePtr = DEVPRIV_AT(rec->parent, offset);
+	SELinuxObjectRec *pobj = dixLookupPrivate(privatePtr, objectKey);
+	tsid = pobj->sid;
+    } else {
+	/* Use the SID of the subject */
+	tsid = subj->sid;
+    }
+
+    /* Perform a transition to obtain the final SID */
+    if (avc_compute_create(subj->sid, tsid, class, &obj->sid) < 0) {
+	ErrorF("SELinux: a compute_create call failed!\n");
+	return BadValue;
+    }
+
+    return Success;
+}
+
 
 /*
  * Libselinux Callbacks
@@ -525,11 +682,15 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 	sidput(dsubj->sid);
 	sidput(obj->sid);
 
-	/* Label the device directly with the process SID */
-	sidget(subj->sid);
-	obj->sid = subj->sid;
-	sidget(subj->sid);
-	dsubj->sid = subj->sid;
+	if (subj->dev_create_sid) {
+	    /* Label the device with the create context */
+	    sidget(obj->sid = subj->dev_create_sid);
+	    sidget(dsubj->sid = subj->dev_create_sid);
+	} else {
+	    /* Label the device directly with the process SID */
+	    sidget(obj->sid = subj->sid);
+	    sidget(dsubj->sid = subj->sid);
+	}
     }
 
     /* XXX only check read permission on XQueryKeymap */
@@ -685,13 +846,76 @@ SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 }
 
 static void
+SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+    XaceSelectionAccessRec *rec = calldata;
+    SELinuxSubjectRec *subj;
+    SELinuxObjectRec *obj, *data;
+    Selection *pSel = *rec->ppSel;
+    Atom name = pSel->selection;
+    SELinuxAuditRec auditdata = { .client = rec->client, .selection = name };
+    security_id_t tsid;
+    int rc;
+
+    subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
+    obj = dixLookupPrivate(&pSel->devPrivates, objectKey);
+
+    /* If this is a new object that needs labeling, do it now */
+    if (rec->access_mode & DixCreateAccess) {
+	sidput(obj->sid);
+	rc = SELinuxSelectionToSID(name, subj, &obj->sid, &obj->poly);
+	if (rc != Success)
+	    obj->sid = unlabeled_sid;
+    }
+    /* If this is a polyinstantiated object, find the right instance */
+    else if (obj->poly) {
+	rc = SELinuxSelectionToSID(name, subj, &tsid, NULL);
+	if (rc != Success) {
+	    rec->status = rc;
+	    return;
+	}
+	while (pSel->selection != name || obj->sid != tsid) {
+	    if ((pSel = pSel->next) == NULL)
+		break;
+	    obj = dixLookupPrivate(&pSel->devPrivates, objectKey);
+	}
+	sidput(tsid);
+	
+	if (pSel)
+	    *rec->ppSel = pSel;
+	else {
+	    rec->status = BadMatch;
+	    return;
+	}
+    }
+
+    /* Perform the security check */
+    rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, rec->access_mode,
+			&auditdata);
+    if (rc != Success)
+	rec->status = rc;
+
+    /* Label the content (advisory only) */
+    if (rec->access_mode & DixSetAttrAccess) {
+	data = dixLookupPrivate(&pSel->devPrivates, dataKey);
+	sidput(data->sid);
+	if (subj->sel_create_sid)
+	    sidget(data->sid = subj->sel_create_sid);
+	else
+	    sidget(data->sid = obj->sid);
+    }
+}
+
+static void
 SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
     XacePropertyAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
-    SELinuxObjectRec *obj;
-    SELinuxAuditRec auditdata = { .client = rec->client };
+    SELinuxObjectRec *obj, *data;
     PropertyPtr pProp = *rec->ppProp;
+    Atom name = pProp->propertyName;
+    SELinuxAuditRec auditdata = { .client = rec->client, .property = name };
+    security_id_t tsid;
     int rc;
 
     subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
@@ -699,42 +923,50 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 
     /* If this is a new object that needs labeling, do it now */
     if (rec->access_mode & DixCreateAccess) {
-	const char *name = NameForAtom(pProp->propertyName);
-	security_context_t con;
-	security_id_t sid;
-
-	/* Look in the mappings of property names to contexts */
-	if (selabel_lookup(label_hnd, &con, name, SELABEL_X_PROP) < 0) {
-	    ErrorF("SELinux: a property label lookup failed!\n");
-	    rec->status = BadValue;
+	sidput(obj->sid);
+	rc = SELinuxPropertyToSID(name, subj, &obj->sid, &obj->poly);
+	if (rc != Success) {
+	    rec->status = rc;
 	    return;
 	}
-	/* Get a SID for context */
-	if (avc_context_to_sid(con, &sid) < 0) {
-	    ErrorF("SELinux: a context_to_SID call failed!\n");
-	    rec->status = BadAlloc;
+    }
+    /* If this is a polyinstantiated object, find the right instance */
+    else if (obj->poly) {
+	rc = SELinuxPropertyToSID(name, subj, &tsid, NULL);
+	if (rc != Success) {
+	    rec->status = rc;
 	    return;
 	}
+	while (pProp->propertyName != name || obj->sid != tsid) {
+	    if ((pProp = pProp->next) == NULL)
+		break;
+	    obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
+	}
+	sidput(tsid);
 
-	sidput(obj->sid);
-
-	/* Perform a transition to obtain the final SID */
-	if (avc_compute_create(subj->sid, sid, SECCLASS_X_PROPERTY,
-			       &obj->sid) < 0) {
-	    ErrorF("SELinux: a SID transition call failed!\n");
-	    freecon(con);
-	    rec->status = BadValue;
+	if (pProp)
+	    *rec->ppProp = pProp;
+	else {
+	    rec->status = BadMatch;
 	    return;
 	}
-	freecon(con);
     }
 
     /* Perform the security check */
-    auditdata.property = pProp->propertyName;
     rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode,
 			&auditdata);
     if (rc != Success)
 	rec->status = rc;
+
+    /* Label the content (advisory only) */
+    if (rec->access_mode & DixWriteAccess) {
+	data = dixLookupPrivate(&pProp->devPrivates, dataKey);
+	sidput(data->sid);
+	if (subj->prp_create_sid)
+	    sidget(data->sid = subj->prp_create_sid);
+	else
+	    sidget(data->sid = obj->sid);
+    }
 }
 
 static void
@@ -742,14 +974,13 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 {
     XaceResourceAccessRec *rec = calldata;
     SELinuxSubjectRec *subj;
-    SELinuxObjectRec *obj, *sobj, *pobj;
+    SELinuxObjectRec *obj;
     SELinuxAuditRec auditdata = { .client = rec->client };
     PrivateRec **privatePtr;
     security_class_t class;
     int rc, offset;
 
     subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
-    sobj = dixLookupPrivate(&rec->client->devPrivates, objectKey);
 
     /* Determine if the resource object has a devPrivates field */
     offset = dixLookupPrivateOffset(rec->rtype);
@@ -767,21 +998,9 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 
     /* If this is a new object that needs labeling, do it now */
     if (rec->access_mode & DixCreateAccess && offset >= 0) {
-	if (rec->parent)
-	    offset = dixLookupPrivateOffset(rec->ptype);
-	if (rec->parent && offset >= 0)
-	    /* Use the SID of the parent object in the labeling operation */
-	    pobj = dixLookupPrivate(DEVPRIV_AT(rec->parent, offset), objectKey);
-	else
-	    /* Use the SID of the subject */
-	    pobj = sobj;
-
-	sidput(obj->sid);
-
-	/* Perform a transition to obtain the final SID */
-	if (avc_compute_create(subj->sid, pobj->sid, class, &obj->sid) < 0) {
-	    ErrorF("SELinux: a compute_create call failed!\n");
-	    rec->status = BadValue;
+	rc = SELinuxLabelResource(rec, subj, obj, class);
+	if (rc != Success) {
+	    rec->status = rc;
 	    return;
 	}
     }
@@ -864,34 +1083,6 @@ SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 	rec->status = rc;
 }
 
-static void
-SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
-    XaceSelectionAccessRec *rec = (XaceSelectionAccessRec *)calldata;
-    SELinuxSubjectRec *subj;
-    SELinuxObjectRec sel_sid;
-    SELinuxAuditRec auditdata = { .client = rec->client };
-    Selection *pSel = *rec->ppSel;
-    int rc;
-
-    if (rec->access_mode & DixCreateAccess)
-	return; /* don't use create currently */
-
-    subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
-
-    rc = SELinuxSelectionToSID(pSel->selection, &sel_sid);
-    if (rc != Success) {
-	rec->status = rc;
-	return;
-    }
-
-    auditdata.selection = pSel->selection;
-    rc = SELinuxDoCheck(subj, &sel_sid, SECCLASS_X_SELECTION, rec->access_mode,
-			&auditdata);
-    if (rc != Success)
-	rec->status = rc;
-}
-
 
 /*
  * DIX Callbacks
@@ -907,14 +1098,6 @@ SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 	SELinuxLabelClient(pci->client);
 	break;
 
-    case ClientStateRetained:
-    case ClientStateGone:
-	if (pci->client == securityManager) {
-	    securityManager = NULL;
-	    securityWindow = 0;
-	}
-	break;
-
     default:
 	break;
     }
@@ -965,18 +1148,6 @@ SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 	FatalError("SELinux: Unexpected unlabeled window found\n");
 }
 
-static void
-SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
-{
-    SelectionInfoRec *rec = calldata;
-
-    switch (rec->kind) {
-    case SelectionSetOwner:
-    default:
-	break;
-    }
-}
-
 
 /*
  * DevPrivates Callbacks
@@ -1002,8 +1173,13 @@ SELinuxSubjectFree(CallbackListPtr *pcbl, pointer unused, pointer calldata)
 
     xfree(subj->command);
 
-    if (avc_active)
+    if (avc_active) {
 	sidput(subj->sid);
+	sidput(subj->dev_create_sid);
+	sidput(subj->win_create_sid);
+	sidput(subj->sel_create_sid);
+	sidput(subj->prp_create_sid);
+    }
 }
 
 static void
@@ -1031,6 +1207,21 @@ SELinuxObjectFree(CallbackListPtr *pcbl, pointer unused, pointer calldata)
  * Extension Dispatch
  */
 
+#define CTX_DEV offsetof(SELinuxSubjectRec, dev_create_sid)
+#define CTX_WIN offsetof(SELinuxSubjectRec, win_create_sid)
+#define CTX_PRP offsetof(SELinuxSubjectRec, prp_create_sid)
+#define CTX_SEL offsetof(SELinuxSubjectRec, sel_create_sid)
+#define USE_PRP offsetof(SELinuxSubjectRec, prp_use_sid)
+#define USE_SEL offsetof(SELinuxSubjectRec, sel_use_sid)
+
+typedef struct {
+    security_context_t octx;
+    security_context_t dctx;
+    CARD32 octx_len;
+    CARD32 dctx_len;
+    CARD32 id;
+} SELinuxListItemRec;
+
 static int
 ProcSELinuxQueryVersion(ClientPtr client)
 {
@@ -1053,65 +1244,101 @@ ProcSELinuxQueryVersion(ClientPtr client)
 }
 
 static int
-ProcSELinuxSetSecurityManager(ClientPtr client)
+SELinuxSendContextReply(ClientPtr client, security_id_t sid)
 {
-    WindowPtr pWin;
-    int rc;
-
-    REQUEST(SELinuxSetSecurityManagerReq);
-    REQUEST_SIZE_MATCH(SELinuxSetSecurityManagerReq);
-
-    if (stuff->window == None) {
-	securityManager = NULL;
-	securityWindow = None;
-    } else {
-	rc = dixLookupResource((pointer *)&pWin, stuff->window, RT_WINDOW,
-			       client, DixGetAttrAccess);
-	if (rc != Success)
-	    return rc;
+    SELinuxGetContextReply rep;
+    security_context_t ctx = NULL;
+    int len = 0;
 
-	securityManager = client;
-	securityWindow = stuff->window;
+    if (sid) {
+	if (avc_sid_to_context(sid, &ctx) < 0)
+	    return BadValue;
+	len = strlen(ctx) + 1;
     }
 
-    return Success;
-}
-
-static int
-ProcSELinuxGetSecurityManager(ClientPtr client)
-{
-    SELinuxGetSecurityManagerReply rep;
-
     rep.type = X_Reply;
-    rep.length = 0;
+    rep.length = (len + 3) >> 2;
     rep.sequenceNumber = client->sequence;
-    rep.window = securityWindow;
+    rep.context_len = len;
+
     if (client->swapped) {
 	int n;
-	swaps(&rep.sequenceNumber, n);
 	swapl(&rep.length, n);
-	swapl(&rep.window, n);
+	swaps(&rep.sequenceNumber, n);
+	swapl(&rep.context_len, n);
     }
-    WriteToClient(client, sizeof(rep), (char *)&rep);
-    return (client->noClientException);
+
+    WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep);
+    WriteToClient(client, len, ctx);
+    freecon(ctx);
+    return client->noClientException;
 }
 
 static int
-ProcSELinuxSetDeviceCreateContext(ClientPtr client)
+ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset)
 {
+    PrivateRec **privPtr = &client->devPrivates;
+    security_id_t *pSid;
+    security_context_t ctx;
+    char *ptr;
+
+    REQUEST(SELinuxSetCreateContextReq);
+    REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len);
+
+    ctx = (char *)(stuff + 1);
+    if (stuff->context_len > 0 && ctx[stuff->context_len - 1])
+	return BadLength;
+
+    if (offset == CTX_DEV) {
+	/* Device create context currently requires manage permission */
+	int rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
+	if (rc != Success)
+	    return rc;
+	privPtr = &serverClient->devPrivates;
+    }
+    else if (offset == USE_SEL) {
+	/* Selection use context currently requires no selections owned */
+	Selection *pSel;
+	for (pSel = CurrentSelections; pSel; pSel = pSel->next)
+	    if (pSel->client == client)
+		return BadMatch;
+    }
+
+    ptr = dixLookupPrivate(privPtr, subjectKey);
+    pSid = (security_id_t *)(ptr + offset);
+    sidput(*pSid);
+    *pSid = NULL;
+
+    if (stuff->context_len > 0) {
+	if (security_check_context(ctx) < 0)
+	    return BadValue;
+	if (avc_context_to_sid(ctx, pSid) < 0)
+	    return BadValue;
+    }
     return Success;
 }
 
 static int
-ProcSELinuxGetDeviceCreateContext(ClientPtr client)
+ProcSELinuxGetCreateContext(ClientPtr client, unsigned offset)
 {
-    return Success;
+    security_id_t *pSid;
+    char *ptr;
+
+    REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq);
+
+    if (offset == CTX_DEV)
+	ptr = dixLookupPrivate(&serverClient->devPrivates, subjectKey);
+    else
+	ptr = dixLookupPrivate(&client->devPrivates, subjectKey);
+
+    pSid = (security_id_t *)(ptr + offset);
+    return SELinuxSendContextReply(client, *pSid);
 }
 
 static int
 ProcSELinuxSetDeviceContext(ClientPtr client)
 {
-    char *ctx;
+    security_context_t ctx;
     security_id_t sid;
     DeviceIntPtr dev;
     SELinuxSubjectRec *subj;
@@ -1122,15 +1349,16 @@ ProcSELinuxSetDeviceContext(ClientPtr client)
     REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len);
 
     ctx = (char *)(stuff + 1);
-    if (ctx[stuff->context_len - 1])
+    if (stuff->context_len < 1 || ctx[stuff->context_len - 1])
 	return BadLength;
 
     rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess);
     if (rc != Success)
 	return rc;
 
-    rc = avc_context_to_sid(ctx, &sid);
-    if (rc != Success)
+    if (security_check_context(ctx) < 0)
+	return BadValue;
+    if (avc_context_to_sid(ctx, &sid) < 0)
 	return BadValue;
 
     subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
@@ -1138,7 +1366,7 @@ ProcSELinuxSetDeviceContext(ClientPtr client)
     subj->sid = sid;
     obj = dixLookupPrivate(&dev->devPrivates, objectKey);
     sidput(obj->sid);
-    obj->sid = sid;
+    sidget(obj->sid = sid);
 
     return Success;
 }
@@ -1146,10 +1374,8 @@ ProcSELinuxSetDeviceContext(ClientPtr client)
 static int
 ProcSELinuxGetDeviceContext(ClientPtr client)
 {
-    char *ctx;
     DeviceIntPtr dev;
     SELinuxSubjectRec *subj;
-    SELinuxGetContextReply rep;
     int rc;
 
     REQUEST(SELinuxGetContextReq);
@@ -1160,48 +1386,33 @@ ProcSELinuxGetDeviceContext(ClientPtr client)
 	return rc;
 
     subj = dixLookupPrivate(&dev->devPrivates, subjectKey);
-    rc = avc_sid_to_context(subj->sid, &ctx);
-    if (rc != Success)
-	return BadValue;
-
-    rep.type = X_Reply;
-    rep.length = (strlen(ctx) + 4) >> 2;
-    rep.sequenceNumber = client->sequence;
-    rep.context_len = strlen(ctx) + 1;
-
-    if (client->swapped) {
-	int n;
-	swapl(&rep.length, n);
-	swaps(&rep.sequenceNumber, n);
-	swaps(&rep.context_len, n);
-    }
-
-    WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep);
-    WriteToClient(client, rep.context_len, ctx);
-    free(ctx);
-    return client->noClientException;
+    return SELinuxSendContextReply(client, subj->sid);
 }
 
 static int
-ProcSELinuxSetPropertyCreateContext(ClientPtr client)
+ProcSELinuxGetWindowContext(ClientPtr client)
 {
-    return Success;
-}
+    WindowPtr pWin;
+    SELinuxObjectRec *obj;
+    int rc;
 
-static int
-ProcSELinuxGetPropertyCreateContext(ClientPtr client)
-{
-    return Success;
+    REQUEST(SELinuxGetContextReq);
+    REQUEST_SIZE_MATCH(SELinuxGetContextReq);
+
+    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
+    if (rc != Success)
+	return rc;
+
+    obj = dixLookupPrivate(&pWin->devPrivates, objectKey);
+    return SELinuxSendContextReply(client, obj->sid);
 }
 
 static int
-ProcSELinuxGetPropertyContext(ClientPtr client)
+ProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey)
 {
-    char *ctx;
     WindowPtr pWin;
     PropertyPtr pProp;
     SELinuxObjectRec *obj;
-    SELinuxGetContextReply rep;
     int rc;
 
     REQUEST(SELinuxGetPropertyContextReq);
@@ -1216,96 +1427,191 @@ ProcSELinuxGetPropertyContext(ClientPtr client)
     if (rc != Success)
 	return rc;
 
-    obj = dixLookupPrivate(&pProp->devPrivates, objectKey);
-    rc = avc_sid_to_context(obj->sid, &ctx);
-    if (rc != Success)
-	return BadValue;


Reply to: