xserver: Branch 'XACE-SELINUX' - 6 commits
Eamon Walsh
ewalsh at kemper.freedesktop.org
Tue Oct 23 17:59:58 PDT 2007
Xext/xace.c | 1
Xext/xacestr.h | 1
Xext/xselinux.c | 424 +++++++++++++++++++++++++++++++++++++++++++++-----------
Xext/xselinux.h | 37 ++++
dix/dispatch.c | 56 ++++---
dix/events.c | 18 +-
dix/registry.c | 2
include/dix.h | 3
8 files changed, 431 insertions(+), 111 deletions(-)
New commits:
commit 0388a59a6ef212c497cc3f64d677b1ca5b410982
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Tue Oct 23 20:59:21 2007 -0400
Revert "registry: special case minor number when looking up core requests."
This reverts commit 31110d6837ee52fd654729d9e5c4b0c5395abab0.
This is handled properly by StandardMinorOpcode().
diff --git a/dix/registry.c b/dix/registry.c
index 0181858..48e1b5d 100644
--- a/dix/registry.c
+++ b/dix/registry.c
@@ -123,8 +123,6 @@ RegisterResourceName(RESTYPE resource, const char *name)
const char *
LookupRequestName(int major, int minor)
{
- if (major < 128)
- minor = 0;
if (major >= nmajor)
return XREGISTRY_UNKNOWN;
if (minor >= nminor[major])
commit 46521f529841e032e198e5df87974088548a68de
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Tue Oct 23 20:58:48 2007 -0400
xselinux: Add basic support for selection access control and redirection.
Probably not fully baked yet. It's difficult to test since so few apps
actually follow the ICCCM with respect to cut & paste.
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index ef5be57..f11bc1a 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -65,6 +65,15 @@ typedef struct {
char *command;
} SELinuxStateRec;
+/* selection manager */
+typedef struct {
+ Atom selection;
+ security_id_t sid;
+} SELinuxSelectionRec;
+
+static ClientPtr selectionManager;
+static Window selectionWindow;
+
/* audit file descriptor */
static int audit_fd;
@@ -99,6 +108,10 @@ static unsigned numKnownTypes;
static security_id_t *knownEvents;
static unsigned numKnownEvents;
+/* Array of selection SID structures */
+static SELinuxSelectionRec *knownSelections;
+static unsigned numKnownSelections;
+
/* dynamically allocated security classes and permissions */
static struct security_class_mapping map[] = {
{ "x_drawable", { "read", "write", "destroy", "create", "getattr", "setattr", "list_property", "get_property", "set_property", "", "", "list_child", "add_child", "remove_child", "hide", "show", "blend", "override", "", "", "", "", "send", "receive", "", "manage", NULL }},
@@ -130,6 +143,52 @@ static pointer truep = (pointer)1;
*/
/*
+ * Looks up the SID corresponding to the given selection atom
+ */
+static int
+SELinuxSelectionToSID(Atom selection, SELinuxStateRec *sid_return)
+{
+ const char *name;
+ unsigned i, size;
+
+ for (i = 0; i < numKnownSelections; i++)
+ if (knownSelections[i].selection == selection) {
+ sid_return->sid = knownSelections[i].sid;
+ return Success;
+ }
+
+ /* 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 selection names to contexts */
+ name = NameForAtom(selection);
+ if (name) {
+ security_context_t con;
+ security_id_t sid;
+
+ if (selabel_lookup(label_hnd, &con, name, SELABEL_X_SELN) < 0) {
+ ErrorF("XSELinux: a selection label lookup failed!\n");
+ return BadValue;
+ }
+ /* Get a SID for context */
+ if (avc_context_to_sid(con, &sid) < 0) {
+ ErrorF("XSELinux: a context_to_SID call failed!\n");
+ return BadAlloc;
+ }
+ freecon(con);
+ knownSelections[i].sid = sid_return->sid = sid;
+ } else
+ knownSelections[i].sid = sid_return->sid = unlabeled_sid;
+
+ return Success;
+}
+
+/*
* Looks up the SID corresponding to the given event type
*/
static int
@@ -240,10 +299,71 @@ SELinuxDoCheck(int clientIndex, SELinuxStateRec *subj, SELinuxStateRec *obj,
}
/*
+ * Labels a newly connected client.
+ */
+static void
+SELinuxLabelClient(ClientPtr client)
+{
+ XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
+ SELinuxStateRec *state;
+ security_context_t ctx;
+
+ state = dixLookupPrivate(&client->devPrivates, stateKey);
+ sidput(state->sid);
+
+ if (_XSERVTransIsLocal(ci)) {
+ int fd = _XSERVTransGetConnectionNumber(ci);
+ struct ucred creds;
+ socklen_t len = sizeof(creds);
+ char path[PATH_MAX + 1];
+ size_t bytes;
+
+ /* For local clients, can get context from the socket */
+ if (getpeercon(fd, &ctx) < 0)
+ FatalError("Client %d: couldn't get context from socket\n",
+ client->index);
+
+ /* Try and determine the client's executable name */
+ memset(&creds, 0, sizeof(creds));
+ if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &len) < 0)
+ goto finish;
+
+ snprintf(path, PATH_MAX + 1, "/proc/%d/cmdline", creds.pid);
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ goto finish;
+
+ bytes = read(fd, path, PATH_MAX + 1);
+ close(fd);
+ if (bytes <= 0)
+ goto finish;
+
+ state->command = xalloc(bytes);
+ if (!state->command)
+ goto finish;
+
+ memcpy(state->command, path, bytes);
+ state->command[bytes - 1] = 0;
+ } else
+ /* For remote clients, need to use a default context */
+ if (selabel_lookup(label_hnd, &ctx, NULL, SELABEL_X_CLIENT) < 0)
+ FatalError("Client %d: couldn't get default remote context\n",
+ client->index);
+
+finish:
+ /* Get a SID from the context */
+ if (avc_context_to_sid(ctx, &state->sid) < 0)
+ FatalError("Client %d: context_to_sid(%s) failed\n",
+ client->index, ctx);
+
+ freecon(ctx);
+}
+
+/*
* Labels initial server objects.
*/
static void
-SELinuxFixupLabels(void)
+SELinuxLabelInitial(void)
{
int i;
XaceScreenAccessRec srec;
@@ -674,6 +794,28 @@ SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
rec->status = rc;
}
+static void
+SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceSelectionAccessRec *rec = (XaceSelectionAccessRec *)calldata;
+ SELinuxStateRec *subj, sel_sid;
+ SELinuxAuditRec auditdata = { rec->client, NULL, 0, 0, 0, NULL };
+ int rc;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+
+ rc = SELinuxSelectionToSID(rec->name, &sel_sid);
+ if (rc != Success) {
+ rec->status = rc;
+ return;
+ }
+
+ rc = SELinuxDoCheck(rec->client->index, subj, &sel_sid,
+ SECCLASS_X_SELECTION, rec->access_mode, &auditdata);
+ if (rc != Success)
+ rec->status = rc;
+}
+
/*
* DIX Callbacks
@@ -683,63 +825,23 @@ static void
SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
{
NewClientInfoRec *pci = calldata;
- ClientPtr client = pci->client;
- XtransConnInfo ci = ((OsCommPtr)client->osPrivate)->trans_conn;
- SELinuxStateRec *state;
- security_context_t ctx;
-
- if (client->clientState != ClientStateInitial)
- return;
-
- state = dixLookupPrivate(&client->devPrivates, stateKey);
- sidput(state->sid);
-
- if (_XSERVTransIsLocal(ci)) {
- int fd = _XSERVTransGetConnectionNumber(ci);
- struct ucred creds;
- socklen_t len = sizeof(creds);
- char path[PATH_MAX + 1];
- size_t bytes;
-
- /* For local clients, can get context from the socket */
- if (getpeercon(fd, &ctx) < 0)
- FatalError("Client %d: couldn't get context from socket\n",
- client->index);
-
- /* Try and determine the client's executable name */
- memset(&creds, 0, sizeof(creds));
- if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &len) < 0)
- goto finish;
-
- snprintf(path, PATH_MAX + 1, "/proc/%d/cmdline", creds.pid);
- fd = open(path, O_RDONLY);
- if (fd < 0)
- goto finish;
-
- bytes = read(fd, path, PATH_MAX + 1);
- close(fd);
- if (bytes <= 0)
- goto finish;
- state->command = xalloc(bytes);
- if (!state->command)
- goto finish;
-
- memcpy(state->command, path, bytes);
- state->command[bytes - 1] = 0;
- } else
- /* For remote clients, need to use a default context */
- if (selabel_lookup(label_hnd, &ctx, NULL, SELABEL_X_CLIENT) < 0)
- FatalError("Client %d: couldn't get default remote context\n",
- client->index);
+ switch (pci->client->clientState) {
+ case ClientStateInitial:
+ SELinuxLabelClient(pci->client);
+ break;
-finish:
- /* Get a SID from the context */
- if (avc_context_to_sid(ctx, &state->sid) < 0)
- FatalError("Client %d: context_to_sid(%s) failed\n",
- client->index, ctx);
+ case ClientStateRetained:
+ case ClientStateGone:
+ if (pci->client == selectionManager) {
+ selectionManager = NULL;
+ selectionWindow = 0;
+ }
+ break;
- freecon(ctx);
+ default:
+ break;
+ }
}
static void
@@ -788,6 +890,50 @@ SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
FatalError("XSELinux: Unexpected unlabeled window found\n");
}
+static void
+SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ SelectionInfoRec *rec = calldata;
+ SELinuxStateRec *subj, *obj;
+
+ switch (rec->kind) {
+ case SelectionSetOwner:
+ /* save off the "real" owner of the selection */
+ rec->selection->alt_client = rec->selection->client;
+ rec->selection->alt_window = rec->selection->window;
+
+ /* figure out the new label for the content */
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&rec->selection->devPrivates, stateKey);
+ sidput(obj->sid);
+
+ if (avc_compute_create(subj->sid, subj->sid, SECCLASS_X_SELECTION,
+ &obj->sid) < 0) {
+ ErrorF("XSELinux: a compute_create call failed!\n");
+ obj->sid = unlabeled_sid;
+ }
+ break;
+
+ case SelectionGetOwner:
+ /* restore the real owner */
+ rec->selection->window = rec->selection->alt_window;
+ break;
+
+ case SelectionConvertSelection:
+ /* redirect the convert request if necessary */
+ if (selectionManager && selectionManager != rec->client) {
+ rec->selection->client = selectionManager;
+ rec->selection->window = selectionWindow;
+ } else {
+ rec->selection->client = rec->selection->alt_client;
+ rec->selection->window = rec->selection->alt_window;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
/*
* DevPrivates Callbacks
@@ -823,9 +969,108 @@ SELinuxStateFree(CallbackListPtr *pcbl, pointer unused, pointer calldata)
*/
static int
+ProcSELinuxQueryVersion(ClientPtr client)
+{
+ SELinuxQueryVersionReply rep;
+ /*
+ REQUEST(SELinuxQueryVersionReq);
+ REQUEST_SIZE_MATCH (SELinuxQueryVersionReq);
+ */
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.server_major = XSELINUX_MAJOR_VERSION;
+ rep.server_minor = XSELINUX_MINOR_VERSION;
+ if (client->swapped) {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.server_major, n);
+ swaps(&rep.server_minor, n);
+ }
+ WriteToClient(client, sizeof(rep), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+ProcSELinuxSetSelectionManager(ClientPtr client)
+{
+ REQUEST(SELinuxSetSelectionManagerReq);
+ WindowPtr pWin;
+ int rc;
+
+ REQUEST_SIZE_MATCH(SELinuxSetSelectionManagerReq);
+
+ if (stuff->window == None) {
+ selectionManager = NULL;
+ selectionWindow = None;
+ } else {
+ rc = dixLookupResource((pointer *)&pWin, stuff->window, RT_WINDOW,
+ client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ selectionManager = client;
+ selectionWindow = stuff->window;
+ }
+
+ return Success;
+}
+
+static int
ProcSELinuxDispatch(ClientPtr client)
{
- return BadRequest;
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_SELinuxQueryVersion:
+ return ProcSELinuxQueryVersion(client);
+ case X_SELinuxSetSelectionManager:
+ return ProcSELinuxSetSelectionManager(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcSELinuxQueryVersion(ClientPtr client)
+{
+ REQUEST(SELinuxQueryVersionReq);
+ int n;
+
+ REQUEST_SIZE_MATCH (SELinuxQueryVersionReq);
+ swaps(&stuff->client_major,n);
+ swaps(&stuff->client_minor,n);
+ return ProcSELinuxQueryVersion(client);
+}
+
+static int
+SProcSELinuxSetSelectionManager(ClientPtr client)
+{
+ REQUEST(SELinuxSetSelectionManagerReq);
+ int n;
+
+ REQUEST_SIZE_MATCH (SELinuxSetSelectionManagerReq);
+ swapl(&stuff->window,n);
+ return ProcSELinuxSetSelectionManager(client);
+}
+
+static int
+SProcSELinuxDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ int n;
+
+ swaps(&stuff->length, n);
+
+ switch (stuff->data) {
+ case X_SELinuxQueryVersion:
+ return SProcSELinuxQueryVersion(client);
+ case X_SELinuxSetSelectionManager:
+ return SProcSELinuxSetSelectionManager(client);
+ default:
+ return BadRequest;
+ }
}
@@ -839,6 +1084,7 @@ SELinuxResetProc(ExtensionEntry *extEntry)
/* Unregister callbacks */
DeleteCallback(&ClientStateCallback, SELinuxClientState, NULL);
DeleteCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
+ DeleteCallback(&SelectionCallback, SELinuxSelectionState, NULL);
XaceDeleteCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
XaceDeleteCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
@@ -849,7 +1095,7 @@ SELinuxResetProc(ExtensionEntry *extEntry)
XaceDeleteCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
XaceDeleteCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
XaceDeleteCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
-// XaceDeleteCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
+ XaceDeleteCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
XaceDeleteCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
XaceDeleteCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
@@ -863,6 +1109,10 @@ SELinuxResetProc(ExtensionEntry *extEntry)
avc_active = 0;
/* Free local state */
+ xfree(knownSelections);
+ knownSelections = NULL;
+ numKnownSelections = 0;
+
xfree(knownEvents);
knownEvents = NULL;
numKnownEvents = 0;
@@ -929,6 +1179,7 @@ XSELinuxExtensionInit(INITARGS)
ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL);
ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
+ ret &= AddCallback(&SelectionCallback, SELinuxSelectionState, NULL);
ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
@@ -939,7 +1190,7 @@ XSELinuxExtensionInit(INITARGS)
ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
-// ret &= XaceRegisterCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
+ ret &= XaceRegisterCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
ret &= XaceRegisterCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
ret &= XaceRegisterCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
if (!ret)
@@ -948,9 +1199,9 @@ XSELinuxExtensionInit(INITARGS)
/* Add extension to server */
extEntry = AddExtension(XSELINUX_EXTENSION_NAME,
XSELinuxNumberEvents, XSELinuxNumberErrors,
- ProcSELinuxDispatch, ProcSELinuxDispatch,
+ ProcSELinuxDispatch, SProcSELinuxDispatch,
SELinuxResetProc, StandardMinorOpcode);
/* Label objects that were created before we could register ourself */
- SELinuxFixupLabels();
+ SELinuxLabelInitial();
}
diff --git a/Xext/xselinux.h b/Xext/xselinux.h
index 407b81f..691154d 100644
--- a/Xext/xselinux.h
+++ b/Xext/xselinux.h
@@ -29,6 +29,43 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define XSELinuxNumberEvents 0
#define XSELinuxNumberErrors 0
+/* Extension protocol */
+#define X_SELinuxQueryVersion 0
+#define X_SELinuxSetSelectionManager 1
+
+typedef struct _SELinuxQueryVersion {
+ CARD8 reqType;
+ CARD8 SELinuxReqType;
+ CARD16 length;
+ CARD8 client_major;
+ CARD8 client_minor;
+ CARD16 unused;
+} SELinuxQueryVersionReq;
+#define sz_SELinuxQueryVersionReq 8
+
+typedef struct {
+ CARD8 type;
+ CARD8 pad1;
+ CARD16 sequenceNumber;
+ CARD32 length;
+ CARD16 server_major;
+ CARD16 server_minor;
+ CARD32 pad2;
+ CARD32 pad3;
+ CARD32 pad4;
+ CARD32 pad5;
+ CARD32 pad6;
+} SELinuxQueryVersionReply;
+#define sz_SELinuxQueryVersionReply 32
+
+typedef struct _SELinuxSetSelectionManager {
+ CARD8 reqType;
+ CARD8 SELinuxReqType;
+ CARD16 length;
+ CARD32 window;
+} SELinuxSetSelectionManagerReq;
+#define sz_SELinuxSetSelectionManagerReq 8
+
/* Private Flask definitions */
#define SECCLASS_X_DRAWABLE 1
#define SECCLASS_X_SCREEN 2
commit 825f09dffd94cfcd0562a01c5181998503851461
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Tue Oct 23 17:12:57 2007 -0400
xace: Still more changes to selection code. Removed the SelectionPtr from
the hook - the hook only needs the Atom to control access to the selection
object. Upgraded the SelectionCallback to take a client argument and
additional type codes so that it can be used for redirection.
diff --git a/Xext/xace.c b/Xext/xace.c
index b126661..7b27ecd 100644
--- a/Xext/xace.c
+++ b/Xext/xace.c
@@ -177,7 +177,6 @@ int XaceHook(int hook, ...)
XaceSelectionAccessRec rec = {
va_arg(ap, ClientPtr),
va_arg(ap, Atom),
- va_arg(ap, Selection*),
va_arg(ap, Mask),
Success /* default allow */
};
diff --git a/Xext/xacestr.h b/Xext/xacestr.h
index 1c61543..045f836 100644
--- a/Xext/xacestr.h
+++ b/Xext/xacestr.h
@@ -112,7 +112,6 @@ typedef struct {
typedef struct {
ClientPtr client;
Atom name;
- Selection *selection;
Mask access_mode;
int status;
} XaceSelectionAccessRec;
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 2cfeb2d..814c2a8 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -1005,6 +1005,11 @@ ProcSetSelectionOwner(ClientPtr client)
{
int i = 0;
+ rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection,
+ DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+
/*
* First, see if the selection is already set...
*/
@@ -1022,12 +1027,6 @@ ProcSetSelectionOwner(ClientPtr client)
if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged)
== EARLIER)
return Success;
-
- rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection,
- CurrentSelections + i, DixSetAttrAccess);
- if (rc != Success)
- return rc;
-
if (CurrentSelections[i].client &&
(!pWin || (CurrentSelections[i].client != client)))
{
@@ -1058,10 +1057,6 @@ ProcSetSelectionOwner(ClientPtr client)
CurrentSelections = newsels;
CurrentSelections[i].selection = stuff->selection;
CurrentSelections[i].devPrivates = NULL;
- rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection,
- CurrentSelections + i, DixSetAttrAccess);
- if (rc != Success)
- return rc;
}
CurrentSelections[i].lastTimeChanged = time;
CurrentSelections[i].window = stuff->window;
@@ -1072,6 +1067,7 @@ ProcSetSelectionOwner(ClientPtr client)
SelectionInfoRec info;
info.selection = &CurrentSelections[i];
+ info.client = client;
info.kind= SelectionSetOwner;
CallCallbacks(&SelectionCallback, &info);
}
@@ -1095,23 +1091,29 @@ ProcGetSelectionOwner(ClientPtr client)
int rc, i;
xGetSelectionOwnerReply reply;
- i = 0;
- while ((i < NumCurrentSelections) &&
- CurrentSelections[i].selection != stuff->id) i++;
-
rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->id,
- CurrentSelections + i, DixGetAttrAccess);
+ DixGetAttrAccess);
if (rc != Success)
return rc;
+ i = 0;
+ while ((i < NumCurrentSelections) &&
+ CurrentSelections[i].selection != stuff->id) i++;
reply.type = X_Reply;
reply.length = 0;
reply.sequenceNumber = client->sequence;
- if (i < NumCurrentSelections)
+ if (i < NumCurrentSelections) {
+ if (SelectionCallback) {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.client = client;
+ info.kind= SelectionGetOwner;
+ CallCallbacks(&SelectionCallback, &info);
+ }
reply.owner = CurrentSelections[i].window;
- else
+ } else
reply.owner = None;
-
WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply);
return(client->noClientException);
}
@@ -1135,6 +1137,10 @@ ProcConvertSelection(ClientPtr client)
rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess);
if (rc != Success)
return rc;
+ rc = XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target));
if (stuff->property != None)
@@ -1146,11 +1152,15 @@ ProcConvertSelection(ClientPtr client)
i = 0;
while ((i < NumCurrentSelections) &&
CurrentSelections[i].selection != stuff->selection) i++;
- if ((i < NumCurrentSelections) &&
- (CurrentSelections[i].window != None) &&
- XaceHook(XACE_SELECTION_ACCESS, client, stuff->selection,
- CurrentSelections + i, DixReadAccess) == Success)
- {
+ if (i < NumCurrentSelections && CurrentSelections[i].window != None) {
+ if (SelectionCallback) {
+ SelectionInfoRec info;
+
+ info.selection = &CurrentSelections[i];
+ info.client = client;
+ info.kind= SelectionConvertSelection;
+ CallCallbacks(&SelectionCallback, &info);
+ }
event.u.u.type = SelectionRequest;
event.u.selectionRequest.time = stuff->time;
event.u.selectionRequest.owner = CurrentSelections[i].window;
diff --git a/include/dix.h b/include/dix.h
index 09ed6d9..30fdc45 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -594,12 +594,15 @@ extern CallbackListPtr SelectionCallback;
typedef enum {
SelectionSetOwner,
+ SelectionGetOwner,
+ SelectionConvertSelection,
SelectionWindowDestroy,
SelectionClientClose
} SelectionCallbackKind;
typedef struct {
struct _Selection *selection;
+ ClientPtr client;
SelectionCallbackKind kind;
} SelectionInfoRec;
commit 660557593ea961948722298ea8ffba83891c9914
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Tue Oct 23 14:46:37 2007 -0400
xselinux: Remove synthetic bit when looking up event type.
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 183a047..ef5be57 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -133,10 +133,11 @@ static pointer truep = (pointer)1;
* Looks up the SID corresponding to the given event type
*/
static int
-SELinuxEventToSID(int type, SELinuxStateRec *sid_return)
+SELinuxEventToSID(unsigned type, SELinuxStateRec *sid_return)
{
const char *name = LookupEventName(type);
security_context_t con;
+ type &= 127;
if (type >= numKnownEvents) {
/* Need to increase size of classes array */
commit d7db549db41a27aef28cff9bfb7973bc741f88b2
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Tue Oct 23 14:08:54 2007 -0400
xselinux: Unregister callbacks on server reset.
diff --git a/Xext/xselinux.c b/Xext/xselinux.c
index 14a2270..183a047 100644
--- a/Xext/xselinux.c
+++ b/Xext/xselinux.c
@@ -121,6 +121,9 @@ static struct security_class_mapping map[] = {
/* forward declarations */
static void SELinuxScreen(CallbackListPtr *, pointer, pointer);
+/* "true" pointer value for use as callback data */
+static pointer truep = (pointer)1;
+
/*
* Support Routines
@@ -832,8 +835,24 @@ ProcSELinuxDispatch(ClientPtr client)
static void
SELinuxResetProc(ExtensionEntry *extEntry)
{
- /* XXX unregister all callbacks here */
-
+ /* Unregister callbacks */
+ DeleteCallback(&ClientStateCallback, SELinuxClientState, NULL);
+ DeleteCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
+
+ XaceDeleteCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
+ XaceDeleteCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
+ XaceDeleteCallback(XACE_DEVICE_ACCESS, SELinuxDevice, NULL);
+ XaceDeleteCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, NULL);
+ XaceDeleteCallback(XACE_SEND_ACCESS, SELinuxSend, NULL);
+ XaceDeleteCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, NULL);
+ XaceDeleteCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
+ XaceDeleteCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
+ XaceDeleteCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
+// XaceDeleteCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
+ XaceDeleteCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
+ XaceDeleteCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
+
+ /* Tear down SELinux stuff */
selabel_close(label_hnd);
label_hnd = NULL;
@@ -842,6 +861,7 @@ SELinuxResetProc(ExtensionEntry *extEntry)
avc_destroy();
avc_active = 0;
+ /* Free local state */
xfree(knownEvents);
knownEvents = NULL;
numKnownEvents = 0;
@@ -906,21 +926,21 @@ XSELinuxExtensionInit(INITARGS)
ret &= dixRegisterPrivateInitFunc(stateKey, SELinuxStateInit, NULL);
ret &= dixRegisterPrivateDeleteFunc(stateKey, SELinuxStateFree, NULL);
- ret &= AddCallback(&ClientStateCallback, SELinuxClientState, 0);
- ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, 0);
-
- ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SELinuxExtension, 0);
- ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SELinuxResource, 0);
- ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SELinuxDevice, 0);
- ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, 0);
- ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SELinuxSend, 0);
- ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, 0);
- ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SELinuxClient, 0);
- ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SELinuxExtension, 0);
- ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SELinuxServer, 0);
-// ret &= XaceRegisterCallback(XACE_SELECTION_ACCESS, SELinuxSelection, 0);
- ret &= XaceRegisterCallback(XACE_SCREEN_ACCESS, SELinuxScreen, 0);
- ret &= XaceRegisterCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, &ret);
+ ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL);
+ ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, NULL);
+
+ ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL);
+ ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL);
+ ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SELinuxDevice, NULL);
+ ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SELinuxProperty, NULL);
+ ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SELinuxSend, NULL);
+ ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SELinuxReceive, NULL);
+ ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SELinuxClient, NULL);
+ ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SELinuxExtension, NULL);
+ ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SELinuxServer, NULL);
+// ret &= XaceRegisterCallback(XACE_SELECTION_ACCESS, SELinuxSelection, NULL);
+ ret &= XaceRegisterCallback(XACE_SCREEN_ACCESS, SELinuxScreen, NULL);
+ ret &= XaceRegisterCallback(XACE_SCREENSAVER_ACCESS, SELinuxScreen, truep);
if (!ret)
FatalError("XSELinux: Failed to register one or more callbacks\n");
commit 9e0a468af19d8e46330bcff37c9adc5e11d3aee7
Author: Eamon Walsh <ewalsh at tycho.nsa.gov>
Date: Tue Oct 23 13:35:30 2007 -0400
xace: try to pretend events were sent when a denial occurs.
Probably need to redo the error return paths in these functions
at some point.
diff --git a/dix/events.c b/dix/events.c
index 246220f..24de947 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1754,7 +1754,7 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
!((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
return 0;
if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
- nondeliveries--;
+ /* do nothing */;
else if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
pWin->eventMask, filter, grab)) )
{
@@ -1785,7 +1785,7 @@ DeliverEventsToWindow(WindowPtr pWin, xEvent *pEvents, int count,
{
if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents,
count))
- nondeliveries--;
+ /* do nothing */;
else if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
other->mask[mskidx], filter, grab)) )
{
@@ -1884,7 +1884,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
wClient(pWin), NullGrab, pWin->eventMask, filter);
#endif
if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
- return 0;
+ return 1; /* don't send, but pretend we did */
return TryClientEvents(wClient(pWin), pEvents, count,
pWin->eventMask, filter, NullGrab);
}
@@ -1901,7 +1901,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
#endif
if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents,
count))
- return 0;
+ return 1; /* don't send, but pretend we did */
return TryClientEvents(rClient(other), pEvents, count,
other->mask, filter, NullGrab);
}
@@ -2896,9 +2896,9 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
return;
}
- /* just deliver it to the focus window */
if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count))
return;
+ /* just deliver it to the focus window */
FixUpEventFromWindow(xE, focus, None, FALSE);
if (xE->u.u.type & EXTENSION_EVENT_BASE)
mskidx = keybd->id;
@@ -2947,9 +2947,11 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
if (!deliveries)
{
FixUpEventFromWindow(xE, grab->window, None, TRUE);
- if (!XaceHook(XACE_SEND_ACCESS, 0, thisDev, grab->window, xE, count) &&
- !XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), grab->window, xE,
- count))
+ if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, grab->window, xE, count) ||
+ XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), grab->window, xE,
+ count))
+ deliveries = 1; /* don't send, but pretend we did */
+ else
deliveries = TryClientEvents(rClient(grab), xE, count,
(Mask)grab->eventMask,
filters[xE->u.u.type], grab);
More information about the xorg-commit
mailing list