wayland: fix titlebar height overflow in frame_paint
The titlebar child frame_buf can have a height smaller than tb_h (fwin->top_width clamped to total_h). The existing bounds check only verified width, not height. The blit loop wrote tb_h rows into a shorter pixman image, overflowing into adjacent heap allocations. This caused 100%% reproducible SIGSEGV in malloc (heap corruption detected by glibc) on any operation following a frame paint where the titlebar child was shorter than expected — e.g. opening the Run dialog after a menu frame was painted. Fix: check both width AND height before using the titlebar child buffer. Fall back to drawing into the parent frame buffer (which is correctly sized) when either dimension is insufficient.
This commit is contained in:
parent
de15ca2282
commit
e00bc6b25a
|
|
@ -588,6 +588,7 @@ wl_frame_paint(struct WFrameWindow *fwin)
|
|||
int state = fwin->flags.state;
|
||||
int total_w = fb->width;
|
||||
int total_h = fb->height;
|
||||
int tb_in_parent = 0;
|
||||
/* Clear the buffer to transparent black. */
|
||||
pixman_color_t clear = {0, 0, 0, 0}; /* transparent */
|
||||
pixman_image_fill_rectangles(PIXMAN_OP_SRC, fb->image, &clear,
|
||||
|
|
@ -614,11 +615,12 @@ wl_frame_paint(struct WFrameWindow *fwin)
|
|||
wlr_scene_node_set_position(&tb_fb->scene_buf->node, 0, 0);
|
||||
}
|
||||
|
||||
/* If titlebar buffer is too narrow, draw directly into the
|
||||
* parent frame buffer to avoid unsafe in-place resize. */
|
||||
if (tb_fb && tb_fb->width < tb_w) {
|
||||
/* If titlebar buffer is too small, draw directly into the
|
||||
* parent frame buffer to avoid buffer overflow. */
|
||||
if (tb_fb && (tb_fb->width < tb_w || tb_fb->height < tb_h)) {
|
||||
tb_img = fb->image;
|
||||
tb_fb = NULL;
|
||||
tb_in_parent = 1;
|
||||
}
|
||||
WTexture *tex = fwin->title_texture[state];
|
||||
|
||||
|
|
@ -815,9 +817,9 @@ wl_frame_paint(struct WFrameWindow *fwin)
|
|||
|
||||
/* Commit the parent frame buffer when it has visible content:
|
||||
* resizebar pixels (unshaded) or titlebar fallback (when the titlebar
|
||||
* child buffer is too narrow and we drew into the parent instead). */
|
||||
* child buffer was too small and we drew into the parent instead). */
|
||||
if (fb->scene_buf) {
|
||||
if (show_resizebar || !fwin->titlebar || !frame_buf_find(fwin->titlebar->window)) {
|
||||
if (show_resizebar || tb_in_parent) {
|
||||
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
|
||||
wlr_scene_node_set_enabled(&fb->scene_buf->node, true);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue