x11/keymap: be more defensive about the number of modifiers
authorRan Benita <ran234@gmail.com>
Fri, 8 Aug 2014 14:21:28 +0000 (17:21 +0300)
committerRan Benita <ran234@gmail.com>
Fri, 8 Aug 2014 14:29:42 +0000 (17:29 +0300)
There can be at most 16 vmods, and we rely on the facts that #vmods +
NUM_REAL_MODS (8) <= XKB_MAX_MODS (32) when accessing keymap->mods.mods.
But msb_pos() can potentially return up to #vmods = 32 if the server is
malicious, so we need to truncate it.

Signed-off-by: Ran Benita <ran234@gmail.com>
src/x11/keymap.c

index f852078..e3f989d 100644 (file)
@@ -508,7 +508,8 @@ get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn,
 {
     uint8_t *iter = xcb_xkb_get_map_map_vmods_rtrn(map);
 
-    keymap->mods.num_mods = NUM_REAL_MODS + msb_pos(reply->virtualMods);
+    keymap->mods.num_mods =
+        NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS);
 
     for (unsigned i = 0; i < NUM_VMODS; i++) {
         if (reply->virtualMods & (1u << i)) {
@@ -918,7 +919,8 @@ get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
      * tells us which vmods exist (a vmod must have a name), so we fix
      * up the size here.
      */
-    keymap->mods.num_mods = NUM_REAL_MODS + msb_pos(reply->virtualMods);
+    keymap->mods.num_mods =
+        NUM_REAL_MODS + MIN(msb_pos(reply->virtualMods), NUM_VMODS);
 
     for (unsigned i = 0; i < NUM_VMODS; i++) {
         if (reply->virtualMods & (1u << i)) {