xfixes/xace: fix pointer type mismatch on XFixesSelectSelectionInput()

This could potentially be security related or crash the server:

XFixesSelectSelectionInput() calls the XACE_SELECTION_ACCESS hook with
wrong parameter type: XID instead of pointer to Selection struct.
It seems that it hadn't been kept up in XACE changed to polyinstantiation.

When XACE is used (eg. Security or SELinux extension enabled), this can
easily lead to memory corruptions at attacker-controlled locations, since
the client-given XID is interpreted as the memory location of Selection
structure.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1556>
This commit is contained in:
Enrico Weigelt, metux IT consult 2024-05-17 17:26:02 +02:00 committed by Marge Bot
parent 9c95347244
commit 601fd0fd84

View File

@ -43,7 +43,7 @@ typedef struct _SelectionEvent *SelectionEventPtr;
typedef struct _SelectionEvent { typedef struct _SelectionEvent {
SelectionEventPtr next; SelectionEventPtr next;
Atom selection; Selection *selection;
CARD32 eventMask; CARD32 eventMask;
ClientPtr pClient; ClientPtr pClient;
WindowPtr pWindow; WindowPtr pWindow;
@ -79,14 +79,14 @@ XFixesSelectionCallback(CallbackListPtr *callbacks, void *data, void *args)
} }
UpdateCurrentTimeIf(); UpdateCurrentTimeIf();
for (e = selectionEvents; e; e = e->next) { for (e = selectionEvents; e; e = e->next) {
if (e->selection == selection->selection && (e->eventMask & eventMask)) { if (e->selection == selection && (e->eventMask & eventMask)) {
xXFixesSelectionNotifyEvent ev = { xXFixesSelectionNotifyEvent ev = {
.type = XFixesEventBase + XFixesSelectionNotify, .type = XFixesEventBase + XFixesSelectionNotify,
.subtype = subtype, .subtype = subtype,
.window = e->pWindow->drawable.id, .window = e->pWindow->drawable.id,
.owner = (subtype == XFixesSetSelectionOwnerNotify) ? .owner = (subtype == XFixesSetSelectionOwnerNotify) ?
selection->window : 0, selection->window : 0,
.selection = e->selection, .selection = e->selection->selection,
.timestamp = currentTime.milliseconds, .timestamp = currentTime.milliseconds,
.selectionTimestamp = selection->lastTimeChanged.milliseconds .selectionTimestamp = selection->lastTimeChanged.milliseconds
}; };
@ -120,13 +120,14 @@ CheckSelectionCallback(void)
static int static int
XFixesSelectSelectionInput(ClientPtr pClient, XFixesSelectSelectionInput(ClientPtr pClient,
Atom selection, WindowPtr pWindow, CARD32 eventMask) Atom selection_name, WindowPtr pWindow, CARD32 eventMask)
{ {
void *val; void *val;
int rc; int rc;
SelectionEventPtr *prev, e; SelectionEventPtr *prev, e;
Selection *selection;
rc = XaceHook(XACE_SELECTION_ACCESS, pClient, selection, DixGetAttrAccess); rc = dixLookupSelection(&selection, selection_name, pClient, DixGetAttrAccess);
if (rc != Success) if (rc != Success)
return rc; return rc;