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.
This commit is contained in:
Simon Ser 2026-05-21 14:32:51 +02:00 committed by Simon Zeni
parent 5cb5373959
commit c91543352a
2 changed files with 14 additions and 11 deletions

View file

@ -344,7 +344,8 @@ static bool source_get_targets(struct wlr_xwm_selection *selection,
} }
const xcb_atom_t *value = xcb_get_property_value(reply); 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; char *mime_type = NULL;
if (value[i] == xwm->atoms[UTF8_STRING]) { if (value[i] == xwm->atoms[UTF8_STRING]) {

View file

@ -839,8 +839,8 @@ static void read_surface_window_type(struct wlr_xwm *xwm,
} }
const xcb_atom_t *atoms = xcb_get_property_value(reply); const xcb_atom_t *atoms = xcb_get_property_value(reply);
size_t atoms_len = reply->value_len; size_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]);
size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; size_t atoms_size = sizeof(atoms[0]) * atoms_len;
free(xsurface->window_type); free(xsurface->window_type);
if (atoms_len > 0) { 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); const xcb_atom_t *atoms = xcb_get_property_value(reply);
size_t atoms_len = reply->value_len; size_t atoms_len = xcb_get_property_value_length(reply) / sizeof(atoms[0]);
size_t atoms_size = sizeof(xcb_atom_t) * atoms_len; size_t atoms_size = sizeof(atoms[0]) * atoms_len;
free(xsurface->protocols); free(xsurface->protocols);
if (atoms_len > 0) { if (atoms_len > 0) {
@ -894,7 +894,7 @@ static void read_surface_hints(struct wlr_xwm *xwm,
} }
free(xsurface->hints); free(xsurface->hints);
if (reply->value_len > 0) { if (xcb_get_property_value_length(reply) > 0) {
xsurface->hints = calloc(1, sizeof(*xsurface->hints)); xsurface->hints = calloc(1, sizeof(*xsurface->hints));
if (xsurface->hints == NULL) { if (xsurface->hints == NULL) {
return; return;
@ -924,7 +924,7 @@ static void read_surface_normal_hints(struct wlr_xwm *xwm,
free(xsurface->size_hints); free(xsurface->size_hints);
xsurface->size_hints = NULL; xsurface->size_hints = NULL;
if (reply->value_len == 0) { if (xcb_get_property_value_length(reply) == 0) {
return; 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, static void read_surface_motif_hints(struct wlr_xwm *xwm,
struct wlr_xwayland_surface *xsurface, struct wlr_xwayland_surface *xsurface,
xcb_get_property_reply_t *reply) { xcb_get_property_reply_t *reply) {
if (reply->value_len == 0) { if (xcb_get_property_value_length(reply) == 0) {
xsurface->decorations = 0; xsurface->decorations = 0;
wl_signal_emit_mutable(&xsurface->events.set_decorations, NULL); wl_signal_emit_mutable(&xsurface->events.set_decorations, NULL);
return; 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"); wlr_log(WLR_DEBUG, "Invalid MOTIF_WM_HINTS property type");
return; return;
} }
const uint32_t *motif_hints = xcb_get_property_value(reply);
if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) { if (motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) {
xsurface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL; xsurface->decorations = WLR_XWAYLAND_SURFACE_DECORATIONS_ALL;
uint32_t decorations = motif_hints[MWM_HINTS_DECORATIONS_FIELD]; 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) { xcb_get_property_reply_t *reply) {
xsurface->fullscreen = 0; xsurface->fullscreen = 0;
const xcb_atom_t *atoms = xcb_get_property_value(reply); 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]) { if (atoms[i] == xwm->atoms[NET_WM_STATE_MODAL]) {
xsurface->modal = true; xsurface->modal = true;
} else if (atoms[i] == xwm->atoms[NET_WM_STATE_FULLSCREEN]) { } else if (atoms[i] == xwm->atoms[NET_WM_STATE_FULLSCREEN]) {