From 63aee871365f9c9e7fa9125672302a0fb250d34d Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Tue, 30 Nov 2021 09:16:24 +0100 Subject: [PATCH 2/2] vrend: propperly check whether the shader image range is correct Also add a test to check the integer underflow. Closes: #251 Signed-off-by: Gert Wollny Reviewed-by: Chia-I Wu cherry-pick from anongit.freedesktop.org/virglrenderer commit 2aed5d4... CVE: CVE-2022-0135 Upstream-Status: Backport Signed-off-by: Joe Slater --- src/vrend_decode.c | 3 +- tests/test_fuzzer_formats.c | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/vrend_decode.c b/src/vrend_decode.c index 91f5f24..6771b10 100644 --- a/src/vrend_decode.c +++ b/src/vrend_decode.c @@ -1249,8 +1249,9 @@ static int vrend_decode_set_shader_images(struct vrend_context *ctx, const uint3 if (num_images < 1) { return 0; } + if (start_slot > PIPE_MAX_SHADER_IMAGES || - start_slot > PIPE_MAX_SHADER_IMAGES - num_images) + start_slot + num_images > PIPE_MAX_SHADER_IMAGES) return EINVAL; for (uint32_t i = 0; i < num_images; i++) { diff --git a/tests/test_fuzzer_formats.c b/tests/test_fuzzer_formats.c index 154a2e5..e32caf0 100644 --- a/tests/test_fuzzer_formats.c +++ b/tests/test_fuzzer_formats.c @@ -958,6 +958,61 @@ static void test_vrend_set_signle_abo_heap_overflow() { virgl_renderer_submit_cmd((void *) cmd, ctx_id, 0xde); } +static void test_vrend_set_shader_images_overflow() +{ + uint32_t num_shaders = PIPE_MAX_SHADER_IMAGES + 1; + uint32_t size = num_shaders * VIRGL_SET_SHADER_IMAGE_ELEMENT_SIZE + 3; + uint32_t cmd[size]; + int i = 0; + cmd[i++] = ((size - 1)<< 16) | 0 << 8 | VIRGL_CCMD_SET_SHADER_IMAGES; + cmd[i++] = PIPE_SHADER_FRAGMENT; + memset(&cmd[i], 0, size - i); + + virgl_renderer_submit_cmd((void *) cmd, ctx_id, size); +} + +/* Test adapted from yaojun8558363@gmail.com: + * https://gitlab.freedesktop.org/virgl/virglrenderer/-/issues/250 +*/ +static void test_vrend_3d_resource_overflow() { + + struct virgl_renderer_resource_create_args resource; + resource.handle = 0x4c474572; + resource.target = PIPE_TEXTURE_2D_ARRAY; + resource.format = VIRGL_FORMAT_Z24X8_UNORM; + resource.nr_samples = 2; + resource.last_level = 0; + resource.array_size = 3; + resource.bind = VIRGL_BIND_SAMPLER_VIEW; + resource.depth = 1; + resource.width = 8; + resource.height = 4; + resource.flags = 0; + + virgl_renderer_resource_create(&resource, NULL, 0); + virgl_renderer_ctx_attach_resource(ctx_id, resource.handle); + + uint32_t size = 0x400; + uint32_t cmd[size]; + int i = 0; + cmd[i++] = (size - 1) << 16 | 0 << 8 | VIRGL_CCMD_RESOURCE_INLINE_WRITE; + cmd[i++] = resource.handle; + cmd[i++] = 0; // level + cmd[i++] = 0; // usage + cmd[i++] = 0; // stride + cmd[i++] = 0; // layer_stride + cmd[i++] = 0; // x + cmd[i++] = 0; // y + cmd[i++] = 0; // z + cmd[i++] = 8; // w + cmd[i++] = 4; // h + cmd[i++] = 3; // d + memset(&cmd[i], 0, size - i); + + virgl_renderer_submit_cmd((void *) cmd, ctx_id, size); +} + + int main() { initialize_environment(); @@ -980,6 +1035,8 @@ int main() test_cs_nullpointer_deference(); test_vrend_set_signle_abo_heap_overflow(); + test_vrend_set_shader_images_overflow(); + test_vrend_3d_resource_overflow(); virgl_renderer_context_destroy(ctx_id); virgl_renderer_cleanup(&cookie); -- 2.25.1