Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- From: zackattackz
- Subject: [PATCH] systray: fix iterator UAF in on_change_systray
- on_change_systray() iterates systray.list_icons and calls reparent_icon()
- for each icon not yet reparented. If the XEMBED handshake fails,
- reparent_icon() calls remove_icon(), which g_slist_remove()s and g_free()s
- the current node. The loop then advances via l = l->next on the freed node,
- and the next iteration dereferences l->data on garbage memory (SIGSEGV).
- Trigger: any tray client that requests dock then destroys its window before
- the embed completes — e.g. Steam's transient 200x200 loader icon, Electron
- apps (Vesktop/Discord) that tear down their GdkWindow mid-embed.
- Fix: capture l->next at the top of the loop body, before any call that
- might free the current node. remove_icon() only frees the current node, so
- the pre-captured next pointer stays valid.
- This is the same iterator-invalidation pattern fixed in uevent_handler() by
- the glib2.76 patch (issue #4). That fix addressed one occurrence; this is
- the missed sibling in systraybar.c.
- Tested with a reproducer that queues N_SYSTEM_TRAY_REQUEST_DOCK events then
- destroys the windows before on_change_systray can reparent them:
- unpatched → SIGSEGV within a few rounds; patched → all rounds survive.
- ---
- src/systray/systraybar.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
- diff --git a/src/systray/systraybar.c b/src/systray/systraybar.c
- --- a/src/systray/systraybar.c
- +++ b/src/systray/systraybar.c
- @@ -299,8 +299,9 @@ void on_change_systray(void *obj)
- TrayWindow *traywin;
- - GSList *l;
- + GSList *l, *next;
- int i;
- - for (i = 1, l = systray.list_icons; l; i++, l = l->next) {
- + for (i = 1, l = systray.list_icons; l; i++, l = next) {
- + next = l->next;
- traywin = l->data;
Advertisement