123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- From 9ed6fdd71890c5cc43747f105382d5677e5d37e7 Mon Sep 17 00:00:00 2001
- From: pldubouilh <pldubouilh@gmail.com>
- Date: Fri, 17 Mar 2023 18:23:47 +0100
- Subject: [PATCH] Fix list traversal issue in client_calc_layer
- The calls to client_calc_layer_internal can modify stacking_list, which
- can cause us to follow dangling ->next pointers (either by the pointer
- itself already being freed, or it pointing to a freed area). Avoid this
- by copying the list first, the goal is to visit every client in the list
- once so this should be fine.
- ---
- openbox/client.c | 9 +++++++--
- 1 file changed, 7 insertions(+), 2 deletions(-)
- diff --git a/openbox/client.c b/openbox/client.c
- index 7168b2407..b8264587c 100644
- --- a/openbox/client.c
- +++ b/openbox/client.c
- @@ -2742,9 +2742,12 @@ static void client_calc_layer_internal(ObClient *self)
- void client_calc_layer(ObClient *self)
- {
- GList *it;
- + /* the client_calc_layer_internal calls below modify stacking_list,
- + so we have to make a copy to iterate over */
- + GList *list = g_list_copy(stacking_list);
-
- /* skip over stuff above fullscreen layer */
- - for (it = stacking_list; it; it = g_list_next(it))
- + for (it = list; it; it = g_list_next(it))
- if (window_layer(it->data) <= OB_STACKING_LAYER_FULLSCREEN) break;
-
- /* find the windows in the fullscreen layer, and mark them not-visited */
- @@ -2757,7 +2760,7 @@ void client_calc_layer(ObClient *self)
- client_calc_layer_internal(self);
-
- /* skip over stuff above fullscreen layer */
- - for (it = stacking_list; it; it = g_list_next(it))
- + for (it = list; it; it = g_list_next(it))
- if (window_layer(it->data) <= OB_STACKING_LAYER_FULLSCREEN) break;
-
- /* now recalc any windows in the fullscreen layer which have not
- @@ -2768,6 +2771,8 @@ void client_calc_layer(ObClient *self)
- !WINDOW_AS_CLIENT(it->data)->visited)
- client_calc_layer_internal(it->data);
- }
- +
- + g_list_free(it);
- }
-
- gboolean client_should_show(ObClient *self)
|