window: remove pointers to widget on destroy
authorPekka Paalanen <ppaalanen@gmail.com>
Thu, 19 Jan 2012 11:51:38 +0000 (13:51 +0200)
committerPekka Paalanen <ppaalanen@gmail.com>
Thu, 19 Jan 2012 14:41:55 +0000 (16:41 +0200)
Input devices may hold a pointer to the widget being destroyed. Reset
such pointers in widget_destroy().

This fixes a use-after-free in window_destroy(), if an application
destroys its widgets before the window.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
clients/window.c

index deb7a97..d1833af 100644 (file)
@@ -973,9 +973,6 @@ window_destroy(struct window *window)
        wl_list_for_each(input, &display->input_list, link) {
                if (input->pointer_focus == window)
                        input->pointer_focus = NULL;
-               if (input->focus_widget &&
-                   input->focus_widget->window == window)
-                       input->focus_widget = NULL;
                if (input->keyboard_focus == window)
                        input->keyboard_focus = NULL;
        }
@@ -1056,6 +1053,14 @@ widget_add_widget(struct widget *parent, void *data)
 void
 widget_destroy(struct widget *widget)
 {
+       struct display *display = widget->window->display;
+       struct input *input;
+
+       wl_list_for_each(input, &display->input_list, link) {
+               if (input->focus_widget == widget)
+                       input->focus_widget = NULL;
+       }
+
        wl_list_remove(&widget->link);
        free(widget);
 }