wayland: add canary-based heap overflow detection to frame_bufs
Each frame_buf gets a canary field (0xDEADBEEF) set at creation. Before every frame_paint, all canaries are checked. If one is trashed, dumps all frame_buf IDs/sizes/addresses to /tmp/wm-canary.log before aborting. Set canary in ALL frame_buf creation paths: - wl_frame_create_toplevel, wl_frame_create_child - wl_fake_leader_create - wl_client_reparent (WINGs view frame_buf creation) - wl_view_commit_backing_impl (WINGs toplevel) - wl_screen dock_shadow and icon frame_bufs - wl_window pixmap-to-frame_buf path
This commit is contained in:
parent
9752672367
commit
01fb5f9e92
|
|
@ -220,6 +220,7 @@ wl_client_reparent(WNativeWindow client, WNativeWindow new_parent, int x, int y)
|
|||
}
|
||||
}
|
||||
|
||||
fb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
|
||||
/* Connect the WINGs view's backing store to this frame_buf's image */
|
||||
|
|
@ -327,6 +328,7 @@ void wl_view_commit_backing_impl(unsigned long id)
|
|||
wlr_scene_node_set_enabled(&fb->scene_buf->node, false);
|
||||
}
|
||||
}
|
||||
fb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
} else {
|
||||
wfree(fb);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ WNativeWindow wl_fake_leader_create(WScreen *scr)
|
|||
}
|
||||
}
|
||||
|
||||
fb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
return fb->id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_buffer.h>
|
||||
|
|
@ -403,6 +404,7 @@ wl_frame_create_toplevel(WScreen *scr,
|
|||
}
|
||||
}
|
||||
|
||||
fb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
/* Register this frame_buf image in the WINGs backing table so
|
||||
* WMDrawString() can resolve the window ID to a pixman_image_t
|
||||
|
|
@ -460,6 +462,7 @@ wl_frame_create_child(WNativeWindow parent_win, WScreen *scr,
|
|||
}
|
||||
}
|
||||
|
||||
fb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
W_RegisterBacking(fb->id, fb->image);
|
||||
return fb->id;
|
||||
|
|
@ -573,9 +576,37 @@ void wl_frame_paint_button(WCoreWindow *button, WTexture *texture,
|
|||
* pixman for bevel lines, and the WINGs font backend for title text.
|
||||
* Returns 1 (handled) so wFrameWindowPaint skips the Xlib code path.
|
||||
*/
|
||||
static void
|
||||
frame_buf_check_canaries(void)
|
||||
{
|
||||
struct wl_frame_buf *fb;
|
||||
wl_list_for_each(fb, &wl_state.frame_list, link) {
|
||||
if (fb->canary != 0xDEADBEEF) {
|
||||
{
|
||||
FILE *f = fopen("/tmp/wm-canary.log", "w");
|
||||
if (f) {
|
||||
fprintf(f, "CANARY TRASHED: fb id=0x%lx size=%dx%d parent=0x%lx canary=0x%08x\n",
|
||||
(unsigned long)fb->id, fb->width, fb->height,
|
||||
(unsigned long)fb->parent_id, fb->canary);
|
||||
struct wl_frame_buf *f2;
|
||||
wl_list_for_each(f2, &wl_state.frame_list, link) {
|
||||
fprintf(f, " fb %p id=0x%lx %dx%d parent=0x%lx canary=%s\n",
|
||||
(void*)f2, (unsigned long)f2->id, f2->width, f2->height,
|
||||
(unsigned long)f2->parent_id,
|
||||
f2->canary == 0xDEADBEEF ? "OK" : "BAD");
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
wl_frame_paint(struct WFrameWindow *fwin)
|
||||
{
|
||||
frame_buf_check_canaries();
|
||||
/* During live resize, skip expensive repaint — decorations content
|
||||
* doesn't change, only geometry. Paint once on grab release. */
|
||||
if (wl_state.grab_type == 2)
|
||||
|
|
|
|||
|
|
@ -513,6 +513,7 @@ wl_screen_create_internals(WScreen *scr)
|
|||
wlr_scene_node_set_enabled(&dsfb->tree->node, false);
|
||||
wlr_scene_node_lower_to_bottom(&dsfb->tree->node);
|
||||
}
|
||||
dsfb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &dsfb->link);
|
||||
scr->dock_shadow = dsfb->id;
|
||||
} else {
|
||||
|
|
@ -562,6 +563,7 @@ wl_screen_create_internals(WScreen *scr)
|
|||
}
|
||||
wlr_scene_node_set_enabled(&fb->tree->node, false);
|
||||
}
|
||||
fb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
W_RegisterBacking(fb->id, fb->image);
|
||||
scr->workspace_name = fb->id;
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ struct wl_frame_buf {
|
|||
int rel_x, rel_y; /* position relative to parent */
|
||||
int width, height;
|
||||
pixman_image_t *bg_pixmap; /* background pixmap for window_clear */
|
||||
uint32_t canary; /* overflow detection: must be 0xDEADBEEF */
|
||||
struct wl_list link; /* wl_state.frame_list */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -618,6 +618,7 @@ void wl_balloon_init(WScreen *scr)
|
|||
wlr_scene_node_set_enabled(&fb->tree->node, false);
|
||||
}
|
||||
|
||||
fb->canary = 0xDEADBEEF;
|
||||
wl_list_insert(&wl_state.frame_list, &fb->link);
|
||||
W_RegisterBacking(fb->id, fb->image);
|
||||
scr->balloon->window = (WNativeWindow)fb->id;
|
||||
|
|
|
|||
Loading…
Reference in New Issue