Skip to content

Commit 71eeacf

Browse files
committed
gfx/x11: NULL-check keysym rlut calloc to avoid OOM segfault
x11_init_keyboard_lut rebuilds the reverse keysym lookup table: if (x11_keysym_rlut) free(x11_keysym_rlut); x11_keysym_rlut = (unsigned*)calloc(++x11_keysym_rlut_size, sizeof(unsigned)); for (map = map_start; map->rk != RETROK_UNKNOWN; map++) x11_keysym_rlut[map->sym] = (enum retro_key)map->rk; If the calloc returns NULL, the populate loop dereferences NULL on its first iteration. The size allocated here is driven by the maximum X11 keysym value observed while building x11_keysym_lut (a few hundred unsigneds, so ~kB), small enough that OOM is unlikely in normal operation but still possible under extreme memory pressure. The lookup-side reader already handles the disabled-rlut case: if (x11_keysym_rlut && sym < x11_keysym_rlut_size) return (enum retro_key)x11_keysym_rlut[sym]; so the correct failure behaviour is to leave x11_keysym_rlut as NULL and set x11_keysym_rlut_size = 0. The reader's NULL + bounds guard then falls through cleanly and the caller transparently gets whatever fallback path follows. The existing 'x11_keysym_rlut_size >= 65536' branch at the bottom of this same function already uses size = 0 as the 'rlut disabled' sentinel, so this matches the existing convention. Thread-safety: unchanged. Called once during X11 context initialisation; x11_keysym_rlut is a file-scope static touched only on the main thread. Reachability: X11 input context init. Runs once per X11 window bring-up.
1 parent 7ecdd2f commit 71eeacf

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

gfx/common/x11_common.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,10 +426,17 @@ static void x11_init_keyboard_lut(void)
426426
if (x11_keysym_rlut)
427427
free(x11_keysym_rlut);
428428

429-
x11_keysym_rlut = (unsigned*)calloc(++x11_keysym_rlut_size, sizeof(unsigned));
430-
431-
for (map = map_start; map->rk != RETROK_UNKNOWN; map++)
432-
x11_keysym_rlut[map->sym] = (enum retro_key)map->rk;
429+
/* NULL-check the calloc: the populate loop below dereferences
430+
* x11_keysym_rlut[map->sym] unconditionally, so an OOM here
431+
* would segfault. The reader (x11_keysym_lookup, line ~493)
432+
* guards with 'if (x11_keysym_rlut && sym < size)', so leaving
433+
* the pointer NULL on failure cleanly disables the rlut path
434+
* without further damage. */
435+
if (!(x11_keysym_rlut = (unsigned*)calloc(++x11_keysym_rlut_size, sizeof(unsigned))))
436+
x11_keysym_rlut_size = 0;
437+
else
438+
for (map = map_start; map->rk != RETROK_UNKNOWN; map++)
439+
x11_keysym_rlut[map->sym] = (enum retro_key)map->rk;
433440
}
434441
else
435442
x11_keysym_rlut_size = 0;

0 commit comments

Comments
 (0)