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
---
 src/input.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/input.c b/src/input.c
index 5ce7f39..72c16c0 100644
--- a/src/input.c
+++ b/src/input.c
@@ -2033,19 +2033,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++;
                }
@@ -2053,16 +2049,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
-- 
1.8.1.2

_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to