backend/x11: reject shm buffers with non-min strides

This fixes an X11 backend direct scanout bug with foot.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/4046
This commit is contained in:
Isaac Freund 2026-02-13 11:48:17 +01:00
parent 910fd264fb
commit 25f94c5965
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11

View file

@ -19,6 +19,7 @@
#include <wlr/util/log.h>
#include "backend/x11.h"
#include "render/pixel_format.h"
#include "util/time.h"
#include "types/wlr_buffer.h"
#include "types/wlr_output.h"
@ -167,11 +168,20 @@ static bool output_test(struct wlr_output *wlr_output,
if (state->committed & WLR_OUTPUT_STATE_BUFFER) {
struct wlr_buffer *buffer = state->buffer;
if (buffer_get_drm_format(buffer) != x11->x11_format->drm) {
uint32_t format = buffer_get_drm_format(buffer);
if (format != x11->x11_format->drm) {
wlr_log(WLR_DEBUG, "Unsupported buffer format");
return false;
}
struct wlr_shm_attributes shm;
if (wlr_buffer_get_shm(buffer, &shm)) {
const struct wlr_pixel_format_info *info = drm_get_pixel_format_info(format);
if (shm.stride != pixel_format_info_min_stride(info, shm.width)) {
// xcb_shm_create_pixmap() does not allow arbitrary strides.
wlr_log(WLR_DEBUG, "Unsupported shm buffer stride");
return false;
}
}
}
if (state->committed & WLR_OUTPUT_STATE_MODE) {
@ -261,6 +271,12 @@ static xcb_pixmap_t import_shm(struct wlr_x11_output *output,
return XCB_PIXMAP_NONE;
}
const struct wlr_pixel_format_info *info = drm_get_pixel_format_info(shm->format);
if (shm->stride != pixel_format_info_min_stride(info, shm->width)) {
// xcb_shm_create_pixmap() does not allow arbitrary strides.
return XCB_PIXMAP_NONE;
}
// xcb closes the FD after sending it
int fd = fcntl(shm->fd, F_DUPFD_CLOEXEC, 0);
if (fd < 0) {