panfrost: Fix NULL pointer dereference in panfrost_emit_images

Fix a crash in image descriptor emission caused by stale image_mask bits.

Root cause:
- set_shader_images used a shift expression with count==64 when clearing
  image_mask, which is undefined behavior in C.
- This could leave image_mask inconsistent with actual image bindings,
  so panfrost_emit_images() might dereferences NULL image resources.

Fixes:
- Use 64-bit-safe bit helpers for mask updates to avoid invalid shifts.

Crash observed when running: OpenCL-CTS api/test_api
Backtrace:
  #0 util_image_to_sampler_view (v->resource is NULL)
  #1 panfrost_emit_images
  #2 panfrost_update_shader_state
  #3 panfrost_launch_grid_on_batch
  #4 panfrost_launch_grid

Backport-to: *
Signed-off-by: Eric Guo <eric.guo@nxp.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
(cherry picked from commit c1770565f3)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40752>
This commit is contained in:
Eric Guo 2026-02-03 15:44:01 +08:00 committed by Eric Engestrom
parent 88cfa8ff29
commit 58ab5760c1
2 changed files with 4 additions and 4 deletions

View file

@ -444,7 +444,7 @@
"description": "panfrost: Fix NULL pointer dereference in panfrost_emit_images",
"nominated": true,
"nomination_type": 4,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -248,7 +248,7 @@ panfrost_set_shader_images(struct pipe_context *pctx,
pipe_resource_reference(&ctx->images[shader][i].resource, NULL);
}
ctx->image_mask[shader] &= ~(((1ull << count) - 1) << start_slot);
ctx->image_mask[shader] &= ~(BITFIELD64_MASK(count) << start_slot);
return;
}
@ -273,7 +273,7 @@ panfrost_set_shader_images(struct pipe_context *pctx,
/* Bind start_slot...start_slot+count */
for (int i = 0; i < count; i++) {
const struct pipe_image_view *image = &iviews[i];
SET_BIT(ctx->image_mask[shader], 1 << (start_slot + i), image->resource);
SET_BIT(ctx->image_mask[shader], BITFIELD64_BIT(start_slot + i), image->resource);
if (!image->resource) {
util_copy_image_view(&ctx->images[shader][start_slot + i], NULL);
continue;
@ -283,7 +283,7 @@ panfrost_set_shader_images(struct pipe_context *pctx,
/* Unbind start_slot+count...start_slot+count+unbind_num_trailing_slots */
for (int i = 0; i < unbind_num_trailing_slots; i++) {
SET_BIT(ctx->image_mask[shader], 1 << (start_slot + count + i), NULL);
SET_BIT(ctx->image_mask[shader], BITFIELD64_BIT(start_slot + count + i), NULL);
util_copy_image_view(&ctx->images[shader][start_slot + count + i], NULL);
}
}