e_policy: Fix use-after-free 15/318115/1
authorSeunghun Lee <shiin@samsung.com>
Tue, 24 Sep 2024 07:11:12 +0000 (16:11 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 24 Sep 2024 23:43:05 +0000 (08:43 +0900)
Removing a listener from the buffer_clear signal of E_Pixmap after
E_Pixmap has been destroyed results in use-after-free issue.

To resolve this problem, E_Pixmap will emit the destroy signal just
before it's destroyed. The implementation using E_Pixmap should remove
all listeners from the E_Pixmap when destroy signal is emitted.

Change-Id: I38f9fd86fd4815f156cc74bfc7934c79a55fbc6f

src/bin/core/e_pixmap.c
src/bin/core/e_pixmap_intern.h
src/bin/windowmgr/e_policy.c
src/bin/windowmgr/e_policy_intern.h

index d8e88f6e0a09323f75994116435cd997380998a0..cbb09c722832020d513f52f41cc267e1de46b895 100644 (file)
@@ -52,6 +52,7 @@ struct _E_Pixmap
    struct wl_listener surface_resource_destroy;
 
    struct {
+      struct wl_signal destroy;
       struct wl_signal buffer_clear;
       struct wl_signal buffer_clear_done;
    } events;
@@ -180,6 +181,7 @@ _e_pixmap_new(E_Pixmap_Type type)
    cp->cdata->pending.buffer_viewport.changed = 0;
    cp->own_cdata = EINA_TRUE;
 
+   wl_signal_init(&cp->events.destroy);
    wl_signal_init(&cp->events.buffer_clear);
    wl_signal_init(&cp->events.buffer_clear_done);
 
@@ -206,6 +208,7 @@ e_pixmap_free(E_Pixmap *cp)
    if (cp->usable)
      e_pixmap_usable_set(cp, 0);
 
+   wl_signal_emit(&cp->events.destroy, cp);
    _e_pixmap_hook_call(E_PIXMAP_HOOK_DEL, cp);
    e_pixmap_image_clear(cp, EINA_FALSE);
    eina_hash_del_by_key(res_ids, &cp->res_id);
@@ -958,6 +961,12 @@ e_pixmap_buffer_type_get(E_Pixmap *pixmap)
    return pixmap->buffer->type;
 }
 
+EINTERN void
+e_pixmap_destroy_listener_add(E_Pixmap *pixmap, struct wl_listener *listener)
+{
+   wl_signal_add(&pixmap->events.destroy, listener);
+}
+
 EINTERN void
 e_pixmap_buffer_clear_listener_add(E_Pixmap *pixmap, struct wl_listener *listener)
 {
index 6786cbd0fa60d94656715be7631e1e7c3ed3a4b6..b68bd2f365c8b8422164e50f43bca510c85643ff 100644 (file)
@@ -32,6 +32,7 @@ EINTERN void         *e_pixmap_ref_resource_get(E_Pixmap *cp);
 EINTERN E_Comp_Wl_Buffer_Type e_pixmap_buffer_type_get(E_Pixmap *pixmap);
 EINTERN void                  e_pixmap_buffer_clear_done_send(E_Pixmap *pixmap);
 
+EINTERN void          e_pixmap_destroy_listener_add(E_Pixmap *pixmap, struct wl_listener *listener);
 EINTERN void          e_pixmap_buffer_clear_listener_add(E_Pixmap *pixmap, struct wl_listener *listener);
 EINTERN void          e_pixmap_buffer_clear_done_listener_add(E_Pixmap *pixmap, struct wl_listener *listener);
 
index 99a55a6c881aada18674ccf16d72ac2dd6d91311..0ee5105f01d574c034314933f3638183c73c6963 100644 (file)
@@ -219,6 +219,7 @@ static void
 _e_policy_client_del(E_Policy_Client *pc)
 {
    wl_list_remove(&pc->pixmap_buffer_clear.link);
+   wl_list_remove(&pc->pixmap_destroy.link);
 
    if (pc->buffer_flush_timer)
      ecore_timer_del(pc->buffer_flush_timer);
@@ -2456,6 +2457,20 @@ _e_policy_client_cb_pixmap_buffer_clear(struct wl_listener *listener, void *data
      _e_policy_client_pixmap_buffer_clear(policy_client, only_free);
 }
 
+static void
+_e_policy_client_cb_pixmap_destroy(struct wl_listener *listener, void *data)
+{
+   E_Policy_Client *pc;
+
+   pc = wl_container_of(listener, pc, pixmap_destroy);
+
+   wl_list_remove(&pc->pixmap_buffer_clear.link);
+   wl_list_init(&pc->pixmap_buffer_clear.link);
+
+   wl_list_remove(&pc->pixmap_destroy.link);
+   wl_list_init(&pc->pixmap_destroy.link);
+}
+
 EINTERN E_Policy_Client *
 e_policy_client_add(E_Client *ec)
 {
@@ -2478,6 +2493,9 @@ e_policy_client_add(E_Client *ec)
    _e_policy_desk_client_add_hook_add(pc);
 
    // pixmap listener add
+   pc->pixmap_destroy.notify = _e_policy_client_cb_pixmap_destroy;
+   e_pixmap_destroy_listener_add(ec->pixmap, &pc->pixmap_destroy);
+
    pc->pixmap_buffer_clear.notify = _e_policy_client_cb_pixmap_buffer_clear;
    e_pixmap_buffer_clear_listener_add(ec->pixmap, &pc->pixmap_buffer_clear);
 
index 95cca29059969addf3106ff49700005e11f560a0..74a511928946788dbfd2a93fb6e8bbd132fcf348 100644 (file)
@@ -72,6 +72,7 @@ struct _E_Policy_Client
    Ecore_Timer *buffer_flush_timer;
    Eina_Bool buffer_flush_only_free;
 
+   struct wl_listener pixmap_destroy;
    struct wl_listener pixmap_buffer_clear;
 };