From a6992c7bbeee4e5e1ddd3555a0d2a25b8113f7d5 Mon Sep 17 00:00:00 2001 From: Alyssa Milburn Date: Sat, 3 Jan 2026 22:06:10 +0100 Subject: [PATCH] nv50,nvc0: Avoid uninitialized cbuf reads in blits Overwrite the whole framebuffer cbuf rather than copying it from the stack; fixes util_framebuffer_get_num_samples getting uninitialized stack contents during validation. Suggested-by: Karol Herbst Reviewed-by: Karol Herbst Signed-off-by: Alyssa Milburn Fixes: 2eb45daa9c8 ("gallium: de-pointerize pipe_surface") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/14082 Part-of: --- .../drivers/nouveau/nv50/nv50_surface.c | 24 +++++++++---------- .../drivers/nouveau/nvc0/nvc0_surface.c | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/gallium/drivers/nouveau/nv50/nv50_surface.c b/src/gallium/drivers/nouveau/nv50/nv50_surface.c index 88c8a17656b..1c1e73758f1 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_surface.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_surface.c @@ -1096,26 +1096,26 @@ nv50_blit_set_dst(struct nv50_blitctx *ctx, { struct nv50_context *nv50 = ctx->nv50; struct pipe_context *pipe = &nv50->base.pipe; - struct pipe_surface templ; - /* We are going to reset this, so no point in refcounting */ - templ.texture = res; if (util_format_is_depth_or_stencil(format)) - templ.format = nv50_blit_zeta_to_colour_format(format); - else - templ.format = format; + format = nv50_blit_zeta_to_colour_format(format); - templ.level = level; - templ.first_layer = templ.last_layer = layer; + /* this will be overwritten (not released) at the end of the blit */ + nv50->framebuffer.cbufs[0] = (struct pipe_surface) { + .texture = res, + .format = format, + .level = level, + .first_layer = layer, + .last_layer = layer, + }; if (layer == -1) { - templ.first_layer = 0; - templ.last_layer = + nv50->framebuffer.cbufs[0].first_layer = 0; + nv50->framebuffer.cbufs[0].last_layer = (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1; } - nv50->fb_cbufs[0] = nv50_miptree_surface_new(pipe, res, &templ); - nv50->framebuffer.cbufs[0] = templ; + nv50->fb_cbufs[0] = nv50_miptree_surface_new(pipe, res, &nv50->framebuffer.cbufs[0]); nv50->framebuffer.nr_cbufs = 1; memset(&nv50->framebuffer.zsbuf, 0, sizeof(nv50->framebuffer.zsbuf)); nv50->fb_zsbuf = NULL; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c index 9dc18d1627a..2609a9a85e5 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_surface.c @@ -963,26 +963,26 @@ nvc0_blit_set_dst(struct nvc0_blitctx *ctx, { struct nvc0_context *nvc0 = ctx->nvc0; struct pipe_context *pipe = &nvc0->base.pipe; - struct pipe_surface templ; - /* We are going to reset this, so no point in refcounting */ - templ.texture = res; if (util_format_is_depth_or_stencil(format)) - templ.format = nv50_blit_zeta_to_colour_format(format); - else - templ.format = format; + format = nv50_blit_zeta_to_colour_format(format); - templ.level = level; - templ.first_layer = templ.last_layer = layer; + /* this will be overwritten (not released) at the end of the blit */ + nvc0->framebuffer.cbufs[0] = (struct pipe_surface) { + .texture = res, + .format = format, + .level = level, + .first_layer = layer, + .last_layer = layer, + }; if (layer == -1) { - templ.first_layer = 0; - templ.last_layer = + nvc0->framebuffer.cbufs[0].first_layer = 0; + nvc0->framebuffer.cbufs[0].last_layer = (res->target == PIPE_TEXTURE_3D ? res->depth0 : res->array_size) - 1; } - nvc0->framebuffer.cbufs[0] = templ; - nvc0->fb_cbufs[0] = nvc0_miptree_surface_new(pipe, res, &templ); + nvc0->fb_cbufs[0] = nvc0_miptree_surface_new(pipe, res, &nvc0->framebuffer.cbufs[0]); nvc0->framebuffer.nr_cbufs = 1; memset(&nvc0->framebuffer.zsbuf, 0, sizeof(nvc0->framebuffer.zsbuf)); pipe_surface_size(&nvc0->framebuffer.cbufs[0], &nvc0->framebuffer.width, &nvc0->framebuffer.height);