From 00083125a12bc8809f5b6d498a85a880e268cc81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 30 Mar 2021 11:08:03 +0200 Subject: [PATCH] sixel: fix double free caused by bad free() in sixel_colors_set() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sixel_color_set() is called when the number of (sixel) color registers is changed. It frees the current palette, and changes the “palette size” variable. Originally, we only had a single palette. This is the one free:d by sixel_color_set(). Later, we added support for private vs. shared palettes. With this change, we now have one palette that is “never” free:d (the shared one), and a private palette that is always free:d after a sixel has been emitted. ‘sixel.palette’ is a pointer to the palette currently in use, and should only be accessed **while emitting a sixel**. This is the pointer sixel_color_set() free:d. So for example, if ‘sixel.palette’ pointed to the shared palette, we’d free the shared palette. But, we didn’t reset ‘sixel.shared_palette’, causing a double free later on. Closes #427 --- CHANGELOG.md | 3 +++ sixel.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40706868..16b5f9c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ * Reverted _"Consumed modifiers are no longer sent to the client application"_ (https://codeberg.org/dnkl/foot/issues/425). +* Crash caused by a double free originating in `XTSMGRAPHICS` - set + number of color registers + (https://codeberg.org/dnkl/foot/issues/427). ### Security diff --git a/sixel.c b/sixel.c index cac60493..903fe8e4 100644 --- a/sixel.c +++ b/sixel.c @@ -1344,8 +1344,10 @@ sixel_colors_set(struct terminal *term, unsigned count) unsigned new_palette_size = min(max(2, count), SIXEL_MAX_COLORS); LOG_DBG("sixel palette size set to %u", new_palette_size); - free(term->sixel.palette); - term->sixel.palette = NULL; + free(term->sixel.private_palette); + free(term->sixel.shared_palette); + term->sixel.private_palette = NULL; + term->sixel.shared_palette = NULL; term->sixel.palette_size = new_palette_size; sixel_colors_report_current(term);