From 0a97d1ebfa24b5016526cf0d79be503810520729 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 29 Jan 2024 15:07:39 -0500 Subject: [PATCH] zink: fix descriptor buffer unmaps on screen destroy descriptor buffer uses mapped buffers. mapping/unmapping buffers uses a ctx in the function params, but at this time there is no ctx. since the ctx is not actually used for unmapping descriptor buffers, this can instead use a special buffer unmap function to avoid invalid access Fixes: b06f6e00fba ("zink: fix heap-use-after-free on batch_state with sub-allocated pipe_resources") Part-of: --- src/gallium/drivers/zink/zink_context.c | 1 + src/gallium/drivers/zink/zink_descriptors.c | 2 +- src/gallium/drivers/zink/zink_resource.c | 10 ++++++++++ src/gallium/drivers/zink/zink_resource.h | 3 ++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 9945ff1ce76..fbe293ad444 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -173,6 +173,7 @@ zink_context_destroy(struct pipe_context *pctx) while (bs) { struct zink_batch_state *bs_next = bs->next; zink_clear_batch_state(ctx, bs); + bs->ctx = NULL; /* restore link as we insert them into the screens free_batch_states * list below */ diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c index 1c3b3fe71be..81b197c2ef0 100644 --- a/src/gallium/drivers/zink/zink_descriptors.c +++ b/src/gallium/drivers/zink/zink_descriptors.c @@ -1501,7 +1501,7 @@ zink_batch_descriptor_deinit(struct zink_screen *screen, struct zink_batch_state } if (bs->dd.db_xfer) - pipe_buffer_unmap(&bs->ctx->base, bs->dd.db_xfer); + zink_screen_buffer_unmap(&screen->base, bs->dd.db_xfer); bs->dd.db_xfer = NULL; if (bs->dd.db) screen->base.resource_destroy(&screen->base, &bs->dd.db->base.b); diff --git a/src/gallium/drivers/zink/zink_resource.c b/src/gallium/drivers/zink/zink_resource.c index 0c796c1a635..a1b142ace9e 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -2985,6 +2985,16 @@ do_transfer_unmap(struct zink_screen *screen, struct zink_transfer *trans) unmap_resource(screen, res); } +void +zink_screen_buffer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptrans) +{ + struct zink_screen *screen = zink_screen(pscreen); + struct zink_transfer *trans = (struct zink_transfer *)ptrans; + if (trans->base.b.usage & PIPE_MAP_ONCE && !trans->staging_res) + do_transfer_unmap(screen, trans); + transfer_unmap(NULL, ptrans); +} + static void zink_buffer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) { diff --git a/src/gallium/drivers/zink/zink_resource.h b/src/gallium/drivers/zink/zink_resource.h index 6bdcaa2a854..f09a4e89f52 100644 --- a/src/gallium/drivers/zink/zink_resource.h +++ b/src/gallium/drivers/zink/zink_resource.h @@ -44,7 +44,8 @@ zink_screen_resource_init(struct pipe_screen *pscreen); void zink_context_resource_init(struct pipe_context *pctx); - +void +zink_screen_buffer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptrans); void zink_get_depth_stencil_resources(struct pipe_resource *res, struct zink_resource **out_z,