Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:mesa
User: [email protected]
Usertags: pu

Hi,

as part of LTS I was working on fixing CVE-2026-40393,
a out-of-bounds memory access vulnerabilty [1].

The upstream patch are these two commits:
https://gitlab.freedesktop.org/mesa/mesa/-/commit/978fd42b4b7d1e9c0435ffa7e1a4d339cba9b76e
 (mesa-26.0.1)
https://gitlab.freedesktop.org/mesa/mesa/-/commit/45ce75f3bcd638dcf7daae09f9bf0b7c015b81c4
 (mesa-26.0.1)
The patches mostly applied cleanly -- only .pick_status.json and the
include sections of the patches needed rework, as the set of includes
were different at the trixie version.

Additionally, the helper-macro STACK_ARRAY had to be backported.
(Technically this macro exists already in another file in the version in trixie,
in the file src/vulkan/util/vk_util.h, however, I've choosen to have it
in a dedicated file as the vk_util.h pulls in a lots of extra stuff by
it's includes)

I've tested the patches in a bookworm VM; mesa's test suite is happy too
and I've also (as upstream suggested) tested the patches with piglit
[2], also happy. (upstream suggests dEQP, however, I couldn't get this
working at all.)

I've reached out the the mesa maintainers for an RFC, hoewever, I didn't
get any response.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[1] https://deb.freexian.com/extended-lts/tracker/CVE-2026-40393
[2] https://docs.mesa3d.org/submittingpatches.html#testing-patches

--
tobi
diff -u mesa-22.3.6/debian/changelog mesa-22.3.6/debian/changelog
--- mesa-22.3.6/debian/changelog
+++ mesa-22.3.6/debian/changelog
@@ -1,3 +1,12 @@
+mesa (22.3.6-1+deb12u2) bookworm; urgency=high
+
+  * Non-maintainer upload by the LTS team
+  * Backport patch for CVE-2026-40393:
+    - backport support function STACK_ARRAY, cherry-pick file from upstream.
+    - backport commits fixing the issue
+
+ -- Tobias Frost <[email protected]>  Thu, 04 Jun 2026 16:25:49 +0200
+
 mesa (22.3.6-1+deb12u1) testing-proposed-updates; urgency=medium
 
   * Upload to testing.
diff -u mesa-22.3.6/debian/patches/series mesa-22.3.6/debian/patches/series
--- mesa-22.3.6/debian/patches/series
+++ mesa-22.3.6/debian/patches/series
@@ -1,3 +1,6 @@
 07_gallium-fix-build-failure-on-powerpcspe.diff
 path_max.diff
 src_glx_dri_common.h.diff
+backport_STACK_ARRAY.patch
+CVE-2026-40393-part1.patch
+CVE-2026-40393-part2.patch
only in patch2:
unchanged:
--- mesa-22.3.6.orig/debian/patches/CVE-2026-40393-part1.patch
+++ mesa-22.3.6/debian/patches/CVE-2026-40393-part1.patch
@@ -0,0 +1,97 @@
+Description: CVE-2026-40393 part 1 - out-of-bounds memory access in WebGPU
+Origin: 
https://gitlab.freedesktop.org/mesa/mesa/-/commit/978fd42b4b7d1e9c0435ffa7e1a4d339cba9b76e
+
+From 978fd42b4b7d1e9c0435ffa7e1a4d339cba9b76e Mon Sep 17 00:00:00 2001
+From: Ian Romanick <[email protected]>
+Date: Fri, 23 Jan 2026 09:58:26 -0800
+Subject: [PATCH] spirv: Use STACK_ARRAY instead of NIR_VLA
+
+The number of fields comes from the shader, so it could be a value large
+enough that using alloca would be problematic.
+
+Fixes: 2a023f30a64 ("nir/spirv: Add basic support for types")
+Reviewed-by: Caio Oliveira <[email protected]>
+Reviewed-by: Ryan Neph <[email protected]>
+Reviewed-by: Lionel Landwerlin <[email protected]>
+(cherry picked from commit 3da828d2dd12e20ba2afc152db8d7236c7a48c13)
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40092>
+
+--- a/src/compiler/spirv/spirv_to_nir.c
++++ b/src/compiler/spirv/spirv_to_nir.c
+@@ -26,7 +26,6 @@
+  */
+ 
+ #include "vtn_private.h"
+-#include "nir/nir_vla.h"
+ #include "nir/nir_control_flow.h"
+ #include "nir/nir_constant_expressions.h"
+ #include "nir/nir_deref.h"
+@@ -35,6 +34,7 @@
+ #include "util/format/u_format.h"
+ #include "util/u_math.h"
+ #include "util/u_string.h"
++#include "util/stack_array.h"
+ 
+ #include <stdio.h>
+ 
+@@ -927,7 +927,7 @@
+       case vtn_base_type_struct: {
+          bool need_new_struct = false;
+          const uint32_t num_fields = type->length;
+-         NIR_VLA(struct glsl_struct_field, fields, num_fields);
++         STACK_ARRAY(struct glsl_struct_field, fields, num_fields);
+          for (unsigned i = 0; i < num_fields; i++) {
+             fields[i] = *glsl_get_struct_field_data(type->type, i);
+             const struct glsl_type *field_nir_type =
+@@ -937,20 +937,25 @@
+                need_new_struct = true;
+             }
+          }
++
++         const struct glsl_type *result;
+          if (need_new_struct) {
+             if (glsl_type_is_interface(type->type)) {
+-               return glsl_interface_type(fields, num_fields,
+-                                          /* packing */ 0, false,
+-                                          glsl_get_type_name(type->type));
++               result = glsl_interface_type(fields, num_fields,
++                                            /* packing */ 0, false,
++                                            glsl_get_type_name(type->type));
+             } else {
+-               return glsl_struct_type(fields, num_fields,
+-                                       glsl_get_type_name(type->type),
+-                                       
glsl_struct_type_is_packed(type->type));
++               result = glsl_struct_type(fields, num_fields,
++                                         glsl_get_type_name(type->type),
++                                         
glsl_struct_type_is_packed(type->type));
+             }
+          } else {
+             /* No changes, just pass it on */
+-            return type->type;
++            result = type->type;
+          }
++
++         STACK_ARRAY_FINISH(fields);
++         return result;
+       }
+ 
+       case vtn_base_type_image:
+@@ -1527,7 +1532,7 @@
+       val->type->offsets = ralloc_array(b, unsigned, num_fields);
+       val->type->packed = false;
+ 
+-      NIR_VLA(struct glsl_struct_field, fields, count);
++      STACK_ARRAY(struct glsl_struct_field, fields, count);
+       for (unsigned i = 0; i < num_fields; i++) {
+          val->type->members[i] = vtn_get_type(b, w[i + 2]);
+          const char *name = NULL;
+@@ -1583,6 +1588,8 @@
+                                             name ? name : "struct",
+                                             val->type->packed);
+       }
++
++      STACK_ARRAY_FINISH(fields);
+       break;
+    }
+ 
only in patch2:
unchanged:
--- mesa-22.3.6.orig/debian/patches/CVE-2026-40393-part2.patch
+++ mesa-22.3.6/debian/patches/CVE-2026-40393-part2.patch
@@ -0,0 +1,53 @@
+Description: CVE-2026-40393 part 2 - out-of-bounds memory access in WebGPU
+Origin: 
https://gitlab.freedesktop.org/mesa/mesa/-/commit/978fd42b4b7d1e9c0435ffa7e1a4d339cba9b76e
+
+From 45ce75f3bcd638dcf7daae09f9bf0b7c015b81c4 Mon Sep 17 00:00:00 2001
+From: Ian Romanick <[email protected]>
+Date: Fri, 23 Jan 2026 10:07:27 -0800
+Subject: [PATCH] nir: Use STACK_ARRAY instead of NIR_VLA
+
+The number of fields comes from the shader, so it could be a value large
+enough that using alloca would be problematic.
+
+Fixes: c11833ab24d ("nir,spirv: Rework function calls")
+Reviewed-by: Caio Oliveira <[email protected]>
+Reviewed-by: Ryan Neph <[email protected]>
+Reviewed-by: Lionel Landwerlin <[email protected]>
+(cherry picked from commit 9017d37e84771f921a63676dd8b955df9ef20f29)
+
+Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40092>
+---
+ .pick_status.json                | 2 +-
+ src/compiler/nir/nir_functions.c | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/src/compiler/nir/nir_inline_functions.c
++++ b/src/compiler/nir/nir_inline_functions.c
+@@ -22,9 +22,10 @@
+  */
+ 
+ #include "nir.h"
++#include "util/stack_array.h"
+ #include "nir_builder.h"
+ #include "nir_control_flow.h"
+-#include "nir_vla.h"
++
+ 
+ static bool function_ends_in_jump(nir_function_impl *impl)
+ {
+@@ -159,13 +160,14 @@
+        * to an SSA value first.
+        */
+       const unsigned num_params = call->num_params;
+-      NIR_VLA(nir_ssa_def *, params, num_params);
++      STACK_ARRAY(nir_ssa_def *, params, num_params);
+       for (unsigned i = 0; i < num_params; i++) {
+          params[i] = nir_ssa_for_src(b, call->params[i],
+                                      call->callee->params[i].num_components);
+       }
+ 
+       nir_inline_function_impl(b, call->callee->impl, params, NULL);
++      STACK_ARRAY_FINISH(params);
+    }
+ 
+    return progress;
only in patch2:
unchanged:
--- mesa-22.3.6.orig/debian/patches/backport_STACK_ARRAY.patch
+++ mesa-22.3.6/debian/patches/backport_STACK_ARRAY.patch
@@ -0,0 +1,54 @@
+Description: backport macro STACK_ARRAY, needed for fix for CVE-226-40393
+Origin: 
https://gitlab.freedesktop.org/mesa/mesa/-/blob/f43cff3728e58c377d1e03b13db62514217abfe1/src/util/stack_array.h
+Forwarded: not-needed
+Last-Update: 2026-05-25 <YYYY-MM-DD, last update of the meta-information, 
optional>
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+--- /dev/null
++++ b/src/util/stack_array.h
+@@ -0,0 +1,45 @@
++/*
++ * Copyright © 2025 Collabora, Ltd.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice (including the next
++ * paragraph) shall be included in all copies or substantial portions of the
++ * Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS
++ * IN THE SOFTWARE.
++ */
++
++#include <stdlib.h>
++
++#ifndef UTIL_STACK_ARRAY_H
++#define UTIL_STACK_ARRAY_H
++
++#define STACK_ARRAY_SIZE 8
++
++/* Sometimes gcc may claim -Wmaybe-uninitialized for the stack array in some
++ * places it can't verify that when size is 0 nobody down the call chain reads
++ * the array. Please don't try to fix it by zero-initializing the array here
++ * since it's used in a lot of different places. An "if (size == 0) return;"
++ * may work for you.
++ */
++#define STACK_ARRAY(type, name, size) \
++   type _stack_##name[STACK_ARRAY_SIZE]; \
++   type *const name = \
++     ((size) <= STACK_ARRAY_SIZE ? _stack_##name : (type *)malloc((size) * 
sizeof(type)))
++
++#define STACK_ARRAY_FINISH(name) \
++   if (name != _stack_##name) free(name)
++
++#endif /* UTIL_STACK_ARRAY_H */

Attachment: signature.asc
Description: PGP signature

Reply via email to