summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGert Wollny <gert.wollny@collabora.com>2023-09-08 14:00:16 +0200
committerMarge Bot <emma+marge@anholt.net>2023-09-11 08:47:20 +0000
commitec2f8bcd16e4f5975ab7c988637113ebc136d4c3 (patch)
tree793a08c87f529e2de63c99c7e9f550e450ab05fb
parent8019cc5e4d4e5e5c53ad4a6cd927b35ecd3df1f0 (diff)
vrend: Use uint64_t to evaluate readback size
This is to avoid integer overflow. Bail out if the size is larger than UINT_MAX because glReadnPixels can't take larger buffers. v2: Fix format specifier Closes: https://gitlab.freedesktop.org/virgl/virglrenderer/-/issues/459 Signed-off-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1225>
-rw-r--r--src/vrend_renderer.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 4f2876d..cc58f7b 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -9310,7 +9310,7 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
bool actually_invert, separate_invert = false;
GLenum format, type;
GLint y1;
- uint32_t send_size = 0;
+ uint64_t send_size = 0;
uint32_t h = u_minify(res->base.height0, info->level);
int elsize = util_format_get_blocksize(res->base.format);
float depth_scale;
@@ -9341,10 +9341,20 @@ static int vrend_transfer_send_readpixels(struct vrend_context *ctx,
need_temp = true;
if (need_temp) {
- send_size = util_format_get_nblocks(res->base.format, info->box->width, info->box->height) * info->box->depth * util_format_get_blocksize(res->base.format);
+ send_size = util_format_get_nblocks(res->base.format, info->box->width, info->box->height);
+ send_size *= info->box->depth;
+ send_size *= util_format_get_blocksize(res->base.format);
+
+ /* glReadnPixels only supports a buffer size of GLsizei = uint32_t, anything larger
+ * is bogous */
+ if (send_size > UINT_MAX) {
+ virgl_error("Readback size out of range %ld\n", send_size);
+ return EINVAL;
+ }
+
data = malloc(send_size);
if (!data) {
- virgl_error("Memory allocation failed for %d\n", send_size);
+ virgl_error("Memory allocation failed for %ld\n", send_size);
return ENOMEM;
}
} else {