From aaa8d5a9558421c0eaa5cc3bf2666caa814d0a47 Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Mon, 5 May 2025 13:56:27 +0200 Subject: [PATCH] xwayland: don't allow clients to modify the keymap Xwayland has no way to affect the keymap of the compositor. If clients modify the keymap, it will stay out of sync with the compositor until some unspecified time in the future when the compositor sends the keymap again, which might be never, requiring Xwayland to be restarted. Signed-off-by: Julian Orth Part-of: --- hw/xfree86/common/xf86Module.h | 2 +- hw/xwayland/xwayland-input.c | 5 ++++- include/inputstr.h | 1 + xkb/xkb.c | 18 ++++++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h index 96dfa8e56..6d96f985d 100644 --- a/hw/xfree86/common/xf86Module.h +++ b/hw/xfree86/common/xf86Module.h @@ -75,7 +75,7 @@ */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) #define ABI_VIDEODRV_VERSION SET_ABI_VERSION(27, 0) -#define ABI_XINPUT_VERSION SET_ABI_VERSION(25, 0) +#define ABI_XINPUT_VERSION SET_ABI_VERSION(26, 0) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(10, 0) #define MODINFOSTRING1 0xef23fdc5 diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 3854149cb..d940d604b 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -1206,10 +1206,13 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, } XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb); + xwl_seat->keyboard->hasDdxKeymap = TRUE; master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD); - if (master) + if (master) { XkbDeviceApplyKeymap(master, xkb); + master->hasDdxKeymap = TRUE; + } XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE); diff --git a/include/inputstr.h b/include/inputstr.h index 208600768..6efc1653a 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -632,6 +632,7 @@ typedef struct _DeviceIntRec { struct _SyncCounter *idle_counter; Bool ignoreXkbActionsBehaviors; /* TRUE if keys don't trigger behaviors and actions */ + Bool hasDdxKeymap; /* TRUE if clients cannot modify the keymap */ } DeviceIntRec; typedef struct { diff --git a/xkb/xkb.c b/xkb/xkb.c index 46a510ded..c4ed3fb1e 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -2728,6 +2728,9 @@ ProcXkbSetMap(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); CHK_MASK_LEGAL(0x01, stuff->present, XkbAllMapComponentsMask); + if (dev->hasDdxKeymap) + return BadAccess; + /* first verify the request length carefully */ rc = _XkbSetMapCheckLength(stuff); if (rc != Success) @@ -3113,6 +3116,9 @@ ProcXkbSetCompatMap(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); + if (dev->hasDdxKeymap) + return BadAccess; + data = (char *) &stuff[1]; /* check first using a dry-run */ @@ -3370,6 +3376,9 @@ ProcXkbSetIndicatorMap(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); + if (dev->hasDdxKeymap) + return BadAccess; + if (stuff->which == 0) return Success; @@ -4466,6 +4475,9 @@ ProcXkbSetNames(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); CHK_MASK_LEGAL(0x01, stuff->which, XkbAllNamesMask); + if (dev->hasDdxKeymap) + return BadAccess; + /* check device-independent stuff */ tmp = (CARD32 *) &stuff[1]; @@ -5681,6 +5693,9 @@ ProcXkbSetGeometry(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); CHK_ATOM_OR_NONE(stuff->name); + if (dev->hasDdxKeymap) + return BadAccess; + rc = _XkbSetGeometry(client, dev, stuff); if (rc != Success) return rc; @@ -5947,6 +5962,9 @@ ProcXkbGetKbdByName(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); master = GetMaster(dev, MASTER_KEYBOARD); + if (stuff->load && dev->hasDdxKeymap) + return BadAccess; + xkb = dev->key->xkbInfo->desc; status = Success; str = (unsigned char *) &stuff[1];