diff --git a/Xext/namespace/config.c b/Xext/namespace/config.c index a62952cb2..72a05faa9 100644 --- a/Xext/namespace/config.c +++ b/Xext/namespace/config.c @@ -7,6 +7,9 @@ struct Xnamespace ns_root = { .allowMouseMotion = TRUE, + .allowShape = TRUE, + .allowXInput = TRUE, + .allowXKeyboard = TRUE, .builtin = TRUE, .name = NS_NAME_ROOT, .refcnt = 1, diff --git a/Xext/namespace/hook-ext-access.c b/Xext/namespace/hook-ext-access.c new file mode 100644 index 000000000..0f86dc47f --- /dev/null +++ b/Xext/namespace/hook-ext-access.c @@ -0,0 +1,67 @@ +#define HOOK_NAME "ext-access" + +#include + +#include "dix/dix_priv.h" +#include "dix/extension_priv.h" +#include "dix/registry_priv.h" +#include "Xext/xacestr.h" + +#include "namespace.h" +#include "hooks.h" + +/* called on X_QueryExtension */ +void hookExtAccess(CallbackListPtr *pcbl, void *unused, void *calldata) +{ + XNS_HOOK_HEAD(XaceExtAccessRec); + + /* root NS has super powers */ + if (subj->ns->superPower) + goto pass; + + switch (param->ext->index + EXTENSION_BASE) { + /* unrestricted access */ + case EXTENSION_MAJOR_BIG_REQUESTS: + case EXTENSION_MAJOR_DAMAGE: + case EXTENSION_MAJOR_DOUBLE_BUFFER: + case EXTENSION_MAJOR_GENERIC_EVENT: + case EXTENSION_MAJOR_PRESENT: + case EXTENSION_MAJOR_SYNC: + case EXTENSION_MAJOR_XC_MISC: + case EXTENSION_MAJOR_XFIXES: + case EXTENSION_MAJOR_XKEYBOARD: + case EXTENSION_MAJOR_XRESOURCE: + goto pass; + + /* really blacklisted */ + case EXTENSION_MAJOR_MIT_SCREEN_SAVER: + case EXTENSION_MAJOR_RECORD: + case EXTENSION_MAJOR_SECURITY: + case EXTENSION_MAJOR_XTEST: + case EXTENSION_MAJOR_XVIDEO: + goto reject; + + /* only allowed if namespace has flag set */ + case EXTENSION_MAJOR_SHAPE: + if (subj->ns->allowShape) + goto pass; + goto reject; + + /* only allowed if namespace has flag set */ + case EXTENSION_MAJOR_XINPUT: + if (subj->ns->allowXInput) + goto pass; + goto reject; + } + + XNS_HOOK_LOG("unhandled extension query: %s (%d)\n", param->ext->name, param->ext->index); + return; + +reject: + param->status = BadAccess; + return; + +pass: + param->status = Success; + return; +} diff --git a/Xext/namespace/hook-ext-dispatch.c b/Xext/namespace/hook-ext-dispatch.c new file mode 100644 index 000000000..085704cf9 --- /dev/null +++ b/Xext/namespace/hook-ext-dispatch.c @@ -0,0 +1,110 @@ +#define HOOK_NAME "ext-dispatch" + +#include + +#include +#include // syncproto.h is broken +#include +#include +#include +#include + +#include "dix/dix_priv.h" +#include "dix/extension_priv.h" +#include "dix/registry_priv.h" +#include "Xext/xacestr.h" + +#include "namespace.h" +#include "hooks.h" + +void hookExtDispatch(CallbackListPtr *pcbl, void *unused, void *calldata) +{ + XNS_HOOK_HEAD(XaceExtAccessRec); + + /* root NS has super powers */ + if (subj->ns->superPower) + goto pass; + + switch (client->majorOp) { + /* unrestricted access to these */ + case EXTENSION_MAJOR_BIG_REQUESTS: + case EXTENSION_MAJOR_DAMAGE: + case EXTENSION_MAJOR_DOUBLE_BUFFER: + case EXTENSION_MAJOR_GENERIC_EVENT: + case EXTENSION_MAJOR_PRESENT: + case EXTENSION_MAJOR_XC_MISC: + case EXTENSION_MAJOR_XRESOURCE: + goto pass; + + /* allow several operations */ + case EXTENSION_MAJOR_XKEYBOARD: + if (subj->ns->allowXKeyboard) + goto pass; + switch (client->minorOp) { + case X_kbUseExtension: + case X_kbGetMap: + case X_kbSelectEvents: // fixme: might need special filtering + case X_kbGetState: + case X_kbGetNames: + case X_kbGetControls: + case X_kbPerClientFlags: + goto pass; + } + XNS_HOOK_LOG("BLOCKED unhandled XKEYBOARD call: %s\n", param->ext->name); + goto reject; + + /* allow if namespace has flag set */ + case EXTENSION_MAJOR_SHAPE: + if (subj->ns->allowShape) + goto pass; + break; + case EXTENSION_MAJOR_XINPUT: + if (subj->ns->allowXInput) + goto pass; + break; + + case EXTENSION_MAJOR_XFIXES: + switch (client->minorOp) { + case X_XFixesQueryVersion: + case X_XFixesCreateRegion: + case X_XFixesSetCursorName: + case X_XFixesSelectSelectionInput: + goto pass; + } + XNS_HOOK_LOG("BLOCKED unhandled XFIXES call: %s\n", param->ext->name); + goto reject; + break; + + case EXTENSION_MAJOR_SYNC: + switch (client->minorOp) { + case X_SyncCreateCounter: + case X_SyncDestroyCounter: + case X_SyncInitialize: + case X_SyncSetCounter: + goto pass; + } + XNS_HOOK_LOG("REJECT unhandled SYNC call: %s\n", param->ext->name); + goto reject; + break; + + /* really blacklisted */ + case EXTENSION_MAJOR_MIT_SCREEN_SAVER: + case EXTENSION_MAJOR_RECORD: + case EXTENSION_MAJOR_SECURITY: + case EXTENSION_MAJOR_XTEST: + goto reject; + break; + } + + XNS_HOOK_LOG("unhandled extension call: %s\n", param->ext->name); + return; + +reject: + XNS_HOOK_LOG("rejecting extension call: %s\n", param->ext->name); + param->status = BadAccess; + return; + +pass: + param->status = Success; + return; +} diff --git a/Xext/namespace/hooks.h b/Xext/namespace/hooks.h index 956ad3dba..5f0b35040 100644 --- a/Xext/namespace/hooks.h +++ b/Xext/namespace/hooks.h @@ -25,6 +25,8 @@ struct XnamespaceClientPriv *subj = XnsClientPriv(client); void hookClientState(CallbackListPtr *pcbl, void *unused, void *calldata); +void hookExtAccess(CallbackListPtr *pcbl, void *unused, void *calldata); +void hookExtDispatch(CallbackListPtr *pcbl, void *unused, void *calldata); void hookInitRootWindow(CallbackListPtr *pcbl, void *unused, void *calldata); void hookReceive(CallbackListPtr *pcbl, void *unused, void *calldata); void hookSelectionFilter(CallbackListPtr *pcbl, void *unused, void *calldata); diff --git a/Xext/namespace/meson.build b/Xext/namespace/meson.build index 92a1c1d6a..d11666131 100644 --- a/Xext/namespace/meson.build +++ b/Xext/namespace/meson.build @@ -3,6 +3,8 @@ libxserver_namespace = static_library( [ 'config.c', 'hook-clientstate.c', + 'hook-ext-access.c', + 'hook-ext-dispatch.c', 'hook-init-rootwindow.c', 'hook-receive.c', 'hook-selection.c', diff --git a/Xext/namespace/namespace.c b/Xext/namespace/namespace.c index 0e8214581..04371d70a 100644 --- a/Xext/namespace/namespace.c +++ b/Xext/namespace/namespace.c @@ -34,6 +34,8 @@ NamespaceExtensionInit(void) AddCallback(&PostInitRootWindowCallback, hookInitRootWindow, NULL) && AddCallback(&PropertyFilterCallback, hookWindowProperty, NULL) && AddCallback(&SelectionFilterCallback, hookSelectionFilter, NULL) && + XaceRegisterCallback(XACE_EXT_DISPATCH, hookExtDispatch, NULL) && + XaceRegisterCallback(XACE_EXT_ACCESS, hookExtAccess, NULL) && XaceRegisterCallback(XACE_RECEIVE_ACCESS, hookReceive, NULL))) FatalError("NamespaceExtensionInit: allocation failure\n"); diff --git a/Xext/namespace/namespace.h b/Xext/namespace/namespace.h index fed2565b7..c5aee7dd8 100644 --- a/Xext/namespace/namespace.h +++ b/Xext/namespace/namespace.h @@ -15,6 +15,9 @@ struct Xnamespace { const char *name; Bool builtin; Bool allowMouseMotion; + Bool allowShape; + Bool allowXInput; + Bool allowXKeyboard; Bool superPower; const char *authProto; char *authTokenData;