* [OE-core][scarthgap 00/21] Patch review
@ 2026-06-12 14:25 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 01/21] libpng: Fix CVE-2026-33416 Jeremy Rosen
` (20 more replies)
0 siblings, 21 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
(Acting as LTS maintainer in training, process has been reviewed by
Yoann Congal)
Please review this set of changes for scarthgap and have comments back by
end of day Tuesday, June 16.
Passed a-full on autobuilder:
https://autobuilder.yoctoproject.org/valkyrie/#/builders/29/builds/3980
The following changes since commit e2864ea1ac022e43af92badc701fa1e2a9571f46:
pseudo: Upgrade 1.9.6 -> 1.9.7 (2026-06-05 11:02:52 +0200)
are available in the Git repository at:
https://git.openembedded.org/openembedded-core-contrib stable/scarthgap-nut
https://git.openembedded.org/openembedded-core-contrib/log/?h=stable/scarthgap-nut
for you to fetch changes up to 5e138a5cfb868b2b545161cb2cc706ccde307512:
meta/lib/oe/package.py: fix path to kernel sources in save_debugsources_info (2026-06-12 11:50:34 +0200)
----------------------------------------------------------------
Enrico Jörns (1):
devtool: prevent 'devtool modify -n' from corrupting kernel Git repos
Hugo SIMELIERE (Schneider Electric) (3):
busybox: Fix CVE-2026-29004
xz: Fix CVE-2026-34743
util-linux: Fix CVE-2026-27456
João Marcos Costa (Schneider Electric) (1):
meta/lib/oe/package.py: fix path to kernel sources in
save_debugsources_info
Sudhir Dumbhare (1):
nfs-utils: fix CVE-2025-12801
Theo Gaige (Schneider Electric) (14):
go: patch CVE-2026-27142
go: patch CVE-2026-32280
go: patch CVE-2026-32283
go: patch CVE-2026-32289
go: patch CVE-2026-33811
go: patch CVE-2026-39817
go: patch CVE-2026-39819
go: patch CVE-2026-39820
go: patch CVE-2026-39825
go: patch CVE-2026-39826
go: patch CVE-2026-42499
go: patch CVE-2026-42501
go: patch CVE-2026-42504
go: patch CVE-2026-42507
Zahir Hussain (1):
libpng: Fix CVE-2026-33416
meta/classes/create-spdx-2.2.bbclass | 2 +-
meta/lib/oe/package.py | 4 +-
.../nfs-utils/CVE-2025-12801-build-fix.patch | 44 ++
.../CVE-2025-12801-dependent_p1.patch | 71 +++
.../CVE-2025-12801-dependent_p2.patch | 81 +++
.../CVE-2025-12801-dependent_p3.patch | 185 +++++++
.../CVE-2025-12801-dependent_p4.patch | 468 ++++++++++++++++++
.../nfs-utils/nfs-utils/CVE-2025-12801.patch | 254 ++++++++++
.../nfs-utils/nfs-utils_2.6.4.bb | 6 +
.../busybox/busybox/CVE-2026-29004-01.patch | 41 ++
.../busybox/busybox/CVE-2026-29004-02.patch | 46 ++
meta/recipes-core/busybox/busybox_1.36.1.bb | 2 +
meta/recipes-core/util-linux/util-linux.inc | 1 +
.../util-linux/CVE-2026-27456.patch | 115 +++++
meta/recipes-devtools/go/go-1.22.12.inc | 14 +
.../go/go/CVE-2026-27142.patch | 386 +++++++++++++++
.../go/go/CVE-2026-32280.patch | 289 +++++++++++
.../go/go/CVE-2026-32283.patch | 177 +++++++
.../go/go/CVE-2026-32289.patch | 217 ++++++++
.../go/go/CVE-2026-33811.patch | 46 ++
.../go/go/CVE-2026-39817.patch | 105 ++++
.../go/go/CVE-2026-39819.patch | 48 ++
.../go/go/CVE-2026-39820.patch | 112 +++++
.../go/go/CVE-2026-39825.patch | 104 ++++
.../go/go/CVE-2026-39826.patch | 65 +++
.../go/go/CVE-2026-42499.patch | 91 ++++
.../go/go/CVE-2026-42501.patch | 127 +++++
.../go/go/CVE-2026-42504.patch | 58 +++
.../go/go/CVE-2026-42507.patch | 160 ++++++
.../xz/xz/CVE-2026-34743.patch | 68 +++
meta/recipes-extended/xz/xz_5.4.7.bb | 1 +
.../libpng/files/CVE-2026-33416-01.patch | 143 ++++++
.../libpng/files/CVE-2026-33416-02.patch | 53 ++
.../libpng/files/CVE-2026-33416-03.patch | 163 ++++++
.../libpng/files/CVE-2026-33416-04.patch | 53 ++
.../libpng/libpng_1.6.42.bb | 4 +
scripts/lib/devtool/standard.py | 3 +-
37 files changed, 3803 insertions(+), 4 deletions(-)
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-build-fix.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p2.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p3.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p4.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801.patch
create mode 100644 meta/recipes-core/busybox/busybox/CVE-2026-29004-01.patch
create mode 100644 meta/recipes-core/busybox/busybox/CVE-2026-29004-02.patch
create mode 100644 meta/recipes-core/util-linux/util-linux/CVE-2026-27456.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-27142.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32280.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32283.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32289.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-33811.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39817.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39819.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39820.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39825.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39826.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42499.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42501.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42504.patch
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42507.patch
create mode 100644 meta/recipes-extended/xz/xz/CVE-2026-34743.patch
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-01.patch
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-02.patch
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-03.patch
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-04.patch
--
2.53.0
^ permalink raw reply [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 01/21] libpng: Fix CVE-2026-33416
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 02/21] busybox: Fix CVE-2026-29004 Jeremy Rosen
` (19 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: Zahir Hussain <mail2szahir@gmail.com>
Backport fixes for CVE-2026-33416
Backport patches from security debian tracker [1] also mentioned at NVD Report [2]
[1] https://security-tracker.debian.org/tracker/CVE-2026-33416
[2] https://nvd.nist.gov/vuln/detail/CVE-2026-33416
Add below patches to fix the CVE:
CVE-2026-33416-01.patch
CVE-2026-33416-02.patch
CVE-2026-33416-03.patch
CVE-2026-33416-04.patch
Signed-off-by: Sourav Kumar Pramanik <souravkumar.pramanik@bmwtechworks.in>
Signed-off-by: Zahir Hussain <zahir.basha@kpit.com>
Signed-off-by: Jérémy Rosen <jeremy.rosen@smile.fr>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
.../libpng/files/CVE-2026-33416-01.patch | 143 +++++++++++++++
.../libpng/files/CVE-2026-33416-02.patch | 53 ++++++
.../libpng/files/CVE-2026-33416-03.patch | 163 ++++++++++++++++++
.../libpng/files/CVE-2026-33416-04.patch | 53 ++++++
.../libpng/libpng_1.6.42.bb | 4 +
5 files changed, 416 insertions(+)
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-01.patch
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-02.patch
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-03.patch
create mode 100644 meta/recipes-multimedia/libpng/files/CVE-2026-33416-04.patch
diff --git a/meta/recipes-multimedia/libpng/files/CVE-2026-33416-01.patch b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-01.patch
new file mode 100644
index 0000000000..a60a8d6b5b
--- /dev/null
+++ b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-01.patch
@@ -0,0 +1,143 @@
+From 23019269764e35ed8458e517f1897bd3c54820eb Mon Sep 17 00:00:00 2001
+From: Oblivionsage <cookieandcream560@gmail.com>
+Date: Sun, 15 Mar 2026 10:35:29 +0100
+Subject: [PATCH] fix: Resolve use-after-free on `png_ptr->trans_alpha`
+
+The function `png_set_tRNS` sets `png_ptr->trans_alpha` to point at
+`info_ptr->trans_alpha` directly, so both structs share the same heap
+buffer. If the application calls `png_free_data(PNG_FREE_TRNS)`, or if
+`png_set_tRNS` is called a second time, the buffer is freed through
+`info_ptr` while `png_ptr` still holds a dangling reference. Any
+subsequent row read that hits the function `png_do_expand_palette` will
+dereference freed memory.
+
+The fix gives `png_struct` its own allocation instead of aliasing the
+`info_ptr` pointer. This was already flagged with a TODO in
+`png_handle_tRNS` ("horrible side effect ... Fix this.") but it was
+never addressed.
+
+Verified with AddressSanitizer. All 34 existing tests pass without
+regressions.
+
+CVE: CVE-2026-33416
+Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/23019269764e35ed8458e517f1897bd3c54820eb]
+Comment: Refreshed hunk to match latest scarthgap
+
+Reviewed-by: Cosmin Truta <ctruta@gmail.com>
+Signed-off-by: Cosmin Truta <ctruta@gmail.com>
+Signed-off-by: Sourav Kumar Pramanik <Souravkumar.Pramanik@bmwtechworks.in>
+Signed-off-by: Zahir Hussain <zahir.basha@kpit.com>
+---
+ pngread.c | 11 +++++------
+ pngrutil.c | 4 ----
+ pngset.c | 31 +++++++++++++++++++------------
+ pngwrite.c | 6 ++++++
+ 4 files changed, 30 insertions(+), 22 deletions(-)
+
+diff --git a/pngread.c b/pngread.c
+index 01b731d8eb..0086edf6cf 100644
+--- a/pngread.c
++++ b/pngread.c
+@@ -968,12 +968,11 @@ png_read_destroy(png_structrp png_ptr)
+
+ #if defined(PNG_tRNS_SUPPORTED) || \
+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+- if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)
+- {
+- png_free(png_ptr, png_ptr->trans_alpha);
+- png_ptr->trans_alpha = NULL;
+- }
+- png_ptr->free_me &= ~PNG_FREE_TRNS;
++ /* png_ptr->trans_alpha is always independently allocated (not aliased
++ * with info_ptr->trans_alpha), so free it unconditionally.
++ */
++ png_free(png_ptr, png_ptr->trans_alpha);
++ png_ptr->trans_alpha = NULL;
+ #endif
+
+ inflateEnd(&png_ptr->zstream);
+diff --git a/pngrutil.c b/pngrutil.c
+index 366379b991..a19507bf1b 100644
+--- a/pngrutil.c
++++ b/pngrutil.c
+@@ -1905,10 +1905,6 @@ png_handle_tRNS(png_structrp png_ptr, pn
+ return;
+ }
+
+- /* TODO: this is a horrible side effect in the palette case because the
+- * png_struct ends up with a pointer to the tRNS buffer owned by the
+- * png_info. Fix this.
+- */
+ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+ &(png_ptr->trans_color));
+ }
+diff --git a/pngset.c b/pngset.c
+index 4b78b8960c..47883684e4 100644
+--- a/pngset.c
++++ b/pngset.c
+@@ -990,28 +990,36 @@ png_set_tRNS(png_structrp png_ptr, png_i
+
+ if (trans_alpha != NULL)
+ {
+- /* It may not actually be necessary to set png_ptr->trans_alpha here;
+- * we do it for backward compatibility with the way the png_handle_tRNS
+- * function used to do the allocation.
+- *
+- * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively
+- * relies on png_set_tRNS storing the information in png_struct
+- * (otherwise it won't be there for the code in pngrtran.c).
+- */
+-
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+
+ if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+ {
+- /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
++ /* Allocate info_ptr's copy of the transparency data. */
+ info_ptr->trans_alpha = png_voidcast(png_bytep,
+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
+ memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
+-
+ info_ptr->free_me |= PNG_FREE_TRNS;
+ info_ptr->valid |= PNG_INFO_tRNS;
++
++
++ /* Allocate an independent copy for png_struct, so that the
++ * lifetime of png_ptr->trans_alpha is decoupled from the
++ * lifetime of info_ptr->trans_alpha. Previously these two
++ * pointers were aliased, which caused a use-after-free if
++ * png_free_data freed info_ptr->trans_alpha while
++ * png_ptr->trans_alpha was still in use by the row transform
++ * functions (e.g. png_do_expand_palette).
++ */
++ png_free(png_ptr, png_ptr->trans_alpha);
++ png_ptr->trans_alpha = png_voidcast(png_bytep,
++ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
++ memcpy(png_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
++ }
++ else
++ {
++ png_free(png_ptr, png_ptr->trans_alpha);
++ png_ptr->trans_alpha = NULL;
+ }
+- png_ptr->trans_alpha = info_ptr->trans_alpha;
+ }
+
+ if (trans_color != NULL)
+diff --git a/pngwrite.c b/pngwrite.c
+index 5fc77d91f7..84af1e73fb 100644
+--- a/pngwrite.c
++++ b/pngwrite.c
+@@ -977,6 +977,12 @@ png_write_destroy(png_structrp png_ptr)
+ png_ptr->chunk_list = NULL;
+ #endif
+
++#if defined(PNG_tRNS_SUPPORTED)
++ /* Free the independent copy of trans_alpha owned by png_struct. */
++ png_free(png_ptr, png_ptr->trans_alpha);
++ png_ptr->trans_alpha = NULL;
++#endif
++
+ /* The error handling and memory handling information is left intact at this
+ * point: the jmp_buf may still have to be freed. See png_destroy_png_struct
+ * for how this happens.
diff --git a/meta/recipes-multimedia/libpng/files/CVE-2026-33416-02.patch b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-02.patch
new file mode 100644
index 0000000000..e746293bf2
--- /dev/null
+++ b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-02.patch
@@ -0,0 +1,53 @@
+From a3a21443ed12bfa1ef46fa0d4fb2b74a0fa34a25 Mon Sep 17 00:00:00 2001
+From: Oblivionsage <cookieandcream560@gmail.com>
+Date: Tue, 17 Mar 2026 08:55:18 +0100
+Subject: [PATCH] fix: Initialize tail bytes in `trans_alpha` buffers
+
+Although the arrays `info_ptr->trans_alpha` and `png_ptr->trans_alpha`
+are allocated 256 bytes, only `num_trans` bytes are copied.
+The remaining entries were left uninitialized. Set them to 0xff (fully
+opaque) before copying, which matches the conventional treatment of
+entries beyond `num_trans`.
+
+This is a follow-up to the previous use-after-free fix.
+
+CVE: CVE-2026-33416
+Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/a3a21443ed12bfa1ef46fa0d4fb2b74a0fa34a25]
+Comment: Refreshed hunk to match latest scarthgap
+
+Reported-by: Cosmin Truta <ctruta@gmail.com>
+Reviewed-by: Cosmin Truta <ctruta@gmail.com>
+Signed-off-by: Cosmin Truta <ctruta@gmail.com>
+Signed-off-by: Sourav Kumar Pramanik <Souravkumar.Pramanik@bmwtechworks.in>
+Signed-off-by: Zahir Hussain <zahir.basha@kpit.com>
+---
+ pngset.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/pngset.c b/pngset.c
+index 47883684e4..dccc6498d7 100644
+--- a/pngset.c
++++ b/pngset.c
+@@ -994,9 +994,13 @@ png_set_tRNS(png_structrp png_ptr, png_i
+
+ if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+ {
+- /* Allocate info_ptr's copy of the transparency data. */
++ /* Allocate info_ptr's copy of the transparency data.
++ * Initialize all entries to fully opaque (0xff), then overwrite
++ * the first num_trans entries with the actual values.
++ */
+ info_ptr->trans_alpha = png_voidcast(png_bytep,
+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
++ memset(info_ptr->trans_alpha, 0xff, PNG_MAX_PALETTE_LENGTH);
+ memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
+ info_ptr->free_me |= PNG_FREE_TRNS;
+ info_ptr->valid |= PNG_INFO_tRNS;
+@@ -1013,6 +1017,7 @@ png_set_tRNS(png_structrp png_ptr, png_i
+ png_free(png_ptr, png_ptr->trans_alpha);
+ png_ptr->trans_alpha = png_voidcast(png_bytep,
+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
++ memset(png_ptr->trans_alpha, 0xff, PNG_MAX_PALETTE_LENGTH);
+ memcpy(png_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
+ }
+ else
diff --git a/meta/recipes-multimedia/libpng/files/CVE-2026-33416-03.patch b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-03.patch
new file mode 100644
index 0000000000..21ce35dcd1
--- /dev/null
+++ b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-03.patch
@@ -0,0 +1,163 @@
+From 7ea9eea884a2328cc7fdcb3c0c00246a50d90667 Mon Sep 17 00:00:00 2001
+From: Cosmin Truta <ctruta@gmail.com>
+Date: Fri, 20 Mar 2026 17:37:22 +0200
+Subject: [PATCH] fix: Resolve use-after-free on `png_ptr->palette`
+
+Give `png_struct` its own independently-allocated copy of the palette
+buffer, decoupling it from `info_struct`'s palette. Allocate both
+copies with `png_calloc` to zero-fill, because the ARM NEON palette
+riffle reads all 256 entries unconditionally.
+
+In function `png_set_PLTE`, `png_ptr->palette` was aliased directly to
+`info_ptr->palette`: a single heap buffer shared across two structs
+with independent lifetimes. If the buffer was freed through `info_ptr`
+(via `png_free_data(PNG_FREE_PLTE)` or a second call to `png_set_PLTE`),
+`png_ptr->palette` became a dangling pointer. Subsequent row reads,
+performed in `png_do_expand_palette` and in other transform functions,
+dereferenced (and in the bit-shift path, wrote to) freed memory.
+
+Also fix `png_set_quantize` to allocate an owned copy of the caller's
+palette rather than aliasing the user pointer, so that the unconditional
+free in `png_read_destroy` does not free unmanaged memory.
+
+CVE: CVE-2026-33416
+Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/7ea9eea884a2328cc7fdcb3c0c00246a50d90667]
+Comment: Refreshed hunk to match latest scarthgap
+
+Signed-off-by: Sourav Kumar Pramanik <Souravkumar.Pramanik@bmwtechworks.in>
+Signed-off-by: Zahir Hussain <zahir.basha@kpit.com>
+---
+ pngread.c | 11 +++++------
+ pngrtran.c | 8 +++++++-
+ pngrutil.c | 13 -------------
+ pngset.c | 28 +++++++++++++++++++---------
+ pngwrite.c | 4 ++++
+ 5 files changed, 35 insertions(+), 29 deletions(-)
+
+diff --git a/pngread.c b/pngread.c
+index 0086edf6cf..e1d38d578a 100644
+--- a/pngread.c
++++ b/pngread.c
+@@ -959,12 +959,11 @@ png_read_destroy(png_structrp png_ptr)
+ png_ptr->quantize_index = NULL;
+ #endif
+
+- if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)
+- {
+- png_zfree(png_ptr, png_ptr->palette);
+- png_ptr->palette = NULL;
+- }
+- png_ptr->free_me &= ~PNG_FREE_PLTE;
++ /* png_ptr->palette is always independently allocated (not aliased
++ * with info_ptr->palette), so free it unconditionally.
++ */
++ png_free(png_ptr, png_ptr->palette);
++ png_ptr->palette = NULL;
+
+ #if defined(PNG_tRNS_SUPPORTED) || \
+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+diff --git a/pngrtran.c b/pngrtran.c
+index bfb7d423b7..fd736ab672 100644
+--- a/pngrtran.c
++++ b/pngrtran.c
+@@ -750,7 +750,13 @@ png_set_quantize(png_structrp png_ptr, p
+ }
+ if (png_ptr->palette == NULL)
+ {
+- png_ptr->palette = palette;
++ /* Allocate an owned copy rather than aliasing the caller's pointer,
++ * so that png_read_destroy can free png_ptr->palette unconditionally.
++ */
++ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
++ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
++ memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
++ (sizeof (png_color)));
+ }
+ png_ptr->num_palette = (png_uint_16)num_palette;
+
+diff --git a/pngrutil.c b/pngrutil.c
+index a19507bf1b..3a35fe9de2 100644
+--- a/pngrutil.c
++++ b/pngrutil.c
+@@ -1047,14 +1047,6 @@ png_handle_PLTE(png_structrp png_ptr, pn
+ }
+ #endif
+
+- /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its
+- * own copy of the palette. This has the side effect that when png_start_row
+- * is called (this happens after any call to png_read_update_info) the
+- * info_ptr palette gets changed. This is extremely unexpected and
+- * confusing.
+- *
+- * Fix this by not sharing the palette in this way.
+- */
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+ /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before
+diff --git a/pngset.c b/pngset.c
+index dccc6498d7..b9ccb7fb15 100644
+--- a/pngset.c
++++ b/pngset.c
+@@ -595,28 +595,38 @@ png_set_PLTE(png_structrp png_ptr, png_i
+ png_error(png_ptr, "Invalid palette");
+ }
+
+- /* It may not actually be necessary to set png_ptr->palette here;
+- * we do it for backward compatibility with the way the png_handle_tRNS
+- * function used to do the allocation.
+- *
+- * 1.6.0: the above statement appears to be incorrect; something has to set
+- * the palette inside png_struct on read.
+- */
+ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+
+ /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
+ * of num_palette entries, in case of an invalid PNG file or incorrect
+ * call to png_set_PLTE() with too-large sample values.
++ *
++ * Allocate independent buffers for info_ptr and png_ptr so that the
++ * lifetime of png_ptr->palette is decoupled from the lifetime of
++ * info_ptr->palette. Previously, these two pointers were aliased,
++ * which caused a use-after-free vulnerability if png_free_data freed
++ * info_ptr->palette while png_ptr->palette was still in use by the
++ * row transform functions (e.g. png_do_expand_palette).
++ *
++ * Both buffers are allocated with png_calloc to zero-fill, because
++ * the ARM NEON palette riffle reads all 256 entries unconditionally,
++ * regardless of num_palette.
+ */
++ png_free(png_ptr, png_ptr->palette);
+ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
+ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
++ info_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
++ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
++ png_ptr->num_palette = info_ptr->num_palette = (png_uint_16)num_palette;
+
+ if (num_palette > 0)
++ {
++ memcpy(info_ptr->palette, palette, (unsigned int)num_palette *
++ (sizeof (png_color)));
+ memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
+ (sizeof (png_color)));
++ }
+
+- info_ptr->palette = png_ptr->palette;
+- info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+ info_ptr->free_me |= PNG_FREE_PLTE;
+ info_ptr->valid |= PNG_INFO_PLTE;
+ }
+diff --git a/pngwrite.c b/pngwrite.c
+index 84af1e73fb..348763e940 100644
+--- a/pngwrite.c
++++ b/pngwrite.c
+@@ -982,6 +982,10 @@ png_write_destroy(png_structrp png_ptr)
+ png_free(png_ptr, png_ptr->trans_alpha);
+ png_ptr->trans_alpha = NULL;
+ #endif
++
++ /* Free the independent copy of the palette owned by png_struct. */
++ png_free(png_ptr, png_ptr->palette);
++ png_ptr->palette = NULL;
+
+ /* The error handling and memory handling information is left intact at this
+ * point: the jmp_buf may still have to be freed. See png_destroy_png_struct
diff --git a/meta/recipes-multimedia/libpng/files/CVE-2026-33416-04.patch b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-04.patch
new file mode 100644
index 0000000000..ff7db53c81
--- /dev/null
+++ b/meta/recipes-multimedia/libpng/files/CVE-2026-33416-04.patch
@@ -0,0 +1,53 @@
+From c1b0318b393c90679e6fa5bc1d329fd5d5012ec1 Mon Sep 17 00:00:00 2001
+From: Cosmin Truta <ctruta@gmail.com>
+Date: Fri, 20 Mar 2026 21:25:12 +0200
+Subject: [PATCH] fix: Sync `info_ptr->palette` after in-place transforms
+
+Copy `png_ptr->palette` into `info_ptr->palette` upon entering
+the function that runs immediately after the in-place transforms.
+
+The palette decoupling in the previous commit gave `png_struct`
+and `png_info` independently-allocated palette buffers, fixing a
+use-after-free vulnerability. However, `png_init_read_transformations`
+modifies `png_ptr->palette` in place (e.g. for gamma correction or
+background compositing), and the old aliasing made those modifications
+visible through `png_get_PLTE`. With independent buffers,
+`info_ptr->palette` retained the original values, causing our tests to
+fail on indexed-colour background compositing.
+
+CVE: CVE-2026-33416
+Upstream-Status: Backport [https://github.com/pnggroup/libpng/commit/c1b0318b393c90679e6fa5bc1d329fd5d5012ec1]
+Comment: Refreshed hunk to match latest scarthgap
+
+Signed-off-by: Sourav Kumar Pramanik <Souravkumar.Pramanik@bmwtechworks.in>
+Signed-off-by: Zahir Hussain <zahir.basha@kpit.com>
+---
+ pngrtran.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/pngrtran.c b/pngrtran.c
+index fd736ab672..978dac5888 100644
+--- a/pngrtran.c
++++ b/pngrtran.c
+@@ -1984,6 +1984,21 @@ png_read_transform_info(png_structrp png
+ {
+ png_debug(1, "in png_read_transform_info");
+
++ if (png_ptr->transformations != 0)
++ {
++ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
++ info_ptr->palette != NULL && png_ptr->palette != NULL)
++ {
++ /* Sync info_ptr->palette with png_ptr->palette.
++ * The function png_init_read_transformations may have modified
++ * png_ptr->palette in place (e.g. for gamma correction or for
++ * background compositing).
++ */
++ memcpy(info_ptr->palette, png_ptr->palette,
++ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)));
++ }
++ }
++
+ #ifdef PNG_READ_EXPAND_SUPPORTED
+ if ((png_ptr->transformations & PNG_EXPAND) != 0)
+ {
diff --git a/meta/recipes-multimedia/libpng/libpng_1.6.42.bb b/meta/recipes-multimedia/libpng/libpng_1.6.42.bb
index 923ed79896..e4cc63686e 100644
--- a/meta/recipes-multimedia/libpng/libpng_1.6.42.bb
+++ b/meta/recipes-multimedia/libpng/libpng_1.6.42.bb
@@ -25,6 +25,10 @@ SRC_URI = "${SOURCEFORGE_MIRROR}/project/${BPN}/${BPN}${LIBV}/${PV}/${BP}.tar.xz
file://CVE-2026-22801.patch \
file://CVE-2026-25646.patch \
file://CVE-2026-33636.patch \
+ file://CVE-2026-33416-01.patch \
+ file://CVE-2026-33416-02.patch \
+ file://CVE-2026-33416-03.patch \
+ file://CVE-2026-33416-04.patch \
"
SRC_URI[sha256sum] = "c919dbc11f4c03b05aba3f8884d8eb7adfe3572ad228af972bb60057bdb48450"
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 02/21] busybox: Fix CVE-2026-29004
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 01/21] libpng: Fix CVE-2026-33416 Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 03/21] nfs-utils: fix CVE-2025-12801 Jeremy Rosen
` (18 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Hugo SIMELIERE (Schneider Electric)" <hsimeliere.opensource@witekio.com>
Pick patches from [1] and [2] as mentioned in Debian report in [3].
[1] https://git.busybox.net/busybox/commit/archival?id=42202bfb1e6ac51fa995beda8be4d7b654aeee2a
[2] https://git.busybox.net/busybox/commit/archival?id=d368f3f7836d1c2484c8f839316e5c93e76d4409
[3] https://security-tracker.debian.org/tracker/CVE-2026-29004
Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
Reviewed-by: Bruno VERNAY <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
.../busybox/busybox/CVE-2026-29004-01.patch | 41 +++++++++++++++++
.../busybox/busybox/CVE-2026-29004-02.patch | 46 +++++++++++++++++++
meta/recipes-core/busybox/busybox_1.36.1.bb | 2 +
3 files changed, 89 insertions(+)
create mode 100644 meta/recipes-core/busybox/busybox/CVE-2026-29004-01.patch
create mode 100644 meta/recipes-core/busybox/busybox/CVE-2026-29004-02.patch
diff --git a/meta/recipes-core/busybox/busybox/CVE-2026-29004-01.patch b/meta/recipes-core/busybox/busybox/CVE-2026-29004-01.patch
new file mode 100644
index 0000000000..0423a76730
--- /dev/null
+++ b/meta/recipes-core/busybox/busybox/CVE-2026-29004-01.patch
@@ -0,0 +1,41 @@
+From e49fb0f6ad0a0f924ec2cfe6838d04c4f1f4c3ba Mon Sep 17 00:00:00 2001
+From: Denys Vlasenko <vda.linux@googlemail.com>
+Date: Thu, 12 Mar 2026 07:25:38 +0100
+Subject: [PATCH 1/2] udhcpc6: fix buffer overflow
+
+CVE: CVE-2026-29004
+Upstream-Status: Backport [https://git.busybox.net/busybox/commit/archival?id=42202bfb1e6ac51fa995beda8be4d7b654aeee2a]
+
+Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
+(cherry picked from commit 42202bfb1e6ac51fa995beda8be4d7b654aeee2a)
+Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
+---
+ networking/udhcp/d6_dhcpc.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
+index cdd06188e..62cc0f466 100644
+--- a/networking/udhcp/d6_dhcpc.c
++++ b/networking/udhcp/d6_dhcpc.c
+@@ -351,15 +351,15 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end)
+ addrs = option[3] >> 4;
+
+ /* Setup environment variable */
+- *new_env() = dlist = xmalloc(4 + addrs * 40 - 1);
++ *new_env() = dlist = xmalloc(4 + addrs * 40 + 1);
+ dlist = stpcpy(dlist, "dns=");
+ option_offset = 0;
+
+- while (addrs--) {
++ while (addrs-- != 0) {
+ sprint_nip6(dlist, option + 4 + option_offset);
+ dlist += 39;
+ option_offset += 16;
+- if (addrs)
++ if (addrs != 0)
+ *dlist++ = ' ';
+ }
+
+--
+2.43.0
+
diff --git a/meta/recipes-core/busybox/busybox/CVE-2026-29004-02.patch b/meta/recipes-core/busybox/busybox/CVE-2026-29004-02.patch
new file mode 100644
index 0000000000..ac8c031cc6
--- /dev/null
+++ b/meta/recipes-core/busybox/busybox/CVE-2026-29004-02.patch
@@ -0,0 +1,46 @@
+From 4d8d5b7c4426e62375235cf4903b6cb53bb193d3 Mon Sep 17 00:00:00 2001
+From: Denys Vlasenko <vda.linux@googlemail.com>
+Date: Thu, 12 Mar 2026 13:23:48 +0100
+Subject: [PATCH 2/2] udhcpc6: check the size of D6_OPT_IAPREFIX option
+
+function old new delta
+option_to_env 694 711 +17
+
+CVE: CVE-2026-29004
+Upstream-Status: Backport [https://git.busybox.net/busybox/commit/archival?id=d368f3f7836d1c2484c8f839316e5c93e76d4409]
+
+Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
+(cherry picked from commit d368f3f7836d1c2484c8f839316e5c93e76d4409)
+Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
+---
+ networking/udhcp/d6_dhcpc.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
+index 62cc0f466..64a41c9d8 100644
+--- a/networking/udhcp/d6_dhcpc.c
++++ b/networking/udhcp/d6_dhcpc.c
+@@ -287,8 +287,8 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end)
+ * | valid-lifetime |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+- /* Make sure payload contains an address */
+- if (option[3] < 24)
++ /* Make sure payload exists */
++ if (option[3] < (16 + 4 + 4))
+ break;
+
+ sprint_nip6(ipv6str, option + 4);
+@@ -332,6 +332,9 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end)
+ * | |
+ * +-+-+-+-+-+-+-+-+
+ */
++ /* Make sure payload exists */
++ if (option[3] < (4 + 4 + 1 + 16))
++ break;
+ move_from_unaligned32(v32, option + 4 + 4);
+ v32 = ntohl(v32);
+ *new_env() = xasprintf("ipv6prefix_lease=%u", (unsigned)v32);
+--
+2.43.0
+
diff --git a/meta/recipes-core/busybox/busybox_1.36.1.bb b/meta/recipes-core/busybox/busybox_1.36.1.bb
index 228bfdadd3..7929d396c8 100644
--- a/meta/recipes-core/busybox/busybox_1.36.1.bb
+++ b/meta/recipes-core/busybox/busybox_1.36.1.bb
@@ -64,6 +64,8 @@ SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \
file://CVE-2025-60876.patch \
file://CVE-2026-26157-CVE-2026-26158-01.patch \
file://CVE-2026-26157-CVE-2026-26158-02.patch \
+ file://CVE-2026-29004-01.patch \
+ file://CVE-2026-29004-02.patch \
"
SRC_URI:append:libc-musl = " file://musl.cfg "
# TODO http://lists.busybox.net/pipermail/busybox/2023-January/090078.html
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 03/21] nfs-utils: fix CVE-2025-12801
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 01/21] libpng: Fix CVE-2026-33416 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 02/21] busybox: Fix CVE-2026-29004 Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-15 7:59 ` Paul Barker
2026-06-12 14:25 ` [OE-core][scarthgap 04/21] xz: Fix CVE-2026-34743 Jeremy Rosen
` (17 subsequent siblings)
20 siblings, 1 reply; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: Sudhir Dumbhare <sudumbha@cisco.com>
- This patch applies the upstream fix [5] as referenced in [7].
- To successfully apply the fixed commit, apply the dependent commits [2] to [4]
which are included in v2.8.6, as referenced in [7].
- Additionally, include dependent commit [1] from v2.8.3, as referenced in [8]
under the [2.5.4-38.2] description, along with compilation fix commit [6]
from v2.7.1
- Reference:
[1] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=cd90f2925790
[2] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=7e8b36522f58
[3] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=42f01e6a78fe
[4] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=51738ae56d92
[5] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=f36bd900a899
[6] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=a2c95e4f557a
[7] https://security-tracker.debian.org/tracker/CVE-2025-12801
[8] https://linux.oracle.com/errata/ELSA-2026-3940.html
Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
.../nfs-utils/CVE-2025-12801-build-fix.patch | 44 ++
.../CVE-2025-12801-dependent_p1.patch | 71 +++
.../CVE-2025-12801-dependent_p2.patch | 81 +++
.../CVE-2025-12801-dependent_p3.patch | 185 +++++++
.../CVE-2025-12801-dependent_p4.patch | 468 ++++++++++++++++++
.../nfs-utils/nfs-utils/CVE-2025-12801.patch | 254 ++++++++++
.../nfs-utils/nfs-utils_2.6.4.bb | 6 +
7 files changed, 1109 insertions(+)
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-build-fix.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p2.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p3.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p4.patch
create mode 100644 meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801.patch
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-build-fix.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-build-fix.patch
new file mode 100644
index 0000000000..d7aaca2242
--- /dev/null
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-build-fix.patch
@@ -0,0 +1,44 @@
+From 30e0f57fff545b0bb3071fa071c7b12c2923bac8 Mon Sep 17 00:00:00 2001
+From: Steve Dickson <steved@redhat.com>
+Date: Mon, 22 Jan 2024 13:23:57 -0500
+Subject: [PATCH] reexport.c: Some Distros need the following include to
+ avoid the following error
+
+reexport.c: In function ‘connect_fsid_service’:
+reexport.c:41:28: error: implicit declaration of function ‘offsetof’ [-Werror=implicit-function-declaration]
+ 41 | addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);
+ | ^~~~~~~~
+reexport.c:19:1: note: ‘offsetof’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
+ 18 | #include "xlog.h"
+ +++ |+#include <stddef.h>
+ 19 |
+reexport.c:41:37: error: expected expression before ‘struct’
+ 41 | addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);
+ | ^~~~~~
+cc1: some warnings being treated as errors
+
+CVE: CVE-2025-12801
+Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=a2c95e4f557a71b482bb62bad6d93ddde51e5dc6]
+
+Signed-off-by: Steve Dickson <steved@redhat.com>
+(cherry picked from commit a2c95e4f557a71b482bb62bad6d93ddde51e5dc6)
+Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
+---
+ support/reexport/reexport.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/support/reexport/reexport.c b/support/reexport/reexport.c
+index 78516586..16dde0fb 100644
+--- a/support/reexport/reexport.c
++++ b/support/reexport/reexport.c
+@@ -8,6 +8,7 @@
+ #include <sys/types.h>
+ #include <sys/vfs.h>
+ #include <errno.h>
++#include <stddef.h>
+
+ #include "nfsd_path.h"
+ #include "conffile.h"
+--
+2.44.4
+
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch
new file mode 100644
index 0000000000..223249a9d6
--- /dev/null
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch
@@ -0,0 +1,71 @@
+From 647c9cb3ac3cbdf9ffd9e29f7d5dd04da84afdbc Mon Sep 17 00:00:00 2001
+From: Christopher Bii <christopherbii@hyub.org>
+Date: Wed, 15 Jan 2025 12:10:48 -0500
+Subject: [PATCH] NFS export symlink vulnerability fix
+
+Replaced dangerous use of realpath within support/nfs/export.c with
+nfsd_realpath variant that is executed within the chrooted thread
+rather than main thread.
+
+Implemented nfsd_path.h methods to work securely within chrooted
+thread using nfsd_run_task() help
+
+CVE: CVE-2025-12801
+Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=cd90f29257904f36509ea5a04a86f42398fbe94a]
+
+Backport Changes:
+- In support/misc/nfsd_path.c file, only nfsd_run_task() and the
+ struct nfsd_task_t have been included to resolve a compilation
+ issue. All other non-essential changes were excluded.
+- The non-required file support/export/cache.c and support/nfs/exports.c
+ has been excluded.
+
+Signed-off-by: Christopher Bii <christopherbii@hyub.org>
+Signed-off-by: Steve Dickson <steved@redhat.com>
+(cherry picked from commit cd90f29257904f36509ea5a04a86f42398fbe94a)
+Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
+---
+ support/include/nfsd_path.h | 1 +
+ support/misc/nfsd_path.c | 14 +++++++++++++-
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/support/include/nfsd_path.h b/support/include/nfsd_path.h
+index aa1e1dd0..4f5fc44e 100644
+--- a/support/include/nfsd_path.h
++++ b/support/include/nfsd_path.h
+@@ -8,6 +8,7 @@
+
+ struct file_handle;
+ struct statfs;
++struct nfsd_task_t;
+
+ void nfsd_path_init(void);
+
+diff --git a/support/misc/nfsd_path.c b/support/misc/nfsd_path.c
+index c3dea4f0..fa908f7c 100644
+--- a/support/misc/nfsd_path.c
++++ b/support/misc/nfsd_path.c
+@@ -19,7 +19,19 @@
+ #include "nfsd_path.h"
+ #include "workqueue.h"
+
+-static struct xthread_workqueue *nfsd_wq;
++static struct xthread_workqueue *nfsd_wq = NULL;
++
++struct nfsd_task_t {
++ int ret;
++ void* data;
++};
++/* Function used to offload tasks that must be ran within the correct
++ * chroot environment.
++ */
++static void
++nfsd_run_task(void (*func)(void*), void* data){
++ nfsd_wq ? xthread_work_run_sync(nfsd_wq, func, data) : func(data);
++};
+
+ static int
+ nfsd_path_isslash(const char *path)
+--
+2.35.6
+
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p2.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p2.patch
new file mode 100644
index 0000000000..f088eadb4b
--- /dev/null
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p2.patch
@@ -0,0 +1,81 @@
+From a6ddd0e9594884cf61816478e8c561f1b3aac709 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+Date: Mon, 10 Nov 2025 11:26:03 -0500
+Subject: [PATCH] mountd: Minor refactor of get_rootfh()
+
+Perform the mountpoint checks before checking the user path.
+
+CVE: CVE-2025-12801
+Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=7e8b36522f58657359c6842119fc516c6dd1baa4]
+
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Steve Dickson <steved@redhat.com>
+(cherry picked from commit 7e8b36522f58657359c6842119fc516c6dd1baa4)
+Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
+---
+ utils/mountd/mountd.c | 34 +++++++++++++++++-----------------
+ 1 file changed, 17 insertions(+), 17 deletions(-)
+
+diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
+index dbd5546d..39afd4aa 100644
+--- a/utils/mountd/mountd.c
++++ b/utils/mountd/mountd.c
+@@ -412,6 +412,23 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
+ *error = MNT3ERR_ACCES;
+ return NULL;
+ }
++ if (nfsd_path_stat(exp->m_export.e_path, &estb) < 0) {
++ xlog(L_WARNING, "can't stat export point %s: %s",
++ p, strerror(errno));
++ *error = MNT3ERR_NOENT;
++ return NULL;
++ }
++ if (exp->m_export.e_mountpoint &&
++ !check_is_mountpoint(exp->m_export.e_mountpoint[0]?
++ exp->m_export.e_mountpoint:
++ exp->m_export.e_path,
++ nfsd_path_lstat)) {
++ xlog(L_WARNING, "request to export an unmounted filesystem: %s",
++ p);
++ *error = MNT3ERR_NOENT;
++ return NULL;
++ }
++
+ if (nfsd_path_stat(p, &stb) < 0) {
+ xlog(L_WARNING, "can't stat exported dir %s: %s",
+ p, strerror(errno));
+@@ -426,12 +443,6 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
+ *error = MNT3ERR_NOTDIR;
+ return NULL;
+ }
+- if (nfsd_path_stat(exp->m_export.e_path, &estb) < 0) {
+- xlog(L_WARNING, "can't stat export point %s: %s",
+- p, strerror(errno));
+- *error = MNT3ERR_NOENT;
+- return NULL;
+- }
+ if (estb.st_dev != stb.st_dev
+ && !(exp->m_export.e_flags & NFSEXP_CROSSMOUNT)) {
+ xlog(L_WARNING, "request to export directory %s below nearest filesystem %s",
+@@ -439,17 +450,6 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
+ *error = MNT3ERR_ACCES;
+ return NULL;
+ }
+- if (exp->m_export.e_mountpoint &&
+- !check_is_mountpoint(exp->m_export.e_mountpoint[0]?
+- exp->m_export.e_mountpoint:
+- exp->m_export.e_path,
+- nfsd_path_lstat)) {
+- xlog(L_WARNING, "request to export an unmounted filesystem: %s",
+- p);
+- *error = MNT3ERR_NOENT;
+- return NULL;
+- }
+-
+ /* This will be a static private nfs_export with just one
+ * address. We feed it to kernel then extract the filehandle,
+ */
+--
+2.44.4
+
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p3.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p3.patch
new file mode 100644
index 0000000000..59b28b557a
--- /dev/null
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p3.patch
@@ -0,0 +1,185 @@
+From 0c2561328ce5e09636663ac2312b5f1f52fc0111 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+Date: Mon, 10 Nov 2025 11:28:39 -0500
+Subject: [PATCH] mountd: Separate lookup of the exported directory and the
+ mount path
+
+When the caller asks to mount a path that does not terminate with an
+exported directory, we want to split up the lookups so that we can
+look up the exported directory using the mountd privileged credential,
+and the remaining subdirectory lookups using the RPC caller's
+credential.
+
+CVE: CVE-2025-12801
+Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=42f01e6a78fed98f12437ac8b28cfb12b6bad056]
+
+Backport Changes:
+- In support/misc/nfsd_path.c, the closing brace of struct
+ nfsd_read_data was adjusted from line 320 to 282.
+
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Steve Dickson <steved@redhat.com>
+(cherry picked from commit 42f01e6a78fed98f12437ac8b28cfb12b6bad056)
+Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
+---
+ support/include/nfsd_path.h | 1 +
+ support/misc/nfsd_path.c | 31 ++++++++++++++++++
+ utils/mountd/mountd.c | 63 +++++++++++++++++++++++++++++++------
+ 3 files changed, 86 insertions(+), 9 deletions(-)
+
+diff --git a/support/include/nfsd_path.h b/support/include/nfsd_path.h
+index 4f5fc44e..be2dc38d 100644
+--- a/support/include/nfsd_path.h
++++ b/support/include/nfsd_path.h
+@@ -18,6 +18,7 @@ char * nfsd_path_prepend_dir(const char *dir, const char *pathname);
+
+ int nfsd_path_stat(const char *pathname, struct stat *statbuf);
+ int nfsd_path_lstat(const char *pathname, struct stat *statbuf);
++int nfsd_openat(int dirfd, const char *path, int flags);
+
+ int nfsd_path_statfs(const char *pathname,
+ struct statfs *statbuf);
+diff --git a/support/misc/nfsd_path.c b/support/misc/nfsd_path.c
+index fa908f7c..1c5aa3f3 100644
+--- a/support/misc/nfsd_path.c
++++ b/support/misc/nfsd_path.c
+@@ -280,6 +280,37 @@ struct nfsd_read_data {
+ int err;
+ };
+
++struct nfsd_openat_t {
++ const char *path;
++ int dirfd;
++ int flags;
++ int res_fd;
++ int res_error;
++};
++
++static void nfsd_openatfunc(void *data)
++{
++ struct nfsd_openat_t *d = data;
++
++ d->res_fd = openat(d->dirfd, d->path, d->flags);
++ if (d->res_fd == -1)
++ d->res_error = errno;
++}
++
++int nfsd_openat(int dirfd, const char *path, int flags)
++{
++ struct nfsd_openat_t open_buf = {
++ .path = path,
++ .dirfd = dirfd,
++ .flags = flags,
++ };
++
++ nfsd_run_task(nfsd_openatfunc, &open_buf);
++ if (open_buf.res_fd == -1)
++ errno = open_buf.res_error;
++ return open_buf.res_fd;
++}
++
+ static void
+ nfsd_readfunc(void *data)
+ {
+diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
+index 39afd4aa..f43ebef5 100644
+--- a/utils/mountd/mountd.c
++++ b/utils/mountd/mountd.c
+@@ -392,7 +392,10 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
+ struct nfs_fh_len *fh;
+ char rpath[MAXPATHLEN+1];
+ char *p = *path;
++ char *subpath;
+ char buf[INET6_ADDRSTRLEN];
++ size_t epathlen;
++ int dirfd;
+
+ if (*p == '\0')
+ p = "/";
+@@ -412,12 +415,21 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
+ *error = MNT3ERR_ACCES;
+ return NULL;
+ }
+- if (nfsd_path_stat(exp->m_export.e_path, &estb) < 0) {
+- xlog(L_WARNING, "can't stat export point %s: %s",
++
++ dirfd = nfsd_openat(AT_FDCWD, exp->m_export.e_path, O_PATH);
++ if (dirfd == -1) {
++ xlog(L_WARNING, "can't open export point %s: %s",
+ p, strerror(errno));
+ *error = MNT3ERR_NOENT;
+ return NULL;
+ }
++ if (fstat(dirfd, &estb) == -1) {
++ xlog(L_WARNING, "can't stat export point %s: %s",
++ p, strerror(errno));
++ *error = MNT3ERR_ACCES;
++ close(dirfd);
++ return NULL;
++ }
+ if (exp->m_export.e_mountpoint &&
+ !check_is_mountpoint(exp->m_export.e_mountpoint[0]?
+ exp->m_export.e_mountpoint:
+@@ -426,18 +438,51 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
+ xlog(L_WARNING, "request to export an unmounted filesystem: %s",
+ p);
+ *error = MNT3ERR_NOENT;
++ close(dirfd);
+ return NULL;
+ }
+
+- if (nfsd_path_stat(p, &stb) < 0) {
+- xlog(L_WARNING, "can't stat exported dir %s: %s",
+- p, strerror(errno));
+- if (errno == ENOENT)
+- *error = MNT3ERR_NOENT;
+- else
+- *error = MNT3ERR_ACCES;
++ epathlen = strlen(exp->m_export.e_path);
++ if (epathlen > strlen(p)) {
++ xlog(L_WARNING, "raced with change of exported path: %s", p);
++ *error = MNT3ERR_NOENT;
++ close(dirfd);
+ return NULL;
+ }
++ subpath = &p[epathlen];
++ while (*subpath == '/')
++ subpath++;
++ if (*subpath != '\0') {
++ int fd;
++
++ /* Just perform a lookup of the path */
++ fd = nfsd_openat(dirfd, subpath, O_PATH);
++ close(dirfd);
++ if (fd == -1) {
++ xlog(L_WARNING, "can't open exported dir %s: %s", p,
++ strerror(errno));
++ if (errno == ENOENT)
++ *error = MNT3ERR_NOENT;
++ else
++ *error = MNT3ERR_ACCES;
++ return NULL;
++ }
++ if (fstat(fd, &stb) == -1) {
++ xlog(L_WARNING, "can't open exported dir %s: %s", p,
++ strerror(errno));
++ if (errno == ENOENT)
++ *error = MNT3ERR_NOENT;
++ else
++ *error = MNT3ERR_ACCES;
++ close(fd);
++ return NULL;
++ }
++ close(fd);
++ } else {
++ close(dirfd);
++ stb = estb;
++ }
++
+ if (!S_ISDIR(stb.st_mode) && !S_ISREG(stb.st_mode)) {
+ xlog(L_WARNING, "%s is not a directory or regular file", p);
+ *error = MNT3ERR_NOTDIR;
+--
+2.44.4
+
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p4.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p4.patch
new file mode 100644
index 0000000000..4ef529e737
--- /dev/null
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p4.patch
@@ -0,0 +1,468 @@
+From 7eef498b6bd01adc45415b03ddf321c84f82aa45 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+Date: Mon, 10 Nov 2025 12:18:38 -0500
+Subject: [PATCH] support: Add a mini-library to extract and apply RPC
+ credentials
+
+Add server functionality to extract the credentials from the client RPC
+call, and apply them. This is needed in order to perform access checking
+on the requested path in the mountd daemon.
+
+CVE: CVE-2025-12801
+Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=51738ae56d922d4961e60dad73ad1c2d97d8d99b]
+
+Backport Changes:
+- In support/misc/Makefile.am, the non-essential file.c was omitted
+ as it does not exist in the current nfs-utils version.
+
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Steve Dickson <steved@redhat.com>
+(cherry picked from commit 51738ae56d922d4961e60dad73ad1c2d97d8d99b)
+Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
+---
+ aclocal/libtirpc.m4 | 11 +++
+ support/include/Makefile.am | 1 +
+ support/include/nfs_ucred.h | 44 ++++++++++
+ support/misc/Makefile.am | 2 +-
+ support/misc/ucred.c | 162 ++++++++++++++++++++++++++++++++++++
+ support/nfs/Makefile.am | 2 +-
+ support/nfs/ucred.c | 147 ++++++++++++++++++++++++++++++++
+ 7 files changed, 367 insertions(+), 2 deletions(-)
+ create mode 100644 support/include/nfs_ucred.h
+ create mode 100644 support/misc/ucred.c
+ create mode 100644 support/nfs/ucred.c
+
+diff --git a/aclocal/libtirpc.m4 b/aclocal/libtirpc.m4
+index bddae022..84e18f7e 100644
+--- a/aclocal/libtirpc.m4
++++ b/aclocal/libtirpc.m4
+@@ -26,6 +26,17 @@ AC_DEFUN([AC_LIBTIRPC], [
+ [Define to 1 if your tirpc library provides libtirpc_set_debug])],,
+ [${LIBS}])])
+
++ AS_IF([test -n "${LIBTIRPC}"],
++ [AC_CHECK_LIB([tirpc], [rpc_gss_getcred],
++ [AC_DEFINE([HAVE_TIRPC_GSS_GETCRED], [1],
++ [Define to 1 if your tirpc library provides rpc_gss_getcred])],,
++ [${LIBS}])])
++
++ AS_IF([test -n "${LIBTIRPC}"],
++ [AC_CHECK_LIB([tirpc], [authdes_getucred],
++ [AC_DEFINE([HAVE_TIRPC_AUTHDES_GETUCRED], [1],
++ [Define to 1 if your tirpc library provides authdes_getucred])],,
++ [${LIBS}])])
+ AC_SUBST([AM_CPPFLAGS])
+ AC_SUBST(LIBTIRPC)
+
+diff --git a/support/include/Makefile.am b/support/include/Makefile.am
+index 1373891a..631a84f8 100644
+--- a/support/include/Makefile.am
++++ b/support/include/Makefile.am
+@@ -10,6 +10,7 @@ noinst_HEADERS = \
+ misc.h \
+ nfs_mntent.h \
+ nfs_paths.h \
++ nfs_ucred.h \
+ nfsd_path.h \
+ nfslib.h \
+ nfsrpc.h \
+diff --git a/support/include/nfs_ucred.h b/support/include/nfs_ucred.h
+new file mode 100644
+index 00000000..d58b61e4
+--- /dev/null
++++ b/support/include/nfs_ucred.h
+@@ -0,0 +1,44 @@
++#ifndef _NFS_UCRED_H
++#define _NFS_UCRED_H
++
++#include <sys/types.h>
++
++struct nfs_ucred {
++ uid_t uid;
++ gid_t gid;
++ int ngroups;
++ gid_t *groups;
++};
++
++struct svc_req;
++struct exportent;
++
++int nfs_ucred_get(struct nfs_ucred **credp, struct svc_req *rqst,
++ const struct exportent *ep);
++
++void nfs_ucred_squash_groups(struct nfs_ucred *cred,
++ const struct exportent *ep);
++int nfs_ucred_reload_groups(struct nfs_ucred *cred, const struct exportent *ep);
++int nfs_ucred_swap_effective(const struct nfs_ucred *cred,
++ struct nfs_ucred **savedp);
++
++static inline void nfs_ucred_free(struct nfs_ucred *cred)
++{
++ free(cred->groups);
++ free(cred);
++}
++
++static inline void nfs_ucred_init_groups(struct nfs_ucred *cred, gid_t *groups,
++ int ngroups)
++{
++ cred->groups = groups;
++ cred->ngroups = ngroups;
++}
++
++static inline void nfs_ucred_free_groups(struct nfs_ucred *cred)
++{
++ free(cred->groups);
++ nfs_ucred_init_groups(cred, NULL, 0);
++}
++
++#endif /* _NFS_UCRED_H */
+diff --git a/support/misc/Makefile.am b/support/misc/Makefile.am
+index 8b0e9db9..ea970064 100644
+--- a/support/misc/Makefile.am
++++ b/support/misc/Makefile.am
+@@ -2,6 +2,6 @@
+
+ noinst_LIBRARIES = libmisc.a
+ libmisc_a_SOURCES = tcpwrapper.c from_local.c mountpoint.c misc.c \
+- nfsd_path.c workqueue.c xstat.c
++ nfsd_path.c ucred.c workqueue.c xstat.c
+
+ MAINTAINERCLEANFILES = Makefile.in
+diff --git a/support/misc/ucred.c b/support/misc/ucred.c
+new file mode 100644
+index 00000000..92d97912
+--- /dev/null
++++ b/support/misc/ucred.c
+@@ -0,0 +1,162 @@
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <alloca.h>
++#include <errno.h>
++#include <pwd.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <grp.h>
++
++#include "exportfs.h"
++#include "nfs_ucred.h"
++
++#include "xlog.h"
++
++void nfs_ucred_squash_groups(struct nfs_ucred *cred, const struct exportent *ep)
++{
++ int i;
++
++ if (!(ep->e_flags & NFSEXP_ROOTSQUASH))
++ return;
++ if (cred->gid == 0)
++ cred->gid = ep->e_anongid;
++ for (i = 0; i < cred->ngroups; i++) {
++ if (cred->groups[i] == 0)
++ cred->groups[i] = ep->e_anongid;
++ }
++}
++
++static int nfs_ucred_init_effective(struct nfs_ucred *cred)
++{
++ int ngroups = getgroups(0, NULL);
++
++ if (ngroups > 0) {
++ size_t sz = ngroups * sizeof(gid_t);
++ gid_t *groups = malloc(sz);
++ if (groups == NULL)
++ return ENOMEM;
++ if (getgroups(ngroups, groups) == -1) {
++ free(groups);
++ return errno;
++ }
++ nfs_ucred_init_groups(cred, groups, ngroups);
++ } else
++ nfs_ucred_init_groups(cred, NULL, 0);
++ cred->uid = geteuid();
++ cred->gid = getegid();
++ return 0;
++}
++
++static size_t nfs_ucred_getpw_r_size_max(void)
++{
++ long buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
++
++ if (buflen == -1)
++ return 16384;
++ return buflen;
++}
++
++int nfs_ucred_reload_groups(struct nfs_ucred *cred, const struct exportent *ep)
++{
++ struct passwd pwd, *pw;
++ uid_t uid = cred->uid;
++ gid_t gid = cred->gid;
++ size_t buflen;
++ char *buf;
++ int ngroups = 0;
++ int ret;
++
++ if (ep->e_flags & (NFSEXP_ALLSQUASH | NFSEXP_ROOTSQUASH) &&
++ (int)uid == ep->e_anonuid)
++ return 0;
++ buflen = nfs_ucred_getpw_r_size_max();
++ buf = alloca(buflen);
++ ret = getpwuid_r(uid, &pwd, buf, buflen, &pw);
++ if (ret != 0)
++ return ret;
++ if (!pw)
++ return ENOENT;
++ if (getgrouplist(pw->pw_name, gid, NULL, &ngroups) == -1 &&
++ ngroups > 0) {
++ gid_t *groups = malloc(ngroups * sizeof(groups[0]));
++ if (groups == NULL)
++ return ENOMEM;
++ if (getgrouplist(pw->pw_name, gid, groups, &ngroups) == -1) {
++ free(groups);
++ return ENOMEM;
++ }
++ free(cred->groups);
++ nfs_ucred_init_groups(cred, groups, ngroups);
++ nfs_ucred_squash_groups(cred, ep);
++ } else
++ nfs_ucred_free_groups(cred);
++ return 0;
++}
++
++static int nfs_ucred_set_effective(const struct nfs_ucred *cred,
++ const struct nfs_ucred *saved)
++{
++ uid_t suid = saved ? saved->uid : geteuid();
++ gid_t sgid = saved ? saved->gid : getegid();
++ int ret;
++
++ /* Start with a privileged effective user */
++ if (setresuid(-1, 0, -1) < 0) {
++ xlog(L_WARNING, "can't change privileged user %u-%u. %s",
++ geteuid(), getegid(), strerror(errno));
++ return errno;
++ }
++
++ if (setgroups(cred->ngroups, cred->groups) == -1) {
++ xlog(L_WARNING, "can't change groups for user %u-%u. %s",
++ geteuid(), getegid(), strerror(errno));
++ return errno;
++ }
++ if (setresgid(-1, cred->gid, sgid) == -1) {
++ xlog(L_WARNING, "can't change gid for user %u-%u. %s",
++ geteuid(), getegid(), strerror(errno));
++ ret = errno;
++ goto restore_groups;
++ }
++ if (setresuid(-1, cred->uid, suid) == -1) {
++ xlog(L_WARNING, "can't change uid for user %u-%u. %s",
++ geteuid(), getegid(), strerror(errno));
++ ret = errno;
++ goto restore_gid;
++ }
++ return 0;
++restore_gid:
++ if (setresgid(-1, sgid, -1) < 0) {
++ xlog(L_WARNING, "can't restore privileged user %u-%u. %s",
++ geteuid(), getegid(), strerror(errno));
++ }
++restore_groups:
++ if (saved)
++ setgroups(saved->ngroups, saved->groups);
++ else
++ setgroups(0, NULL);
++ return ret;
++}
++
++int nfs_ucred_swap_effective(const struct nfs_ucred *cred,
++ struct nfs_ucred **savedp)
++{
++ struct nfs_ucred *saved = malloc(sizeof(*saved));
++ int ret;
++
++ if (saved == NULL)
++ return ENOMEM;
++ ret = nfs_ucred_init_effective(saved);
++ if (ret != 0) {
++ free(saved);
++ return ret;
++ }
++ ret = nfs_ucred_set_effective(cred, saved);
++ if (savedp == NULL || ret != 0)
++ nfs_ucred_free(saved);
++ else
++ *savedp = saved;
++ return ret;
++}
+diff --git a/support/nfs/Makefile.am b/support/nfs/Makefile.am
+index 2e1577cc..f6921265 100644
+--- a/support/nfs/Makefile.am
++++ b/support/nfs/Makefile.am
+@@ -7,7 +7,7 @@ libnfs_la_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \
+ xcommon.c wildmat.c mydaemon.c \
+ rpc_socket.c getport.c \
+ svc_socket.c cacheio.c closeall.c nfs_mntent.c \
+- svc_create.c atomicio.c strlcat.c strlcpy.c
++ svc_create.c atomicio.c strlcat.c strlcpy.c ucred.c
+ libnfs_la_LIBADD = libnfsconf.la
+ libnfs_la_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -I$(top_srcdir)/support/reexport
+
+diff --git a/support/nfs/ucred.c b/support/nfs/ucred.c
+new file mode 100644
+index 00000000..6ea8efdf
+--- /dev/null
++++ b/support/nfs/ucred.c
+@@ -0,0 +1,147 @@
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <errno.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <rpc/rpc.h>
++
++#include "exportfs.h"
++#include "nfs_ucred.h"
++
++#ifdef HAVE_TIRPC_GSS_GETCRED
++#include <rpc/rpcsec_gss.h>
++#endif /* HAVE_TIRPC_GSS_GETCRED */
++#ifdef HAVE_TIRPC_AUTHDES_GETUCRED
++#include <rpc/auth_des.h>
++#endif /* HAVE_TIRPC_AUTHDES_GETUCRED */
++
++static int nfs_ucred_copy_cred(struct nfs_ucred *cred, uid_t uid, gid_t gid,
++ const gid_t *groups, int ngroups)
++{
++ if (ngroups > 0) {
++ size_t sz = ngroups * sizeof(groups[0]);
++ cred->groups = malloc(sz);
++ if (cred->groups == NULL)
++ return ENOMEM;
++ cred->ngroups = ngroups;
++ memcpy(cred->groups, groups, sz);
++ } else
++ nfs_ucred_init_groups(cred, NULL, 0);
++ cred->uid = uid;
++ cred->gid = gid;
++ return 0;
++}
++
++static int nfs_ucred_init_cred_squashed(struct nfs_ucred *cred,
++ const struct exportent *ep)
++{
++ cred->uid = ep->e_anonuid;
++ cred->gid = ep->e_anongid;
++ nfs_ucred_init_groups(cred, NULL, 0);
++ return 0;
++}
++
++static int nfs_ucred_init_cred(struct nfs_ucred *cred, uid_t uid, gid_t gid,
++ const gid_t *groups, int ngroups,
++ const struct exportent *ep)
++{
++ if (ep->e_flags & NFSEXP_ALLSQUASH) {
++ nfs_ucred_init_cred_squashed(cred, ep);
++ } else if (ep->e_flags & NFSEXP_ROOTSQUASH && uid == 0) {
++ nfs_ucred_init_cred_squashed(cred, ep);
++ if (gid != 0)
++ cred->gid = gid;
++ } else {
++ int ret = nfs_ucred_copy_cred(cred, uid, gid, groups, ngroups);
++ if (ret != 0)
++ return ret;
++ nfs_ucred_squash_groups(cred, ep);
++ }
++ return 0;
++}
++
++static int nfs_ucred_init_null(struct nfs_ucred *cred,
++ const struct exportent *ep)
++{
++ return nfs_ucred_init_cred_squashed(cred, ep);
++}
++
++static int nfs_ucred_init_unix(struct nfs_ucred *cred, struct svc_req *rqst,
++ const struct exportent *ep)
++{
++ struct authunix_parms *aup;
++
++ aup = (struct authunix_parms *)rqst->rq_clntcred;
++ return nfs_ucred_init_cred(cred, aup->aup_uid, aup->aup_gid,
++ aup->aup_gids, aup->aup_len, ep);
++}
++
++#ifdef HAVE_TIRPC_GSS_GETCRED
++static int nfs_ucred_init_gss(struct nfs_ucred *cred, struct svc_req *rqst,
++ const struct exportent *ep)
++{
++ rpc_gss_ucred_t *gss_ucred = NULL;
++
++ if (!rpc_gss_getcred(rqst, NULL, &gss_ucred, NULL) || gss_ucred == NULL)
++ return EINVAL;
++ return nfs_ucred_init_cred(cred, gss_ucred->uid, gss_ucred->gid,
++ gss_ucred->gidlist, gss_ucred->gidlen, ep);
++}
++#endif /* HAVE_TIRPC_GSS_GETCRED */
++
++#ifdef HAVE_TIRPC_AUTHDES_GETUCRED
++int authdes_getucred(struct authdes_cred *adc, uid_t *uid, gid_t *gid,
++ int *grouplen, gid_t *groups);
++
++static int nfs_ucred_init_des(struct nfs_ucred *cred, struct svc_req *rqst,
++ const struct exportent *ep)
++{
++ struct authdes_cred *des_cred;
++ uid_t uid;
++ gid_t gid;
++ int grouplen;
++ gid_t groups[NGROUPS];
++
++ des_cred = (struct authdes_cred *)rqst->rq_clntcred;
++ if (!authdes_getucred(des_cred, &uid, &gid, &grouplen, &groups[0]))
++ return EINVAL;
++ return nfs_ucred_init_cred(cred, uid, gid, groups, grouplen, ep);
++}
++#endif /* HAVE_TIRPC_AUTHDES_GETUCRED */
++
++int nfs_ucred_get(struct nfs_ucred **credp, struct svc_req *rqst,
++ const struct exportent *ep)
++{
++ struct nfs_ucred *cred = malloc(sizeof(*cred));
++ int ret;
++
++ *credp = NULL;
++ if (cred == NULL)
++ return ENOMEM;
++ switch (rqst->rq_cred.oa_flavor) {
++ case AUTH_UNIX:
++ ret = nfs_ucred_init_unix(cred, rqst, ep);
++ break;
++#ifdef HAVE_TIRPC_GSS_GETCRED
++ case RPCSEC_GSS:
++ ret = nfs_ucred_init_gss(cred, rqst, ep);
++ break;
++#endif /* HAVE_TIRPC_GSS_GETCRED */
++#ifdef HAVE_TIRPC_AUTHDES_GETUCRED
++ case AUTH_DES:
++ ret = nfs_ucred_init_des(cred, rqst, ep);
++ break;
++#endif /* HAVE_TIRPC_AUTHDES_GETUCRED */
++ default:
++ ret = nfs_ucred_init_null(cred, ep);
++ break;
++ }
++ if (ret == 0) {
++ *credp = cred;
++ return 0;
++ }
++ free(cred);
++ return ret;
++}
+--
+2.44.4
+
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801.patch
new file mode 100644
index 0000000000..3381d6e645
--- /dev/null
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801.patch
@@ -0,0 +1,254 @@
+From e22a15eb39c88367c35bfd4e057bccbddc6519d4 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@hammerspace.com>
+Date: Thu, 5 Mar 2026 10:41:02 -0500
+Subject: [PATCH] Fix access checks when mounting subdirectories in NFSv3
+
+If a NFSv3 client asks to mount a subdirectory of one of the exported
+directories, then apply the RPC credential together with any root
+or all squash rules that would apply to the client in question.
+
+CVE: CVE-2025-12801
+Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=f36bd900a899088ca1925de079bd58d6205a1f3c]
+
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
+Signed-off-by: Scott Mayhew <smayhew@redhat.com>
+Signed-off-by: Steve Dickson <steved@redhat.com>
+(cherry picked from commit f36bd900a899088ca1925de079bd58d6205a1f3c)
+Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
+---
+ nfs.conf | 1 +
+ support/include/nfsd_path.h | 9 ++++++++-
+ support/misc/nfsd_path.c | 32 ++++++++++++++++++++++++++++++--
+ utils/mountd/mountd.c | 28 ++++++++++++++++++++++++++--
+ utils/mountd/mountd.man | 26 ++++++++++++++++++++++++++
+ 5 files changed, 91 insertions(+), 5 deletions(-)
+
+diff --git a/nfs.conf b/nfs.conf
+index 323f072b..e08cd9a9 100644
+--- a/nfs.conf
++++ b/nfs.conf
+@@ -45,6 +45,7 @@
+ # ttl=1800
+ [mountd]
+ # debug="all|auth|call|general|parse"
++# apply-root-cred=n
+ # manage-gids=n
+ # descriptors=0
+ # port=0
+diff --git a/support/include/nfsd_path.h b/support/include/nfsd_path.h
+index be2dc38d..834925ec 100644
+--- a/support/include/nfsd_path.h
++++ b/support/include/nfsd_path.h
+@@ -9,6 +9,7 @@
+ struct file_handle;
+ struct statfs;
+ struct nfsd_task_t;
++struct nfs_ucred;
+
+ void nfsd_path_init(void);
+
+@@ -18,7 +19,8 @@ char * nfsd_path_prepend_dir(const char *dir, const char *pathname);
+
+ int nfsd_path_stat(const char *pathname, struct stat *statbuf);
+ int nfsd_path_lstat(const char *pathname, struct stat *statbuf);
+-int nfsd_openat(int dirfd, const char *path, int flags);
++int nfsd_cred_openat(const struct nfs_ucred *cred, int dirfd,
++ const char *path, int flags);
+
+ int nfsd_path_statfs(const char *pathname,
+ struct statfs *statbuf);
+@@ -31,4 +33,9 @@ ssize_t nfsd_path_write(int fd, const char *buf, size_t len);
+ int nfsd_name_to_handle_at(int fd, const char *path,
+ struct file_handle *fh,
+ int *mount_id, int flags);
++
++static inline int nfsd_openat(int dirfd, const char *path, int flags)
++{
++ return nfsd_cred_openat(NULL, dirfd, path, flags);
++}
+ #endif
+diff --git a/support/misc/nfsd_path.c b/support/misc/nfsd_path.c
+index 1c5aa3f3..a2083989 100644
+--- a/support/misc/nfsd_path.c
++++ b/support/misc/nfsd_path.c
+@@ -17,6 +17,7 @@
+ #include "xstat.h"
+ #include "nfslib.h"
+ #include "nfsd_path.h"
++#include "nfs_ucred.h"
+ #include "workqueue.h"
+
+ static struct xthread_workqueue *nfsd_wq = NULL;
+@@ -281,6 +282,7 @@ struct nfsd_read_data {
+ };
+
+ struct nfsd_openat_t {
++ const struct nfs_ucred *cred;
+ const char *path;
+ int dirfd;
+ int flags;
+@@ -297,15 +299,41 @@ static void nfsd_openatfunc(void *data)
+ d->res_error = errno;
+ }
+
+-int nfsd_openat(int dirfd, const char *path, int flags)
++static void nfsd_cred_openatfunc(void *data)
++{
++ struct nfsd_openat_t *d = data;
++ struct nfs_ucred *saved = NULL;
++ int ret;
++
++ ret = nfs_ucred_swap_effective(d->cred, &saved);
++ if (ret != 0) {
++ d->res_fd = -1;
++ d->res_error = ret;
++ return;
++ }
++
++ nfsd_openatfunc(data);
++
++ if (saved != NULL) {
++ nfs_ucred_swap_effective(saved, NULL);
++ nfs_ucred_free(saved);
++ }
++}
++
++int nfsd_cred_openat(const struct nfs_ucred *cred, int dirfd, const char *path,
++ int flags)
+ {
+ struct nfsd_openat_t open_buf = {
++ .cred = cred,
+ .path = path,
+ .dirfd = dirfd,
+ .flags = flags,
+ };
+
+- nfsd_run_task(nfsd_openatfunc, &open_buf);
++ if (cred)
++ nfsd_run_task(nfsd_cred_openatfunc, &open_buf);
++ else
++ nfsd_run_task(nfsd_openatfunc, &open_buf);
+ if (open_buf.res_fd == -1)
+ errno = open_buf.res_error;
+ return open_buf.res_fd;
+diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
+index f43ebef5..6e6777cd 100644
+--- a/utils/mountd/mountd.c
++++ b/utils/mountd/mountd.c
+@@ -31,6 +31,7 @@
+ #include "nfsd_path.h"
+ #include "nfslib.h"
+ #include "export.h"
++#include "nfs_ucred.h"
+
+ extern void my_svc_run(void);
+
+@@ -40,6 +41,7 @@ static struct nfs_fh_len *get_rootfh(struct svc_req *, dirpath *, nfs_export **,
+
+ int reverse_resolve = 0;
+ int manage_gids;
++int apply_root_cred;
+ int use_ipaddr = -1;
+
+ /* PRC: a high-availability callout program can be specified with -H
+@@ -74,9 +76,10 @@ static struct option longopts[] =
+ { "log-auth", 0, 0, 'l'},
+ { "cache-use-ipaddr", 0, 0, 'i'},
+ { "ttl", 1, 0, 'T'},
++ { "apply-root-cred", 0, 0, 'c' },
+ { NULL, 0, 0, 0 }
+ };
+-static char shortopts[] = "o:nFd:p:P:hH:N:V:vurs:t:gliT:";
++static char shortopts[] = "o:nFd:p:P:hH:N:V:vurs:t:gliT:c";
+
+ #define NFSVERSBIT(vers) (0x1 << (vers - 1))
+ #define NFSVERSBIT_ALL (NFSVERSBIT(2) | NFSVERSBIT(3) | NFSVERSBIT(4))
+@@ -453,11 +456,27 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
+ while (*subpath == '/')
+ subpath++;
+ if (*subpath != '\0') {
++ struct nfs_ucred *cred = NULL;
+ int fd;
+
++ /* Load the user cred */
++ if (!apply_root_cred) {
++ nfs_ucred_get(&cred, rqstp, &exp->m_export);
++ if (cred == NULL) {
++ xlog(L_WARNING, "can't retrieve credential");
++ *error = MNT3ERR_ACCES;
++ close(dirfd);
++ return NULL;
++ }
++ if (manage_gids)
++ nfs_ucred_reload_groups(cred, &exp->m_export);
++ }
++
+ /* Just perform a lookup of the path */
+- fd = nfsd_openat(dirfd, subpath, O_PATH);
++ fd = nfsd_cred_openat(cred, dirfd, subpath, O_PATH);
+ close(dirfd);
++ if (cred)
++ nfs_ucred_free(cred);
+ if (fd == -1) {
+ xlog(L_WARNING, "can't open exported dir %s: %s", p,
+ strerror(errno));
+@@ -681,6 +700,8 @@ read_mountd_conf(char **argv)
+ ttl = conf_get_num("mountd", "ttl", default_ttl);
+ if (ttl > 0)
+ default_ttl = ttl;
++ apply_root_cred = conf_get_bool("mountd", "apply-root-cred",
++ apply_root_cred);
+ }
+
+ int
+@@ -794,6 +815,9 @@ main(int argc, char **argv)
+ }
+ default_ttl = ttl;
+ break;
++ case 'c':
++ apply_root_cred = 1;
++ break;
+ case 0:
+ break;
+ case '?':
+diff --git a/utils/mountd/mountd.man b/utils/mountd/mountd.man
+index a206a3e2..f4f1fc23 100644
+--- a/utils/mountd/mountd.man
++++ b/utils/mountd/mountd.man
+@@ -242,6 +242,32 @@ can support both NFS version 2 and the newer version 3.
+ Print the version of
+ .B rpc.mountd
+ and exit.
++.TP
++.B \-c " or " \-\-apply-root-cred
++When mountd is asked to allow a NFSv3 mount to a subdirectory of the
++exported directory, then it will check if the user asking to mount has
++lookup rights to the directories below that exported directory. When
++performing the check, mountd will apply any root squash or all squash
++rules that were specified for that client.
++
++Performing lookup checks as the user requires that the mountd daemon
++be run as root or that it be given CAP_SETUID and CAP_SETGID privileges
++so that it can change its own effective user and effective group settings.
++When troubleshooting, please also note that LSM frameworks such as SELinux
++can sometimes prevent the daemon from changing the effective user/groups
++despite the capability settings.
++
++In earlier versions of mountd, the same checks were performed using the
++mountd daemon's root privileges, meaning that it could authorise access
++to directories that are not normally accessible to the user requesting
++to mount them. This option enables that legacy behaviour.
++
++.BR Note:
++If there is a need to provide access to specific subdirectories that
++are not normally accessible to a client, it is always possible to add
++export entries that explicitly grant such access. That ability does
++not depend on this option being enabled.
++
+ .TP
+ .B \-g " or " \-\-manage-gids
+ Accept requests from the kernel to map user id numbers into lists of
+--
+2.44.4
+
diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils_2.6.4.bb b/meta/recipes-connectivity/nfs-utils/nfs-utils_2.6.4.bb
index 2f2644f9a8..91c74fe5ef 100644
--- a/meta/recipes-connectivity/nfs-utils/nfs-utils_2.6.4.bb
+++ b/meta/recipes-connectivity/nfs-utils/nfs-utils_2.6.4.bb
@@ -33,6 +33,12 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/nfs-utils/${PV}/nfs-utils-${PV}.tar.x
file://0001-locktest-Makefile.am-Do-not-use-build-flags.patch \
file://0001-tools-locktest-Use-intmax_t-to-print-off_t.patch \
file://0001-reexport.h-Include-unistd.h-to-compile-with-musl.patch \
+ file://CVE-2025-12801-dependent_p1.patch \
+ file://CVE-2025-12801-dependent_p2.patch \
+ file://CVE-2025-12801-dependent_p3.patch \
+ file://CVE-2025-12801-dependent_p4.patch \
+ file://CVE-2025-12801.patch \
+ file://CVE-2025-12801-build-fix.patch \
"
SRC_URI[sha256sum] = "01b3b0fb9c7d0bbabf5114c736542030748c788ec2fd9734744201e9b0a1119d"
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 04/21] xz: Fix CVE-2026-34743
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (2 preceding siblings ...)
2026-06-12 14:25 ` [OE-core][scarthgap 03/21] nfs-utils: fix CVE-2025-12801 Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 05/21] util-linux: Fix CVE-2026-27456 Jeremy Rosen
` (16 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Hugo SIMELIERE (Schneider Electric)" <hsimeliere.opensource@witekio.com>
Pick patch from [1] as 5.4.x upstream backport of [2] mentioned in Debian report in [3].
[1] https://github.com/tukaani-project/xz/commit/8538443d08591693a8c61f3a03656650f39c7c32
[2] https://github.com/tukaani-project/xz/commit/c8c22869e780ff57c96b46939c3d79ff99395f87
[3] https://security-tracker.debian.org/tracker/CVE-2026-34743
Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
Reviewed-by: Bruno VERNAY <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
.../xz/xz/CVE-2026-34743.patch | 68 +++++++++++++++++++
meta/recipes-extended/xz/xz_5.4.7.bb | 1 +
2 files changed, 69 insertions(+)
create mode 100644 meta/recipes-extended/xz/xz/CVE-2026-34743.patch
diff --git a/meta/recipes-extended/xz/xz/CVE-2026-34743.patch b/meta/recipes-extended/xz/xz/CVE-2026-34743.patch
new file mode 100644
index 0000000000..f890851cb2
--- /dev/null
+++ b/meta/recipes-extended/xz/xz/CVE-2026-34743.patch
@@ -0,0 +1,68 @@
+From ae7abca7c721c73bb4aadf41a82a720a842a4364 Mon Sep 17 00:00:00 2001
+From: Lasse Collin <lasse.collin@tukaani.org>
+Date: Sun, 29 Mar 2026 19:11:21 +0300
+Subject: [PATCH] liblzma: Fix a buffer overflow in lzma_index_append()
+
+If lzma_index_decoder() was used to decode an Index that contained no
+Records, the resulting lzma_index had an invalid internal "prealloc"
+value. If lzma_index_append() was called on this lzma_index, too
+little memory would be allocated and a buffer overflow would occur.
+
+While this combination of the API functions is meant to work, in the
+real-world apps this call sequence is rare or might not exist at all.
+
+This bug is older than xz 5.0.0, so all stable releases are affected.
+
+CVE: CVE-2026-34743
+Upstream-Status: Backport [https://github.com/tukaani-project/xz/commit/8538443d08591693a8c61f3a03656650f39c7c32]
+
+Reported-by: GitHub user christos-spearbit
+(cherry picked from commit c8c22869e780ff57c96b46939c3d79ff99395f87)
+(cherry picked from commit 8538443d08591693a8c61f3a03656650f39c7c32)
+Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
+---
+ src/liblzma/common/index.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/src/liblzma/common/index.c b/src/liblzma/common/index.c
+index 8a35f439..dae7cab5 100644
+--- a/src/liblzma/common/index.c
++++ b/src/liblzma/common/index.c
+@@ -434,6 +434,26 @@ lzma_index_prealloc(lzma_index *i, lzma_vli records)
+ if (records > PREALLOC_MAX)
+ records = PREALLOC_MAX;
+
++ // If index_decoder.c calls us with records == 0, it's decoding
++ // an Index that has no Records. In that case the decoder won't call
++ // lzma_index_append() at all, and i->prealloc isn't used during
++ // the Index decoding either.
++ //
++ // Normally the first lzma_index_append() call from the Index decoder
++ // would reset i->prealloc to INDEX_GROUP_SIZE. With no Records,
++ // lzma_index_append() isn't called and the resetting of prealloc
++ // won't occur either. Thus, if records == 0, use the default value
++ // INDEX_GROUP_SIZE instead.
++ //
++ // NOTE: lzma_index_append() assumes i->prealloc > 0. liblzma <= 5.8.2
++ // didn't have this check and could set i->prealloc = 0, which would
++ // result in a buffer overflow if the application called
++ // lzma_index_append() after decoding an empty Index. Appending
++ // Records after decoding an Index is a rare thing to do, but
++ // it is supposed to work.
++ if (records == 0)
++ records = INDEX_GROUP_SIZE;
++
+ i->prealloc = (size_t)(records);
+ return;
+ }
+@@ -686,6 +706,7 @@ lzma_index_append(lzma_index *i, const lzma_allocator *allocator,
+ ++g->last;
+ } else {
+ // We need to allocate a new group.
++ assert(i->prealloc > 0);
+ g = lzma_alloc(sizeof(index_group)
+ + i->prealloc * sizeof(index_record),
+ allocator);
+--
+2.43.0
+
diff --git a/meta/recipes-extended/xz/xz_5.4.7.bb b/meta/recipes-extended/xz/xz_5.4.7.bb
index 30a4c8e88c..72759edea0 100644
--- a/meta/recipes-extended/xz/xz_5.4.7.bb
+++ b/meta/recipes-extended/xz/xz_5.4.7.bb
@@ -30,6 +30,7 @@ SRC_URI = "https://github.com/tukaani-project/xz/releases/download/v${PV}/xz-${P
file://CVE-2025-31115-02.patch \
file://CVE-2025-31115-03.patch \
file://CVE-2025-31115-04.patch \
+ file://CVE-2026-34743.patch \
"
SRC_URI[sha256sum] = "8db6664c48ca07908b92baedcfe7f3ba23f49ef2476864518ab5db6723836e71"
UPSTREAM_CHECK_REGEX = "releases/tag/v(?P<pver>\d+(\.\d+)+)"
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 05/21] util-linux: Fix CVE-2026-27456
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (3 preceding siblings ...)
2026-06-12 14:25 ` [OE-core][scarthgap 04/21] xz: Fix CVE-2026-34743 Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 06/21] devtool: prevent 'devtool modify -n' from corrupting kernel Git repos Jeremy Rosen
` (15 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Hugo SIMELIERE (Schneider Electric)" <hsimeliere.opensource@witekio.com>
Pick patch from [1] as 2.39.x upstream backport of [2] mentioned in Debian report in [3].
[1] https://github.com/util-linux/util-linux/commit/79164668a412b71fcb1495c7d299cc5e9741fa30
[2] https://github.com/util-linux/util-linux/commit/0ba0f14caa812349424df0da00ac2d97fee9d972
[3] https://security-tracker.debian.org/tracker/CVE-2026-27456
Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
Reviewed-by: Bruno VERNAY <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-core/util-linux/util-linux.inc | 1 +
.../util-linux/CVE-2026-27456.patch | 115 ++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100644 meta/recipes-core/util-linux/util-linux/CVE-2026-27456.patch
diff --git a/meta/recipes-core/util-linux/util-linux.inc b/meta/recipes-core/util-linux/util-linux.inc
index 4797682c5d..8380419634 100644
--- a/meta/recipes-core/util-linux/util-linux.inc
+++ b/meta/recipes-core/util-linux/util-linux.inc
@@ -46,6 +46,7 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/util-linux/v${MAJOR_VERSION}/util-lin
file://sys-utils-hwclock-rtc-fix-pointer-usage.patch \
file://CVE-2025-14104-01.patch \
file://CVE-2025-14104-02.patch \
+ file://CVE-2026-27456.patch \
"
SRC_URI[sha256sum] = "7b6605e48d1a49f43cc4b4cfc59f313d0dd5402fa40b96810bd572e167dfed0f"
diff --git a/meta/recipes-core/util-linux/util-linux/CVE-2026-27456.patch b/meta/recipes-core/util-linux/util-linux/CVE-2026-27456.patch
new file mode 100644
index 0000000000..4a5fef26d3
--- /dev/null
+++ b/meta/recipes-core/util-linux/util-linux/CVE-2026-27456.patch
@@ -0,0 +1,115 @@
+From af0b619f8eb15f738c69e33e0bb3a794e9cccf17 Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Thu, 19 Feb 2026 13:59:46 +0100
+Subject: [PATCH] loopdev: add LOOPDEV_FL_NOFOLLOW to prevent symlink attacks
+
+Add a new LOOPDEV_FL_NOFOLLOW flag for loop device context that
+prevents symlink following in both path canonicalization and file open.
+
+When set:
+- loopcxt_set_backing_file() uses strdup() instead of
+ ul_canonicalize_path() (which calls realpath() and follows symlinks)
+- loopcxt_setup_device() adds O_NOFOLLOW to open() flags
+
+The flag is set for non-root (restricted) mount operations in
+libmount's loop device hook. This prevents a TOCTOU race condition
+where an attacker could replace the backing file (specified in
+/etc/fstab) with a symlink to an arbitrary root-owned file between
+path resolution and open().
+
+Vulnerable Code Flow:
+
+ mount /mnt/point (non-root, SUID)
+ mount.c: sanitize_paths() on user args (mountpoint only)
+ mnt_context_mount()
+ mnt_context_prepare_mount()
+ mnt_context_apply_fstab() <-- source path from fstab
+ hooks run at MNT_STAGE_PREP_SOURCE
+ hook_loopdev.c: setup_loopdev()
+ backing_file = fstab source path ("/home/user/disk.img")
+ loopcxt_set_backing_file() <-- calls realpath() as ROOT
+ ul_canonicalize_path() <-- follows symlinks!
+ loopcxt_setup_device()
+ open(lc->filename, O_RDWR|O_CLOEXEC) <-- no O_NOFOLLOW
+
+Two vulnerabilities in the path:
+
+1) loopcxt_set_backing_file() calls ul_canonicalize_path() which uses
+ realpath() -- this follows symlinks as euid=0. If the attacker swaps
+ the file to a symlink before this call, lc->filename becomes the
+ resolved target path (e.g., /root/secret.img).
+
+2) loopcxt_setup_device() opens lc->filename without O_NOFOLLOW. Even
+ if canonicalization happened correctly, the file can be swapped to a
+ symlink between canonicalize and open.
+
+CVE: CVE-2026-27456
+Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/79164668a412b71fcb1495c7d299cc5e9741fa30]
+
+Addresses: https://github.com/util-linux/util-linux/security/advisories/GHSA-qq4x-vfq4-9h9g
+Signed-off-by: Karel Zak <kzak@redhat.com>
+(cherry picked from commit 5e390467b26a3cf3fecc04e1a0d482dff3162fc4)
+(cherry picked from commit 79164668a412b71fcb1495c7d299cc5e9741fa30)
+Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
+---
+ include/loopdev.h | 3 ++-
+ lib/loopdev.c | 7 ++++++-
+ libmount/src/hook_loopdev.c | 3 ++-
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/include/loopdev.h b/include/loopdev.h
+index 903adc491..d03e9b65e 100644
+--- a/include/loopdev.h
++++ b/include/loopdev.h
+@@ -139,7 +139,8 @@ enum {
+ LOOPDEV_FL_NOIOCTL = (1 << 6),
+ LOOPDEV_FL_DEVSUBDIR = (1 << 7),
+ LOOPDEV_FL_CONTROL = (1 << 8), /* system with /dev/loop-control */
+- LOOPDEV_FL_SIZELIMIT = (1 << 9)
++ LOOPDEV_FL_SIZELIMIT = (1 << 9),
++ LOOPDEV_FL_NOFOLLOW = (1 << 10) /* O_NOFOLLOW, don't follow symlinks */
+ };
+
+ /*
+diff --git a/lib/loopdev.c b/lib/loopdev.c
+index dd9ead3ee..4da251812 100644
+--- a/lib/loopdev.c
++++ b/lib/loopdev.c
+@@ -1193,7 +1193,10 @@ int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename)
+ if (!lc)
+ return -EINVAL;
+
+- lc->filename = canonicalize_path(filename);
++ if (lc->flags & LOOPDEV_FL_NOFOLLOW)
++ lc->filename = strdup(filename);
++ else
++ lc->filename = canonicalize_path(filename);
+ if (!lc->filename)
+ return -errno;
+
+@@ -1332,6 +1335,8 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
+
+ if (lc->config.info.lo_flags & LO_FLAGS_DIRECT_IO)
+ flags |= O_DIRECT;
++ if (lc->flags & LOOPDEV_FL_NOFOLLOW)
++ flags |= O_NOFOLLOW;
+
+ if ((file_fd = open(lc->filename, mode | flags)) < 0) {
+ if (mode != O_RDONLY && (errno == EROFS || errno == EACCES))
+diff --git a/libmount/src/hook_loopdev.c b/libmount/src/hook_loopdev.c
+index 8c8f7f218..ce39a7a70 100644
+--- a/libmount/src/hook_loopdev.c
++++ b/libmount/src/hook_loopdev.c
+@@ -276,7 +276,8 @@ static int setup_loopdev(struct libmnt_context *cxt,
+ }
+
+ DBG(LOOP, ul_debugobj(cxt, "not found; create a new loop device"));
+- rc = loopcxt_init(&lc, 0);
++ rc = loopcxt_init(&lc,
++ mnt_context_is_restricted(cxt) ? LOOPDEV_FL_NOFOLLOW : 0);
+ if (rc)
+ goto done_no_deinit;
+ if (mnt_opt_has_value(loopopt)) {
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 06/21] devtool: prevent 'devtool modify -n' from corrupting kernel Git repos
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (4 preceding siblings ...)
2026-06-12 14:25 ` [OE-core][scarthgap 05/21] util-linux: Fix CVE-2026-27456 Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 07/21] go: patch CVE-2026-27142 Jeremy Rosen
` (14 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: Enrico Jörns <ejo@pengutronix.de>
Running 'devtool modify -n' on a kernel recipe that inherits
'kernel-yocto' can unintentionally corrupt an existing Git repo or
worktree.
The work-shared optimization introduced in 3c3a9bae ("devtool/standard.py:
Update devtool modify to copy source from work-shared if its already
downloaded") is not skipped when '--no-extract' ('args.no_extract') is set.
As a result, for kernel builds where STAGING_KERNEL_DIR was already
populated when running 'devtool modify -n', the existing source tree is
overwritten (via oe.path.copyhardlinktree()) with the contents of
STAGING_KERNEL_DIR.
Fix by adding 'and not args.no_extract' to the kernel-yocto guard
condition.
(cherry picked from commit d383ea37e4987ecabe011226f1a8e658a52ede12)
Signed-off-by: Enrico Jörns <ejo@pengutronix.de>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
scripts/lib/devtool/standard.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/lib/devtool/standard.py b/scripts/lib/devtool/standard.py
index 908869cc4f..e1e519ce5b 100644
--- a/scripts/lib/devtool/standard.py
+++ b/scripts/lib/devtool/standard.py
@@ -841,7 +841,8 @@ def modify(args, config, basepath, workspace):
commits = {}
check_commits = False
- if bb.data.inherits_class('kernel-yocto', rd):
+ if bb.data.inherits_class('kernel-yocto', rd) and not args.no_extract:
+
# Current set kernel version
kernelVersion = rd.getVar('LINUX_VERSION')
srcdir = rd.getVar('STAGING_KERNEL_DIR')
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 07/21] go: patch CVE-2026-27142
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (5 preceding siblings ...)
2026-06-12 14:25 ` [OE-core][scarthgap 06/21] devtool: prevent 'devtool modify -n' from corrupting kernel Git repos Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 08/21] go: patch CVE-2026-32280 Jeremy Rosen
` (13 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/752081
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-27142.patch | 386 ++++++++++++++++++
2 files changed, 387 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-27142.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 3fa421e223..8efa82f862 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -41,6 +41,7 @@ SRC_URI += "\
file://CVE-2025-68121_p1.patch \
file://CVE-2025-68121_p2.patch \
file://CVE-2025-68121_p3.patch \
+ file://CVE-2026-27142.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-27142.patch b/meta/recipes-devtools/go/go/CVE-2026-27142.patch
new file mode 100644
index 0000000000..e735abaf4b
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-27142.patch
@@ -0,0 +1,386 @@
+From 1ac19df75e9c25951c04008a52b23a1cd95e81cc Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker <bracewell@google.com>
+Date: Fri, 9 Jan 2026 11:12:01 -0800
+Subject: [PATCH] html/template: properly escape URLs in meta content
+ attributes
+
+The meta tag can include a content attribute that contains URLs, which
+we currently don't escape if they are inserted via a template action.
+This can plausibly lead to XSS vulnerabilities if untrusted data is
+inserted there, the http-equiv attribute is set to "refresh", and the
+content attribute contains an action like `url={{.}}`.
+
+Track whether we are inside of a meta element, if we are inside of a
+content attribute, _and_ if the content attribute contains "url=". If
+all of those are true, then we will apply the same URL escaping that we
+use elsewhere.
+
+Also add a new GODEBUG, htmlmetacontenturlescape, to allow disabling this
+escaping for cases where this behavior is considered safe. The behavior
+can be disabled by setting htmlmetacontenturlescape=0.
+
+Updates #77954
+Fixes #77972
+Fixes CVE-2026-27142
+
+Change-Id: I9bbca263be9894688e6ef1e9a8f8d2f4304f5873
+Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3360
+Reviewed-by: Neal Patel <nealpatel@google.com>
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3643
+Reviewed-by: Damien Neil <dneil@google.com>
+Reviewed-on: https://go-review.googlesource.com/c/go/+/752081
+Auto-Submit: Gopher Robot <gobot@golang.org>
+Reviewed-by: Cherry Mui <cherryyz@google.com>
+TryBot-Bypass: Gopher Robot <gobot@golang.org>
+Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
+
+CVE: CVE-2026-27142
+Upstream-Status: Backport [https://github.com/golang/go/commit/994692847a2cd3efd319f0cb61a07c0012c8a4ff]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ doc/godebug.md | 5 +++
+ src/html/template/attr_string.go | 5 +--
+ src/html/template/context.go | 8 +++++
+ src/html/template/element_string.go | 5 +--
+ src/html/template/escape.go | 14 +++++++++
+ src/html/template/escape_test.go | 34 +++++++++++++++++++++
+ src/html/template/state_string.go | 8 +++--
+ src/html/template/transition.go | 47 +++++++++++++++++++++++++----
+ src/internal/godebugs/table.go | 1 +
+ src/runtime/metrics/doc.go | 5 +++
+ 10 files changed, 119 insertions(+), 13 deletions(-)
+
+diff --git a/doc/godebug.md b/doc/godebug.md
+index 635597e..07b63cb 100644
+--- a/doc/godebug.md
++++ b/doc/godebug.md
+@@ -126,6 +126,11 @@ for example,
+ see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables)
+ and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
+
++Go 1.26.1 added a new `htmlmetacontenturlescape` setting that controls whether
++html/template will escape URLs in the `url=` portion of the content attribute of
++HTML meta tags. The default `htmlmetacontentescape=1` will cause URLs to be
++escaped. Setting `htmlmetacontentescape=0` disables this behavior.
++
+ Go 1.26 added a new `urlmaxqueryparams` setting that controls the maximum number
+ of query parameters that net/url will accept when parsing a URL-encoded query string.
+ If the number of parameters exceeds the number set in `urlmaxqueryparams`,
+diff --git a/src/html/template/attr_string.go b/src/html/template/attr_string.go
+index 51c3f26..7159fa9 100644
+--- a/src/html/template/attr_string.go
++++ b/src/html/template/attr_string.go
+@@ -14,11 +14,12 @@ func _() {
+ _ = x[attrStyle-3]
+ _ = x[attrURL-4]
+ _ = x[attrSrcset-5]
++ _ = x[attrMetaContent-6]
+ }
+
+-const _attr_name = "attrNoneattrScriptattrScriptTypeattrStyleattrURLattrSrcset"
++const _attr_name = "attrNoneattrScriptattrScriptTypeattrStyleattrURLattrSrcsetattrMetaContent"
+
+-var _attr_index = [...]uint8{0, 8, 18, 32, 41, 48, 58}
++var _attr_index = [...]uint8{0, 8, 18, 32, 41, 48, 58, 73}
+
+ func (i attr) String() string {
+ if i >= attr(len(_attr_index)-1) {
+diff --git a/src/html/template/context.go b/src/html/template/context.go
+index b78f0f7..8b3af2f 100644
+--- a/src/html/template/context.go
++++ b/src/html/template/context.go
+@@ -156,6 +156,10 @@ const (
+ // stateError is an infectious error state outside any valid
+ // HTML/CSS/JS construct.
+ stateError
++ // stateMetaContent occurs inside a HTML meta element content attribute.
++ stateMetaContent
++ // stateMetaContentURL occurs inside a "url=" tag in a HTML meta element content attribute.
++ stateMetaContentURL
+ // stateDead marks unreachable code after a {{break}} or {{continue}}.
+ stateDead
+ )
+@@ -267,6 +271,8 @@ const (
+ elementTextarea
+ // elementTitle corresponds to the RCDATA <title> element.
+ elementTitle
++ // elementMeta corresponds to the HTML <meta> element.
++ elementMeta
+ )
+
+ //go:generate stringer -type attr
+@@ -288,4 +294,6 @@ const (
+ attrURL
+ // attrSrcset corresponds to a srcset attribute.
+ attrSrcset
++ // attrMetaContent corresponds to the content attribute in meta HTML element.
++ attrMetaContent
+ )
+diff --git a/src/html/template/element_string.go b/src/html/template/element_string.go
+index db28665..bdf9da7 100644
+--- a/src/html/template/element_string.go
++++ b/src/html/template/element_string.go
+@@ -13,11 +13,12 @@ func _() {
+ _ = x[elementStyle-2]
+ _ = x[elementTextarea-3]
+ _ = x[elementTitle-4]
++ _ = x[elementMeta-5]
+ }
+
+-const _element_name = "elementNoneelementScriptelementStyleelementTextareaelementTitle"
++const _element_name = "elementNoneelementScriptelementStyleelementTextareaelementTitleelementMeta"
+
+-var _element_index = [...]uint8{0, 11, 24, 36, 51, 63}
++var _element_index = [...]uint8{0, 11, 24, 36, 51, 63, 74}
+
+ func (i element) String() string {
+ if i >= element(len(_element_index)-1) {
+diff --git a/src/html/template/escape.go b/src/html/template/escape.go
+index 1eace16..b368cab 100644
+--- a/src/html/template/escape.go
++++ b/src/html/template/escape.go
+@@ -165,6 +165,8 @@ func (e *escaper) escape(c context, n parse.Node) context {
+
+ var debugAllowActionJSTmpl = godebug.New("jstmpllitinterp")
+
++var htmlmetacontenturlescape = godebug.New("htmlmetacontenturlescape")
++
+ // escapeAction escapes an action template node.
+ func (e *escaper) escapeAction(c context, n *parse.ActionNode) context {
+ if len(n.Pipe.Decl) != 0 {
+@@ -222,6 +224,18 @@ func (e *escaper) escapeAction(c context, n *parse.ActionNode) context {
+ default:
+ panic(c.urlPart.String())
+ }
++ case stateMetaContent:
++ // Handled below in delim check.
++ case stateMetaContentURL:
++ if htmlmetacontenturlescape.Value() != "0" {
++ s = append(s, "_html_template_urlfilter")
++ } else {
++ // We don't have a great place to increment this, since it's hard to
++ // know if we actually escape any urls in _html_template_urlfilter,
++ // since it has no information about what context it is being
++ // executed in etc. This is probably the best we can do.
++ htmlmetacontenturlescape.IncNonDefault()
++ }
+ case stateJS:
+ s = append(s, "_html_template_jsvalescaper")
+ // A slash after a value starts a div operator.
+diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
+index 497ead8..1970db1 100644
+--- a/src/html/template/escape_test.go
++++ b/src/html/template/escape_test.go
+@@ -734,6 +734,16 @@ func TestEscape(t *testing.T) {
+ "<script>var a = `${ var a = \"{{\"a \\\" d\"}}\" }`</script>",
+ "<script>var a = `${ var a = \"a \\u0022 d\" }`</script>",
+ },
++ {
++ "meta content attribute url",
++ `<meta http-equiv="refresh" content="asd; url={{"javascript:alert(1)"}}; asd; url={{"vbscript:alert(1)"}}; asd">`,
++ `<meta http-equiv="refresh" content="asd; url=#ZgotmplZ; asd; url=#ZgotmplZ; asd">`,
++ },
++ {
++ "meta content string",
++ `<meta http-equiv="refresh" content="{{"asd: 123"}}">`,
++ `<meta http-equiv="refresh" content="asd: 123">`,
++ },
+ }
+
+ for _, test := range tests {
+@@ -1016,6 +1026,14 @@ func TestErrors(t *testing.T) {
+ "<script>var tmpl = `asd ${return \"{\"}`;</script>",
+ ``,
+ },
++ {
++ `{{if eq "" ""}}<meta>{{end}}`,
++ ``,
++ },
++ {
++ `{{if eq "" ""}}<meta content="url={{"asd"}}">{{end}}`,
++ ``,
++ },
+
+ // Error cases.
+ {
+@@ -2194,3 +2212,19 @@ func TestAliasedParseTreeDoesNotOverescape(t *testing.T) {
+ t.Fatalf(`Template "foo" and "bar" rendered %q and %q respectively, expected equal values`, got1, got2)
+ }
+ }
++
++func TestMetaContentEscapeGODEBUG(t *testing.T) {
++ savedGODEBUG := os.Getenv("GODEBUG")
++ os.Setenv("GODEBUG", savedGODEBUG+",htmlmetacontenturlescape=0")
++ defer func() { os.Setenv("GODEBUG", savedGODEBUG) }()
++
++ tmpl := Must(New("").Parse(`<meta http-equiv="refresh" content="asd; url={{"javascript:alert(1)"}}; asd; url={{"vbscript:alert(1)"}}; asd">`))
++ var b strings.Builder
++ if err := tmpl.Execute(&b, nil); err != nil {
++ t.Fatalf("unexpected error: %s", err)
++ }
++ want := `<meta http-equiv="refresh" content="asd; url=javascript:alert(1); asd; url=vbscript:alert(1); asd">`
++ if got := b.String(); got != want {
++ t.Fatalf("got %q, want %q", got, want)
++ }
++}
+diff --git a/src/html/template/state_string.go b/src/html/template/state_string.go
+index eed1e8b..f5a70b2 100644
+--- a/src/html/template/state_string.go
++++ b/src/html/template/state_string.go
+@@ -36,12 +36,14 @@ func _() {
+ _ = x[stateCSSBlockCmt-25]
+ _ = x[stateCSSLineCmt-26]
+ _ = x[stateError-27]
+- _ = x[stateDead-28]
++ _ = x[stateMetaContent-28]
++ _ = x[stateMetaContentURL-29]
++ _ = x[stateDead-30]
+ }
+
+-const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSTmplLitstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateDead"
++const _state_name = "stateTextstateTagstateAttrNamestateAfterNamestateBeforeValuestateHTMLCmtstateRCDATAstateAttrstateURLstateSrcsetstateJSstateJSDqStrstateJSSqStrstateJSTmplLitstateJSRegexpstateJSBlockCmtstateJSLineCmtstateJSHTMLOpenCmtstateJSHTMLCloseCmtstateCSSstateCSSDqStrstateCSSSqStrstateCSSDqURLstateCSSSqURLstateCSSURLstateCSSBlockCmtstateCSSLineCmtstateErrorstateMetaContentstateMetaContentURLstateDead"
+
+-var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 156, 169, 184, 198, 216, 235, 243, 256, 269, 282, 295, 306, 322, 337, 347, 356}
++var _state_index = [...]uint16{0, 9, 17, 30, 44, 60, 72, 83, 92, 100, 111, 118, 130, 142, 156, 169, 184, 198, 216, 235, 243, 256, 269, 282, 295, 306, 322, 337, 347, 363, 382, 391}
+
+ func (i state) String() string {
+ if i >= state(len(_state_index)-1) {
+diff --git a/src/html/template/transition.go b/src/html/template/transition.go
+index d5a05f6..5aa3c35 100644
+--- a/src/html/template/transition.go
++++ b/src/html/template/transition.go
+@@ -23,6 +23,8 @@ var transitionFunc = [...]func(context, []byte) (context, int){
+ stateRCDATA: tSpecialTagEnd,
+ stateAttr: tAttr,
+ stateURL: tURL,
++ stateMetaContent: tMetaContent,
++ stateMetaContentURL: tMetaContentURL,
+ stateSrcset: tURL,
+ stateJS: tJS,
+ stateJSDqStr: tJSDelimited,
+@@ -83,6 +85,7 @@ var elementContentType = [...]state{
+ elementStyle: stateCSS,
+ elementTextarea: stateRCDATA,
+ elementTitle: stateRCDATA,
++ elementMeta: stateText,
+ }
+
+ // tTag is the context transition function for the tag state.
+@@ -93,6 +96,11 @@ func tTag(c context, s []byte) (context, int) {
+ return c, len(s)
+ }
+ if s[i] == '>' {
++ // Treat <meta> specially, because it doesn't have an end tag, and we
++ // want to transition into the correct state/element for it.
++ if c.element == elementMeta {
++ return context{state: stateText, element: elementNone}, i + 1
++ }
+ return context{
+ state: elementContentType[c.element],
+ element: c.element,
+@@ -113,6 +121,8 @@ func tTag(c context, s []byte) (context, int) {
+ attrName := strings.ToLower(string(s[i:j]))
+ if c.element == elementScript && attrName == "type" {
+ attr = attrScriptType
++ } else if c.element == elementMeta && attrName == "content" {
++ attr = attrMetaContent
+ } else {
+ switch attrType(attrName) {
+ case contentTypeURL:
+@@ -162,12 +172,13 @@ func tAfterName(c context, s []byte) (context, int) {
+ }
+
+ var attrStartStates = [...]state{
+- attrNone: stateAttr,
+- attrScript: stateJS,
+- attrScriptType: stateAttr,
+- attrStyle: stateCSS,
+- attrURL: stateURL,
+- attrSrcset: stateSrcset,
++ attrNone: stateAttr,
++ attrScript: stateJS,
++ attrScriptType: stateAttr,
++ attrStyle: stateCSS,
++ attrURL: stateURL,
++ attrSrcset: stateSrcset,
++ attrMetaContent: stateMetaContent,
+ }
+
+ // tBeforeValue is the context transition function for stateBeforeValue.
+@@ -203,6 +214,7 @@ var specialTagEndMarkers = [...][]byte{
+ elementStyle: []byte("style"),
+ elementTextarea: []byte("textarea"),
+ elementTitle: []byte("title"),
++ elementMeta: []byte(""),
+ }
+
+ var (
+@@ -612,6 +624,28 @@ func tError(c context, s []byte) (context, int) {
+ return c, len(s)
+ }
+
++// tMetaContent is the context transition function for the meta content attribute state.
++func tMetaContent(c context, s []byte) (context, int) {
++ for i := 0; i < len(s); i++ {
++ if i+3 <= len(s)-1 && bytes.Equal(bytes.ToLower(s[i:i+4]), []byte("url=")) {
++ c.state = stateMetaContentURL
++ return c, i + 4
++ }
++ }
++ return c, len(s)
++}
++
++// tMetaContentURL is the context transition function for the "url=" part of a meta content attribute state.
++func tMetaContentURL(c context, s []byte) (context, int) {
++ for i := 0; i < len(s); i++ {
++ if s[i] == ';' {
++ c.state = stateMetaContent
++ return c, i + 1
++ }
++ }
++ return c, len(s)
++}
++
+ // eatAttrName returns the largest j such that s[i:j] is an attribute name.
+ // It returns an error if s[i:] does not look like it begins with an
+ // attribute name, such as encountering a quote mark without a preceding
+@@ -638,6 +672,7 @@ var elementNameMap = map[string]element{
+ "style": elementStyle,
+ "textarea": elementTextarea,
+ "title": elementTitle,
++ "meta": elementMeta,
+ }
+
+ // asciiAlpha reports whether c is an ASCII letter.
+diff --git a/src/internal/godebugs/table.go b/src/internal/godebugs/table.go
+index 7178df6..90311eb 100644
+--- a/src/internal/godebugs/table.go
++++ b/src/internal/godebugs/table.go
+@@ -31,6 +31,7 @@ var All = []Info{
+ {Name: "gocachetest", Package: "cmd/go"},
+ {Name: "gocacheverify", Package: "cmd/go"},
+ {Name: "gotypesalias", Package: "go/types"},
++ {Name: "htmlmetacontenturlescape", Package: "html/template"},
+ {Name: "http2client", Package: "net/http"},
+ {Name: "http2debug", Package: "net/http", Opaque: true},
+ {Name: "http2server", Package: "net/http"},
+diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go
+index 335f787..f68e386 100644
+--- a/src/runtime/metrics/doc.go
++++ b/src/runtime/metrics/doc.go
+@@ -255,6 +255,11 @@ Below is the full list of supported metrics, ordered lexicographically.
+ The number of non-default behaviors executed by the go/types
+ package due to a non-default GODEBUG=gotypesalias=... setting.
+
++ /godebug/non-default-behavior/htmlmetacontenturlescape:events
++ The number of non-default behaviors executed by
++ the html/template package due to a non-default
++ GODEBUG=htmlmetacontenturlescape=... setting.
++
+ /godebug/non-default-behavior/http2client:events
+ The number of non-default behaviors executed by the net/http
+ package due to a non-default GODEBUG=http2client=... setting.
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 08/21] go: patch CVE-2026-32280
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (6 preceding siblings ...)
2026-06-12 14:25 ` [OE-core][scarthgap 07/21] go: patch CVE-2026-27142 Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 09/21] go: patch CVE-2026-32283 Jeremy Rosen
` (12 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/758320
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-32280.patch | 289 ++++++++++++++++++
2 files changed, 290 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32280.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 8efa82f862..0d4dff6c21 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -42,6 +42,7 @@ SRC_URI += "\
file://CVE-2025-68121_p2.patch \
file://CVE-2025-68121_p3.patch \
file://CVE-2026-27142.patch \
+ file://CVE-2026-32280.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-32280.patch b/meta/recipes-devtools/go/go/CVE-2026-32280.patch
new file mode 100644
index 0000000000..9a6f7950ae
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-32280.patch
@@ -0,0 +1,289 @@
+From 1d71a2882078ea5057e68a7d2fedc83a5227c764 Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker <bracewell@google.com>
+Date: Thu, 5 Mar 2026 14:28:44 -0800
+Subject: [PATCH] crypto/x509: fix signature checking limit
+
+We added the "is this cert already in the chain" check (alreadyInChain)
+to considerCandidates before the signature limit. considerCandidates
+bails out when we exceed the signature check, but buildChains keeps
+calling considerCandidates until it exhausts all potential parents. In
+the case where a large number of certificates look to have signed each
+other (e.g. all have subject==issuerSubject and the same key),
+alreadyInChain is not particularly cheap, meaning even though we hit our
+"this is too much work" limit, we still do a lot of work.
+
+Move alreadyInChain after the signature limit, and also return a
+sentinel error, and check it in buildChains so we can break out of the
+loop early if we aren't actually going to do any more work.
+
+Thanks to Jakub Ciolek for reporting this issue.
+
+Fixes #78282
+Fixes CVE-2026-32280
+
+Change-Id: Ie6f05c6ba3b0a40c21f64f7c4f846e74fae3b10e
+Reviewed-on: https://go-review.googlesource.com/c/go/+/758320
+Reviewed-by: Damien Neil <dneil@google.com>
+Reviewed-by: Neal Patel <nealpatel@google.com>
+LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Reviewed-by: Jakub Ciolek <jakub@ciolek.dev>
+
+CVE: CVE-2026-32280
+Upstream-Status: Backport [https://github.com/golang/go/commit/26d8a902002a2b41bc4c302044110f2eae8d597f]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/crypto/x509/verify.go | 31 ++++---
+ src/crypto/x509/verify_test.go | 150 ++++++++++++++++-----------------
+ 2 files changed, 96 insertions(+), 85 deletions(-)
+
+diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
+index 0ae8aef..1de06bc 100644
+--- a/src/crypto/x509/verify.go
++++ b/src/crypto/x509/verify.go
+@@ -939,6 +939,8 @@ func alreadyInChain(candidate *Certificate, chain []*Certificate) bool {
+ // for failed checks due to different intermediates having the same Subject.
+ const maxChainSignatureChecks = 100
+
++var errSignatureLimit = errors.New("x509: signature check attempts limit reached while verifying certificate chain")
++
+ func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, opts *VerifyOptions) (chains [][]*Certificate, err error) {
+ var (
+ hintErr error
+@@ -946,16 +948,16 @@ func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, o
+ )
+
+ considerCandidate := func(certType int, candidate potentialParent) {
+- if candidate.cert.PublicKey == nil || alreadyInChain(candidate.cert, currentChain) {
+- return
+- }
+-
+ if sigChecks == nil {
+ sigChecks = new(int)
+ }
+ *sigChecks++
+ if *sigChecks > maxChainSignatureChecks {
+- err = errors.New("x509: signature check attempts limit reached while verifying certificate chain")
++ err = errSignatureLimit
++ return
++ }
++
++ if candidate.cert.PublicKey == nil || alreadyInChain(candidate.cert, currentChain) {
+ return
+ }
+
+@@ -996,11 +998,20 @@ func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, o
+ }
+ }
+
+- for _, root := range opts.Roots.findPotentialParents(c) {
+- considerCandidate(rootCertificate, root)
+- }
+- for _, intermediate := range opts.Intermediates.findPotentialParents(c) {
+- considerCandidate(intermediateCertificate, intermediate)
++candidateLoop:
++ for _, parents := range []struct {
++ certType int
++ potentials []potentialParent
++ }{
++ {rootCertificate, opts.Roots.findPotentialParents(c)},
++ {intermediateCertificate, opts.Intermediates.findPotentialParents(c)},
++ } {
++ for _, parent := range parents.potentials {
++ considerCandidate(parents.certType, parent)
++ if err == errSignatureLimit {
++ break candidateLoop
++ }
++ }
+ }
+
+ if len(chains) > 0 {
+diff --git a/src/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
+index 223c250..f3711ac 100644
+--- a/src/crypto/x509/verify_test.go
++++ b/src/crypto/x509/verify_test.go
+@@ -1765,10 +1765,13 @@ func TestValidHostname(t *testing.T) {
+ }
+ }
+
+-func generateCert(cn string, isCA bool, issuer *Certificate, issuerKey crypto.PrivateKey) (*Certificate, crypto.PrivateKey, error) {
+- priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+- if err != nil {
+- return nil, nil, err
++func generateCert(cn string, isCA bool, issuer *Certificate, issuerKey crypto.PrivateKey, priv crypto.PrivateKey) (*Certificate, crypto.PrivateKey, error) {
++ if priv == nil {
++ var err error
++ priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
++ if err != nil {
++ return nil, nil, err
++ }
+ }
+
+ serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
+@@ -1779,6 +1782,7 @@ func generateCert(cn string, isCA bool, issuer *Certificate, issuerKey crypto.Pr
+ Subject: pkix.Name{CommonName: cn},
+ NotBefore: time.Now().Add(-1 * time.Hour),
+ NotAfter: time.Now().Add(24 * time.Hour),
++ DNSNames: []string{rand.Text()},
+
+ KeyUsage: KeyUsageKeyEncipherment | KeyUsageDigitalSignature | KeyUsageCertSign,
+ ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth},
+@@ -1790,7 +1794,7 @@ func generateCert(cn string, isCA bool, issuer *Certificate, issuerKey crypto.Pr
+ issuerKey = priv
+ }
+
+- derBytes, err := CreateCertificate(rand.Reader, template, issuer, priv.Public(), issuerKey)
++ derBytes, err := CreateCertificate(rand.Reader, template, issuer, priv.(crypto.Signer).Public(), issuerKey)
+ if err != nil {
+ return nil, nil, err
+ }
+@@ -1802,81 +1806,77 @@ func generateCert(cn string, isCA bool, issuer *Certificate, issuerKey crypto.Pr
+ return cert, priv, nil
+ }
+
+-func TestPathologicalChain(t *testing.T) {
+- if testing.Short() {
+- t.Skip("skipping generation of a long chain of certificates in short mode")
+- }
+-
+- // Build a chain where all intermediates share the same subject, to hit the
+- // path building worst behavior.
+- roots, intermediates := NewCertPool(), NewCertPool()
+-
+- parent, parentKey, err := generateCert("Root CA", true, nil, nil)
+- if err != nil {
+- t.Fatal(err)
+- }
+- roots.AddCert(parent)
+-
+- for i := 1; i < 100; i++ {
+- parent, parentKey, err = generateCert("Intermediate CA", true, parent, parentKey)
+- if err != nil {
+- t.Fatal(err)
+- }
+- intermediates.AddCert(parent)
+- }
+-
+- leaf, _, err := generateCert("Leaf", false, parent, parentKey)
+- if err != nil {
+- t.Fatal(err)
+- }
+-
+- start := time.Now()
+- _, err = leaf.Verify(VerifyOptions{
+- Roots: roots,
+- Intermediates: intermediates,
+- })
+- t.Logf("verification took %v", time.Since(start))
+-
+- if err == nil || !strings.Contains(err.Error(), "signature check attempts limit") {
+- t.Errorf("expected verification to fail with a signature checks limit error; got %v", err)
+- }
+-}
+-
+-func TestLongChain(t *testing.T) {
++func TestPathologicalChains(t *testing.T) {
+ if testing.Short() {
+- t.Skip("skipping generation of a long chain of certificates in short mode")
+- }
+-
+- roots, intermediates := NewCertPool(), NewCertPool()
+-
+- parent, parentKey, err := generateCert("Root CA", true, nil, nil)
+- if err != nil {
+- t.Fatal(err)
+- }
+- roots.AddCert(parent)
++ t.Skip("skipping generation of a long chains of certificates in short mode")
++ }
++
++ // Test four pathological cases, where the intermediates in the chain have
++ // the same/different subjects and the same/different keys. This covers a
++ // number of cases where the chain building algorithm might be inefficient,
++ // such as when there are many intermediates with the same subject but
++ // different keys, many intermediates with the same key but different
++ // subjects, many intermediates with the same subject and key, or many
++ // intermediates with different subjects and keys.
++ //
++ // The worst case for our algorithm is when all of the intermediates share
++ // both subject and key, in which case all of the intermediates appear to
++ // have signed each other, causing us to see a large number of potential
++ // parents for each intermediate.
++ //
++ // All of these cases, Certificate.Verify should return errSignatureLimit.
++ //
++ // In all cases, don't have a root in the pool, so a valid chain cannot actually be built.
++
++ for _, test := range []struct {
++ sameSubject bool
++ sameKey bool
++ }{
++ {sameSubject: false, sameKey: false},
++ {sameSubject: true, sameKey: false},
++ {sameSubject: false, sameKey: true},
++ {sameSubject: true, sameKey: true},
++ } {
++ t.Run(fmt.Sprintf("sameSubject=%t,sameKey=%t", test.sameSubject, test.sameKey), func(t *testing.T) {
++ intermediates := NewCertPool()
++
++ var intermediateKey crypto.PrivateKey
++ if test.sameKey {
++ var err error
++ intermediateKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
++ if err != nil {
++ t.Fatal(err)
++ }
++ }
+
+- for i := 1; i < 15; i++ {
+- name := fmt.Sprintf("Intermediate CA #%d", i)
+- parent, parentKey, err = generateCert(name, true, parent, parentKey)
+- if err != nil {
+- t.Fatal(err)
+- }
+- intermediates.AddCert(parent)
+- }
++ var leafSigner crypto.PrivateKey
++ var intermediate *Certificate
++ for i := range 100 {
++ cn := "Intermediate CA"
++ if !test.sameSubject {
++ cn += fmt.Sprintf(" #%d", i)
++ }
++ var err error
++ intermediate, leafSigner, err = generateCert(cn, true, intermediate, leafSigner, intermediateKey)
++ if err != nil {
++ t.Fatal(err)
++ }
++ intermediates.AddCert(intermediate)
++ }
+
+- leaf, _, err := generateCert("Leaf", false, parent, parentKey)
+- if err != nil {
+- t.Fatal(err)
+- }
++ leaf, _, err := generateCert("Leaf", false, intermediate, leafSigner, nil)
++ if err != nil {
++ t.Fatal(err)
++ }
+
+- start := time.Now()
+- if _, err := leaf.Verify(VerifyOptions{
+- Roots: roots,
+- Intermediates: intermediates,
+- }); err != nil {
+- t.Error(err)
++ start := time.Now()
++ _, err = leaf.Verify(VerifyOptions{
++ Roots: NewCertPool(),
++ Intermediates: intermediates,
++ })
++ t.Logf("verification took %v", time.Since(start))
++ })
+ }
+- t.Logf("verification took %v", time.Since(start))
+ }
+
+ func TestSystemRootsError(t *testing.T) {
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 09/21] go: patch CVE-2026-32283
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (7 preceding siblings ...)
2026-06-12 14:25 ` [OE-core][scarthgap 08/21] go: patch CVE-2026-32280 Jeremy Rosen
@ 2026-06-12 14:25 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 10/21] go: patch CVE-2026-32289 Jeremy Rosen
` (11 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:25 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/763767
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-32283.patch | 177 ++++++++++++++++++
2 files changed, 178 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32283.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 0d4dff6c21..99c2945a8c 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -43,6 +43,7 @@ SRC_URI += "\
file://CVE-2025-68121_p3.patch \
file://CVE-2026-27142.patch \
file://CVE-2026-32280.patch \
+ file://CVE-2026-32283.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-32283.patch b/meta/recipes-devtools/go/go/CVE-2026-32283.patch
new file mode 100644
index 0000000000..87bcc5816f
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-32283.patch
@@ -0,0 +1,177 @@
+From f560f55d3f804dcc3002dfe963b37bfa3a67202c Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker <bracewell@google.com>
+Date: Mon, 23 Mar 2026 11:54:41 -0700
+Subject: [PATCH] crypto/tls: prevent deadlock when client sends multiple key
+ update messages
+
+When we made setReadTrafficSecret send an alert when there are pending
+handshake messages, we introduced a deadlock when the client sends
+multiple key update messages that request a response, as handleKeyUpdate
+will lock the mutex, and defer the unlocking until the end of the
+function, but setReadTrafficSecret called sendAlert in the failure case,
+which also tries to lock the mutex.
+
+Add an argument to setReadTrafficSecret which lets the caller indicate
+if the mutex is already locked, and if so, call sendAlertLocked instead
+of sendAlert.
+
+Thanks to Jakub Ciolek for reporting this issue.
+
+Fixes #78334
+Fixes CVE-2026-32283
+
+Change-Id: Id8e56974233c910e0d66ba96eafbd2ea57832610
+Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3881
+Reviewed-by: Damien Neil <dneil@google.com>
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-on: https://go-review.googlesource.com/c/go/+/763767
+LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Auto-Submit: David Chase <drchase@google.com>
+Reviewed-by: Russ Cox <rsc@golang.org>
+Reviewed-by: Jakub Ciolek <jakub@ciolek.dev>
+
+CVE: CVE-2026-32283
+Upstream-Status: Backport [https://github.com/golang/go/commit/1ea7966042731bae941511fb2b261b9536ad268f]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/crypto/tls/conn.go | 10 +++--
+ src/crypto/tls/handshake_client_tls13.go | 4 +-
+ src/crypto/tls/handshake_server_tls13.go | 4 +-
+ src/crypto/tls/handshake_test.go | 48 ++++++++++++++++++++++++
+ 4 files changed, 59 insertions(+), 7 deletions(-)
+
+diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
+index 08609ce..770d456 100644
+--- a/src/crypto/tls/conn.go
++++ b/src/crypto/tls/conn.go
+@@ -1345,7 +1345,7 @@ func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
+ }
+
+ newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
+- if err := c.setReadTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret); err != nil {
++ if err := c.setReadTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret, keyUpdate.updateRequested); err != nil {
+ return err
+ }
+
+@@ -1675,12 +1675,16 @@ func (c *Conn) VerifyHostname(host string) error {
+ // setReadTrafficSecret sets the read traffic secret for the given encryption level. If
+ // being called at the same time as setWriteTrafficSecret, the caller must ensure the call
+ // to setWriteTrafficSecret happens first so any alerts are sent at the write level.
+-func (c *Conn) setReadTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) error {
++func (c *Conn) setReadTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte, locked bool) error {
+ // Ensure that there are no buffered handshake messages before changing the
+ // read keys, since that can cause messages to be parsed that were encrypted
+ // using old keys which are no longer appropriate.
+ if c.hand.Len() != 0 {
+- c.sendAlert(alertUnexpectedMessage)
++ if locked {
++ c.sendAlertLocked(alertUnexpectedMessage)
++ } else {
++ c.sendAlert(alertUnexpectedMessage)
++ }
+ return errors.New("tls: handshake buffer not empty before setting read traffic secret")
+ }
+ c.in.setTrafficSecret(suite, level, secret)
+diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
+index 68ff92b..2d58b21 100644
+--- a/src/crypto/tls/handshake_client_tls13.go
++++ b/src/crypto/tls/handshake_client_tls13.go
+@@ -396,7 +396,7 @@ func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
+ c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
+ serverSecret := hs.suite.deriveSecret(handshakeSecret,
+ serverHandshakeTrafficLabel, hs.transcript)
+- if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret); err != nil {
++ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret, false); err != nil {
+ return err
+ }
+
+@@ -607,7 +607,7 @@ func (hs *clientHandshakeStateTLS13) readServerFinished() error {
+ clientApplicationTrafficLabel, hs.transcript)
+ serverSecret := hs.suite.deriveSecret(hs.masterSecret,
+ serverApplicationTrafficLabel, hs.transcript)
+- if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret); err != nil {
++ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret, false); err != nil {
+ return err
+ }
+
+diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
+index 1ecee3a..f73b536 100644
+--- a/src/crypto/tls/handshake_server_tls13.go
++++ b/src/crypto/tls/handshake_server_tls13.go
+@@ -636,7 +636,7 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
+ c.setWriteTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
+ clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
+ clientHandshakeTrafficLabel, hs.transcript)
+- if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret); err != nil {
++ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret, false); err != nil {
+ return err
+ }
+
+@@ -1005,7 +1005,7 @@ func (hs *serverHandshakeStateTLS13) readClientFinished() error {
+ return errors.New("tls: invalid client finished hash")
+ }
+
+- if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret); err != nil {
++ if err := c.setReadTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret, false); err != nil {
+ return err
+ }
+
+diff --git a/src/crypto/tls/handshake_test.go b/src/crypto/tls/handshake_test.go
+index 4991a0e..a95d751 100644
+--- a/src/crypto/tls/handshake_test.go
++++ b/src/crypto/tls/handshake_test.go
+@@ -673,3 +673,51 @@ func concatHandshakeMessages(msgs ...handshakeMessage) ([]byte, error) {
+ outBuf = append(outBuf, marshalled...)
+ return outBuf, nil
+ }
++
++func TestMultipleKeyUpdate(t *testing.T) {
++ for _, requestUpdate := range []bool{true, false} {
++ t.Run(fmt.Sprintf("requestUpdate=%t", requestUpdate), func(t *testing.T) {
++
++ c, s := localPipe(t)
++ cfg := testConfig.Clone()
++ cfg.MinVersion = VersionTLS13
++ cfg.MaxVersion = VersionTLS13
++ client := Client(c, testConfig)
++ server := Server(s, testConfig)
++
++ clientHandshakeDone := make(chan struct{})
++ go func() {
++ if err := client.Handshake(); err != nil {
++ }
++ close(clientHandshakeDone)
++ io.Copy(io.Discard, server)
++ }()
++
++ if err := server.Handshake(); err != nil {
++ t.Fatalf("server handshake failed: %v\n", err)
++ }
++ <-clientHandshakeDone
++
++ c.SetReadDeadline(time.Now().Add(1 * time.Second))
++ s.SetReadDeadline(time.Now().Add(1 * time.Second))
++
++ kuMsg, err := (&keyUpdateMsg{updateRequested: requestUpdate}).marshal()
++ if err != nil {
++ t.Fatalf("failed to marshal key update message: %v", err)
++ }
++
++ client.out.Lock()
++ if _, err := client.writeRecordLocked(recordTypeHandshake, append(kuMsg, kuMsg...)); err != nil {
++ t.Fatalf("failed to write key update messages: %v", err)
++ }
++ client.out.Unlock()
++
++ _, err = io.Copy(io.Discard, client)
++ if err == nil {
++ t.Fatal("expected multiple key update messages to cause an error, got nil")
++ } else if !strings.HasSuffix(err.Error(), "tls: unexpected message") {
++ t.Fatalf("unexpected error: %v", err)
++ }
++ })
++ }
++}
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 10/21] go: patch CVE-2026-32289
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (8 preceding siblings ...)
2026-06-12 14:25 ` [OE-core][scarthgap 09/21] go: patch CVE-2026-32283 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 11/21] go: patch CVE-2026-33811 Jeremy Rosen
` (10 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/763762
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-32289.patch | 217 ++++++++++++++++++
2 files changed, 218 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-32289.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 99c2945a8c..288cd5c95f 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -44,6 +44,7 @@ SRC_URI += "\
file://CVE-2026-27142.patch \
file://CVE-2026-32280.patch \
file://CVE-2026-32283.patch \
+ file://CVE-2026-32289.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-32289.patch b/meta/recipes-devtools/go/go/CVE-2026-32289.patch
new file mode 100644
index 0000000000..28ff0c00e0
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-32289.patch
@@ -0,0 +1,217 @@
+From 5291c6d3e6d0bc0a764a9a6bd6b3de1be64b8264 Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker <bracewell@google.com>
+Date: Mon, 23 Mar 2026 13:34:23 -0700
+Subject: [PATCH] html/template: properly track JS template literal brace depth
+ across contexts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Properly track JS template literal brace depth across branches/ranges,
+and prevent accidental re-use of escape analysis by including the
+brace depth in the stringification/mangling for contexts.
+
+Fixes #78331
+Fixes CVE-2026-32289
+
+Change-Id: I9f3f47c29e042220b18e4d3299db7a3fae4207fa
+Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/3882
+Reviewed-by: Neal Patel <nealpatel@google.com>
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-on: https://go-review.googlesource.com/c/go/+/763762
+Reviewed-by: Russ Cox <rsc@golang.org>
+LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Auto-Submit: David Chase <drchase@google.com>
+Reviewed-by: Fan Mỹ Tâm Club <letrivien97@gmail.com>
+
+CVE: CVE-2026-32289
+Upstream-Status: Backport [https://github.com/golang/go/commit/199c4d1c3c9d509a51f777c81cb17d4b17728097]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/html/template/context.go | 14 +++++++++++-
+ src/html/template/escape.go | 4 ++--
+ src/html/template/escape_test.go | 38 +++++++++++++++++++++-----------
+ 3 files changed, 40 insertions(+), 16 deletions(-)
+
+diff --git a/src/html/template/context.go b/src/html/template/context.go
+index 8b3af2feab..132ae2d28d 100644
+--- a/src/html/template/context.go
++++ b/src/html/template/context.go
+@@ -6,6 +6,7 @@ package template
+
+ import (
+ "fmt"
++ "slices"
+ "text/template/parse"
+ )
+
+@@ -37,7 +38,7 @@ func (c context) String() string {
+ if c.err != nil {
+ err = c.err
+ }
+- return fmt.Sprintf("{%v %v %v %v %v %v %v}", c.state, c.delim, c.urlPart, c.jsCtx, c.attr, c.element, err)
++ return fmt.Sprintf("{%v %v %v %v %v %v %v %v}", c.state, c.delim, c.urlPart, c.jsCtx, c.jsBraceDepth, c.attr, c.element, err)
+ }
+
+ // eq reports whether two contexts are equal.
+@@ -46,6 +47,7 @@ func (c context) eq(d context) bool {
+ c.delim == d.delim &&
+ c.urlPart == d.urlPart &&
+ c.jsCtx == d.jsCtx &&
++ slices.Equal(c.jsBraceDepth, d.jsBraceDepth) &&
+ c.attr == d.attr &&
+ c.element == d.element &&
+ c.err == d.err
+@@ -68,6 +70,9 @@ func (c context) mangle(templateName string) string {
+ if c.jsCtx != jsCtxRegexp {
+ s += "_" + c.jsCtx.String()
+ }
++ if c.jsBraceDepth != nil {
++ s += fmt.Sprintf("_jsBraceDepth(%v)", c.jsBraceDepth)
++ }
+ if c.attr != attrNone {
+ s += "_" + c.attr.String()
+ }
+@@ -77,6 +82,13 @@ func (c context) mangle(templateName string) string {
+ return s
+ }
+
++// clone returns a copy of c with the same field values.
++func (c context) clone() context {
++ clone := c
++ clone.jsBraceDepth = slices.Clone(c.jsBraceDepth)
++ return clone
++}
++
+ // state describes a high-level HTML parser state.
+ //
+ // It bounds the top of the element stack, and by extension the HTML insertion
+diff --git a/src/html/template/escape.go b/src/html/template/escape.go
+index b368cab38c..c031ed27b9 100644
+--- a/src/html/template/escape.go
++++ b/src/html/template/escape.go
+@@ -522,7 +522,7 @@ func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string)
+ if nodeName == "range" {
+ e.rangeContext = &rangeContext{outer: e.rangeContext}
+ }
+- c0 := e.escapeList(c, n.List)
++ c0 := e.escapeList(c.clone(), n.List)
+ if nodeName == "range" {
+ if c0.state != stateError {
+ c0 = joinRange(c0, e.rangeContext)
+@@ -553,7 +553,7 @@ func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string)
+ return c0
+ }
+ }
+- c1 := e.escapeList(c, n.ElseList)
++ c1 := e.escapeList(c.clone(), n.ElseList)
+ return join(c0, c1, n, nodeName)
+ }
+
+diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
+index 1970db1695..435c83378f 100644
+--- a/src/html/template/escape_test.go
++++ b/src/html/template/escape_test.go
+@@ -1181,6 +1181,18 @@ func TestErrors(t *testing.T) {
+ // html is allowed since it is the last command in the pipeline, but urlquery is not.
+ `predefined escaper "urlquery" disallowed in template`,
+ },
++ {
++ "<script>var a = `{{if .X}}`{{end}}",
++ `{{if}} branches end in different contexts`,
++ },
++ {
++ "<script>var a = `{{if .X}}a{{else}}`{{end}}",
++ `{{if}} branches end in different contexts`,
++ },
++ {
++ "<script>var a = `{{if .X}}a{{else}}b{{end}}`</script>",
++ ``,
++ },
+ }
+ for _, test := range tests {
+ buf := new(bytes.Buffer)
+@@ -1752,7 +1764,7 @@ func TestEscapeText(t *testing.T) {
+ },
+ {
+ "<script>var a = `${",
+- context{state: stateJS, element: elementScript},
++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var a = `${}",
+@@ -1760,27 +1772,27 @@ func TestEscapeText(t *testing.T) {
+ },
+ {
+ "<script>var a = `${`",
+- context{state: stateJSTmplLit, element: elementScript},
++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var a = `${var a = \"",
+- context{state: stateJSDqStr, element: elementScript},
++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var a = `${var a = \"`",
+- context{state: stateJSDqStr, element: elementScript},
++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var a = `${var a = \"}",
+- context{state: stateJSDqStr, element: elementScript},
++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var a = `${``",
+- context{state: stateJS, element: elementScript},
++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var a = `${`}",
+- context{state: stateJSTmplLit, element: elementScript},
++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>`${ {} } asd`</script><script>`${ {} }",
+@@ -1788,7 +1800,7 @@ func TestEscapeText(t *testing.T) {
+ },
+ {
+ "<script>var foo = `${ (_ => { return \"x\" })() + \"${",
+- context{state: stateJSDqStr, element: elementScript},
++ context{state: stateJSDqStr, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var a = `${ {</script><script>var b = `${ x }",
+@@ -1816,23 +1828,23 @@ func TestEscapeText(t *testing.T) {
+ },
+ {
+ "<script>`${ { `` }",
+- context{state: stateJS, element: elementScript},
++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>`${ { }`",
+- context{state: stateJSTmplLit, element: elementScript},
++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ {
+ "<script>var foo = `${ foo({ a: { c: `${",
+- context{state: stateJS, element: elementScript},
++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{2, 0}},
+ },
+ {
+ "<script>var foo = `${ foo({ a: { c: `${ {{.}} }` }, b: ",
+- context{state: stateJS, element: elementScript},
++ context{state: stateJS, element: elementScript, jsBraceDepth: []int{1}},
+ },
+ {
+ "<script>`${ `}",
+- context{state: stateJSTmplLit, element: elementScript},
++ context{state: stateJSTmplLit, element: elementScript, jsBraceDepth: []int{0}},
+ },
+ }
+
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 11/21] go: patch CVE-2026-33811
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (9 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 10/21] go: patch CVE-2026-32289 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 12/21] go: patch CVE-2026-39817 Jeremy Rosen
` (9 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/767860
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-33811.patch | 46 +++++++++++++++++++
2 files changed, 47 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-33811.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 288cd5c95f..9a7695e754 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -45,6 +45,7 @@ SRC_URI += "\
file://CVE-2026-32280.patch \
file://CVE-2026-32283.patch \
file://CVE-2026-32289.patch \
+ file://CVE-2026-33811.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-33811.patch b/meta/recipes-devtools/go/go/CVE-2026-33811.patch
new file mode 100644
index 0000000000..216b33ed8b
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-33811.patch
@@ -0,0 +1,46 @@
+From 9082277a0a78af39190c1f23b622f02b89e46196 Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Thu, 26 Mar 2026 12:17:06 -0700
+Subject: [PATCH] net: avoid double-free of cgo pointer when handling large DNS
+ response
+
+No test, unfortunately: I've had no luck triggering this without
+the ability to override the local recursive resolver.
+
+Thanks to hamayanhamayan for reporting this issue.
+
+Fixes CVE-2026-33811
+Fixes #78803
+
+Change-Id: I9e51410337316c20e4b9fd5b86657f436a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/767860
+Reviewed-by: Nicholas Husin <nsh@golang.org>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Reviewed-by: Nicholas Husin <husin@google.com>
+
+CVE: CVE-2026-33811
+Upstream-Status: Backport [https://github.com/golang/go/commit/ab2c7eb1c43011dda118282c1e757d8c27cd7d4f]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/net/cgo_unix.go | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go
+index 7ed5daad73..bd694859ab 100644
+--- a/src/net/cgo_unix.go
++++ b/src/net/cgo_unix.go
+@@ -343,7 +343,10 @@ func cgoResSearch(hostname string, rtype, class int) ([]dnsmessage.Resource, err
+ // useful in the response, even though there *is* a response.
+ bufSize := maxDNSPacketSize
+ buf := (*_C_uchar)(_C_malloc(uintptr(bufSize)))
+- defer _C_free(unsafe.Pointer(buf))
++ defer func() {
++ // Free in a closure which captures buf to pick up a reallocated buffer from below.
++ _C_free(unsafe.Pointer(buf))
++ }()
+
+ s, err := syscall.BytePtrFromString(hostname)
+ if err != nil {
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 12/21] go: patch CVE-2026-39817
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (10 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 11/21] go: patch CVE-2026-33811 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 13/21] go: patch CVE-2026-39819 Jeremy Rosen
` (8 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1] mentionned in [2]
[1] https://go.dev/cl/767520
[2] https://security-tracker.debian.org/tracker/CVE-2026-39817
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-39817.patch | 105 ++++++++++++++++++
2 files changed, 106 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39817.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 9a7695e754..f06b974e04 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -46,6 +46,7 @@ SRC_URI += "\
file://CVE-2026-32283.patch \
file://CVE-2026-32289.patch \
file://CVE-2026-33811.patch \
+ file://CVE-2026-39817.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-39817.patch b/meta/recipes-devtools/go/go/CVE-2026-39817.patch
new file mode 100644
index 0000000000..103fbedb7a
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-39817.patch
@@ -0,0 +1,105 @@
+From 7d35508ad684c808ec11fb6ef3ab27f9258a9418 Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Wed, 15 Apr 2026 16:27:23 -0400
+Subject: [PATCH] cmd/pack: refuse to extract files with directory components
+
+Do not write to /etc/passwd when running "go tool pack x evil.a"
+on an archive containing a file named /etc/passwd.
+
+Fixes #78778
+
+Change-Id: I4cf69b81af62321ffbb41ace679672a86a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/767520
+Reviewed-by: Nicholas Husin <nsh@golang.org>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Reviewed-by: Nicholas Husin <husin@google.com>
+
+CVE: CVE-2026-39817
+Upstream-Status: Backport [https://github.com/golang/go/commit/7409ada33f99c0d74db2b0389c51a15de116e48d]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/cmd/pack/pack.go | 5 +++++
+ src/cmd/pack/pack_test.go | 44 +++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 49 insertions(+)
+
+diff --git a/src/cmd/pack/pack.go b/src/cmd/pack/pack.go
+index 412ea36d60..2fe0258f01 100644
+--- a/src/cmd/pack/pack.go
++++ b/src/cmd/pack/pack.go
+@@ -135,6 +135,11 @@ func openArchive(name string, mode int, files []string) *Archive {
+ if err != nil {
+ log.Fatal(err)
+ }
++ for _, f := range a.Entries {
++ if !filepath.IsLocal(f.Name) || filepath.Base(f.Name) != f.Name {
++ log.Fatalf("%q: invalid name", f.Name)
++ }
++ }
+ return &Archive{
+ a: a,
+ files: files,
+diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
+index c3a63424dd..c4a8c78cbf 100644
+--- a/src/cmd/pack/pack_test.go
++++ b/src/cmd/pack/pack_test.go
+@@ -6,6 +6,7 @@ package main
+
+ import (
+ "bufio"
++ "bytes"
+ "cmd/internal/archive"
+ "fmt"
+ "internal/testenv"
+@@ -409,6 +410,49 @@ func TestRWithNonexistentFile(t *testing.T) {
+ run(packPath(t), "r", "p.a", "p.o") // should succeed
+ }
+
++func TestOutputPathSanitization(t *testing.T) {
++ dir := t.TempDir()
++
++ // Create pack.a containing a file named "longpathname".
++ // Note that "go tool pack" requires that all files be at least 8 bytes long.
++ const validPathName = "longpathname"
++ if err := os.WriteFile(dir+"/"+validPathName, make([]byte, 8), 0o666); err != nil {
++ t.Fatal(err)
++ }
++ doRun(t, dir, packPath(t), "grc", "pack.a", validPathName)
++
++ // Create evil.a from pack.a, replacing "longpathname" with "out/pathname".
++ b, err := os.ReadFile(dir + "/pack.a")
++ if err != nil {
++ t.Fatal(err)
++ }
++ idx := bytes.Index(b, []byte(validPathName))
++ if idx < 0 {
++ t.Fatalf("%v not found in pack.a", validPathName)
++ }
++ copy(b[idx:], "out/")
++ os.WriteFile(dir+"/evil.a", b, 0o666)
++
++ // Extract evil.a. It should fail and not extract a file to /out.
++ os.Mkdir(dir+"/out", 0o777)
++
++ cmd := testenv.Command(t, packPath(t), "x", "evil.a")
++ cmd.Dir = dir
++ _, err = cmd.CombinedOutput()
++ if err == nil {
++ t.Errorf("pack x evil.a: unexpected success")
++ }
++
++ ents, err := os.ReadDir(dir + "/out")
++ if err != nil {
++ t.Error(err)
++ }
++ for _, e := range ents {
++ t.Errorf("unexpected file in /out: %q", e.Name())
++ }
++
++}
++
+ // doRun runs a program in a directory and returns the output.
+ func doRun(t *testing.T, dir string, args ...string) string {
+ cmd := testenv.Command(t, args[0], args[1:]...)
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 13/21] go: patch CVE-2026-39819
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (11 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 12/21] go: patch CVE-2026-39817 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 14/21] go: patch CVE-2026-39820 Jeremy Rosen
` (7 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/763882
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-39819.patch | 48 +++++++++++++++++++
2 files changed, 49 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39819.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index f06b974e04..dba826011b 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -47,6 +47,7 @@ SRC_URI += "\
file://CVE-2026-32289.patch \
file://CVE-2026-33811.patch \
file://CVE-2026-39817.patch \
+ file://CVE-2026-39819.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-39819.patch b/meta/recipes-devtools/go/go/CVE-2026-39819.patch
new file mode 100644
index 0000000000..cb767e1320
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-39819.patch
@@ -0,0 +1,48 @@
+From db6ceacb046779c763f87060d8a1ba5c936309c9 Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Wed, 8 Apr 2026 09:55:54 -0700
+Subject: [PATCH] cmd/go: use MkdirTemp to create temp directory for "go bug"
+
+Don't use a predictable, potentially attacker-controlled filename in /tmp.
+
+Fixes #78584
+Fixes CVE-2026-39819
+
+Change-Id: I72116aa6dd8fa50f65b6dc0292a15a8c6a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/763882
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-by: Nicholas Husin <nsh@golang.org>
+LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+
+CVE: CVE-2026-39819
+Upstream-Status: Backport [https://github.com/golang/go/commit/5d6aa23e5b6151d25955a512532383c28c745e18]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/cmd/go/internal/bug/bug.go | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/cmd/go/internal/bug/bug.go b/src/cmd/go/internal/bug/bug.go
+index ed1813605e..9bf97dd511 100644
+--- a/src/cmd/go/internal/bug/bug.go
++++ b/src/cmd/go/internal/bug/bug.go
+@@ -182,14 +182,14 @@ func firstLine(buf []byte) []byte {
+ // printGlibcVersion prints information about the glibc version.
+ // It ignores failures.
+ func printGlibcVersion(w io.Writer) {
+- tempdir := os.TempDir()
+- if tempdir == "" {
++ tempdir, err := os.MkdirTemp("", "")
++ if err != nil {
+ return
+ }
+ src := []byte(`int main() {}`)
+ srcfile := filepath.Join(tempdir, "go-bug.c")
+ outfile := filepath.Join(tempdir, "go-bug")
+- err := os.WriteFile(srcfile, src, 0644)
++ err = os.WriteFile(srcfile, src, 0644)
+ if err != nil {
+ return
+ }
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 14/21] go: patch CVE-2026-39820
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (12 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 13/21] go: patch CVE-2026-39819 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 15/21] go: patch CVE-2026-39825 Jeremy Rosen
` (6 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1] mentionned in [2]
[1] https://go.dev/cl/759940
[2] https://security-tracker.debian.org/tracker/CVE-2026-39820
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-39820.patch | 112 ++++++++++++++++++
2 files changed, 113 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39820.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index dba826011b..002d443059 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -48,6 +48,7 @@ SRC_URI += "\
file://CVE-2026-33811.patch \
file://CVE-2026-39817.patch \
file://CVE-2026-39819.patch \
+ file://CVE-2026-39820.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-39820.patch b/meta/recipes-devtools/go/go/CVE-2026-39820.patch
new file mode 100644
index 0000000000..c5f84282a9
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-39820.patch
@@ -0,0 +1,112 @@
+From e459f8fe1061679f866c599210466db386348f08 Mon Sep 17 00:00:00 2001
+From: mohammadmseet-hue <mohammadmseet@gmail.com>
+Date: Sat, 4 Apr 2026 05:17:25 +0000
+Subject: [PATCH] net/mail: fix quadratic complexity in consumeComment
+
+consumeComment builds the comment string by repeated string
+concatenation inside a loop. Each concatenation copies the
+entire string built so far, making the function O(n^2) in the
+depth of nested comments.
+
+Replace the concatenation with a strings.Builder, which
+amortizes allocation by doubling its internal buffer. This
+reduces consumeComment from O(n^2) to O(n).
+
+This is the same bug class as the consumeDomainLiteral fix
+in CVE-2025-61725.
+
+Benchmark results (benchstat, 8 runs):
+
+ name old time/op new time/op delta
+ ConsumeComment/depth10 2.481us 1.838us -25.92%
+ ConsumeComment/depth100 86.58us 6.498us -92.50%
+ ConsumeComment/depth1000 7.963ms 52.82us -99.34%
+ ConsumeComment/depth10000 897.8ms 521.3us -99.94%
+
+The quadratic cost becomes visible at depth 100 and dominant
+by depth 1000. At depth 10000, the fix is roughly 1700x
+faster.
+
+Change-Id: I3c927f02646fcab7bab167cb82fd46d3327d6d34
+GitHub-Last-Rev: 7742dad716ee371766543f88e82bd163bd9d7ac2
+GitHub-Pull-Request: golang/go#78393
+Reviewed-on: https://go-review.googlesource.com/c/go/+/759940
+Reviewed-by: Sean Liao <sean@liao.dev>
+LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Auto-Submit: Sean Liao <sean@liao.dev>
+Reviewed-by: David Chase <drchase@google.com>
+Reviewed-by: Junyang Shao <shaojunyang@google.com>
+
+CVE: CVE-2026-39820
+Upstream-Status: Backport [https://github.com/golang/go/commit/0d0799f055dcc9b3b41df74bee3fbe398ae2f0e7]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/net/mail/message.go | 6 +++---
+ src/net/mail/message_test.go | 19 +++++++++++++++++++
+ 2 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/src/net/mail/message.go b/src/net/mail/message.go
+index fc2a9e46f8..37d7ff5df1 100644
+--- a/src/net/mail/message.go
++++ b/src/net/mail/message.go
+@@ -780,7 +780,7 @@ func (p *addrParser) consumeComment() (string, bool) {
+ // '(' already consumed.
+ depth := 1
+
+- var comment string
++ var comment strings.Builder
+ for {
+ if p.empty() || depth == 0 {
+ break
+@@ -794,12 +794,12 @@ func (p *addrParser) consumeComment() (string, bool) {
+ depth--
+ }
+ if depth > 0 {
+- comment += p.s[:1]
++ comment.WriteByte(p.s[0])
+ }
+ p.s = p.s[1:]
+ }
+
+- return comment, depth == 0
++ return comment.String(), depth == 0
+ }
+
+ func (p *addrParser) decodeRFC2047Word(s string) (word string, isEncoded bool, err error) {
+diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
+index 1f2f62afbf..1b165317f9 100644
+--- a/src/net/mail/message_test.go
++++ b/src/net/mail/message_test.go
+@@ -6,6 +6,7 @@ package mail
+
+ import (
+ "bytes"
++ "fmt"
+ "io"
+ "mime"
+ "reflect"
+@@ -1217,3 +1218,21 @@ func TestEmptyAddress(t *testing.T) {
+ t.Errorf(`ParseAddressList("") = %v, %v, want nil, error`, list, err)
+ }
+ }
++
++func BenchmarkConsumeComment(b *testing.B) {
++ for _, n := range []int{10, 100, 1000, 10000} {
++ b.Run(fmt.Sprintf("depth-%d", n), func(b *testing.B) {
++ // Build a deeply nested comment: (((...a...)))
++ open := strings.Repeat("(", n)
++ close := strings.Repeat(")", n)
++ // consumeComment expects the leading '(' already consumed,
++ // so we start with one fewer opening paren and the parser
++ // will handle nesting from there.
++ input := open[:n-1] + "a" + close
++ for b.Loop() {
++ p := addrParser{s: input}
++ p.consumeComment()
++ }
++ })
++ }
++}
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 15/21] go: patch CVE-2026-39825
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (13 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 14/21] go: patch CVE-2026-39820 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 16/21] go: patch CVE-2026-39826 Jeremy Rosen
` (5 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/770541
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-39825.patch | 104 ++++++++++++++++++
2 files changed, 105 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39825.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 002d443059..952c0e4638 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -49,6 +49,7 @@ SRC_URI += "\
file://CVE-2026-39817.patch \
file://CVE-2026-39819.patch \
file://CVE-2026-39820.patch \
+ file://CVE-2026-39825.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-39825.patch b/meta/recipes-devtools/go/go/CVE-2026-39825.patch
new file mode 100644
index 0000000000..6082f5fc37
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-39825.patch
@@ -0,0 +1,104 @@
+From 96b1a3f872971fc38d9f2c0ed4a3d1f3ceeb517f Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Fri, 24 Apr 2026 14:10:47 -0700
+Subject: [PATCH] net/http/httputil: reencode queries with many parameters in
+ proxy
+
+When ReverseProxy forwards a request containing more than
+urlmaxqueryparams (GODEBUG) query parameters, reencode the
+outbound query parameters.
+
+Avoids potential smuggling of query parameters, where the
+sender sends many query parameters, the user's Rewrite hook
+fails to observe those parameters due to the limit being
+exceeded, and the request is forwarded with the full set
+of parameters.
+
+Fixes #78948
+Fixes CVE-2026-39825
+
+Change-Id: I691be7899c4b6208bf61f6b78dacfdf56a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/770541
+Reviewed-by: Nicholas Husin <nsh@golang.org>
+Reviewed-by: Nicholas Husin <husin@google.com>
+Auto-Submit: Damien Neil <dneil@google.com>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+
+CVE: CVE-2026-39825
+Upstream-Status: Backport [https://github.com/golang/go/commit/6795bb331782b33691f772d30c810b4c3a317aeb]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/net/http/httputil/reverseproxy.go | 14 ++++++++++++++
+ src/net/http/httputil/reverseproxy_test.go | 6 ++++++
+ src/net/url/url.go | 1 +
+ 3 files changed, 21 insertions(+)
+
+diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
+index 5c70f0d27b..37b0eab6b0 100644
+--- a/src/net/http/httputil/reverseproxy.go
++++ b/src/net/http/httputil/reverseproxy.go
+@@ -10,6 +10,7 @@ import (
+ "context"
+ "errors"
+ "fmt"
++ "internal/godebug"
+ "io"
+ "log"
+ "mime"
+@@ -797,11 +798,24 @@ func (c switchProtocolCopier) copyToBackend(errc chan<- error) {
+ errc <- err
+ }
+
++var urlmaxqueryparams = godebug.New("urlmaxqueryparams")
++
++// Keep this in sync with net/url.
++const defaultMaxParams = 10000
++
+ func cleanQueryParams(s string) string {
+ reencode := func(s string) string {
+ v, _ := url.ParseQuery(s)
+ return v.Encode()
+ }
++ if urlmaxqueryparams.Value() != "" {
++ // Always reencode when a non-default urlmaxqueryparams is set.
++ return reencode(s)
++ }
++ if numParams := strings.Count(s, "&") + 1; numParams > defaultMaxParams {
++ // Too many query parameters.
++ return reencode(s)
++ }
+ for i := 0; i < len(s); {
+ switch s[i] {
+ case ';':
+diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
+index dd3330b615..deb1ab9ce2 100644
+--- a/src/net/http/httputil/reverseproxy_test.go
++++ b/src/net/http/httputil/reverseproxy_test.go
+@@ -1845,6 +1845,12 @@ func testReverseProxyQueryParameterSmuggling(t *testing.T, wantCleanQuery bool,
+ }, {
+ rawQuery: "a=1&a=%zz&b=3",
+ cleanQuery: "a=1&b=3",
++ }, {
++ rawQuery: "a=%zz",
++ cleanQuery: "",
++ }, {
++ rawQuery: strings.Repeat("a=1&", 10000) + "a=1",
++ cleanQuery: "",
+ }} {
+ res, err := frontend.Client().Get(frontend.URL + "?" + test.rawQuery)
+ if err != nil {
+diff --git a/src/net/url/url.go b/src/net/url/url.go
+index 5219e3c130..41f3bef1ee 100644
+--- a/src/net/url/url.go
++++ b/src/net/url/url.go
+@@ -961,6 +961,7 @@ func ParseQuery(query string) (Values, error) {
+
+ var urlmaxqueryparams = godebug.New("urlmaxqueryparams")
+
++// Keep this in sync with net/http/httputil.
+ const defaultMaxParams = 10000
+
+ func urlParamsWithinMax(params int) bool {
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 16/21] go: patch CVE-2026-39826
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (14 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 15/21] go: patch CVE-2026-39825 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 17/21] go: patch CVE-2026-42499 Jeremy Rosen
` (4 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/771180
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-39826.patch | 65 +++++++++++++++++++
2 files changed, 66 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39826.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 952c0e4638..77e6bcd59d 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -50,6 +50,7 @@ SRC_URI += "\
file://CVE-2026-39819.patch \
file://CVE-2026-39820.patch \
file://CVE-2026-39825.patch \
+ file://CVE-2026-39826.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-39826.patch b/meta/recipes-devtools/go/go/CVE-2026-39826.patch
new file mode 100644
index 0000000000..d9fa751adc
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-39826.patch
@@ -0,0 +1,65 @@
+From 0d41a827f4d691be89c0285cd136cc45640341d4 Mon Sep 17 00:00:00 2001
+From: Neal Patel <nealpatel@google.com>
+Date: Mon, 27 Apr 2026 17:34:58 -0400
+Subject: [PATCH] html/template: fix escaper bypass by treating empty script
+ type as JavaScript
+
+Thank you to Mundur (https://github.com/M0nd0R) for reporting this issue.
+
+Fixes #78981
+Fixes CVE-2026-39826
+
+Change-Id: I3f2e06496020ece655d156fb099ff556af8cc836
+Reviewed-on: https://go-review.googlesource.com/c/go/+/771180
+Reviewed-by: Roland Shoemaker <roland@golang.org>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+
+CVE: CVE-2026-39826
+Upstream-Status: Backport [https://github.com/golang/go/commit/a63b23ffb2eebc9ca3a14c369b615ca623bb20f7]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/html/template/escape_test.go | 15 +++++++++++++++
+ src/html/template/js.go | 1 +
+ 2 files changed, 16 insertions(+)
+
+diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
+index 435c83378f..ce06440738 100644
+--- a/src/html/template/escape_test.go
++++ b/src/html/template/escape_test.go
+@@ -231,6 +231,21 @@ func TestEscape(t *testing.T) {
+ "<script>alert({{.A}})</script>",
+ `<script>alert(["\u003ca\u003e","\u003cb\u003e"])</script>`,
+ },
++ {
++ "scriptTypeSpace",
++ "<script type=\" \">{{.H}}</script>",
++ "<script type=\" \">\"\\u003cHello\\u003e\"</script>",
++ },
++ {
++ "scriptTypeTab",
++ "<script type=\"\t\">{{.H}}</script>",
++ "<script type=\"\t\">\"\\u003cHello\\u003e\"</script>",
++ },
++ {
++ "scriptTypeEmpty",
++ "<script type=\"\">{{.H}}</script>",
++ "<script type=\"\">\"\\u003cHello\\u003e\"</script>",
++ },
+ {
+ "jsObjValueNotOverEscaped",
+ "<button onclick='alert({{.A | html}})'>",
+diff --git a/src/html/template/js.go b/src/html/template/js.go
+index d911ada26d..90cf2dc982 100644
+--- a/src/html/template/js.go
++++ b/src/html/template/js.go
+@@ -459,6 +459,7 @@ func isJSType(mimeType string) bool {
+ mimeType = strings.TrimSpace(mimeType)
+ switch mimeType {
+ case
++ "",
+ "application/ecmascript",
+ "application/javascript",
+ "application/json",
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 17/21] go: patch CVE-2026-42499
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (15 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 16/21] go: patch CVE-2026-39826 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 18/21] go: patch CVE-2026-42501 Jeremy Rosen
` (3 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/771520
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-42499.patch | 91 +++++++++++++++++++
2 files changed, 92 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42499.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 77e6bcd59d..85f75f0d89 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -51,6 +51,7 @@ SRC_URI += "\
file://CVE-2026-39820.patch \
file://CVE-2026-39825.patch \
file://CVE-2026-39826.patch \
+ file://CVE-2026-42499.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-42499.patch b/meta/recipes-devtools/go/go/CVE-2026-42499.patch
new file mode 100644
index 0000000000..d4ac9b3823
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-42499.patch
@@ -0,0 +1,91 @@
+From dd339e72189d59f249786afd4021b9fb391f3562 Mon Sep 17 00:00:00 2001
+From: Neal Patel <nealpatel@google.com>
+Date: Tue, 28 Apr 2026 12:10:24 -0400
+Subject: [PATCH] net/mail: fix quadratic consumePhrase behavior
+
+Updates #78987
+Fixes CVE-2026-42499
+
+Change-Id: I8438e5dee7e6433573d4161baf8fb2151e7fbc2f
+Reviewed-on: https://go-review.googlesource.com/c/go/+/771520
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-by: Nicholas Husin <nsh@golang.org>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+
+CVE: CVE-2026-42499
+Upstream-Status: Backport [https://github.com/golang/go/commit/2c59389fcc5194aeae742fb413e55b656c22343f]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/net/mail/message.go | 23 +++++++++++++++++------
+ src/net/mail/message_test.go | 11 +++++++++++
+ 2 files changed, 28 insertions(+), 6 deletions(-)
+
+diff --git a/src/net/mail/message.go b/src/net/mail/message.go
+index 37d7ff5df1..f57742068e 100644
+--- a/src/net/mail/message.go
++++ b/src/net/mail/message.go
+@@ -567,8 +567,10 @@ func (p *addrParser) consumeAddrSpec() (spec string, err error) {
+ func (p *addrParser) consumePhrase() (phrase string, err error) {
+ debug.Printf("consumePhrase: [%s]", p.s)
+ // phrase = 1*word
+- var words []string
+- var isPrevEncoded bool
++ var (
++ words []string
++ sb strings.Builder
++ )
+ for {
+ // obs-phrase allows CFWS after one word
+ if len(words) > 0 {
+@@ -600,13 +602,22 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
+ break
+ }
+ debug.Printf("consumePhrase: consumed %q", word)
+- if isPrevEncoded && isEncoded {
+- words[len(words)-1] += word
+- } else {
++ switch {
++ case isEncoded:
++ sb.WriteString(word)
++ case !isEncoded && sb.Len() > 0:
++ words = append(words, sb.String())
++ sb.Reset()
++ words = append(words, word)
++ default:
+ words = append(words, word)
+ }
+- isPrevEncoded = isEncoded
+ }
++
++ if sb.Len() > 0 {
++ words = append(words, sb.String())
++ }
++
+ // Ignore any error if we got at least one word.
+ if err != nil && len(words) == 0 {
+ debug.Printf("consumePhrase: hit err: %v", err)
+diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
+index 1b165317f9..27837a9cbd 100644
+--- a/src/net/mail/message_test.go
++++ b/src/net/mail/message_test.go
+@@ -1219,6 +1219,17 @@ func TestEmptyAddress(t *testing.T) {
+ }
+ }
+
++func BenchmarkConsumePhrase(b *testing.B) {
++ for _, n := range []int{10, 100, 1000, 10000} {
++ b.Run(fmt.Sprintf("words-%d", n), func(b *testing.B) {
++ input := strings.Repeat("=?utf-8?q?hello?= ", n) + "<user@example.com>"
++ for b.Loop() {
++ (&addrParser{s: input}).consumePhrase()
++ }
++ })
++ }
++}
++
+ func BenchmarkConsumeComment(b *testing.B) {
+ for _, n := range []int{10, 100, 1000, 10000} {
+ b.Run(fmt.Sprintf("depth-%d", n), func(b *testing.B) {
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 18/21] go: patch CVE-2026-42501
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (16 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 17/21] go: patch CVE-2026-42499 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 19/21] go: patch CVE-2026-42504 Jeremy Rosen
` (2 subsequent siblings)
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/775321
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-42501.patch | 127 ++++++++++++++++++
2 files changed, 128 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42501.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 85f75f0d89..03a1a81fc3 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -52,6 +52,7 @@ SRC_URI += "\
file://CVE-2026-39825.patch \
file://CVE-2026-39826.patch \
file://CVE-2026-42499.patch \
+ file://CVE-2026-42501.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-42501.patch b/meta/recipes-devtools/go/go/CVE-2026-42501.patch
new file mode 100644
index 0000000000..82b2fa02a1
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-42501.patch
@@ -0,0 +1,127 @@
+From 52d8958ce7e102a5ebd3b4748aa03989b5469084 Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Thu, 30 Apr 2026 13:10:49 -0700
+Subject: [PATCH] cmd/go: reject sumdb response lacking module hash
+
+Report an error when a sumdb /lookup/ request does not
+include a hash for the requested module, rather than
+silently proceeding.
+
+Previously, we would verify that a returned sum matched
+the expected module hash, but did not verify that the
+response contained a sum. This permits a malicous
+proxy to serve a corrupted module along with a
+valid-but-irrelevant sumdb response for some other
+module. We now ensure that the sumdb response contains
+a valid hash for the module we are validating.
+
+Thanks to Mundur (https://github.com/M0nd0R) for reporting this issue.
+
+Fixes CVE-2026-42501
+Fixes #79070
+
+Change-Id: I7d9a367deb237aa70cade2434495998f6a6a6964
+Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/4340
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-by: Neal Patel <nealpatel@google.com>
+Reviewed-on: https://go-review.googlesource.com/c/go/+/775321
+Reviewed-by: Michael Pratt <mpratt@google.com>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+
+CVE: CVE-2026-42501
+Upstream-Status: Backport [https://github.com/golang/go/commit/1a9af07120312d368815712a4dce2dd2070342e5]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/cmd/go/internal/modfetch/fetch.go | 15 ++++++++++++++-
+ src/cmd/go/proxy_test.go | 17 +++++++++++++++++
+ src/cmd/go/testdata/script/mod_sum_absent.txt | 17 +++++++++++++++++
+ 3 files changed, 48 insertions(+), 1 deletion(-)
+ create mode 100644 src/cmd/go/testdata/script/mod_sum_absent.txt
+
+diff --git a/src/cmd/go/internal/modfetch/fetch.go b/src/cmd/go/internal/modfetch/fetch.go
+index eeab6da62a..75769d7c61 100644
+--- a/src/cmd/go/internal/modfetch/fetch.go
++++ b/src/cmd/go/internal/modfetch/fetch.go
+@@ -740,7 +740,7 @@ func checkSumDB(mod module.Version, h string) error {
+ return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum mismatch\n\tdownloaded: %v\n\t%s: %v"+sumdbMismatch, noun, h, db, line[len(prefix)-len("h1:"):]))
+ }
+ }
+- return nil
++ return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum missing from sumdb response"+sumdbAbsent, noun))
+ }
+
+ // Sum returns the checksum for the downloaded copy of the given module,
+@@ -931,6 +931,19 @@ have intercepted the download attempt.
+ For more information, see 'go help module-auth'.
+ `
+
++const sumdbAbsent = `
++
++SECURITY ERROR
++This download does NOT match one reported by the checksum server.
++The checksum server has provided checksums, but the checksums do
++not contain an entry for the download.
++The checksum server may be malfunctioning, or an attacker may have
++intercepted the checksum request.
++The download cannot be verified.
++
++For more information, see 'go help module-auth'.
++`
++
+ const hashVersionMismatch = `
+
+ SECURITY WARNING
+diff --git a/src/cmd/go/proxy_test.go b/src/cmd/go/proxy_test.go
+index cb3d9f92f1..88e5052b89 100644
+--- a/src/cmd/go/proxy_test.go
++++ b/src/cmd/go/proxy_test.go
+@@ -172,6 +172,23 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) {
+ return
+ }
+
++ // Request for $GOPROXY/sumdb-redirect/module@version:/lookup/...
++ // performs a lookup for module@version rather than the requested module.
++ if strings.HasPrefix(path, "sumdb-redirect/") {
++ redirect, rest, ok := strings.Cut(path[len("sumdb-redirect"):], ":")
++ if !ok {
++ w.WriteHeader(500)
++ return
++ }
++ if strings.HasPrefix(rest, "/lookup/") {
++ r.URL.Path = "/lookup" + redirect
++ } else {
++ r.URL.Path = rest
++ }
++ sumdbServer.ServeHTTP(w, r)
++ return
++ }
++
+ // Request for $GOPROXY/redirect/<count>/... goes to redirects.
+ if strings.HasPrefix(path, "redirect/") {
+ path = path[len("redirect/"):]
+diff --git a/src/cmd/go/testdata/script/mod_sum_absent.txt b/src/cmd/go/testdata/script/mod_sum_absent.txt
+new file mode 100644
+index 0000000000..c2dd814542
+--- /dev/null
++++ b/src/cmd/go/testdata/script/mod_sum_absent.txt
+@@ -0,0 +1,17 @@
++# When the sumdb returns a response which does not
++# include a sum for the requested module,
++# we should report an error.
++# Verifies CVE-2026-42501.
++env sumdb=$GOSUMDB
++env proxy=$GOPROXY
++env GOPROXY GONOPROXY GOSUMDB GONOSUMDB
++
++# /sumdb-redirect/ causes the sumdb to return /lookup/ responses
++# for rsc.io/quote@v1.0.0, not for the requested module.
++env GOSUMDB=$sumdb' '$proxy/sumdb-redirect/rsc.io/quote@v1.0.0:
++
++! go get rsc.io/fortune@v1.0.0
++stderr 'SECURITY ERROR'
++! grep rsc.io go.sum
++-- go.mod --
++module m
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 19/21] go: patch CVE-2026-42504
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (17 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 18/21] go: patch CVE-2026-42501 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 20/21] go: patch CVE-2026-42507 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 21/21] meta/lib/oe/package.py: fix path to kernel sources in save_debugsources_info Jeremy Rosen
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/774481
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Reviewed-by: Bruno Vernay <bruno.vernay@se.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-42504.patch | 58 +++++++++++++++++++
2 files changed, 59 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42504.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index 03a1a81fc3..ba4fe9a734 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -53,6 +53,7 @@ SRC_URI += "\
file://CVE-2026-39826.patch \
file://CVE-2026-42499.patch \
file://CVE-2026-42501.patch \
+ file://CVE-2026-42504.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-42504.patch b/meta/recipes-devtools/go/go/CVE-2026-42504.patch
new file mode 100644
index 0000000000..1ae104ae19
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-42504.patch
@@ -0,0 +1,58 @@
+From 41ca50d68cd74e0a68f3917cd902885c84fedbf7 Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Tue, 5 May 2026 15:20:34 -0700
+Subject: [PATCH] mime: avoid quadratic complexity in WordDecoder.DecodeHeader
+
+When encountering an undecodable encoded-word,
+skip over the entire word rather than just the initial "=?".
+
+Fixes #79217
+Fixes CVE-2026-42504
+
+Change-Id: I28605faa235459d2ba71bd0f3ae3dce96a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/774481
+Reviewed-by: Nicholas Husin <nsh@golang.org>
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Reviewed-by: Nicholas Husin <husin@google.com>
+
+CVE: CVE-2026-42504
+Upstream-Status: Backport [https://github.com/golang/go/commit/f230dd8a1d0a63d73e92685e378dcd725f7aac00]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/mime/encodedword.go | 4 ++--
+ src/mime/encodedword_test.go | 4 ++++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/mime/encodedword.go b/src/mime/encodedword.go
+index e6b470b1fb..a7059f3bc4 100644
+--- a/src/mime/encodedword.go
++++ b/src/mime/encodedword.go
+@@ -275,8 +275,8 @@ func (d *WordDecoder) DecodeHeader(header string) (string, error) {
+ content, err := decode(encoding, text)
+ if err != nil {
+ betweenWords = false
+- buf.WriteString(header[:start+2])
+- header = header[start+2:]
++ buf.WriteString(header[:end])
++ header = header[end:]
+ continue
+ }
+
+diff --git a/src/mime/encodedword_test.go b/src/mime/encodedword_test.go
+index 2a98794380..befc3cd996 100644
+--- a/src/mime/encodedword_test.go
++++ b/src/mime/encodedword_test.go
+@@ -140,6 +140,10 @@ func TestDecodeHeader(t *testing.T) {
+ {"=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=", "ab"},
+ {"=?ISO-8859-1?Q?a?= \r\n\t =?ISO-8859-1?Q?b?=", "ab"},
+ {"=?ISO-8859-1?Q?a_b?=", "a b"},
++ // Undecodable words
++ {"=?UTF-8?b?garbage?= =?UTF-8?b?QW5kcsOp?= =?UTF-8?b?garbage?=", "=?UTF-8?b?garbage?= André =?UTF-8?b?garbage?="},
++ {"=?UTF-8?b?QW5kcsOp", "=?UTF-8?b?QW5kcsOp"},
++ {"=?UTF-8?x?y?=?UTF-8?x?y=?", "=?UTF-8?x?y?=?UTF-8?x?y=?"},
+ }
+
+ for _, test := range tests {
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 20/21] go: patch CVE-2026-42507
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (18 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 19/21] go: patch CVE-2026-42504 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 21/21] meta/lib/oe/package.py: fix path to kernel sources in save_debugsources_info Jeremy Rosen
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: "Theo Gaige (Schneider Electric)" <tgaige.opensource@witekio.com>
Backport patch from [1]
[1] https://go.dev/cl/777060
Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/recipes-devtools/go/go-1.22.12.inc | 1 +
.../go/go/CVE-2026-42507.patch | 160 ++++++++++++++++++
2 files changed, 161 insertions(+)
create mode 100644 meta/recipes-devtools/go/go/CVE-2026-42507.patch
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc
index ba4fe9a734..f67da3e078 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -54,6 +54,7 @@ SRC_URI += "\
file://CVE-2026-42499.patch \
file://CVE-2026-42501.patch \
file://CVE-2026-42504.patch \
+ file://CVE-2026-42507.patch \
"
SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
diff --git a/meta/recipes-devtools/go/go/CVE-2026-42507.patch b/meta/recipes-devtools/go/go/CVE-2026-42507.patch
new file mode 100644
index 0000000000..d48b2b53eb
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2026-42507.patch
@@ -0,0 +1,160 @@
+From 943e53a7b667a1570648b5f1c4592b9d9d5b4aac Mon Sep 17 00:00:00 2001
+From: "Nicholas S. Husin" <nsh@golang.org>
+Date: Mon, 11 May 2026 18:04:07 -0400
+Subject: [PATCH] net/textproto: escape arbitrary input when including them in
+ errors
+
+When returning errors, functions in the net/textproto package would
+include its input as part of the error, without any escaping. Note that
+said input is often controlled by external parties when using this
+package naturally. For example, a net/http client uses ReadMIMEHeader
+when parsing the headers it receive from a server.
+
+As a result, an attacker could inject arbitrary content into the error.
+Practically, this can result in an attacker injecting misleading
+content, terminal control bytes, etc. into a victim's output or logs.
+
+Fix this issue by making sure that ProtocolError usages within the
+package are properly escaped, and that Error.String will escape its Msg.
+
+Fixes #79346
+Fixes CVE-2026-42507
+
+Change-Id: Ide4c1005d8254f90d95d7a389b8ca3a26a6a6964
+Reviewed-on: https://go-review.googlesource.com/c/go/+/777060
+LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
+Reviewed-by: Roland Shoemaker <roland@golang.org>
+Reviewed-by: Nicholas Husin <husin@google.com>
+Reviewed-by: Damien Neil <dneil@google.com>
+
+CVE: CVE-2026-42507
+Upstream-Status: Backport [https://github.com/golang/go/commit/1a7e601d07b67aec8d795c8182ee7257ba7d1960]
+Signed-off-by: Theo Gaige (Schneider Electric) <tgaige.opensource@witekio.com>
+---
+ src/net/smtp/smtp_test.go | 6 +++---
+ src/net/textproto/reader.go | 14 +++++++-------
+ src/net/textproto/reader_test.go | 6 ++++--
+ src/net/textproto/textproto.go | 2 +-
+ 4 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go
+index 259b10b93d..3e03da5208 100644
+--- a/src/net/smtp/smtp_test.go
++++ b/src/net/smtp/smtp_test.go
+@@ -664,7 +664,7 @@ func TestHello(t *testing.T) {
+ err = c.Hello("customhost")
+ case 1:
+ err = c.StartTLS(nil)
+- if err.Error() == "502 Not implemented" {
++ if err.Error() == `502 "Not implemented"` {
+ err = nil
+ }
+ case 2:
+@@ -922,8 +922,8 @@ func TestAuthFailed(t *testing.T) {
+
+ if err == nil {
+ t.Error("Auth: expected error; got none")
+- } else if err.Error() != "535 Invalid credentials\nplease see www.example.com" {
+- t.Errorf("Auth: got error: %v, want: %s", err, "535 Invalid credentials\nplease see www.example.com")
++ } else if err.Error() != `535 "Invalid credentials\nplease see www.example.com"` {
++ t.Errorf("Auth: got error: %v, want: %s", err, `535 "Invalid credentials\nplease see www.example.com"`)
+ }
+
+ bcmdbuf.Flush()
+diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go
+index 0027efe3ca..b4cd22a6ed 100644
+--- a/src/net/textproto/reader.go
++++ b/src/net/textproto/reader.go
+@@ -213,13 +213,13 @@ func (r *Reader) readCodeLine(expectCode int) (code int, continued bool, message
+
+ func parseCodeLine(line string, expectCode int) (code int, continued bool, message string, err error) {
+ if len(line) < 4 || line[3] != ' ' && line[3] != '-' {
+- err = ProtocolError("short response: " + line)
++ err = ProtocolError(fmt.Sprintf("short response: %q", line))
+ return
+ }
+ continued = line[3] == '-'
+ code, err = strconv.Atoi(line[0:3])
+ if err != nil || code < 100 {
+- err = ProtocolError("invalid response code: " + line)
++ err = ProtocolError(fmt.Sprintf("invalid response code: %q", line))
+ return
+ }
+ message = line[4:]
+@@ -251,7 +251,7 @@ func parseCodeLine(line string, expectCode int) (code int, continued bool, messa
+ func (r *Reader) ReadCodeLine(expectCode int) (code int, message string, err error) {
+ code, continued, message, err := r.readCodeLine(expectCode)
+ if err == nil && continued {
+- err = ProtocolError("unexpected multi-line response: " + message)
++ err = ProtocolError(fmt.Sprintf("unexpected multi-line response: %q", message))
+ }
+ return
+ }
+@@ -536,7 +536,7 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
+ if err != nil {
+ return m, err
+ }
+- return m, ProtocolError("malformed MIME header initial line: " + string(line))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header initial line: %q", line))
+ }
+
+ for {
+@@ -548,15 +548,15 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
+ // Key ends at first colon.
+ k, v, ok := bytes.Cut(kv, colon)
+ if !ok {
+- return m, ProtocolError("malformed MIME header line: " + string(kv))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header line: %q", kv))
+ }
+ key, ok := canonicalMIMEHeaderKey(k)
+ if !ok {
+- return m, ProtocolError("malformed MIME header line: " + string(kv))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header line: %q", kv))
+ }
+ for _, c := range v {
+ if !validHeaderValueByte(c) {
+- return m, ProtocolError("malformed MIME header line: " + string(kv))
++ return m, ProtocolError(fmt.Sprintf("malformed MIME header line: %q", kv))
+ }
+ }
+
+diff --git a/src/net/textproto/reader_test.go b/src/net/textproto/reader_test.go
+index 26ff617470..844069a4ad 100644
+--- a/src/net/textproto/reader_test.go
++++ b/src/net/textproto/reader_test.go
+@@ -409,6 +409,8 @@ func TestReadMultiLineError(t *testing.T) {
+ "Unexpected but legal text!\n" +
+ "5.1.1 https://support.google.com/mail/answer/6596 h20si25154304pfd.166 - gsmtp"
+
++ wantError := `550 "5.1.1 The email account that you tried to reach does not exist. Please try\n5.1.1 double-checking the recipient's email address for typos or\n5.1.1 unnecessary spaces. Learn more at\nUnexpected but legal text!\n5.1.1 https://support.google.com/mail/answer/6596 h20si25154304pfd.166 - gsmtp"`
++
+ code, msg, err := r.ReadResponse(250)
+ if err == nil {
+ t.Errorf("ReadResponse: no error, want error")
+@@ -419,8 +421,8 @@ func TestReadMultiLineError(t *testing.T) {
+ if msg != wantMsg {
+ t.Errorf("ReadResponse: msg=%q, want %q", msg, wantMsg)
+ }
+- if err != nil && err.Error() != "550 "+wantMsg {
+- t.Errorf("ReadResponse: error=%q, want %q", err.Error(), "550 "+wantMsg)
++ if err != nil && err.Error() != wantError {
++ t.Errorf("ReadResponse: error=%q, want %q", err.Error(), wantError)
+ }
+ }
+
+diff --git a/src/net/textproto/textproto.go b/src/net/textproto/textproto.go
+index 4ae3ecff74..a2291eff2b 100644
+--- a/src/net/textproto/textproto.go
++++ b/src/net/textproto/textproto.go
+@@ -38,7 +38,7 @@ type Error struct {
+ }
+
+ func (e *Error) Error() string {
+- return fmt.Sprintf("%03d %s", e.Code, e.Msg)
++ return fmt.Sprintf("%03d %q", e.Code, e.Msg)
+ }
+
+ // A ProtocolError describes a protocol violation such
+--
+2.43.0
+
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* [OE-core][scarthgap 21/21] meta/lib/oe/package.py: fix path to kernel sources in save_debugsources_info
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
` (19 preceding siblings ...)
2026-06-12 14:26 ` [OE-core][scarthgap 20/21] go: patch CVE-2026-42507 Jeremy Rosen
@ 2026-06-12 14:26 ` Jeremy Rosen
20 siblings, 0 replies; 24+ messages in thread
From: Jeremy Rosen @ 2026-06-12 14:26 UTC (permalink / raw)
To: openembedded-core; +Cc: Paul Barker
From: João Marcos Costa (Schneider Electric) <joaomarcos.costa@bootlin.com>
This is no more than a backport of the current (i.e., from 'master')
version of this same chunk in save_debugsources_info(), where BP is used
instead of PF to form the path to the kernel sources.
This replacement in package.py is followed by a similar change in
meta/classes/create-spdx-2.2.bbclass, so that 'BP' is also used in
spdx_get_src() and we don't face any regressions in SPDX v2.2. As a
matter of fact, SPDX3 also uses 'BP' in get_patched_src() (from
spdx_common.py).
Overall, this backport ensures a coherence between Scarthgap and master,
namely regarding the how the kernel sources are provided by package.py
and consumed by SPDX v2.2 and 3.0.
Signed-off-by: João Marcos Costa (Schneider Electric) <joaomarcos.costa@bootlin.com>
Co-authored-by: Benjamin Robin (Schneider Electric) <benjamin.robin@bootlin.com>
Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
---
meta/classes/create-spdx-2.2.bbclass | 2 +-
meta/lib/oe/package.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/meta/classes/create-spdx-2.2.bbclass b/meta/classes/create-spdx-2.2.bbclass
index 037193bb4b..61bad66ae0 100644
--- a/meta/classes/create-spdx-2.2.bbclass
+++ b/meta/classes/create-spdx-2.2.bbclass
@@ -933,7 +933,7 @@ def spdx_get_src(d):
share_src = d.getVar('WORKDIR')
d.setVar('WORKDIR', spdx_workdir)
d.setVar('STAGING_DIR_NATIVE', spdx_sysroot_native)
- src_dir = spdx_workdir + "/" + d.getVar('PN')+ "-" + d.getVar('PV') + "-" + d.getVar('PR')
+ src_dir = spdx_workdir + "/" + d.getVar('BP')
bb.utils.mkdirhier(src_dir)
if bb.data.inherits_class('kernel',d):
share_src = d.getVar('STAGING_KERNEL_DIR')
diff --git a/meta/lib/oe/package.py b/meta/lib/oe/package.py
index ba0d326781..fc5185ced4 100644
--- a/meta/lib/oe/package.py
+++ b/meta/lib/oe/package.py
@@ -1055,13 +1055,13 @@ def save_debugsources_info(debugsrcdir, sources_raw, d):
# we format the sources as expected by spdx by replacing /usr/src/kernel/
# into BP/
kernel_src = d.getVar('KERNEL_SRC_PATH')
- pf = d.getVar('PF')
+ bp = d.getVar('BP')
sources_dict = {}
for file, src_files in sources_raw:
file_clean = file.replace(f"{workdir}/package/","")
sources_clean = [
src.replace(f"{debugsrcdir}/{pn}/", "")
- if not kernel_src else src.replace(f"{kernel_src}/", f"{pf}/")
+ if not kernel_src else src.replace(f"{kernel_src}/", f"{bp}/")
for src in src_files
if not any(keyword in src for keyword in ("<internal>", "<built-in>")) and not src.endswith("/")
]
--
2.53.0
^ permalink raw reply related [flat|nested] 24+ messages in thread
* Re: [OE-core][scarthgap 03/21] nfs-utils: fix CVE-2025-12801
2026-06-12 14:25 ` [OE-core][scarthgap 03/21] nfs-utils: fix CVE-2025-12801 Jeremy Rosen
@ 2026-06-15 7:59 ` Paul Barker
2026-06-16 7:43 ` [scarthgap " Sudhir Dumbhare
0 siblings, 1 reply; 24+ messages in thread
From: Paul Barker @ 2026-06-15 7:59 UTC (permalink / raw)
To: jeremy.rosen, openembedded-core; +Cc: Sudhir Dumbhare, Yoann Congal
[-- Attachment #1: Type: text/plain, Size: 4773 bytes --]
On Fri, 2026-06-12 at 16:25 +0200, Jérémy Rosen via
lists.openembedded.org wrote:
> From: Sudhir Dumbhare <sudumbha@cisco.com>
+Cc Sudhir
>
> - This patch applies the upstream fix [5] as referenced in [7].
> - To successfully apply the fixed commit, apply the dependent commits [2] to [4]
> which are included in v2.8.6, as referenced in [7].
> - Additionally, include dependent commit [1] from v2.8.3, as referenced in [8]
> under the [2.5.4-38.2] description, along with compilation fix commit [6]
> from v2.7.1
> - Reference:
> [1] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=cd90f2925790
> [2] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=7e8b36522f58
> [3] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=42f01e6a78fe
> [4] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=51738ae56d92
> [5] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=f36bd900a899
> [6] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=a2c95e4f557a
> [7] https://security-tracker.debian.org/tracker/CVE-2025-12801
> [8] https://linux.oracle.com/errata/ELSA-2026-3940.html
>
> Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
> Signed-off-by: Jeremy Rosen <jeremy.rosen@smile.fr>
[snip]
> diff --git a/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch
> new file mode 100644
> index 0000000000..223249a9d6
> --- /dev/null
> +++ b/meta/recipes-connectivity/nfs-utils/nfs-utils/CVE-2025-12801-dependent_p1.patch
> @@ -0,0 +1,71 @@
> +From 647c9cb3ac3cbdf9ffd9e29f7d5dd04da84afdbc Mon Sep 17 00:00:00 2001
> +From: Christopher Bii <christopherbii@hyub.org>
> +Date: Wed, 15 Jan 2025 12:10:48 -0500
> +Subject: [PATCH] NFS export symlink vulnerability fix
> +
> +Replaced dangerous use of realpath within support/nfs/export.c with
> +nfsd_realpath variant that is executed within the chrooted thread
> +rather than main thread.
> +
> +Implemented nfsd_path.h methods to work securely within chrooted
> +thread using nfsd_run_task() help
> +
> +CVE: CVE-2025-12801
> +Upstream-Status: Backport [https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=cd90f29257904f36509ea5a04a86f42398fbe94a]
> +
> +Backport Changes:
> +- In support/misc/nfsd_path.c file, only nfsd_run_task() and the
> + struct nfsd_task_t have been included to resolve a compilation
> + issue. All other non-essential changes were excluded.
> +- The non-required file support/export/cache.c and support/nfs/exports.c
> + has been excluded.
> +
> +Signed-off-by: Christopher Bii <christopherbii@hyub.org>
> +Signed-off-by: Steve Dickson <steved@redhat.com>
> +(cherry picked from commit cd90f29257904f36509ea5a04a86f42398fbe94a)
> +Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
> +---
> + support/include/nfsd_path.h | 1 +
> + support/misc/nfsd_path.c | 14 +++++++++++++-
> + 2 files changed, 14 insertions(+), 1 deletion(-)
> +
> +diff --git a/support/include/nfsd_path.h b/support/include/nfsd_path.h
> +index aa1e1dd0..4f5fc44e 100644
> +--- a/support/include/nfsd_path.h
> ++++ b/support/include/nfsd_path.h
> +@@ -8,6 +8,7 @@
> +
> + struct file_handle;
> + struct statfs;
> ++struct nfsd_task_t;
> +
> + void nfsd_path_init(void);
> +
> +diff --git a/support/misc/nfsd_path.c b/support/misc/nfsd_path.c
> +index c3dea4f0..fa908f7c 100644
> +--- a/support/misc/nfsd_path.c
> ++++ b/support/misc/nfsd_path.c
> +@@ -19,7 +19,19 @@
> + #include "nfsd_path.h"
> + #include "workqueue.h"
> +
> +-static struct xthread_workqueue *nfsd_wq;
> ++static struct xthread_workqueue *nfsd_wq = NULL;
> ++
> ++struct nfsd_task_t {
> ++ int ret;
> ++ void* data;
> ++};
> ++/* Function used to offload tasks that must be ran within the correct
> ++ * chroot environment.
> ++ */
> ++static void
> ++nfsd_run_task(void (*func)(void*), void* data){
> ++ nfsd_wq ? xthread_work_run_sync(nfsd_wq, func, data) : func(data);
> ++};
> +
> + static int
> + nfsd_path_isslash(const char *path)
> +--
> +2.35.6
> +
Reading the commit message, and looking at the diff in the original
commit [1], I think we should apply the complete patch here. And it
seems that's what RedHat have done when backporting this fix for RHEL
9 [2].
Sudhir, what's the reason for trimming the patch down?
[1]: https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=cd90f29257904f36509ea5a04a86f42398fbe94a
[2]: https://gitlab.com/redhat/centos-stream/rpms/nfs-utils/-/commit/6f332316f7aa605d67f6b60db0be68f63bf28f9c
Best regards,
--
Paul Barker
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 252 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
* Re: [scarthgap 03/21] nfs-utils: fix CVE-2025-12801
2026-06-15 7:59 ` Paul Barker
@ 2026-06-16 7:43 ` Sudhir Dumbhare
0 siblings, 0 replies; 24+ messages in thread
From: Sudhir Dumbhare @ 2026-06-16 7:43 UTC (permalink / raw)
To: openembedded-core
[-- Attachment #1: Type: text/plain, Size: 1400 bytes --]
Hi Paul,
Thank you for pointing this out and for referencing both the original upstream commit and the RHEL backport.
When applying the upstream change, including prerequisites [1][2][3] and the fix [4], as noted in [6],
we observed the following compilation failure on scarthgap with nfs-utils v2.6.4:
nfsd_path.c:322:17: error: implicit declaration of function 'nfsd_run_task'
Because of this, we backported only the required changes from [5], specifically nfsd_run_task() and
struct nfsd_task_t, to support the fix. Non-essential parts were trimmed to keep the patch minimal
and build-safe for scarthgap.
Please let us know if you would prefer us to align with the full backport, similar to the RHEL approach.
References:
[1] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=7e8b36522f58657359c6842119fc516c6dd1baa4
[2] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=42f01e6a78fed98f12437ac8b28cfb12b6bad056
[3] https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=51738ae56d922d4961e60dad73ad1c2d97d8d99b
[4] Fixed by: https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=f36bd900a899088ca1925de079bd58d6205a1f3c
[5] Dependent patch: https://git.linux-nfs.org/?p=steved/nfs-utils.git;a=commit;h=cd90f29257904f36509ea5a04a86f42398fbe94a
[6] https://security-tracker.debian.org/tracker/CVE-2025-12801
Thanks and regards,
Sudhir
[-- Attachment #2: Type: text/html, Size: 1499 bytes --]
^ permalink raw reply [flat|nested] 24+ messages in thread
end of thread, other threads:[~2026-06-16 7:43 UTC | newest]
Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-12 14:25 [OE-core][scarthgap 00/21] Patch review Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 01/21] libpng: Fix CVE-2026-33416 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 02/21] busybox: Fix CVE-2026-29004 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 03/21] nfs-utils: fix CVE-2025-12801 Jeremy Rosen
2026-06-15 7:59 ` Paul Barker
2026-06-16 7:43 ` [scarthgap " Sudhir Dumbhare
2026-06-12 14:25 ` [OE-core][scarthgap 04/21] xz: Fix CVE-2026-34743 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 05/21] util-linux: Fix CVE-2026-27456 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 06/21] devtool: prevent 'devtool modify -n' from corrupting kernel Git repos Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 07/21] go: patch CVE-2026-27142 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 08/21] go: patch CVE-2026-32280 Jeremy Rosen
2026-06-12 14:25 ` [OE-core][scarthgap 09/21] go: patch CVE-2026-32283 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 10/21] go: patch CVE-2026-32289 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 11/21] go: patch CVE-2026-33811 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 12/21] go: patch CVE-2026-39817 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 13/21] go: patch CVE-2026-39819 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 14/21] go: patch CVE-2026-39820 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 15/21] go: patch CVE-2026-39825 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 16/21] go: patch CVE-2026-39826 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 17/21] go: patch CVE-2026-42499 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 18/21] go: patch CVE-2026-42501 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 19/21] go: patch CVE-2026-42504 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 20/21] go: patch CVE-2026-42507 Jeremy Rosen
2026-06-12 14:26 ` [OE-core][scarthgap 21/21] meta/lib/oe/package.py: fix path to kernel sources in save_debugsources_info Jeremy Rosen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.