diff --git a/backport-CVE-2019-18388.patch b/backport-CVE-2019-18388.patch new file mode 100644 index 0000000000000000000000000000000000000000..7543ddeb1a3acd1ede770bab76f4c7ab484ebb39 --- /dev/null +++ b/backport-CVE-2019-18388.patch @@ -0,0 +1,135 @@ +From 0d9a2c88dc3a70023541b3260b9f00c982abda16 Mon Sep 17 00:00:00 2001 +From: Gert Wollny +Date: Thu, 10 Oct 2019 09:42:25 +0200 +Subject: [PATCH] vrend: Check resource creation more thoroughly + +While we are at it: + - free memory if texture allocation fails + +Closes #144 +Closes #145 +Closes #146 + +v2: Move the error string creation to extra patch (Emil) +v3: Fix whitespace errors (Emil) and one logic error + +Signed-off-by: Gert Wollny +Reviewed-by: Emil Velikov +--- + src/vrend_renderer.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 56 insertions(+), 2 deletions(-) + +diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c +index 8801f94..6f7d045 100644 +--- a/src/vrend_renderer.c ++++ b/src/vrend_renderer.c +@@ -5474,6 +5474,8 @@ static int check_resource_valid(struct vrend_renderer_resource_create_args *args + + if (args->format >= VIRGL_FORMAT_MAX) + return -1; ++ bool format_can_texture_storage = has_feature(feat_texture_storage) && ++ (tex_conv_table[args->format].flags & VIRGL_BIND_CAN_TEXTURE_STORAGE); + + /* only texture 2d and 2d array can have multiple samples */ + if (args->nr_samples > 1) { +@@ -5491,15 +5493,18 @@ static int check_resource_valid(struct vrend_renderer_resource_create_args *args + /* buffer and rect textures can't have mipmaps */ + if (args->target == PIPE_BUFFER || args->target == PIPE_TEXTURE_RECT) + return -1; ++ + if (args->last_level > (floor(log2(MAX2(args->width, args->height))) + 1)) + return -1; + } ++ + if (args->flags != 0 && args->flags != VIRGL_RESOURCE_Y_0_TOP) + return -1; + +- if (args->flags & VIRGL_RESOURCE_Y_0_TOP) ++ if (args->flags & VIRGL_RESOURCE_Y_0_TOP) { + if (args->target != PIPE_TEXTURE_2D && args->target != PIPE_TEXTURE_RECT) + return -1; ++ } + + /* array size for array textures only */ + if (args->target == PIPE_TEXTURE_CUBE) { +@@ -5518,6 +5523,9 @@ static int check_resource_valid(struct vrend_renderer_resource_create_args *args + if (!has_feature(feat_texture_array)) + return -1; + } ++ if (format_can_texture_storage && !args->width) { ++ return -1; ++ } + + if (args->bind == 0 || + args->bind == VIRGL_BIND_CUSTOM || +@@ -5544,11 +5552,55 @@ static int check_resource_valid(struct vrend_renderer_resource_create_args *args + args->target == PIPE_TEXTURE_CUBE_ARRAY) { + if (args->depth != 1) + return -1; ++ if (format_can_texture_storage && !args->height) { ++ return -1; ++ } + } + if (args->target == PIPE_TEXTURE_1D || + args->target == PIPE_TEXTURE_1D_ARRAY) { + if (args->height != 1 || args->depth != 1) + return -1; ++ if (args->width > vrend_state.max_texture_2d_size) { ++ return -1; ++ } ++ } ++ ++ if (args->target == PIPE_TEXTURE_2D || ++ args->target == PIPE_TEXTURE_RECT || ++ args->target == PIPE_TEXTURE_2D_ARRAY) { ++ if (args->width > vrend_state.max_texture_2d_size || ++ args->height > vrend_state.max_texture_2d_size) { ++ return -1; ++ } ++ } ++ ++ if (args->target == PIPE_TEXTURE_3D) { ++ if (format_can_texture_storage && ++ (!args->height || !args->depth)) { ++ return -1; ++ } ++ if (args->width > vrend_state.max_texture_3d_size || ++ args->height > vrend_state.max_texture_3d_size || ++ args->depth > vrend_state.max_texture_3d_size) { ++ return -1; ++ } ++ } ++ if (args->target == PIPE_TEXTURE_2D_ARRAY || ++ args->target == PIPE_TEXTURE_CUBE_ARRAY || ++ args->target == PIPE_TEXTURE_1D_ARRAY) { ++ if (format_can_texture_storage && ++ !args->array_size) { ++ return -1; ++ } ++ } ++ if (args->target == PIPE_TEXTURE_CUBE || ++ args->target == PIPE_TEXTURE_CUBE_ARRAY) { ++ if (args->width != args->height) { ++ return -1; ++ } ++ if (args->width > vrend_state.max_texture_cube_size) { ++ return -1; ++ } + } + } + return 0; +@@ -5787,8 +5839,10 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a + vrend_create_buffer(gr, args->width); + } else { + int r = vrend_renderer_resource_allocate_texture(gr, image_oes); +- if (r) ++ if (r) { ++ FREE(gr); + return r; ++ } + } + + ret = vrend_resource_insert(gr, args->handle); +-- +1.8.3.1 + diff --git a/backport-CVE-2019-18389.patch b/backport-CVE-2019-18389.patch new file mode 100644 index 0000000000000000000000000000000000000000..c99b74bcedfcea6c089988c8211600cee75483c0 --- /dev/null +++ b/backport-CVE-2019-18389.patch @@ -0,0 +1,88 @@ +From cbc8d8b75be360236cada63784046688aeb6d921 Mon Sep 17 00:00:00 2001 +From: Gert Wollny +Date: Tue, 8 Oct 2019 16:51:11 +0200 +Subject: [PATCH] vrend: check transfer bounds for negative values too and + report error + +Closes #138 + +Signed-off-by: Gert Wollny +Reviewed-by: Emil Velikov +--- + src/virgl_hw.h | 1 + + src/vrend_renderer.c | 16 ++++++++++------ + 2 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/virgl_hw.h b/src/virgl_hw.h +index 82b0ccc..5656795 100644 +--- a/src/virgl_hw.h ++++ b/src/virgl_hw.h +@@ -380,6 +380,7 @@ enum virgl_ctx_errors { + VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT, + VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, + VIRGL_ERROR_CTX_ILLEGAL_FORMAT, ++ VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS, + }; + + +diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c +index 10c60ec..57f446d 100644 +--- a/src/vrend_renderer.c ++++ b/src/vrend_renderer.c +@@ -643,7 +643,7 @@ static inline const char *pipe_shader_to_prefix(int shader_type) + }; + } + +-static const char *vrend_ctx_error_strings[] = { "None", "Unknown", "Illegal shader", "Illegal handle", "Illegal resource", "Illegal surface", "Illegal vertex format", "Illegal command buffer", "Illegal format ID" }; ++static const char *vrend_ctx_error_strings[] = { "None", "Unknown", "Illegal shader", "Illegal handle", "Illegal resource", "Illegal surface", "Illegal vertex format", "Illegal command buffer", "Illegal format ID", "IOV data size exceeds resource capacity" }; + + static void __report_context_error(const char *fname, struct vrend_context *ctx, enum virgl_ctx_errors error, uint32_t value) + { +@@ -5969,7 +5969,7 @@ static bool check_transfer_bounds(struct vrend_resource *res, + return false; + /* these will catch bad y/z/w/d with 1D textures etc */ + lwidth = u_minify(res->base.width0, info->level); +- if (info->box->width > lwidth) ++ if (info->box->width > lwidth || info->box->width < 0) + return false; + if (info->box->x > lwidth) + return false; +@@ -5977,7 +5977,7 @@ static bool check_transfer_bounds(struct vrend_resource *res, + return false; + + lheight = u_minify(res->base.height0, info->level); +- if (info->box->height > lheight) ++ if (info->box->height > lheight || info->box->height < 0) + return false; + if (info->box->y > lheight) + return false; +@@ -5986,7 +5986,7 @@ static bool check_transfer_bounds(struct vrend_resource *res, + + if (res->base.target == PIPE_TEXTURE_3D) { + int ldepth = u_minify(res->base.depth0, info->level); +- if (info->box->depth > ldepth) ++ if (info->box->depth > ldepth || info->box->depth < 0) + return false; + if (info->box->z > ldepth) + return false; +@@ -6651,11 +6651,15 @@ int vrend_renderer_transfer_iov(const struct vrend_transfer_info *info, + return EINVAL; + } + +- if (!check_transfer_bounds(res, info)) ++ if (!check_transfer_bounds(res, info)) { ++ report_context_error(ctx, VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS, res->id); + return EINVAL; ++ } + +- if (!check_iov_bounds(res, info, iov, num_iovs)) ++ if (!check_iov_bounds(res, info, iov, num_iovs)) { ++ report_context_error(ctx, VIRGL_ERROR_CTX_TRANSFER_IOV_BOUNDS, res->id); + return EINVAL; ++ } + + vrend_hw_switch_context(vrend_lookup_renderer_ctx(0), true); + +-- +1.8.3.1 + diff --git a/backport-CVE-2019-18390.patch b/backport-CVE-2019-18390.patch new file mode 100644 index 0000000000000000000000000000000000000000..b6197f7c6630cf1cec74216e2b4eb04fcaeafced --- /dev/null +++ b/backport-CVE-2019-18390.patch @@ -0,0 +1,62 @@ +From 24f67de7a9088a873844a39be03cee6882260ac9 Mon Sep 17 00:00:00 2001 +From: Gert Wollny +Date: Mon, 7 Oct 2019 10:59:56 +0200 +Subject: [PATCH] vrend: check info formats in blits + +Closes #141 +Closes #142 + +v2 : drop colon in error description (Emil) + +Signed-off-by: Gert Wollny +Reviewed-by: Emil Velikov +--- + src/virgl_hw.h | 1 + + src/vrend_renderer.c | 12 +++++++++++- + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/virgl_hw.h b/src/virgl_hw.h +index 7736ceb..82b0ccc 100644 +--- a/src/virgl_hw.h ++++ b/src/virgl_hw.h +@@ -379,6 +379,7 @@ enum virgl_ctx_errors { + VIRGL_ERROR_CTX_ILLEGAL_SURFACE, + VIRGL_ERROR_CTX_ILLEGAL_VERTEX_FORMAT, + VIRGL_ERROR_CTX_ILLEGAL_CMD_BUFFER, ++ VIRGL_ERROR_CTX_ILLEGAL_FORMAT, + }; + + +diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c +index 3769fe0..10c60ec 100644 +--- a/src/vrend_renderer.c ++++ b/src/vrend_renderer.c +@@ -643,7 +643,7 @@ static inline const char *pipe_shader_to_prefix(int shader_type) + }; + } + +-static const char *vrend_ctx_error_strings[] = { "None", "Unknown", "Illegal shader", "Illegal handle", "Illegal resource", "Illegal surface", "Illegal vertex format", "Illegal command buffer" }; ++static const char *vrend_ctx_error_strings[] = { "None", "Unknown", "Illegal shader", "Illegal handle", "Illegal resource", "Illegal surface", "Illegal vertex format", "Illegal command buffer", "Illegal format ID" }; + + static void __report_context_error(const char *fname, struct vrend_context *ctx, enum virgl_ctx_errors error, uint32_t value) + { +@@ -7392,6 +7392,16 @@ void vrend_renderer_blit(struct vrend_context *ctx, + if (ctx->in_error) + return; + ++ if (!info->src.format || (enum virgl_formats)info->src.format >= VIRGL_FORMAT_MAX) { ++ report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_FORMAT, info->src.format); ++ return; ++ } ++ ++ if (!info->dst.format || (enum virgl_formats)info->dst.format >= VIRGL_FORMAT_MAX) { ++ report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_FORMAT, info->dst.format); ++ return; ++ } ++ + if (info->render_condition_enable == false) + vrend_pause_render_condition(ctx, true); + +-- +1.8.3.1 + diff --git a/backport-CVE-2019-18391.patch b/backport-CVE-2019-18391.patch new file mode 100644 index 0000000000000000000000000000000000000000..c0208373ee9164fbcbd0d1099ed815cc2ee1e9ee --- /dev/null +++ b/backport-CVE-2019-18391.patch @@ -0,0 +1,46 @@ +From 2abeb1802e3c005b17a7123e382171b3fb665971 Mon Sep 17 00:00:00 2001 +From: Gert Wollny +Date: Tue, 8 Oct 2019 17:27:01 +0200 +Subject: [PATCH] vrend: check that the transfer iov holds enough data for the + data upload + +Closes #140 + +Signed-off-by: Gert Wollny +Reviewed-by: Emil Velikov +--- + src/vrend_renderer.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c +index 57f446d..8801f94 100644 +--- a/src/vrend_renderer.c ++++ b/src/vrend_renderer.c +@@ -6115,15 +6115,22 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx, + invert = true; + } + ++ send_size = util_format_get_nblocks(res->base.format, info->box->width, ++ info->box->height) * elsize; ++ if (res->target == GL_TEXTURE_3D || ++ res->target == GL_TEXTURE_2D_ARRAY || ++ res->target == GL_TEXTURE_CUBE_MAP_ARRAY) ++ send_size *= info->box->depth; ++ + if (need_temp) { +- send_size = util_format_get_nblocks(res->base.format, info->box->width, +- info->box->height) * elsize * info->box->depth; + data = malloc(send_size); + if (!data) + return ENOMEM; + read_transfer_data(&res->base, iov, num_iovs, data, stride, + info->box, info->level, info->offset, invert); + } else { ++ if (send_size > iov[0].iov_len - info->offset) ++ return EINVAL; + data = (char*)iov[0].iov_base + info->offset; + } + +-- +1.8.3.1 + diff --git a/backport-vrend-Keep-the-max-texture-sizes-in-the-vrend_state.patch b/backport-vrend-Keep-the-max-texture-sizes-in-the-vrend_state.patch new file mode 100644 index 0000000000000000000000000000000000000000..32a7b4c2f1abdc3e5ab6d884ea34150332893260 --- /dev/null +++ b/backport-vrend-Keep-the-max-texture-sizes-in-the-vrend_state.patch @@ -0,0 +1,51 @@ +From 5d03711f88643b6b6639aebd8983c179cdd248b0 Mon Sep 17 00:00:00 2001 +From: Gert Wollny +Date: Mon, 7 Oct 2019 17:15:37 +0200 +Subject: [PATCH] vrend: Keep the max texture sizes in the vrend_state + +This is needed to check the resource creation parameters. + +Signed-off-by: Gert Wollny +Reviewed-by: Emil Velikov +--- + src/vrend_renderer.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c +index 28ce9bd..613fac9 100644 +--- a/src/vrend_renderer.c ++++ b/src/vrend_renderer.c +@@ -233,6 +233,9 @@ struct global_renderer_state { + bool use_explicit_locations; + uint32_t max_uniform_blocks; + uint32_t max_draw_buffers; ++ uint32_t max_texture_2d_size; ++ uint32_t max_texture_3d_size; ++ uint32_t max_texture_cube_size; + struct list_head active_ctx_list; + + /* threaded sync */ +@@ -5182,6 +5182,10 @@ int vrend_renderer_init(struct vrend_if_cbs *cbs, uint32_t flags) + vrend_state.inited = true; + vrend_object_init_resource_table(); + vrend_clicbs = cbs; ++ /* Give some defaults to be able to run the tests */ ++ vrend_state.max_texture_2d_size = ++ vrend_state.max_texture_3d_size = ++ vrend_state.max_texture_cube_size = 16384; + } + + ctx_params.shared = false; +@@ -8204,6 +8211,9 @@ static void vrend_renderer_fill_caps_v2(int gl_ver, int gles_ver, union virgl_c + glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*)&caps->v2.max_texture_2d_size); + glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&caps->v2.max_texture_3d_size); + glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&caps->v2.max_texture_cube_size); ++ vrend_state.max_texture_2d_size = caps->v2.max_texture_2d_size; ++ vrend_state.max_texture_3d_size = caps->v2.max_texture_3d_size; ++ vrend_state.max_texture_cube_size = caps->v2.max_texture_cube_size; + + if (has_feature(feat_geometry_shader)) { + glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, (GLint*)&caps->v2.max_geom_output_vertices); +-- +1.8.3.1 + diff --git a/virglrenderer.spec b/virglrenderer.spec index f500931efaed755d4c566d2ebead610e9bcdb98d..49c2b561a8c39fb1772dab2f069c8e411376f499 100644 --- a/virglrenderer.spec +++ b/virglrenderer.spec @@ -1,12 +1,18 @@ Name: virglrenderer Version: 0.7.0 -Release: 1 +Release: 2 Summary: VirGL virtual OpenGL renderer License: MIT URL: https://virgil3d.github.io Source0: https://www.freedesktop.org/software/virgl/virglrenderer-%{version}.tar.gz +Patch0: backport-CVE-2019-18390.patch +Patch1: backport-CVE-2019-18389.patch +Patch2: backport-CVE-2019-18391.patch +Patch3: backport-vrend-Keep-the-max-texture-sizes-in-the-vrend_state.patch +Patch4: backport-CVE-2019-18388.patch + BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool @@ -34,7 +40,7 @@ It is required while building qemu. Requires: %{name}%{?_isa} = %{version}-%{release} %prep -%setup -q +%autosetup -n %{name}-%{version} -p1 %build autoreconf -if @@ -60,5 +66,8 @@ rm -rf %{buildroot}%{_bindir}/virgl_test_server %{_libdir}/pkgconfig/*.pc %changelog +* Thu Nov 4 2021 panxiaohe - 0.7.0-2 +- Fix CVE-2019-18388 CVE-2019-18389 CVE-2019-18390 CVE-2019-18391 + * Fri Oct 18 2019 openEuler Buildteam - 0.7.0-1 - Package init