wayland: Check that wl_shm buffer stride is multiple of bytes per pixel

This is needed to ensure that the values passed to GL_UNPACK_ROW_LENGTH
are reasonable. It's not described in the spec but wlroots already does
the same.
This commit is contained in:
Vlad Zahorodnii 2024-08-15 18:21:12 +03:00
parent 49b2b0d001
commit 6a1db91191

View file

@ -6,8 +6,9 @@
#include "config-kwin.h" #include "config-kwin.h"
#include "wayland/shmclientbuffer.h" #include "utils/drm_format_helper.h"
#include "wayland/display.h" #include "wayland/display.h"
#include "wayland/shmclientbuffer.h"
#include "wayland/shmclientbuffer_p.h" #include "wayland/shmclientbuffer_p.h"
#include <drm_fourcc.h> #include <drm_fourcc.h>
@ -118,12 +119,26 @@ void ShmPool::shm_pool_create_buffer(Resource *resource, uint32_t id, int32_t of
return; return;
} }
const uint32_t drmFormat = shmFormatToDrmFormat(format);
if (auto formatInfo = FormatInfo::get(drmFormat)) {
const uint32_t bytesPerPixel = formatInfo->bitsPerPixel / 8;
if ((stride % bytesPerPixel) != 0) {
wl_resource_post_error(resource->handle,
WL_SHM_ERROR_INVALID_STRIDE,
"invalid stride, %d is not a multiple of %d",
stride,
bytesPerPixel);
return;
}
}
ShmAttributes attributes{ ShmAttributes attributes{
.fd = fd.duplicate(), .fd = fd.duplicate(),
.stride = stride, .stride = stride,
.offset = offset, .offset = offset,
.size = QSize(width, height), .size = QSize(width, height),
.format = shmFormatToDrmFormat(format), .format = drmFormat,
}; };
new ShmClientBuffer(this, std::move(attributes), resource->client(), id); new ShmClientBuffer(this, std::move(attributes), resource->client(), id);