9ed6fdd.patch 2.0 KB

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