From c91543352aff18052946e6ac3703a152f66307d7 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 21 May 2026 14:32:51 +0200 Subject: [PATCH] xwayland: stop using xcb_get_property_reply_t.value_len This field is difficult to use correctly, its meaning depends on format. xcb docs read: > You should use the corresponding accessor instead of this field. Replace all uses with the safe accessor. This fixes potential out-of-bounds array accesses when the format field isn't what we expect. --- xwayland/selection/incoming.c | 3 ++- xwayland/xwm.c | 22 ++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/xwayland/selection/incoming.c b/xwayland/selection/incoming.c index 53789f0f1..2e512e7db 100644 --- a/xwayland/selection/incoming.c +++ b/xwayland/selection/incoming.c @@ -344,7 +344,8 @@ static bool source_get_targets(struct wlr_xwm_selection *selection, } const xcb_atom_t *value = xcb_get_property_value(reply); - for (uint32_t i = 0; i < reply->value_len; i++) { + uint32_t value_len = xcb_get_property_value_length(reply) / sizeof(value); + for (uint32_t i = 0; i < value_len; i++) { char *mime_type = NULL; if (value[i] == xwm->atoms[UTF8_STRING]) { diff --git a/xwayland/xwm.c b/xwayland/xwm.c index 6a625ea5b..f561893cc 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -839,8 +839,8 @@ static void read_surface_window_type(struct wlr_xwm *xwm, } const xcb_atom_t *atoms = xcb_get_property_value(reply); - size_t atoms_len = reply->value_len; - size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; + size_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]); + size_t atoms_size = sizeof(atoms[0]) * atoms_len; free(xsurface->window_type); if (atoms_len > 0) { @@ -866,8 +866,8 @@ static void read_surface_protocols(struct wlr_xwm *xwm, } const xcb_atom_t *atoms = xcb_get_property_value(reply); - size_t atoms_len = reply->value_len; - size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; + size_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]); + size_t atoms_size = sizeof(atoms[0]) * atoms_len; free(xsurface->protocols); if (atoms_len > 0) { @@ -894,7 +894,7 @@ static void read_surface_hints(struct wlr_xwm *xwm, } free(xsurface->hints); - if (reply->value_len > 0) { + if (xcb_get_property_value_length(reply) > 0) { xsurface->hints = calloc(1, sizeof(*xsurface->hints)); if (xsurface->hints == NULL) { return; @@ -924,7 +924,7 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, free(xsurface->size_hints); xsurface->size_hints = NULL; - if (reply->value_len == 0) { + if (xcb_get_property_value_length(reply) == 0) { return; } @@ -971,18 +971,19 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm, static void read_surface_motif_hints(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { - if (reply->value_len == 0) { + if (xcb_get_property_value_length(reply) == 0) { xsurface->decorations = 0; wl_signal_emit_mutable(&xsurface->events.set_decorations, NULL); return; } - if (reply->value_len < 5) { + const uint32_t *motif_hints = xcb_get_property_value(reply); + int motif_hints_len = xcb_get_property_value_length(reply) / sizeof(motif_hints[0]); + if (motif_hints_len < 5) { wlr_log(WLR_DEBUG, "Invalid MOTIF_WM_HINTS property type"); return; } - const uint32_t *motif_hints = xcb_get_property_value(reply); if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { xsurface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; uint32_t decorations = motif_hints[MWM_HINTS_DECORATIONS_FIELD]; @@ -1031,7 +1032,8 @@ static void read_surface_net_wm_state(struct wlr_xwm *xwm, xcb_get_property_reply_t *reply) { xsurface->fullscreen = 0; const xcb_atom_t *atoms = xcb_get_property_value(reply); - for (uint32_t i = 0; i < reply->value_len; i++) { + uint32_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]); + for (uint32_t i = 0; i < atoms_len; i++) { if (atoms[i] == xwm->atoms[NET_WM_STATE_MODAL]) { xsurface->modal = true; } else if (atoms[i] == xwm->atoms[NET_WM_STATE_FULLSCREEN]) {