This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch wl/browser-all
in repository enlightenment.
View the commit online.
commit 690a0854258f69cb29edd297b9915f28ca6717b2
Author: Cedric BAIL <[email protected]>
AuthorDate: Sun Aug 9 00:13:18 2026 -0600
e_comp_wl - do not trust a client's shm stride
E-21, partly.
libwayland's wl_shm validates the requested format, and separately validates
the geometry, but never checks one against the other. shm_pool_create_buffer
tests "stride < width" - a byte count against a pixel count - so a client can
declare a 200x200 ARGB8888 buffer with a stride of 200 rather than 800, and
libwayland accepts it because 200*200 does fit the pool it was told about.
We then map that and hand evas a pointer it reads width*height*4 bytes from,
four times what is there. Any client that can connect can do it.
Check the stride against the format's bytes per pixel when we take the
buffer, and refuse it. This is the same check wlroots does in its own wl_shm
(pixel_format_info_check_stride); we cannot do it where wlroots does because
create_buffer is libwayland's request, not ours, so the error lands on the
wl_buffer rather than on the wl_shm_pool.
That means wlcs BadBufferTest.client_lies_about_buffer_size still fails: it
asserts the error arrives on wl_shm_pool from create_buffer. Satisfying that
needs the fix in libwayland - written up in libwayland-shm-stride-bug.md -
or E reimplementing wl_shm wholesale. The out-of-bounds read is closed
either way, which is the part that matters.
Only the two formats we advertise are checked; anything else keeps the
previous behaviour rather than being rejected on a guess.
The other half of E-21, BadBufferTest.test_truncated_shm_file, is not
addressed here. A client that shrinks its file after creating a buffer makes
the compositor take SIGBUS on read, and E holds the mapping across frames
with evas doing the actual access, so libwayland's begin_access/end_access
cannot simply be wrapped around it. That wants its own change.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01FtoiXoSKUmZb6Aix6U3GZS
---
src/bin/e_comp_wl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c
index 99e16295c..9d3ba65d7 100644
--- a/src/bin/e_comp_wl.c
+++ b/src/bin/e_comp_wl.c
@@ -3268,8 +3268,56 @@ e_comp_wl_buffer_get(struct wl_resource *resource)
dmabuf = linux_dmabuf_buffer_get(resource);
if (shmbuff)
{
+ int32_t stride, bpp;
+
buffer->w = wl_shm_buffer_get_width(shmbuff);
buffer->h = wl_shm_buffer_get_height(shmbuff);
+
+ /* Do not trust the client's stride.
+ *
+ * libwayland's wl_shm validates a pool the client declares against
+ * the geometry it declares, but it has no notion of bytes per pixel:
+ * shm_pool_create_buffer only rejects stride < width, comparing bytes
+ * against pixels. So a client can create a 200x200 ARGB8888 buffer
+ * with stride 200 - a quarter of the 800 bytes a row actually needs -
+ * and libwayland accepts it, because 200*200 does fit in the pool it
+ * was told about.
+ *
+ * We then map that and hand evas a pointer it will read w*h*4 bytes
+ * from, which is four times what is there. Any client that can
+ * connect can do this, so it is worth checking here rather than
+ * trusting the pool arithmetic to have meant what we assumed.
+ *
+ * wlcs BadBufferTest.client_lies_about_buffer_size covers the case,
+ * although it expects the error on wl_shm_pool from create_buffer -
+ * i.e. from libwayland - so it will still fail until libwayland
+ * grows a per-format check. The out-of-bounds read is closed either
+ * way, which is the part that matters. */
+ switch (wl_shm_buffer_get_format(shmbuff))
+ {
+ case WL_SHM_FORMAT_ARGB8888:
+ case WL_SHM_FORMAT_XRGB8888:
+ bpp = 4;
+ break;
+ default:
+ /* Only the two formats we advertise are checked; anything else
+ * we would not know the row size of anyway. */
+ bpp = 0;
+ break;
+ }
+
+ stride = wl_shm_buffer_get_stride(shmbuff);
+ if (bpp && ((stride < (buffer->w * bpp)) ||
+ (buffer->w && (stride / bpp < buffer->w))))
+ {
+ ERR("shm buffer stride %d is too small for %dx%d at %d bpp",
+ stride, buffer->w, buffer->h, bpp);
+ wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_STRIDE,
+ "stride %d cannot hold %d pixels at %d "
+ "bytes per pixel", stride, buffer->w, bpp);
+ free(buffer);
+ return NULL;
+ }
}
else if (dmabuf)
{
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.