From a570bb33bb9139fdeb41a1b3f8a6b1b1e918b73c Mon Sep 17 00:00:00 2001 From: Patrick Lerda Date: Mon, 22 May 2023 13:40:31 +0200 Subject: [PATCH] r600: fix cayman_convert_border_color() swizzle behavior This change fixes a buffer overflow by implementing the special swizzles. This behavior is already available with evergreen_convert_border_color(). For instance, this issue is triggered on a cayman gpu with "piglit/bin/texwrap bordercolor -auto -fbo" or "piglit/bin/max-samplers -auto -fbo": ==5610==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000012d20 at pc 0x7fb798cb876f bp 0x7ffd78670460 sp 0x7ffd78670458 READ of size 4 at 0x603000012d20 thread T0 #0 0x7fb798cb876e in cayman_convert_border_color ../src/gallium/drivers/r600/evergreen_state.c:2444 #1 0x7fb798cb876e in evergreen_emit_sampler_states ../src/gallium/drivers/r600/evergreen_state.c:2539 #2 0x7fb7989e6cb2 in r600_emit_atom ../src/gallium/drivers/r600/r600_pipe.h:655 #3 0x7fb7989e6cb2 in r600_draw_vbo ../src/gallium/drivers/r600/r600_state_common.c:2333 #4 0x7fb7985082c7 in u_vbuf_draw_vbo ../src/gallium/auxiliary/util/u_vbuf.c:1497 #5 0x7fb796ef2eda in cso_draw_vbo ../src/gallium/auxiliary/cso_cache/cso_context.h:262 #6 0x7fb796ef2eda in st_draw_gallium_multimode ../src/mesa/state_tracker/st_draw.c:170 #7 0x7fb7970d9cfd in vbo_exec_vtx_flush ../src/mesa/vbo/vbo_exec_draw.c:341 #8 0x7fb7970d32d7 in vbo_exec_FlushVertices_internal ../src/mesa/vbo/vbo_exec_api.c:693 #9 0x7fb7970d32d7 in vbo_exec_FlushVertices ../src/mesa/vbo/vbo_exec_api.c:1193 #10 0x7fb7975f237c in enable_texture ../src/mesa/main/enable.c:337 Fixes: 923d635357f6 ("r600: fix some border color swizzles on CAYMAN") Signed-off-by: Patrick Lerda Reviewed-by: Gert Wollny Part-of: (cherry picked from commit 42847057334d41225931dd333253afbb1eeace47) --- .pick_status.json | 2 +- src/gallium/drivers/r600/evergreen_state.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 6c68d6177a76..933026646c00 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2065,7 +2065,7 @@ "description": "r600: fix cayman_convert_border_color() swizzle behavior", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "923d635357f6f8600c72fd9c972c6ec0c0b700ac" }, diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 75acc62dbc72..006e67d2eb8f 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -2435,15 +2435,19 @@ static void cayman_convert_border_color(union pipe_color_union *in, (util_format_is_srgb(format) || util_format_is_s3tc(format)) ) { - - for (int i = 0; i < 4; ++i) { - switch (i) { - case 0: out->f[0] = in->f[view->swizzle_r];break; - case 1: out->f[1] = in->f[view->swizzle_g];break; - case 2: out->f[2] = in->f[view->swizzle_b];break; - case 3: out->f[3] = in->f[view->swizzle_a];break; - } - } + const float values[PIPE_SWIZZLE_MAX] = { + in->f[0], in->f[1], in->f[2], in->f[3], 0.0f, 1.0f, 0.0f /* none */ + }; + + STATIC_ASSERT(PIPE_SWIZZLE_0 == 4); + STATIC_ASSERT(PIPE_SWIZZLE_1 == 5); + STATIC_ASSERT(PIPE_SWIZZLE_NONE == 6); + STATIC_ASSERT(PIPE_SWIZZLE_MAX == 7); + + out->f[0] = values[view->swizzle_r]; + out->f[1] = values[view->swizzle_g]; + out->f[2] = values[view->swizzle_b]; + out->f[3] = values[view->swizzle_a]; } else { memcpy(out->f, in->f, 4 * sizeof(float)); }