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: