[Mesa-dev] [PATCH] gallium/radeon: fix crash in r600_set_streamout_targets
Marek Olšák
maraeo at gmail.com
Fri Apr 29 15:24:40 UTC 2016
Reviewed-by: Marek Olšák <marek.olsak at amd.com>
Marek
On Fri, Apr 29, 2016 at 1:58 AM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> Protect against dereferencing a gap in the targets array. This was triggered
> by a test in the Khronos CTS.
>
> Cc: "11.1 11.2" <mesa-stable at lists.freedesktop.org>
> ---
> src/gallium/drivers/r600/r600_state_common.c | 3 ++-
> src/gallium/drivers/radeon/r600_streamout.c | 13 +++++++------
> 2 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
> index 5317de0..cac240e 100644
> --- a/src/gallium/drivers/r600/r600_state_common.c
> +++ b/src/gallium/drivers/r600/r600_state_common.c
> @@ -2802,7 +2802,8 @@ static void r600_invalidate_buffer(struct pipe_context *ctx, struct pipe_resourc
> }
> /* Streamout buffers. */
> for (i = 0; i < rctx->b.streamout.num_targets; i++) {
> - if (rctx->b.streamout.targets[i]->b.buffer == &rbuffer->b.b) {
> + if (rctx->b.streamout.targets[i] &&
> + rctx->b.streamout.targets[i]->b.buffer == &rbuffer->b.b) {
> if (rctx->b.streamout.begin_emitted) {
> r600_emit_streamout_end(&rctx->b);
> }
> diff --git a/src/gallium/drivers/radeon/r600_streamout.c b/src/gallium/drivers/radeon/r600_streamout.c
> index fc9ec48..a001700 100644
> --- a/src/gallium/drivers/radeon/r600_streamout.c
> +++ b/src/gallium/drivers/radeon/r600_streamout.c
> @@ -116,7 +116,7 @@ void r600_set_streamout_targets(struct pipe_context *ctx,
> {
> struct r600_common_context *rctx = (struct r600_common_context *)ctx;
> unsigned i;
> - unsigned append_bitmask = 0;
> + unsigned enabled_mask = 0, append_bitmask = 0;
>
> /* Stop streamout. */
> if (rctx->streamout.num_targets && rctx->streamout.begin_emitted) {
> @@ -126,18 +126,19 @@ void r600_set_streamout_targets(struct pipe_context *ctx,
> /* Set the new targets. */
> for (i = 0; i < num_targets; i++) {
> pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], targets[i]);
> + if (!targets[i])
> + continue;
> +
> r600_context_add_resource_size(ctx, targets[i]->buffer);
> + enabled_mask |= 1 << i;
> if (offsets[i] == ((unsigned)-1))
> - append_bitmask |= 1 << i;
> + append_bitmask |= 1 << i;
> }
> for (; i < rctx->streamout.num_targets; i++) {
> pipe_so_target_reference((struct pipe_stream_output_target**)&rctx->streamout.targets[i], NULL);
> }
>
> - rctx->streamout.enabled_mask = (num_targets >= 1 && targets[0] ? 1 : 0) |
> - (num_targets >= 2 && targets[1] ? 2 : 0) |
> - (num_targets >= 3 && targets[2] ? 4 : 0) |
> - (num_targets >= 4 && targets[3] ? 8 : 0);
> + rctx->streamout.enabled_mask = enabled_mask;
>
> rctx->streamout.num_targets = num_targets;
> rctx->streamout.append_bitmask = append_bitmask;
> --
> 2.5.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list