llvmpipe: memcpy user_buffers at set_constant_buffer time.

The data in the user buffer is only valid for a short period of time, and
we could use-after-free it if rendering hadn't been flushed by shader
deletion time.

Fixes: #5254
Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12724>
This commit is contained in:
Emma Anholt 2021-09-03 10:54:36 -07:00 committed by Marge Bot
parent a83a2b980c
commit a2dfb49961
2 changed files with 17 additions and 59 deletions

View file

@ -1,38 +0,0 @@
# https://gitlab.freedesktop.org/mesa/mesa/-/issues/5254
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8_rgb8.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8_rgb8.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8i_rgb8.cubemap_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_24_bits.rgb8i_rgb8.texture2d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16i.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16i.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16ui.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rg16ui.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgb10_a2.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgb10_a2ui.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgba8i.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgba8i.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rg16f_rgba8ui.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rg16i.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rg16ui.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rg16ui.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8i.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8i.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_32_bits.rgba8_snorm_rgba8ui.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_r8.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_r8.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_r8i.texture2d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_snorm_r8i.cubemap_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_snorm_r8ui.cubemap_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8_snorm_r8ui.texture2d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8.cubemap_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8.texture2d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8i.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8i.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8i_r8ui.texture2d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8.texture2d_array_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8i.cubemap_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8i.texture2d_to_renderbuffer,Crash
dEQP-GLES31.functional.copy_image.non_compressed.viewclass_8_bits.r8ui_r8ui.texture3d_to_renderbuffer,Crash
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.12,Crash
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.2,Crash

View file

@ -67,6 +67,7 @@
#include "util/u_string.h"
#include "util/simple_list.h"
#include "util/u_dual_blend.h"
#include "util/u_upload_mgr.h"
#include "util/os_time.h"
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
@ -3984,7 +3985,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
const struct pipe_constant_buffer *cb)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
struct pipe_resource *constants = cb ? cb->buffer : NULL;
struct pipe_constant_buffer *constants = &llvmpipe->constants[shader][index];
assert(shader < PIPE_SHADER_TYPES);
assert(index < ARRAY_SIZE(llvmpipe->constants[shader]));
@ -3993,10 +3994,19 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
util_copy_constant_buffer(&llvmpipe->constants[shader][index], cb,
take_ownership);
if (constants) {
if (!(constants->bind & PIPE_BIND_CONSTANT_BUFFER)) {
/* user_buffer is only valid until the next set_constant_buffer (at most,
* possibly until shader deletion), so we need to upload it now to make sure
* it doesn't get updated/freed out from under us.
*/
if (constants->user_buffer) {
u_upload_data(llvmpipe->pipe.const_uploader, 0, constants->buffer_size, 16,
constants->user_buffer, &constants->buffer_offset,
&constants->buffer);
}
if (constants->buffer) {
if (!(constants->buffer->bind & PIPE_BIND_CONSTANT_BUFFER)) {
debug_printf("Illegal set constant without bind flag\n");
constants->bind |= PIPE_BIND_CONSTANT_BUFFER;
constants->buffer->bind |= PIPE_BIND_CONSTANT_BUFFER;
}
}
@ -4006,20 +4016,10 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
shader == PIPE_SHADER_TESS_EVAL) {
/* Pass the constants to the 'draw' module */
const unsigned size = cb ? cb->buffer_size : 0;
const ubyte *data;
if (constants) {
data = (ubyte *) llvmpipe_resource_data(constants);
}
else if (cb && cb->user_buffer) {
data = (ubyte *) cb->user_buffer;
}
else {
data = NULL;
}
if (data)
data += cb->buffer_offset;
const ubyte *data = NULL;
if (constants->buffer)
data = (ubyte *) llvmpipe_resource_data(constants->buffer) + constants->buffer_offset;
draw_set_mapped_constant_buffer(llvmpipe->draw, shader,
index, data, size);
@ -4028,10 +4028,6 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
llvmpipe->cs_dirty |= LP_CSNEW_CONSTANTS;
else
llvmpipe->dirty |= LP_NEW_FS_CONSTANTS;
if (cb && cb->user_buffer) {
pipe_resource_reference(&constants, NULL);
}
}
static void