summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorentin Noël <corentin.noel@collabora.com>2023-09-05 12:36:37 +0200
committerMarge Bot <emma+marge@anholt.net>2023-09-06 07:25:30 +0000
commita26186a820abe6c0f98201d09f8a40ebb6b04b62 (patch)
tree9e0dd5f968d53edc7bc76619c4e4c8ee4573af78
parentb91e7b417672878d4d56dda4aadbd61310a16f2b (diff)
renderer: Ensure that the box of the copy region is within the original resource
Makes sure to never copy a region of the resource larger than the original one. Signed-off-by: Corentin Noël <corentin.noel@collabora.com> Part-of: <https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1217>
-rw-r--r--src/vrend_renderer.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c
index 3ff230a..7cb7c5c 100644
--- a/src/vrend_renderer.c
+++ b/src/vrend_renderer.c
@@ -10199,6 +10199,52 @@ vrend_copy_sub_image(struct vrend_resource* src_res, struct vrend_resource * dst
}
}
+static inline bool resource_contains_box(struct vrend_resource *res,
+ const struct pipe_box *box,
+ uint32_t level)
+{
+ int64_t end_x, end_y, end_z;
+ int64_t width, height, depth;
+
+ /* check mipmap level is in bounds */
+ if (unlikely(level > res->base.last_level))
+ return false;
+
+ width = u_minify(res->base.width0, level);
+ height = u_minify(res->base.height0, level);
+
+ /* The z value has two meanings depending of the texture type */
+ switch (res->base.target) {
+ case PIPE_TEXTURE_CUBE:
+ case PIPE_TEXTURE_1D_ARRAY:
+ case PIPE_TEXTURE_2D_ARRAY:
+ case PIPE_TEXTURE_CUBE_ARRAY:
+ depth = res->base.array_size;
+ break;
+ case PIPE_TEXTURE_3D:
+ depth = u_minify(res->base.depth0, level);
+ break;
+ default:
+ depth = 1;
+ break;
+ }
+
+ /* check that the starting point is not outside of the range */
+ if (unlikely(box->x < 0 || box->y < 0 || box->z < 0 ||
+ box->x > width || box->y > height || box->z > depth))
+ return false;
+
+ end_x = (int64_t) box->x + (int64_t) box->width;
+ end_y = (int64_t) box->y + (int64_t) box->height;
+ end_z = (int64_t) box->z + (int64_t) box->depth;
+
+ /* check that the end point is not outside of the range */
+ if (unlikely(end_x < 0 || end_y < 0 || end_z < 0 ||
+ end_x > width || end_y > height || end_z > depth ))
+ return false;
+
+ return true;
+}
void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
uint32_t dst_handle, uint32_t dst_level,
@@ -10226,6 +10272,11 @@ void vrend_renderer_resource_copy_region(struct vrend_context *ctx,
return;
}
+ if (!resource_contains_box(src_res, src_box, src_level)) {
+ vrend_report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, src_handle);
+ return;
+ }
+
VREND_DEBUG(dbg_copy_resource, ctx, "COPY_REGION: From %s ms:%d [%d, %d, %d]+[%d, %d, %d] lvl:%d "
"To %s ms:%d [%d, %d, %d]\n",
util_format_name(src_res->base.format), src_res->base.nr_samples,