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