Skip to content

Commit

Permalink
Merge pull request #1337 from yshui/leader-wm-consistency
Browse files Browse the repository at this point in the history
Fix NULL dereference when refreshing window leader with an inconsistent wm tree
  • Loading branch information
yshui authored Sep 10, 2024
2 parents 61361ad + 67ec733 commit 5f69580
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/picom.c
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,8 @@ static void unredirect(session_t *ps) {
/// keeps an internal queue of events, so we have to be 100% sure no events are
/// left in that queue before we go to sleep.
static void handle_x_events(struct session *ps) {
bool wm_was_consistent = wm_is_consistent(ps->wm);

if (ps->vblank_scheduler) {
vblank_handle_x_events(ps->vblank_scheduler);
}
Expand Down Expand Up @@ -1478,6 +1480,12 @@ static void handle_x_events(struct session *ps) {
log_fatal("X11 server connection broke (error %d)", err);
exit(1);
}

if (wm_is_consistent(ps->wm) != wm_was_consistent && !wm_was_consistent) {
log_debug("Window tree has just become consistent, queueing redraw.");
ps->pending_updates = true;
queue_redraw(ps);
}
}

static void handle_x_events_ev(EV_P attr_unused, ev_prepare *w, int revents attr_unused) {
Expand Down
19 changes: 19 additions & 0 deletions src/wm/wm.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,22 @@ void wm_refresh_leaders(struct wm *wm) {
if (!wm->needs_leader_refresh) {
return;
}
if (!wm_is_consistent(wm)) {
// The window tree has not been fully replicated, we might be missing
// windows, so we couldn't refresh the leaders here, but also can't leave
// them NULL. So we just set them to themselves.
log_debug("Window tree is not consistent, setting all leaders to "
"themselves");
list_foreach(struct wm_tree_node, i, &wm->tree.root->children, siblings) {
if (i->is_zombie) {
// Don't change anything about a zombie window.
continue;
}
i->leader_final = i;
}
return;
}
log_debug("Refreshing window leaders");
wm->needs_leader_refresh = false;
list_foreach(struct wm_tree_node, i, &wm->tree.root->children, siblings) {
if (i->is_zombie) {
Expand All @@ -249,6 +265,9 @@ void wm_refresh_leaders(struct wm *wm) {
continue;
}
wm_find_leader(wm, i);
BUG_ON_NULL(i->leader_final);
log_verbose("Window %#010x has leader %#010x", i->id.x,
i->leader_final->id.x);
}
}

Expand Down

0 comments on commit 5f69580

Please sign in to comment.