diff options
author | Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com> | 2014-01-31 17:35:45 +0200 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2014-02-01 01:14:22 -0800 |
commit | 4d363cfcf6025db2277005845957e0b0e956ebd0 (patch) | |
tree | ded678ab4e0af1a9646059224b9b4c85ddc7f1dd /src | |
parent | 23900f70e57277805db652316b76d18b2d59281c (diff) | |
download | weston-4d363cfcf6025db2277005845957e0b0e956ebd0.tar.gz |
input: Fix weston_seat_init_keyboard() error path
The pointer seat->keyboard was set before some possible error returns.
That pointer was left unchanged in case of failure, pointing to an
uninitialized keyboard struct (that was also leaked). If a client sent
a wl_seat::get_keyboard request, that would cause Weston to crash.
Fix this by setting the seat->keyboard pointer only after the keymap
initialization is done and there is no more possibilities for failure.
Also plug the memory leaks on the error path.
https://bugs.freedesktop.org/show_bug.cgi?id=74035
Diffstat (limited to 'src')
-rw-r--r-- | src/input.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/input.c b/src/input.c index f7ae47d2..1d3bd1b5 100644 --- a/src/input.c +++ b/src/input.c @@ -2019,19 +2019,15 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap) return -1; } - seat->keyboard = keyboard; - seat->keyboard_device_count = 1; - keyboard->seat = seat; - #ifdef ENABLE_XKBCOMMON if (seat->compositor->use_xkbcommon) { if (keymap != NULL) { keyboard->xkb_info = weston_xkb_info_create(keymap); if (keyboard->xkb_info == NULL) - return -1; + goto err; } else { if (weston_compositor_build_global_keymap(seat->compositor) < 0) - return -1; + goto err; keyboard->xkb_info = seat->compositor->xkb_info; keyboard->xkb_info->ref_count++; } @@ -2039,16 +2035,27 @@ weston_seat_init_keyboard(struct weston_seat *seat, struct xkb_keymap *keymap) keyboard->xkb_state.state = xkb_state_new(keyboard->xkb_info->keymap); if (keyboard->xkb_state.state == NULL) { weston_log("failed to initialise XKB state\n"); - return -1; + goto err; } keyboard->xkb_state.leds = 0; } #endif + seat->keyboard = keyboard; + seat->keyboard_device_count = 1; + keyboard->seat = seat; + seat_send_updated_caps(seat); return 0; + +err: + if (keyboard->xkb_info) + weston_xkb_info_destroy(keyboard->xkb_info); + free(keyboard); + + return -1; } static void |