From fc8e14a5bb01caddf2ee6671c805fded86fcb15d 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 --- 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 307713cf8..1a623a24b 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 35905829e..35d412c9a 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -1205,10 +1205,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 6ed2d928d..288efec4f 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -620,6 +620,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 744dba63d..74336d17b 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -2726,6 +2726,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) @@ -3109,6 +3112,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 */ @@ -3366,6 +3372,9 @@ ProcXkbSetIndicatorMap(ClientPtr client) CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); + if (dev->hasDdxKeymap) + return BadAccess; + if (stuff->which == 0) return Success; @@ -4461,6 +4470,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]; @@ -5676,6 +5688,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; @@ -5981,6 +5996,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];