mirror of
https://github.com/X11Libre/xserver.git
synced 2026-11-14 05:14:45 +00:00
xkb: Guard XkbAdjustGroup() against a keymap with no groups
When every key in a keymap has zero groups, ctrls->num_groups is 0 and each out-of-range action here misbehaves. XkbWrapIntoRange divides by zero, which is the reported crash. XkbClampIntoRange is worse: it computes -1, returns it through this function's unsigned type, and the callers truncate it into XkbStateRec's unsigned char group fields as 255, after which XkbComputeCompatState() reads map->groups[255] out of a four element array and reports what it finds to clients in the compat state of every core event. The negative-group case adds zero forever, wedging the server thread, in one path while it holds input_lock. XkbComputeDerivedState() treats group 0 as out of range once num_groups is 0, so all of this is reachable from an ordinary key event. XQuartz gets there because it asks for model "empty", whose keycodes file declares no key names, so a keymap compiled at a client's request has no key definitions at all. Guard the arithmetic itself and not just the places that compute num_groups: groups_wrap selects between these actions and is client settable, and this is exported for DDXes that supply their own controls. Fixes: https://github.com/XQuartz/XQuartz/issues/422 Signed-off-by: Jeremy Huddleston Sequoia <jeremyhu@apple.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2278>
This commit is contained in:
parent
cfbc5224a6
commit
bdb14dce4b
1 changed files with 7 additions and 0 deletions
|
|
@ -665,6 +665,13 @@ XkbAdjustGroup(int group, XkbControlsPtr ctrls)
|
|||
{
|
||||
unsigned act;
|
||||
|
||||
/* A keymap with no groups leaves nothing to adjust into, and every action
|
||||
* below misbehaves: wrapping divides by zero, clamping underflows to -1,
|
||||
* and the negative-group loop never terminates.
|
||||
*/
|
||||
if (ctrls->num_groups == 0)
|
||||
return XkbGroup1Index;
|
||||
|
||||
act = XkbOutOfRangeGroupAction(ctrls->groups_wrap);
|
||||
if (group < 0) {
|
||||
while (group < 0) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue