Fix a use-after-free

paint_preprocess takes head of the window list as an argument. The
actual head of the window list might be freed and deleted during processing
of fade, but paint_preprocess will keep using the old head of the list,
thus uses freed memory.

Solution is just don't pass the head as an argument. paint_preprocess
will use session_t::list directly.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-02-21 01:40:04 +00:00
parent 64e08cc1e3
commit 9aaf0fc707
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
1 changed files with 4 additions and 4 deletions

View File

@ -468,7 +468,7 @@ find_client_win(session_t *ps, xcb_window_t w) {
} }
static win * static win *
paint_preprocess(session_t *ps, win *list, bool *fade_running) { paint_preprocess(session_t *ps, bool *fade_running) {
// XXX need better, more general name for `fade_running`. It really // XXX need better, more general name for `fade_running`. It really
// means if fade is still ongoing after the current frame is rendered // means if fade is still ongoing after the current frame is rendered
win *t = NULL, *next = NULL; win *t = NULL, *next = NULL;
@ -488,7 +488,7 @@ paint_preprocess(session_t *ps, win *list, bool *fade_running) {
ps->fade_time += steps * ps->o.fade_delta; ps->fade_time += steps * ps->o.fade_delta;
// First, let's process fading // First, let's process fading
for (win *w = list; w; w = next) { for (win *w = ps->list; w; w = next) {
next = w->next; next = w->next;
const winmode_t mode_old = w->mode; const winmode_t mode_old = w->mode;
const bool was_painted = w->to_paint; const bool was_painted = w->to_paint;
@ -539,7 +539,7 @@ paint_preprocess(session_t *ps, win *list, bool *fade_running) {
// Trace whether it's the highest window to paint // Trace whether it's the highest window to paint
bool is_highest = true; bool is_highest = true;
bool reg_ignore_valid = true; bool reg_ignore_valid = true;
for (win *w = list; w; w = next) { for (win *w = ps->list; w; w = next) {
__label__ skip_window; __label__ skip_window;
bool to_paint = true; bool to_paint = true;
// w->to_paint remembers whether this window is painted last time // w->to_paint remembers whether this window is painted last time
@ -2115,7 +2115,7 @@ _draw_callback(EV_P_ session_t *ps, int revents) {
} }
bool fade_running = false; bool fade_running = false;
win *t = paint_preprocess(ps, ps->list, &fade_running); win *t = paint_preprocess(ps, &fade_running);
ps->tmout_unredir_hit = false; ps->tmout_unredir_hit = false;
// Start/stop fade timer depends on whether window are fading // Start/stop fade timer depends on whether window are fading