Skip to content

Commit e9ad4d5

Browse files
npitregregkh
authored andcommitted
vt: fix spurious modifier in CSI/cursor key sequences
csi_modifier_param() builds the xterm modifier parameter from shift_state, counting KG_SHIFTL/KG_SHIFTR as Shift, KG_ALTGR as Alt and KG_CTRLL/KG_CTRLR as Ctrl in addition to the canonical KG_SHIFT, KG_ALT and KG_CTRL. That is wrong when those weights are not plain modifiers. Keymaps derived from XKB layouts (by kbd's xkbsupport, and by the console-setup used in Debian, Ubuntu and others) encode the active layout group using KG_SHIFTL/KG_SHIFTR: group 1: - group 2: shiftl group 3: shiftr group 4: shiftl | shiftr So while a non-default layout group is selected, KG_SHIFTL and/or KG_SHIFTR are set in shift_state with no Shift key held. csi_modifier_param() then adds a spurious Shift to every cursor and CSI key: pressing Up while group 2 is active emits ESC[1;2A (Shift+Up) instead of ESC[A. KG_ALTGR has the same problem since it is the standard third-level selector. Normal keymaps bind the physical Shift/Ctrl/Alt keys to KG_SHIFT, KG_CTRL and KG_ALT, leaving the left/right and AltGr weights free for layout and level selection. Count only those canonical weights, so genuine modifiers are still encoded while layout/level selectors are not. Fixes: 4af70f1 ("vt: add modifier support to cursor keys") Reported-by: Alexey Gladkov <legion@kernel.org> Closes: https://lore.kernel.org/kbd/aj2gR0Y7sM6i9s2G@example.org/ Cc: stable <stable@kernel.org> Signed-off-by: Nicolas Pitre <npitre@baylibre.com> Link: https://patch.msgid.link/20260626024833.3419086-1-nico@fluxnic.net Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 22dd277 commit e9ad4d5

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

drivers/tty/vt/keyboard.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -765,16 +765,22 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
765765
/*
766766
* Compute xterm-style modifier parameter for CSI sequences.
767767
* Returns 1 + (shift ? 1 : 0) + (alt ? 2 : 0) + (ctrl ? 4 : 0)
768+
*
769+
* Only the canonical modifier weights are counted. The left/right variants
770+
* (KG_SHIFTL, KG_SHIFTR, KG_CTRLL, KG_CTRLR) and KG_ALTGR are commonly
771+
* repurposed as keymap layout-group or level selectors rather than as plain
772+
* modifiers (for instance XKB-derived keymaps select the layout group with
773+
* KG_SHIFTL/KG_SHIFTR), so counting them would encode a spurious modifier.
768774
*/
769775
static int csi_modifier_param(void)
770776
{
771777
int mod = 1;
772778

773-
if (shift_state & (BIT(KG_SHIFT) | BIT(KG_SHIFTL) | BIT(KG_SHIFTR)))
779+
if (shift_state & BIT(KG_SHIFT))
774780
mod += 1;
775-
if (shift_state & (BIT(KG_ALT) | BIT(KG_ALTGR)))
781+
if (shift_state & BIT(KG_ALT))
776782
mod += 2;
777-
if (shift_state & (BIT(KG_CTRL) | BIT(KG_CTRLL) | BIT(KG_CTRLR)))
783+
if (shift_state & BIT(KG_CTRL))
778784
mod += 4;
779785
return mod;
780786
}

0 commit comments

Comments
 (0)