aboutsummaryrefslogtreecommitdiff
path: root/render/gles2
diff options
context:
space:
mode:
authorSimon Ser <contact@emersion.fr>2021-02-19 09:59:49 +0100
committerSimon Ser <contact@emersion.fr>2021-02-19 23:35:38 +0100
commit6ca59519c9377eb0406a0539557996128e8d8101 (patch)
tree33be05162382f403c50f77b35fab635082f343e3 /render/gles2
parentf3758d1d0acc4e07c9a88647c77a2ed668016e0b (diff)
render/gles2: check buffer stride when uploading texture
If the stride is too small, the driver could end up segfaulting (e.g. radeonsi segfaults in __memmove_sse2_unaligned_erms).
Diffstat (limited to 'render/gles2')
-rw-r--r--render/gles2/texture.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/render/gles2/texture.c b/render/gles2/texture.c
index 28cb095b..41d71f3c 100644
--- a/render/gles2/texture.c
+++ b/render/gles2/texture.c
@@ -30,6 +30,21 @@ static bool gles2_texture_is_opaque(struct wlr_texture *wlr_texture) {
return !texture->has_alpha;
}
+static bool check_stride(const struct wlr_gles2_pixel_format *fmt,
+ uint32_t stride, uint32_t width) {
+ if (stride % (fmt->bpp / 8) != 0) {
+ wlr_log(WLR_ERROR, "Invalid stride %d (incompatible with %d "
+ "bytes-per-pixel)", stride, fmt->bpp / 8);
+ return false;
+ }
+ if (stride < width * (fmt->bpp / 8)) {
+ wlr_log(WLR_ERROR, "Invalid stride %d (too small for %d "
+ "bytes-per-pixel and width %d)", stride, fmt->bpp / 8, width);
+ return false;
+ }
+ return true;
+}
+
static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
uint32_t stride, uint32_t width, uint32_t height,
uint32_t src_x, uint32_t src_y, uint32_t dst_x, uint32_t dst_y,
@@ -45,6 +60,10 @@ static bool gles2_texture_write_pixels(struct wlr_texture *wlr_texture,
get_gles2_format_from_wl(texture->wl_format);
assert(fmt);
+ if (!check_stride(fmt, stride, width)) {
+ return false;
+ }
+
struct wlr_egl_context prev_ctx;
wlr_egl_save_context(&prev_ctx);
wlr_egl_make_current(texture->renderer->egl);
@@ -142,6 +161,10 @@ struct wlr_texture *gles2_texture_from_pixels(struct wlr_renderer *wlr_renderer,
return NULL;
}
+ if (!check_stride(fmt, stride, width)) {
+ return NULL;
+ }
+
struct wlr_gles2_texture *texture =
calloc(1, sizeof(struct wlr_gles2_texture));
if (texture == NULL) {