From c63275d75e479bf39a104715423d1d6681c3163c Mon Sep 17 00:00:00 2001 From: Ilia Bozhinov Date: Sat, 20 Apr 2024 14:59:40 +0200 Subject: [PATCH] xwayland: add a size-safe wrapper for xcb_send_event xcb_send_event expects the caller to always provide 32 byte data, even if the actual event struct is smaller than that. Reference: https://gitlab.freedesktop.org/xorg/lib/libxcb/-/issues/18 --- include/xwayland/xwm.h | 4 ++++ xwayland/selection/dnd.c | 5 +++-- xwayland/selection/outgoing.c | 5 +++-- xwayland/xwm.c | 29 +++++++++++++++++++++++++---- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h index 66108e2b..6259dd9b 100644 --- a/include/xwayland/xwm.h +++ b/include/xwayland/xwm.h @@ -162,4 +162,8 @@ char *xwm_get_atom_name(struct wlr_xwm *xwm, xcb_atom_t atom); bool xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms, size_t num_atoms, enum atom_name needle); +xcb_void_cookie_t xwm_send_event_with_size(xcb_connection_t *c, + uint8_t propagate, xcb_window_t destination, + uint32_t event_mask, const void *event, uint32_t length); + #endif diff --git a/xwayland/selection/dnd.c b/xwayland/selection/dnd.c index 1c053e5e..e9cc63d9 100644 --- a/xwayland/selection/dnd.c +++ b/xwayland/selection/dnd.c @@ -49,11 +49,12 @@ static void xwm_dnd_send_event(struct wlr_xwm *xwm, xcb_atom_t type, .data = *data, }; - xcb_send_event(xwm->xcb_conn, + xwm_send_event_with_size(xwm->xcb_conn, 0, // propagate dest->window_id, XCB_EVENT_MASK_NO_EVENT, - (const char *)&event); + &event, + sizeof(event)); xcb_flush(xwm->xcb_conn); } diff --git a/xwayland/selection/outgoing.c b/xwayland/selection/outgoing.c index d2d0932c..3f2e2c71 100644 --- a/xwayland/selection/outgoing.c +++ b/xwayland/selection/outgoing.c @@ -27,11 +27,12 @@ static void xwm_selection_send_notify(struct wlr_xwm *xwm, " requestor=%" PRIu32 " selection=%" PRIu32 " target=%" PRIu32 " property=%" PRIu32, req->requestor, req->time, req->requestor, req->selection, req->target, selection_notify.property); - xcb_send_event(xwm->xcb_conn, + xwm_send_event_with_size(xwm->xcb_conn, 0, // propagate req->requestor, XCB_EVENT_MASK_NO_EVENT, - (const char *)&selection_notify); + &selection_notify, + sizeof(selection_notify)); xcb_flush(xwm->xcb_conn); } diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 0aa33336..d5b2aed8 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -257,6 +257,25 @@ static void xwm_set_net_active_window(struct wlr_xwm *xwm, xwm->atoms[WINDOW], 32, 1, &window); } +/* + * Wrapper for xcb_send_event, which ensures that the event data is 32 byte big. + */ +xcb_void_cookie_t xwm_send_event_with_size(xcb_connection_t *c, + uint8_t propagate, xcb_window_t destination, + uint32_t event_mask, const void *event, uint32_t length) +{ + if (length == 32) { + return xcb_send_event(c, propagate, destination, event_mask, event); + } else if (length < 32) { + char buf[32]; + memcpy(buf, event, length); + memset(buf + length, 0, 32 - length); + return xcb_send_event(c, propagate, destination, event_mask, buf); + } else { + assert(false && "Event too long"); + } +} + static void xwm_send_wm_message(struct wlr_xwayland_surface *surface, xcb_client_message_data_t *data, uint32_t event_mask) { struct wlr_xwm *xwm = surface->xwm; @@ -270,11 +289,12 @@ static void xwm_send_wm_message(struct wlr_xwayland_surface *surface, .data = *data, }; - xcb_send_event(xwm->xcb_conn, + xwm_send_event_with_size(xwm->xcb_conn, 0, // propagate surface->window_id, event_mask, - (const char *)&event); + &event, + sizeof(event)); xcb_flush(xwm->xcb_conn); } @@ -1824,9 +1844,10 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland_surface *xsurface, .height = height, }; - xcb_send_event(xwm->xcb_conn, 0, xsurface->window_id, + xwm_send_event_with_size(xwm->xcb_conn, 0, xsurface->window_id, XCB_EVENT_MASK_STRUCTURE_NOTIFY, - (const char *)&configure_notify); + &configure_notify, + sizeof(configure_notify)); } xcb_flush(xwm->xcb_conn);