From 627a6d792aa6cf5415ea51a636c7cbb18247cabd 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: (cherry picked from commit 0a97d1ebfa24b5016526cf0d79be503810520729) --- .pick_status.json | 2 +- 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 ++- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index dab99729303..461819b1e38 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -484,7 +484,7 @@ "description": "zink: fix descriptor buffer unmaps on screen destroy", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": "b06f6e00fba6e33c28a198a1bb14b89e9dfbb4ae", "notes": null diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index d9b6c0bc8db..42ff1bf8b0c 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -172,6 +172,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 994694de856..1435bdf58f3 100644 --- a/src/gallium/drivers/zink/zink_resource.c +++ b/src/gallium/drivers/zink/zink_resource.c @@ -2840,6 +2840,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,