From e92d6ad8e466b32e334cb7e8b2d387e0bda2cfbc Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Wed, 19 Mar 2025 10:50:56 +0100 Subject: [PATCH] Xnamespace: filter client-to-client message sending Filter message sending by clients. Only sending within the same namespace is allowed (except for clients in a NS with superpowers, e.g. root) Signed-off-by: Enrico Weigelt, metux IT consult --- Xext/namespace/hook-send.c | 53 ++++++++++++++++++++++++++++++++++++++ Xext/namespace/hooks.h | 1 + Xext/namespace/meson.build | 1 + Xext/namespace/namespace.c | 1 + 4 files changed, 56 insertions(+) create mode 100644 Xext/namespace/hook-send.c diff --git a/Xext/namespace/hook-send.c b/Xext/namespace/hook-send.c new file mode 100644 index 000000000..b06250c7c --- /dev/null +++ b/Xext/namespace/hook-send.c @@ -0,0 +1,53 @@ +#define HOOK_NAME "send" + +#include + +#include "dix/registry_priv.h" +#include "dix/resource_priv.h" +#include "Xext/xacestr.h" + +#include "namespace.h" +#include "hooks.h" + +/* TRUE if subj client is allowed to do things on obj) + * usually if they're in the same namespace or subj is in a parent + * namespace of obj + */ +static Bool clientAllowedOnClient(ClientPtr subj, ClientPtr obj) { + struct XnamespaceClientPriv *subjPriv = XnsClientPriv(subj); + struct XnamespaceClientPriv *objPriv = XnsClientPriv(obj); + + if (subjPriv && subjPriv->ns->superPower) + return TRUE; + + return XnsClientSameNS(subjPriv, objPriv); +} + +void hookSend(CallbackListPtr *pcbl, void *unused, void *calldata) +{ + XNS_HOOK_HEAD(XaceSendAccessRec); + + /* if no sending client, then it's coming internally from the server itself */ + if (!client) + goto pass; + + ClientPtr targetClient = dixClientForWindow(param->pWin); + struct XnamespaceClientPriv *obj = XnsClientPriv(targetClient); + if (clientAllowedOnClient(client, targetClient)) + goto pass; + + XNS_HOOK_LOG("BLOCK target @ %s\n", obj->ns->name); + for (int i = 0; i < param->count; i++) { + XNS_HOOK_LOG("sending event of type %s to window 0x%lx of client %d\n", + LookupEventName(param->events[i].u.u.type), + (unsigned long)param->pWin->drawable.id, + targetClient->index); + } + + param->status = BadAccess; + return; + +pass: + param->status = Success; + return; +} diff --git a/Xext/namespace/hooks.h b/Xext/namespace/hooks.h index 08093ac40..05e309f85 100644 --- a/Xext/namespace/hooks.h +++ b/Xext/namespace/hooks.h @@ -32,6 +32,7 @@ void hookInitRootWindow(CallbackListPtr *pcbl, void *unused, void *calldata); void hookReceive(CallbackListPtr *pcbl, void *unused, void *calldata); void hookResourceAccess(CallbackListPtr *pcbl, void *unused, void *calldata); void hookSelectionFilter(CallbackListPtr *pcbl, void *unused, void *calldata); +void hookSend(CallbackListPtr *pcbl, void *unused, void *calldata); void hookServerAccess(CallbackListPtr *pcbl, void *unused, void *calldata); void hookWindowProperty(CallbackListPtr *pcbl, void *unused, void *calldata); diff --git a/Xext/namespace/meson.build b/Xext/namespace/meson.build index 61cc47fae..ab4ccf2c6 100644 --- a/Xext/namespace/meson.build +++ b/Xext/namespace/meson.build @@ -10,6 +10,7 @@ libxserver_namespace = static_library( 'hook-receive.c', 'hook-resource.c', 'hook-selection.c', + 'hook-send.c', 'hook-server.c', 'hook-windowproperty.c', 'namespace.c', diff --git a/Xext/namespace/namespace.c b/Xext/namespace/namespace.c index da1b5f1dd..e1484e5de 100644 --- a/Xext/namespace/namespace.c +++ b/Xext/namespace/namespace.c @@ -39,6 +39,7 @@ NamespaceExtensionInit(void) XaceRegisterCallback(XACE_EXT_ACCESS, hookExtAccess, NULL) && XaceRegisterCallback(XACE_RECEIVE_ACCESS, hookReceive, NULL) && XaceRegisterCallback(XACE_RESOURCE_ACCESS, hookResourceAccess, NULL) && + XaceRegisterCallback(XACE_SEND_ACCESS, hookSend, NULL) && XaceRegisterCallback(XACE_SERVER_ACCESS, hookServerAccess, NULL))) FatalError("NamespaceExtensionInit: allocation failure\n");