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: 923d635357 ("r600: fix some border color swizzles on CAYMAN")
Signed-off-by: Patrick Lerda <patrick9876@free.fr>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23435>
(cherry picked from commit 4284705733)
This commit is contained in:
Patrick Lerda 2023-05-22 13:40:31 +02:00 committed by Eric Engestrom
parent 006648a4db
commit a570bb33bb
2 changed files with 13 additions and 9 deletions

View file

@ -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"
},

View file

@ -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))
) {
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 */
};
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;
}
}
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));
}