* [OE-core][kirkstone 1/8] tiff: fix CVE-2025-8176
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 2/8] tiff: fix CVE-2025-8177 Steve Sakoman
` (6 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Yogita Urade <yogita.urade@windriver.com>
A vulnerability was found in LibTIFF up to 4.7.0. It has
been declared as critical. This vulnerability affects the
function get_histogram of the file tools/tiffmedian.c. The
manipulation leads to use after free. The attack needs to
be approached locally. The exploit has been disclosed to
the public and may be used. The patch is identified as
fe10872e53efba9cc36c66ac4ab3b41a839d5172. It is recommended
to apply a patch to fix this issue.
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2025-8176
Upstream patches:
https://gitlab.com/libtiff/libtiff/-/commit/3994cf3b3bc6b54c32f240ca5a412cffa11633fa
https://gitlab.com/libtiff/libtiff/-/commit/ce46f002eca4148497363f80fab33f9396bcbeda
https://gitlab.com/libtiff/libtiff/-/commit/ecc4ddbf1f0fed7957d1e20361e37f01907898e0
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
.../libtiff/tiff/CVE-2025-8176-0001.patch | 61 +++++++++++++++++++
.../libtiff/tiff/CVE-2025-8176-0002.patch | 31 ++++++++++
.../libtiff/tiff/CVE-2025-8176-0003.patch | 28 +++++++++
meta/recipes-multimedia/libtiff/tiff_4.3.0.bb | 3 +
4 files changed, 123 insertions(+)
create mode 100644 meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0001.patch
create mode 100644 meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0002.patch
create mode 100644 meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0003.patch
diff --git a/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0001.patch b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0001.patch
new file mode 100644
index 0000000000..83dc695528
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0001.patch
@@ -0,0 +1,61 @@
+From 3994cf3b3bc6b54c32f240ca5a412cffa11633fa Mon Sep 17 00:00:00 2001
+From: Lee Howard <faxguy@howardsilvan.com>
+Date: Mon, 19 May 2025 10:53:30 -0700
+Subject: [PATCH] Don't skip the first line of the input image. Addresses
+ issue #703
+
+CVE: CVE-2025-8176
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/3994cf3b3bc6b54c32f240ca5a412cffa11633fa]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ tools/tiffdither.c | 4 ++--
+ tools/tiffmedian.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/tools/tiffdither.c b/tools/tiffdither.c
+index 062fd60..d352554 100644
+--- a/tools/tiffdither.c
++++ b/tools/tiffdither.c
+@@ -95,7 +95,7 @@ fsdither(TIFF* in, TIFF* out)
+ nextptr = nextline;
+ for (j = 0; j < imagewidth; ++j)
+ *nextptr++ = *inptr++;
+- for (i = 1; i < imagelength; ++i) {
++ for (i = 0; i < imagelength; ++i) {
+ tmpptr = thisline;
+ thisline = nextline;
+ nextline = tmpptr;
+@@ -138,7 +138,7 @@ fsdither(TIFF* in, TIFF* out)
+ nextptr[0] += v / 16;
+ }
+ }
+- if (TIFFWriteScanline(out, outline, i-1, 0) < 0)
++ if (TIFFWriteScanline(out, outline, i, 0) < 0)
+ goto skip_on_error;
+ }
+ goto exit_label;
+diff --git a/tools/tiffmedian.c b/tools/tiffmedian.c
+index 93a1741..93e57cf 100644
+--- a/tools/tiffmedian.c
++++ b/tools/tiffmedian.c
+@@ -844,7 +844,7 @@ quant_fsdither(TIFF* in, TIFF* out)
+ outline = (unsigned char *) _TIFFmalloc(TIFFScanlineSize(out));
+
+ GetInputLine(in, 0, goto bad); /* get first line */
+- for (i = 1; i <= imagelength; ++i) {
++ for (i = 0; i <= imagelength; ++i) {
+ SWAP(short *, thisline, nextline);
+ lastline = (i >= imax);
+ if (i <= imax)
+@@ -915,7 +915,7 @@ quant_fsdither(TIFF* in, TIFF* out)
+ nextptr += 3;
+ }
+ }
+- if (TIFFWriteScanline(out, outline, i-1, 0) < 0)
++ if (TIFFWriteScanline(out, outline, i, 0) < 0)
+ break;
+ }
+ bad:
+--
+2.40.0
diff --git a/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0002.patch b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0002.patch
new file mode 100644
index 0000000000..c28969e1d8
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0002.patch
@@ -0,0 +1,31 @@
+From ce46f002eca4148497363f80fab33f9396bcbeda Mon Sep 17 00:00:00 2001
+From: Lee Howard <faxguy@howardsilvan.com>
+Date: Sat, 24 May 2025 21:25:16 -0700
+Subject: [PATCH] Fix tiffmedian bug #707
+
+CVE: CVE-2025-8176
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/ce46f002eca4148497363f80fab33f9396bcbeda]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ tools/tiffmedian.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/tools/tiffmedian.c b/tools/tiffmedian.c
+index 93e57cf..a0b4b5d 100644
+--- a/tools/tiffmedian.c
++++ b/tools/tiffmedian.c
+@@ -385,7 +385,10 @@ get_histogram(TIFF* in, Colorbox* box)
+ }
+ for (i = 0; i < imagelength; i++) {
+ if (TIFFReadScanline(in, inputline, i, 0) <= 0)
+- break;
++ {
++ fprintf(stderr, "Error reading scanline\n");
++ exit(EXIT_FAILURE);
++ }
+ inptr = inputline;
+ for (j = imagewidth; j-- > 0;) {
+ red = (*inptr++) & 0xff >> COLOR_SHIFT;
+--
+2.40.0
diff --git a/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0003.patch b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0003.patch
new file mode 100644
index 0000000000..b5ee36c5b8
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8176-0003.patch
@@ -0,0 +1,28 @@
+From ecc4ddbf1f0fed7957d1e20361e37f01907898e0 Mon Sep 17 00:00:00 2001
+From: Lee Howard <faxguy@howardsilvan.com>
+Date: Sat, 24 May 2025 21:38:09 -0700
+Subject: [PATCH] conflict resolution
+
+CVE: CVE-2025-8176
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/ecc4ddbf1f0fed7957d1e20361e37f01907898e0]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ tools/tiffmedian.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/tiffmedian.c b/tools/tiffmedian.c
+index a0b4b5d..ca1c51f 100644
+--- a/tools/tiffmedian.c
++++ b/tools/tiffmedian.c
+@@ -847,7 +847,7 @@ quant_fsdither(TIFF* in, TIFF* out)
+ outline = (unsigned char *) _TIFFmalloc(TIFFScanlineSize(out));
+
+ GetInputLine(in, 0, goto bad); /* get first line */
+- for (i = 0; i <= imagelength; ++i) {
++ for (i = 0; i < imagelength; ++i) {
+ SWAP(short *, thisline, nextline);
+ lastline = (i >= imax);
+ if (i <= imax)
+--
+2.40.0
diff --git a/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb b/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb
index 5ec7b20e61..6ff31bd0bb 100644
--- a/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb
+++ b/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb
@@ -55,6 +55,9 @@ SRC_URI = "http://download.osgeo.org/libtiff/tiff-${PV}.tar.gz \
file://CVE-2023-6277-4.patch \
file://CVE-2024-7006.patch \
file://CVE-2023-3164.patch \
+ file://CVE-2025-8176-0001.patch \
+ file://CVE-2025-8176-0002.patch \
+ file://CVE-2025-8176-0003.patch \
"
SRC_URI[sha256sum] = "0e46e5acb087ce7d1ac53cf4f56a09b221537fc86dfc5daaad1c2e89e1b37ac8"
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [OE-core][kirkstone 2/8] tiff: fix CVE-2025-8177
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 1/8] tiff: fix CVE-2025-8176 Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 3/8] python3: patch CVE-2025-8194 Steve Sakoman
` (5 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Yogita Urade <yogita.urade@windriver.com>
A vulnerability was found in LibTIFF up to 4.7.0. It has been
rated as critical. This issue affects the function setrow of the
file tools/thumbnail.c. The manipulation leads to buffer overflow.
An attack has to be approached locally. The patch is named
e8c9d6c616b19438695fd829e58ae4fde5bfbc22. It is recommended to
apply a patch to fix this issue. This vulnerability only affects
products that are no longer supported by the maintainer.
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2025-8177
Upstream patch:
https://gitlab.com/libtiff/libtiff/-/commit/e8de4dc1f923576dce9d625caeebd93f9db697e1
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
.../libtiff/tiff/CVE-2025-8177.patch | 35 +++++++++++++++++++
meta/recipes-multimedia/libtiff/tiff_4.3.0.bb | 1 +
2 files changed, 36 insertions(+)
create mode 100644 meta/recipes-multimedia/libtiff/tiff/CVE-2025-8177.patch
diff --git a/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8177.patch b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8177.patch
new file mode 100644
index 0000000000..30dbccd94f
--- /dev/null
+++ b/meta/recipes-multimedia/libtiff/tiff/CVE-2025-8177.patch
@@ -0,0 +1,35 @@
+From e8de4dc1f923576dce9d625caeebd93f9db697e1 Mon Sep 17 00:00:00 2001
+From: Lee Howard <faxguy@howardsilvan.com>
+Date: Wed, 25 Jun 2025 17:14:18 +0000
+Subject: [PATCH] Fix for thumbnail issue #715
+
+CVE: CVE-2025-8177
+Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/e8de4dc1f923576dce9d625caeebd93f9db697e1]
+
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
+---
+ tools/thumbnail.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/tools/thumbnail.c b/tools/thumbnail.c
+index 274705d..8960d36 100644
+--- a/tools/thumbnail.c
++++ b/tools/thumbnail.c
+@@ -538,7 +538,15 @@ setrow(uint8_t* row, uint32_t nrows, const uint8_t* rows[])
+ }
+ acc += bits[*src & mask1];
+ }
++ if (255 * acc / area < 256)
++ {
+ *row++ = cmap[(255*acc)/area];
++ }
++ else
++ {
++ fprintf(stderr, "acc=%d, area=%d\n", acc, area);
++ *row++ = cmap[0];
++ }
+ }
+ }
+
+--
+2.40.0
diff --git a/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb b/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb
index 6ff31bd0bb..4c9c212312 100644
--- a/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb
+++ b/meta/recipes-multimedia/libtiff/tiff_4.3.0.bb
@@ -58,6 +58,7 @@ SRC_URI = "http://download.osgeo.org/libtiff/tiff-${PV}.tar.gz \
file://CVE-2025-8176-0001.patch \
file://CVE-2025-8176-0002.patch \
file://CVE-2025-8176-0003.patch \
+ file://CVE-2025-8177.patch \
"
SRC_URI[sha256sum] = "0e46e5acb087ce7d1ac53cf4f56a09b221537fc86dfc5daaad1c2e89e1b37ac8"
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [OE-core][kirkstone 3/8] python3: patch CVE-2025-8194
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 1/8] tiff: fix CVE-2025-8176 Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 2/8] tiff: fix CVE-2025-8177 Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 4/8] go: ignore CVE-2025-0913 Steve Sakoman
` (4 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Peter Marko <peter.marko@siemens.com>
Pick commit from 3.12 branch mentioned in NVD report.
https://nvd.nist.gov/vuln/detail/CVE-2025-8194
Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
.../python/python3/CVE-2025-8194.patch | 219 ++++++++++++++++++
.../python/python3_3.10.18.bb | 7 +-
2 files changed, 223 insertions(+), 3 deletions(-)
create mode 100644 meta/recipes-devtools/python/python3/CVE-2025-8194.patch
diff --git a/meta/recipes-devtools/python/python3/CVE-2025-8194.patch b/meta/recipes-devtools/python/python3/CVE-2025-8194.patch
new file mode 100644
index 0000000000..44ada01133
--- /dev/null
+++ b/meta/recipes-devtools/python/python3/CVE-2025-8194.patch
@@ -0,0 +1,219 @@
+From c9d9f78feb1467e73fd29356c040bde1c104f29f Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-islington@users.noreply.github.com>
+Date: Mon, 4 Aug 2025 13:45:06 +0200
+Subject: [PATCH] [3.12] gh-130577: tarfile now validates archives to ensure
+ member offsets are non-negative (GH-137027) (#137171)
+
+(cherry picked from commit 7040aa54f14676938970e10c5f74ea93cd56aa38)
+
+Co-authored-by: Alexander Urieles <aeurielesn@users.noreply.github.com>
+Co-authored-by: Gregory P. Smith <greg@krypto.org>
+
+CVE: CVE-2025-8194
+Upstream-Status: Backport [https://github.com/python/cpython/commit/c9d9f78feb1467e73fd29356c040bde1c104f29f]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ Lib/tarfile.py | 3 +
+ Lib/test/test_tarfile.py | 156 ++++++++++++++++++
+ ...-07-23-00-35-29.gh-issue-130577.c7EITy.rst | 3 +
+ 3 files changed, 162 insertions(+)
+ create mode 100644 Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
+
+diff --git a/Lib/tarfile.py b/Lib/tarfile.py
+index 9999a99d54..59d3f6e5cc 100755
+--- a/Lib/tarfile.py
++++ b/Lib/tarfile.py
+@@ -1613,6 +1613,9 @@ class TarInfo(object):
+ """Round up a byte count by BLOCKSIZE and return it,
+ e.g. _block(834) => 1024.
+ """
++ # Only non-negative offsets are allowed
++ if count < 0:
++ raise InvalidHeaderError("invalid offset")
+ blocks, remainder = divmod(count, BLOCKSIZE)
+ if remainder:
+ blocks += 1
+diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
+index a184ba75a8..759fa03ead 100644
+--- a/Lib/test/test_tarfile.py
++++ b/Lib/test/test_tarfile.py
+@@ -49,6 +49,7 @@ bz2name = os.path.join(TEMPDIR, "testtar.tar.bz2")
+ xzname = os.path.join(TEMPDIR, "testtar.tar.xz")
+ tmpname = os.path.join(TEMPDIR, "tmp.tar")
+ dotlessname = os.path.join(TEMPDIR, "testtar")
++SPACE = b" "
+
+ sha256_regtype = (
+ "e09e4bc8b3c9d9177e77256353b36c159f5f040531bbd4b024a8f9b9196c71ce"
+@@ -4273,6 +4274,161 @@ class TestExtractionFilters(unittest.TestCase):
+ self.expect_exception(TypeError) # errorlevel is not int
+
+
++class OffsetValidationTests(unittest.TestCase):
++ tarname = tmpname
++ invalid_posix_header = (
++ # name: 100 bytes
++ tarfile.NUL * tarfile.LENGTH_NAME
++ # mode, space, null terminator: 8 bytes
++ + b"000755" + SPACE + tarfile.NUL
++ # uid, space, null terminator: 8 bytes
++ + b"000001" + SPACE + tarfile.NUL
++ # gid, space, null terminator: 8 bytes
++ + b"000001" + SPACE + tarfile.NUL
++ # size, space: 12 bytes
++ + b"\xff" * 11 + SPACE
++ # mtime, space: 12 bytes
++ + tarfile.NUL * 11 + SPACE
++ # chksum: 8 bytes
++ + b"0011407" + tarfile.NUL
++ # type: 1 byte
++ + tarfile.REGTYPE
++ # linkname: 100 bytes
++ + tarfile.NUL * tarfile.LENGTH_LINK
++ # magic: 6 bytes, version: 2 bytes
++ + tarfile.POSIX_MAGIC
++ # uname: 32 bytes
++ + tarfile.NUL * 32
++ # gname: 32 bytes
++ + tarfile.NUL * 32
++ # devmajor, space, null terminator: 8 bytes
++ + tarfile.NUL * 6 + SPACE + tarfile.NUL
++ # devminor, space, null terminator: 8 bytes
++ + tarfile.NUL * 6 + SPACE + tarfile.NUL
++ # prefix: 155 bytes
++ + tarfile.NUL * tarfile.LENGTH_PREFIX
++ # padding: 12 bytes
++ + tarfile.NUL * 12
++ )
++ invalid_gnu_header = (
++ # name: 100 bytes
++ tarfile.NUL * tarfile.LENGTH_NAME
++ # mode, null terminator: 8 bytes
++ + b"0000755" + tarfile.NUL
++ # uid, null terminator: 8 bytes
++ + b"0000001" + tarfile.NUL
++ # gid, space, null terminator: 8 bytes
++ + b"0000001" + tarfile.NUL
++ # size, space: 12 bytes
++ + b"\xff" * 11 + SPACE
++ # mtime, space: 12 bytes
++ + tarfile.NUL * 11 + SPACE
++ # chksum: 8 bytes
++ + b"0011327" + tarfile.NUL
++ # type: 1 byte
++ + tarfile.REGTYPE
++ # linkname: 100 bytes
++ + tarfile.NUL * tarfile.LENGTH_LINK
++ # magic: 8 bytes
++ + tarfile.GNU_MAGIC
++ # uname: 32 bytes
++ + tarfile.NUL * 32
++ # gname: 32 bytes
++ + tarfile.NUL * 32
++ # devmajor, null terminator: 8 bytes
++ + tarfile.NUL * 8
++ # devminor, null terminator: 8 bytes
++ + tarfile.NUL * 8
++ # padding: 167 bytes
++ + tarfile.NUL * 167
++ )
++ invalid_v7_header = (
++ # name: 100 bytes
++ tarfile.NUL * tarfile.LENGTH_NAME
++ # mode, space, null terminator: 8 bytes
++ + b"000755" + SPACE + tarfile.NUL
++ # uid, space, null terminator: 8 bytes
++ + b"000001" + SPACE + tarfile.NUL
++ # gid, space, null terminator: 8 bytes
++ + b"000001" + SPACE + tarfile.NUL
++ # size, space: 12 bytes
++ + b"\xff" * 11 + SPACE
++ # mtime, space: 12 bytes
++ + tarfile.NUL * 11 + SPACE
++ # chksum: 8 bytes
++ + b"0010070" + tarfile.NUL
++ # type: 1 byte
++ + tarfile.REGTYPE
++ # linkname: 100 bytes
++ + tarfile.NUL * tarfile.LENGTH_LINK
++ # padding: 255 bytes
++ + tarfile.NUL * 255
++ )
++ valid_gnu_header = tarfile.TarInfo("filename").tobuf(tarfile.GNU_FORMAT)
++ data_block = b"\xff" * tarfile.BLOCKSIZE
++
++ def _write_buffer(self, buffer):
++ with open(self.tarname, "wb") as f:
++ f.write(buffer)
++
++ def _get_members(self, ignore_zeros=None):
++ with open(self.tarname, "rb") as f:
++ with tarfile.open(
++ mode="r", fileobj=f, ignore_zeros=ignore_zeros
++ ) as tar:
++ return tar.getmembers()
++
++ def _assert_raises_read_error_exception(self):
++ with self.assertRaisesRegex(
++ tarfile.ReadError, "file could not be opened successfully"
++ ):
++ self._get_members()
++
++ def test_invalid_offset_header_validations(self):
++ for tar_format, invalid_header in (
++ ("posix", self.invalid_posix_header),
++ ("gnu", self.invalid_gnu_header),
++ ("v7", self.invalid_v7_header),
++ ):
++ with self.subTest(format=tar_format):
++ self._write_buffer(invalid_header)
++ self._assert_raises_read_error_exception()
++
++ def test_early_stop_at_invalid_offset_header(self):
++ buffer = self.valid_gnu_header + self.invalid_gnu_header + self.valid_gnu_header
++ self._write_buffer(buffer)
++ members = self._get_members()
++ self.assertEqual(len(members), 1)
++ self.assertEqual(members[0].name, "filename")
++ self.assertEqual(members[0].offset, 0)
++
++ def test_ignore_invalid_archive(self):
++ # 3 invalid headers with their respective data
++ buffer = (self.invalid_gnu_header + self.data_block) * 3
++ self._write_buffer(buffer)
++ members = self._get_members(ignore_zeros=True)
++ self.assertEqual(len(members), 0)
++
++ def test_ignore_invalid_offset_headers(self):
++ for first_block, second_block, expected_offset in (
++ (
++ (self.valid_gnu_header),
++ (self.invalid_gnu_header + self.data_block),
++ 0,
++ ),
++ (
++ (self.invalid_gnu_header + self.data_block),
++ (self.valid_gnu_header),
++ 1024,
++ ),
++ ):
++ self._write_buffer(first_block + second_block)
++ members = self._get_members(ignore_zeros=True)
++ self.assertEqual(len(members), 1)
++ self.assertEqual(members[0].name, "filename")
++ self.assertEqual(members[0].offset, expected_offset)
++
++
+ def setUpModule():
+ os_helper.unlink(TEMPDIR)
+ os.makedirs(TEMPDIR)
+diff --git a/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst b/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
+new file mode 100644
+index 0000000000..342cabbc86
+--- /dev/null
++++ b/Misc/NEWS.d/next/Library/2025-07-23-00-35-29.gh-issue-130577.c7EITy.rst
+@@ -0,0 +1,3 @@
++:mod:`tarfile` now validates archives to ensure member offsets are
++non-negative. (Contributed by Alexander Enrique Urieles Nieto in
++:gh:`130577`.)
diff --git a/meta/recipes-devtools/python/python3_3.10.18.bb b/meta/recipes-devtools/python/python3_3.10.18.bb
index 875b52cde9..89036ff3b8 100644
--- a/meta/recipes-devtools/python/python3_3.10.18.bb
+++ b/meta/recipes-devtools/python/python3_3.10.18.bb
@@ -37,6 +37,7 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
file://0001-Avoid-shebang-overflow-on-python-config.py.patch \
file://0001-test_storlines-skip-due-to-load-variability.patch \
file://0001-gh-107811-tarfile-treat-overflow-in-UID-GID-as-failu.patch \
+ file://CVE-2025-8194.patch \
"
SRC_URI:append:class-native = " \
@@ -170,7 +171,7 @@ do_install:append:class-native() {
# when they're only used for python called with -O or -OO.
#find ${D} -name *opt-*.pyc -delete
# Remove all pyc files. There are a ton of them and it is probably faster to let
- # python create the ones it wants at runtime rather than manage in the sstate
+ # python create the ones it wants at runtime rather than manage in the sstate
# tarballs and sysroot creation.
find ${D} -name *.pyc -delete
@@ -206,7 +207,7 @@ do_install:append() {
rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/test/__pycache__/test_range.cpython*
rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/test/__pycache__/test_xml_etree.cpython*
- # Similar to the above, we're getting reproducibility issues with
+ # Similar to the above, we're getting reproducibility issues with
# /usr/lib/python3.10/__pycache__/traceback.cpython-310.pyc
# so remove it too
rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/__pycache__/traceback.cpython*
@@ -266,7 +267,7 @@ py_package_preprocess () {
cd -
mv ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config-${MULTILIB_SUFFIX}
-
+
#Remove the unneeded copy of target sysconfig data
rm -rf ${PKGD}/${libdir}/python-sysconfigdata
}
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [OE-core][kirkstone 4/8] go: ignore CVE-2025-0913
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
` (2 preceding siblings ...)
2025-08-13 21:28 ` [OE-core][kirkstone 3/8] python3: patch CVE-2025-8194 Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 5/8] libarchive: patch CVE-2025-5918 Steve Sakoman
` (3 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Peter Marko <peter.marko@siemens.com>
This is problem on Windows platform only.
Per NVD report [1], CPE has "and" clause
Running on/with
cpe:2.3:o:microsoft:windows:-:*:*:*:*:*:*:*
Also linked patch [2] changes Windows files only (and tests).
[1] https://nvd.nist.gov/vuln/detail/CVE-2025-0913
[2] https://go-review.googlesource.com/c/go/+/672396
Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
meta/recipes-devtools/go/go-1.17.13.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/meta/recipes-devtools/go/go-1.17.13.inc b/meta/recipes-devtools/go/go-1.17.13.inc
index 033f770f64..36356349d2 100644
--- a/meta/recipes-devtools/go/go-1.17.13.inc
+++ b/meta/recipes-devtools/go/go-1.17.13.inc
@@ -73,4 +73,4 @@ SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784
CVE_CHECK_IGNORE += "CVE-2021-29923"
# This are specific to Microsoft Windows
-CVE_CHECK_IGNORE += "CVE-2022-41716 CVE-2023-45283 CVE-2023-45284"
+CVE_CHECK_IGNORE += "CVE-2022-41716 CVE-2023-45283 CVE-2023-45284 CVE-2025-0913"
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [OE-core][kirkstone 5/8] libarchive: patch CVE-2025-5918
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
` (3 preceding siblings ...)
2025-08-13 21:28 ` [OE-core][kirkstone 4/8] go: ignore CVE-2025-0913 Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 6/8] libxslt: fix CVE-2023-40403 Steve Sakoman
` (2 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Peter Marko <peter.marko@siemens.com>
Pick 2 commits as in scarthgap branch plus one additional precondition
to apply those.
Signed-off-by: Peter Marko <peter.marko@siemens.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
.../0001-FILE-seeking-support-2539.patch | 190 +++++++++++
.../0001-Improve-lseek-handling-2564.patch | 320 ++++++++++++++++++
.../libarchive/libarchive/CVE-2025-5918.patch | 217 ++++++++++++
.../libarchive/libarchive_3.6.2.bb | 3 +
4 files changed, 730 insertions(+)
create mode 100644 meta/recipes-extended/libarchive/libarchive/0001-FILE-seeking-support-2539.patch
create mode 100644 meta/recipes-extended/libarchive/libarchive/0001-Improve-lseek-handling-2564.patch
create mode 100644 meta/recipes-extended/libarchive/libarchive/CVE-2025-5918.patch
diff --git a/meta/recipes-extended/libarchive/libarchive/0001-FILE-seeking-support-2539.patch b/meta/recipes-extended/libarchive/libarchive/0001-FILE-seeking-support-2539.patch
new file mode 100644
index 0000000000..2126fcf058
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/0001-FILE-seeking-support-2539.patch
@@ -0,0 +1,190 @@
+From 09a2ed4853cd177264076a88c98e525e892a0d0b Mon Sep 17 00:00:00 2001
+From: ljdarj <ljd@luigiscorner.mu>
+Date: Sat, 15 Mar 2025 19:17:27 +0100
+Subject: [PATCH] FILE* seeking support (#2539)
+
+Adding a seeker function to archive_read_open_FILE().
+
+Fixes #437.
+
+Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/09a2ed4853cd177264076a88c98e525e892a0d0b]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ libarchive/archive_read_open_file.c | 82 +++++++++++++++++++++++------
+ libarchive/test/test_open_file.c | 9 ++--
+ 2 files changed, 71 insertions(+), 20 deletions(-)
+
+diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c
+index cf49ebd8..ecd56dce 100644
+--- a/libarchive/archive_read_open_file.c
++++ b/libarchive/archive_read_open_file.c
+@@ -57,9 +57,10 @@ struct read_FILE_data {
+ char can_skip;
+ };
+
+-static int file_close(struct archive *, void *);
+-static ssize_t file_read(struct archive *, void *, const void **buff);
+-static int64_t file_skip(struct archive *, void *, int64_t request);
++static int FILE_close(struct archive *, void *);
++static ssize_t FILE_read(struct archive *, void *, const void **buff);
++static int64_t FILE_seek(struct archive *, void *, int64_t, int);
++static int64_t FILE_skip(struct archive *, void *, int64_t);
+
+ int
+ archive_read_open_FILE(struct archive *a, FILE *f)
+@@ -70,7 +71,7 @@ archive_read_open_FILE(struct archive *a, FILE *f)
+ void *b;
+
+ archive_clear_error(a);
+- mine = (struct read_FILE_data *)malloc(sizeof(*mine));
++ mine = (struct read_FILE_data *)calloc(1, sizeof(*mine));
+ b = malloc(block_size);
+ if (mine == NULL || b == NULL) {
+ archive_set_error(a, ENOMEM, "No memory");
+@@ -91,22 +92,22 @@ archive_read_open_FILE(struct archive *a, FILE *f)
+ archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
+ /* Enable the seek optimization only for regular files. */
+ mine->can_skip = 1;
+- } else
+- mine->can_skip = 0;
++ }
+
+ #if defined(__CYGWIN__) || defined(_WIN32)
+ setmode(fileno(mine->f), O_BINARY);
+ #endif
+
+- archive_read_set_read_callback(a, file_read);
+- archive_read_set_skip_callback(a, file_skip);
+- archive_read_set_close_callback(a, file_close);
++ archive_read_set_read_callback(a, FILE_read);
++ archive_read_set_skip_callback(a, FILE_skip);
++ archive_read_set_seek_callback(a, FILE_seek);
++ archive_read_set_close_callback(a, FILE_close);
+ archive_read_set_callback_data(a, mine);
+ return (archive_read_open1(a));
+ }
+
+ static ssize_t
+-file_read(struct archive *a, void *client_data, const void **buff)
++FILE_read(struct archive *a, void *client_data, const void **buff)
+ {
+ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+ size_t bytes_read;
+@@ -120,13 +121,13 @@ file_read(struct archive *a, void *client_data, const void **buff)
+ }
+
+ static int64_t
+-file_skip(struct archive *a, void *client_data, int64_t request)
++FILE_skip(struct archive *a, void *client_data, int64_t request)
+ {
+ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+-#if HAVE_FSEEKO
+- off_t skip = (off_t)request;
+-#elif HAVE__FSEEKI64
++#if HAVE__FSEEKI64
+ int64_t skip = request;
++#elif HAVE_FSEEKO
++ off_t skip = (off_t)request;
+ #else
+ long skip = (long)request;
+ #endif
+@@ -168,8 +169,57 @@ file_skip(struct archive *a, void *client_data, int64_t request)
+ return (request);
+ }
+
++/*
++ * TODO: Store the offset and use it in the read callback.
++ */
++static int64_t
++FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
++{
++ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
++#if HAVE__FSEEKI64
++ int64_t skip = request;
++#elif HAVE_FSEEKO
++ off_t skip = (off_t)request;
++#else
++ long skip = (long)request;
++#endif
++ int skip_bits = sizeof(skip) * 8 - 1;
++ (void)a; /* UNUSED */
++
++ /* If request is too big for a long or an off_t, reduce it. */
++ if (sizeof(request) > sizeof(skip)) {
++ int64_t max_skip =
++ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
++ if (request > max_skip)
++ skip = max_skip;
++ }
++
++#ifdef __ANDROID__
++ /* Newer Android versions have fseeko...to meditate. */
++ int64_t ret = lseek(fileno(mine->f), skip, whence);
++ if (ret >= 0) {
++ return ret;
++ }
++#elif HAVE__FSEEKI64
++ if (_fseeki64(mine->f, skip, whence) == 0) {
++ return _ftelli64(mine->f);
++ }
++#elif HAVE_FSEEKO
++ if (fseeko(mine->f, skip, whence) == 0) {
++ return ftello(mine->f);
++ }
++#else
++ if (fseek(mine->f, skip, whence) == 0) {
++ return ftell(mine->f);
++ }
++#endif
++ /* If we arrive here, the input is corrupted or truncated so fail. */
++ archive_set_error(a, errno, "Error seeking in FILE* pointer");
++ return (ARCHIVE_FATAL);
++}
++
+ static int
+-file_close(struct archive *a, void *client_data)
++FILE_close(struct archive *a, void *client_data)
+ {
+ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+
+@@ -177,4 +227,4 @@ file_close(struct archive *a, void *client_data)
+ free(mine->buffer);
+ free(mine);
+ return (ARCHIVE_OK);
+-}
++}
+\ No newline at end of file
+diff --git a/libarchive/test/test_open_file.c b/libarchive/test/test_open_file.c
+index f4ca82bb..cc6b04d0 100644
+--- a/libarchive/test/test_open_file.c
++++ b/libarchive/test/test_open_file.c
+@@ -32,14 +32,14 @@ DEFINE_TEST(test_open_file)
+ struct archive *a;
+ FILE *f;
+
+- f = fopen("test.tar", "wb");
++ f = fopen("test.7z", "wb");
+ assert(f != NULL);
+ if (f == NULL)
+ return;
+
+ /* Write an archive through this FILE *. */
+ assert((a = archive_write_new()) != NULL);
+- assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
++ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_7zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_none(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_FILE(a, f));
+
+@@ -71,9 +71,10 @@ DEFINE_TEST(test_open_file)
+ fclose(f);
+
+ /*
+- * Now, read the data back.
++ * Now, read the data back. 7z requiring seeking, that also
++ * tests that the seeking support works.
+ */
+- f = fopen("test.tar", "rb");
++ f = fopen("test.7z", "rb");
+ assert(f != NULL);
+ if (f == NULL)
+ return;
diff --git a/meta/recipes-extended/libarchive/libarchive/0001-Improve-lseek-handling-2564.patch b/meta/recipes-extended/libarchive/libarchive/0001-Improve-lseek-handling-2564.patch
new file mode 100644
index 0000000000..a00674f5dc
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/0001-Improve-lseek-handling-2564.patch
@@ -0,0 +1,320 @@
+From 89b8c35ff4b5addc08a85bf5df02b407f8af1f6c Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com>
+Date: Sun, 6 Apr 2025 22:34:37 +0200
+Subject: [PATCH] Improve lseek handling (#2564)
+
+The skip functions are limited to 1 GB for cases in which libarchive
+runs on a system with an off_t or long with 32 bits. This has negative
+impact on 64 bit systems.
+
+Instead, make sure that _all_ subsequent functions truncate properly.
+Some of them already did and some had regressions for over 10 years.
+
+Tests pass on Debian 12 i686 configured with --disable-largefile, i.e.
+running with an off_t with 32 bits.
+
+Casts added where needed to still pass MSVC builds.
+
+---------
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+
+Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/89b8c35ff4b5addc08a85bf5df02b407f8af1f6c]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ libarchive/archive_read.c | 6 ----
+ libarchive/archive_read_disk_posix.c | 3 +-
+ libarchive/archive_read_open_fd.c | 29 +++++++++++++------
+ libarchive/archive_read_open_file.c | 35 ++++++++++++-----------
+ libarchive/archive_read_open_filename.c | 37 ++++++++++++++++++-------
+ libarchive/test/read_open_memory.c | 2 +-
+ libarchive/test/test_sparse_basic.c | 6 ++--
+ libarchive/test/test_tar_large.c | 2 +-
+ 8 files changed, 75 insertions(+), 45 deletions(-)
+
+diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
+index 822c534b..50db8701 100644
+--- a/libarchive/archive_read.c
++++ b/libarchive/archive_read.c
+@@ -177,15 +177,9 @@ client_skip_proxy(struct archive_read_filter *self, int64_t request)
+ return 0;
+
+ if (self->archive->client.skipper != NULL) {
+- /* Seek requests over 1GiB are broken down into
+- * multiple seeks. This avoids overflows when the
+- * requests get passed through 32-bit arguments. */
+- int64_t skip_limit = (int64_t)1 << 30;
+ int64_t total = 0;
+ for (;;) {
+ int64_t get, ask = request;
+- if (ask > skip_limit)
+- ask = skip_limit;
+ get = (self->archive->client.skipper)
+ (&self->archive->archive, self->data, ask);
+ total += get;
+diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
+index 09965eb9..4839d62b 100644
+--- a/libarchive/archive_read_disk_posix.c
++++ b/libarchive/archive_read_disk_posix.c
+@@ -779,7 +779,8 @@ _archive_read_data_block(struct archive *_a, const void **buff,
+ */
+ if (t->current_sparse->offset > t->entry_total) {
+ if (lseek(t->entry_fd,
+- (off_t)t->current_sparse->offset, SEEK_SET) < 0) {
++ (off_t)t->current_sparse->offset, SEEK_SET) !=
++ t->current_sparse->offset) {
+ archive_set_error(&a->archive, errno, "Seek error");
+ r = ARCHIVE_FATAL;
+ a->archive.state = ARCHIVE_STATE_FATAL;
+diff --git a/libarchive/archive_read_open_fd.c b/libarchive/archive_read_open_fd.c
+index debfde20..3fd536d5 100644
+--- a/libarchive/archive_read_open_fd.c
++++ b/libarchive/archive_read_open_fd.c
+@@ -132,7 +132,7 @@ static int64_t
+ file_skip(struct archive *a, void *client_data, int64_t request)
+ {
+ struct read_fd_data *mine = (struct read_fd_data *)client_data;
+- int64_t skip = request;
++ off_t skip = (off_t)request;
+ int64_t old_offset, new_offset;
+ int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
+
+@@ -141,15 +141,15 @@ file_skip(struct archive *a, void *client_data, int64_t request)
+
+ /* Reduce a request that would overflow the 'skip' variable. */
+ if (sizeof(request) > sizeof(skip)) {
+- int64_t max_skip =
++ const int64_t max_skip =
+ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
+ if (request > max_skip)
+- skip = max_skip;
++ skip = (off_t)max_skip;
+ }
+
+- /* Reduce request to the next smallest multiple of block_size */
+- request = (request / mine->block_size) * mine->block_size;
+- if (request == 0)
++ /* Reduce 'skip' to the next smallest multiple of block_size */
++ skip = (off_t)(((int64_t)skip / mine->block_size) * mine->block_size);
++ if (skip == 0)
+ return (0);
+
+ if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
+@@ -179,11 +179,24 @@ static int64_t
+ file_seek(struct archive *a, void *client_data, int64_t request, int whence)
+ {
+ struct read_fd_data *mine = (struct read_fd_data *)client_data;
++ off_t seek = (off_t)request;
+ int64_t r;
++ int seek_bits = sizeof(seek) * 8 - 1; /* off_t is a signed type. */
+
+ /* We use off_t here because lseek() is declared that way. */
+- /* See above for notes about when off_t is less than 64 bits. */
+- r = lseek(mine->fd, request, whence);
++
++ /* Reduce a request that would overflow the 'seek' variable. */
++ if (sizeof(request) > sizeof(seek)) {
++ const int64_t max_seek =
++ (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
++ const int64_t min_seek = ~max_seek;
++ if (request > max_seek)
++ seek = (off_t)max_seek;
++ else if (request < min_seek)
++ seek = (off_t)min_seek;
++ }
++
++ r = lseek(mine->fd, seek, whence);
+ if (r >= 0)
+ return r;
+
+diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c
+index ecd56dce..2829b9a5 100644
+--- a/libarchive/archive_read_open_file.c
++++ b/libarchive/archive_read_open_file.c
+@@ -146,7 +146,7 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
+
+ /* If request is too big for a long or an off_t, reduce it. */
+ if (sizeof(request) > sizeof(skip)) {
+- int64_t max_skip =
++ const int64_t max_skip =
+ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
+ if (request > max_skip)
+ skip = max_skip;
+@@ -177,39 +177,42 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
+ {
+ struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
+ #if HAVE__FSEEKI64
+- int64_t skip = request;
++ int64_t seek = request;
+ #elif HAVE_FSEEKO
+- off_t skip = (off_t)request;
++ off_t seek = (off_t)request;
+ #else
+- long skip = (long)request;
++ long seek = (long)request;
+ #endif
+- int skip_bits = sizeof(skip) * 8 - 1;
++ int seek_bits = sizeof(seek) * 8 - 1;
+ (void)a; /* UNUSED */
+
+- /* If request is too big for a long or an off_t, reduce it. */
+- if (sizeof(request) > sizeof(skip)) {
+- int64_t max_skip =
+- (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
+- if (request > max_skip)
+- skip = max_skip;
++ /* Reduce a request that would overflow the 'seek' variable. */
++ if (sizeof(request) > sizeof(seek)) {
++ const int64_t max_seek =
++ (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
++ const int64_t min_seek = ~max_seek;
++ if (request > max_seek)
++ seek = max_seek;
++ else if (request < min_seek)
++ seek = min_seek;
+ }
+
+ #ifdef __ANDROID__
+ /* Newer Android versions have fseeko...to meditate. */
+- int64_t ret = lseek(fileno(mine->f), skip, whence);
++ int64_t ret = lseek(fileno(mine->f), seek, whence);
+ if (ret >= 0) {
+ return ret;
+ }
+ #elif HAVE__FSEEKI64
+- if (_fseeki64(mine->f, skip, whence) == 0) {
++ if (_fseeki64(mine->f, seek, whence) == 0) {
+ return _ftelli64(mine->f);
+ }
+ #elif HAVE_FSEEKO
+- if (fseeko(mine->f, skip, whence) == 0) {
++ if (fseeko(mine->f, seek, whence) == 0) {
+ return ftello(mine->f);
+ }
+ #else
+- if (fseek(mine->f, skip, whence) == 0) {
++ if (fseek(mine->f, seek, whence) == 0) {
+ return ftell(mine->f);
+ }
+ #endif
+@@ -227,4 +230,4 @@ FILE_close(struct archive *a, void *client_data)
+ free(mine->buffer);
+ free(mine);
+ return (ARCHIVE_OK);
+-}
+\ No newline at end of file
++}
+diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c
+index 05f0ffbd..3894b15c 100644
+--- a/libarchive/archive_read_open_filename.c
++++ b/libarchive/archive_read_open_filename.c
+@@ -449,20 +449,24 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
+ struct read_file_data *mine = (struct read_file_data *)client_data;
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+ /* We use _lseeki64() on Windows. */
+- int64_t old_offset, new_offset;
++ int64_t old_offset, new_offset, skip = request;
+ #else
+- off_t old_offset, new_offset;
++ off_t old_offset, new_offset, skip = (off_t)request;
+ #endif
++ int skip_bits = sizeof(skip) * 8 - 1;
+
+ /* We use off_t here because lseek() is declared that way. */
+
+- /* TODO: Deal with case where off_t isn't 64 bits.
+- * This shouldn't be a problem on Linux or other POSIX
+- * systems, since the configuration logic for libarchive
+- * tries to obtain a 64-bit off_t.
+- */
++ /* Reduce a request that would overflow the 'skip' variable. */
++ if (sizeof(request) > sizeof(skip)) {
++ const int64_t max_skip =
++ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
++ if (request > max_skip)
++ skip = max_skip;
++ }
++
+ if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
+- (new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
++ (new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
+ return (new_offset - old_offset);
+
+ /* If lseek() fails, don't bother trying again. */
+@@ -510,11 +514,24 @@ static int64_t
+ file_seek(struct archive *a, void *client_data, int64_t request, int whence)
+ {
+ struct read_file_data *mine = (struct read_file_data *)client_data;
++ off_t seek = (off_t)request;
+ int64_t r;
++ int seek_bits = sizeof(seek) * 8 - 1;
+
+ /* We use off_t here because lseek() is declared that way. */
+- /* See above for notes about when off_t is less than 64 bits. */
+- r = lseek(mine->fd, request, whence);
++
++ /* Reduce a request that would overflow the 'seek' variable. */
++ if (sizeof(request) > sizeof(seek)) {
++ const int64_t max_seek =
++ (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
++ const int64_t min_seek = ~max_seek;
++ if (request > max_seek)
++ seek = (off_t)max_seek;
++ else if (request < min_seek)
++ seek = (off_t)min_seek;
++ }
++
++ r = lseek(mine->fd, seek, whence);
+ if (r >= 0)
+ return r;
+
+diff --git a/libarchive/test/read_open_memory.c b/libarchive/test/read_open_memory.c
+index 6d2468cd..9262ab9d 100644
+--- a/libarchive/test/read_open_memory.c
++++ b/libarchive/test/read_open_memory.c
+@@ -168,7 +168,7 @@ memory_read_skip(struct archive *a, void *client_data, int64_t skip)
+
+ (void)a; /* UNUSED */
+ /* We can't skip by more than is available. */
+- if ((off_t)skip > (off_t)(mine->end - mine->p))
++ if (skip > mine->end - mine->p)
+ skip = mine->end - mine->p;
+ /* Always do small skips by prime amounts. */
+ if (skip > 71)
+diff --git a/libarchive/test/test_sparse_basic.c b/libarchive/test/test_sparse_basic.c
+index 23cde567..93710cb6 100644
+--- a/libarchive/test/test_sparse_basic.c
++++ b/libarchive/test/test_sparse_basic.c
+@@ -606,7 +606,8 @@ DEFINE_TEST(test_sparse_basic)
+ verify_sparse_file(a, "file2", sparse_file2, 20);
+ /* Encoded non sparse; expect a data block but no sparse entries. */
+ verify_sparse_file(a, "file3", sparse_file3, 0);
+- verify_sparse_file(a, "file4", sparse_file4, 2);
++ if (sizeof(off_t) > 4)
++ verify_sparse_file(a, "file4", sparse_file4, 2);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+@@ -633,7 +634,8 @@ DEFINE_TEST(test_sparse_basic)
+ verify_sparse_file(a, "file1", sparse_file1, 0);
+ verify_sparse_file(a, "file2", sparse_file2, 0);
+ verify_sparse_file(a, "file3", sparse_file3, 0);
+- verify_sparse_file(a, "file4", sparse_file4, 0);
++ if (sizeof(off_t) > 4)
++ verify_sparse_file(a, "file4", sparse_file4, 0);
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+
+diff --git a/libarchive/test/test_tar_large.c b/libarchive/test/test_tar_large.c
+index c1f37916..1cde3218 100644
+--- a/libarchive/test/test_tar_large.c
++++ b/libarchive/test/test_tar_large.c
+@@ -176,7 +176,7 @@ memory_read_skip(struct archive *a, void *_private, int64_t skip)
+ }
+ if (private->filebytes > 0) {
+ if (private->filebytes < skip)
+- skip = (off_t)private->filebytes;
++ skip = private->filebytes;
+ private->filebytes -= skip;
+ } else {
+ skip = 0;
diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2025-5918.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2025-5918.patch
new file mode 100644
index 0000000000..6ca6f6678c
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/CVE-2025-5918.patch
@@ -0,0 +1,217 @@
+From dcbf1e0ededa95849f098d154a25876ed5754bcf Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com>
+Date: Tue, 15 Apr 2025 06:02:17 +0200
+Subject: [PATCH] Do not skip past EOF while reading (#2584)
+
+Make sure to not skip past end of file for better error messages. One
+such example is now visible with rar testsuite. You can see the
+difference already by an actually not useless use of cat:
+
+```
+$ cat .../test_read_format_rar_ppmd_use_after_free.rar | bsdtar -t
+bsdtar: Archive entry has empty or unreadable filename ... skipping.
+bsdtar: Archive entry has empty or unreadable filename ... skipping.
+bsdtar: Truncated input file (needed 119 bytes, only 0 available)
+bsdtar: Error exit delayed from previous errors.
+```
+
+compared to
+
+```
+$ bsdtar -tf .../test_read_format_rar_ppmd_use_after_free.rar
+bsdtar: Archive entry has empty or unreadable filename ... skipping.
+bsdtar: Archive entry has empty or unreadable filename ... skipping.
+bsdtar: Error exit delayed from previous errors.
+```
+
+Since the former cannot lseek, the error is a different one
+(ARCHIVE_FATAL vs ARCHIVE_EOF). The piped version states explicitly that
+truncation occurred, while the latter states EOF because the skip past
+the end of file was successful.
+
+Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
+
+CVE: CVE-2025-5918
+Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/dcbf1e0ededa95849f098d154a25876ed5754bcf]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ libarchive/archive_read_open_fd.c | 13 +++++++---
+ libarchive/archive_read_open_file.c | 33 +++++++++++++++++++------
+ libarchive/archive_read_open_filename.c | 16 +++++++++---
+ libarchive/test/test_read_format_rar.c | 6 ++---
+ 4 files changed, 50 insertions(+), 18 deletions(-)
+
+diff --git a/libarchive/archive_read_open_fd.c b/libarchive/archive_read_open_fd.c
+index 3fd536d5..dc7c9e52 100644
+--- a/libarchive/archive_read_open_fd.c
++++ b/libarchive/archive_read_open_fd.c
+@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_fd.c 201103 2009-12-28
+ struct read_fd_data {
+ int fd;
+ size_t block_size;
++ int64_t size;
+ char use_lseek;
+ void *buffer;
+ };
+@@ -96,6 +97,7 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size)
+ if (S_ISREG(st.st_mode)) {
+ archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
+ mine->use_lseek = 1;
++ mine->size = st.st_size;
+ }
+ #if defined(__CYGWIN__) || defined(_WIN32)
+ setmode(mine->fd, O_BINARY);
+@@ -152,9 +154,14 @@ file_skip(struct archive *a, void *client_data, int64_t request)
+ if (skip == 0)
+ return (0);
+
+- if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
+- ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0))
+- return (new_offset - old_offset);
++ if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) {
++ if (old_offset >= mine->size ||
++ skip > mine->size - old_offset) {
++ /* Do not seek past end of file. */
++ errno = ESPIPE;
++ } else if ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
++ return (new_offset - old_offset);
++ }
+
+ /* If seek failed once, it will probably fail again. */
+ mine->use_lseek = 0;
+diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c
+index 2829b9a5..6ed18a0c 100644
+--- a/libarchive/archive_read_open_file.c
++++ b/libarchive/archive_read_open_file.c
+@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_read_open_file.c 201093 2009-12-
+ struct read_FILE_data {
+ FILE *f;
+ size_t block_size;
++ int64_t size;
+ void *buffer;
+ char can_skip;
+ };
+@@ -92,6 +93,7 @@ archive_read_open_FILE(struct archive *a, FILE *f)
+ archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
+ /* Enable the seek optimization only for regular files. */
+ mine->can_skip = 1;
++ mine->size = st.st_size;
+ }
+
+ #if defined(__CYGWIN__) || defined(_WIN32)
+@@ -131,6 +133,7 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
+ #else
+ long skip = (long)request;
+ #endif
++ int64_t old_offset, new_offset;
+ int skip_bits = sizeof(skip) * 8 - 1;
+
+ (void)a; /* UNUSED */
+@@ -154,19 +157,33 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
+
+ #ifdef __ANDROID__
+ /* fileno() isn't safe on all platforms ... see above. */
+- if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
++ old_offset = lseek(fileno(mine->f), 0, SEEK_CUR);
+ #elif HAVE_FSEEKO
+- if (fseeko(mine->f, skip, SEEK_CUR) != 0)
++ old_offset = ftello(mine->f);
+ #elif HAVE__FSEEKI64
+- if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
++ old_offset = _ftelli64(mine->f);
+ #else
+- if (fseek(mine->f, skip, SEEK_CUR) != 0)
++ old_offset = ftell(mine->f);
+ #endif
+- {
+- mine->can_skip = 0;
+- return (0);
++ if (old_offset >= 0) {
++ if (old_offset < mine->size &&
++ skip <= mine->size - old_offset) {
++#ifdef __ANDROID__
++ new_offset = lseek(fileno(mine->f), skip, SEEK_CUR);
++#elif HAVE__FSEEKI64
++ new_offset = _fseeki64(mine->f, skip, SEEK_CUR);
++#elif HAVE_FSEEKO
++ new_offset = fseeko(mine->f, skip, SEEK_CUR);
++#else
++ new_offset = fseek(mine->f, skip, SEEK_CUR);
++#endif
++ if (new_offset >= 0)
++ return (new_offset - old_offset);
++ }
+ }
+- return (request);
++
++ mine->can_skip = 0;
++ return (0);
+ }
+
+ /*
+diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c
+index 3894b15c..5f5b3f1f 100644
+--- a/libarchive/archive_read_open_filename.c
++++ b/libarchive/archive_read_open_filename.c
+@@ -75,6 +75,7 @@ struct read_file_data {
+ size_t block_size;
+ void *buffer;
+ mode_t st_mode; /* Mode bits for opened file. */
++ int64_t size;
+ char use_lseek;
+ enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type;
+ union {
+@@ -370,8 +371,10 @@ file_open(struct archive *a, void *client_data)
+ mine->st_mode = st.st_mode;
+
+ /* Disk-like inputs can use lseek(). */
+- if (is_disk_like)
++ if (is_disk_like) {
+ mine->use_lseek = 1;
++ mine->size = st.st_size;
++ }
+
+ return (ARCHIVE_OK);
+ fail:
+@@ -465,9 +468,14 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
+ skip = max_skip;
+ }
+
+- if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
+- (new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
+- return (new_offset - old_offset);
++ if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) {
++ if (old_offset >= mine->size ||
++ skip > mine->size - old_offset) {
++ /* Do not seek past end of file. */
++ errno = ESPIPE;
++ } else if ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
++ return (new_offset - old_offset);
++ }
+
+ /* If lseek() fails, don't bother trying again. */
+ mine->use_lseek = 0;
+diff --git a/libarchive/test/test_read_format_rar.c b/libarchive/test/test_read_format_rar.c
+index dce567af..fce44a9d 100644
+--- a/libarchive/test/test_read_format_rar.c
++++ b/libarchive/test/test_read_format_rar.c
+@@ -3776,8 +3776,8 @@ DEFINE_TEST(test_read_format_rar_ppmd_use_after_free)
+ assertA(ARCHIVE_OK == archive_read_next_header(a, &ae));
+ assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
+
+- /* Test EOF */
+- assertA(1 == archive_read_next_header(a, &ae));
++ /* Test for truncation */
++ assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+@@ -3803,7 +3803,7 @@ DEFINE_TEST(test_read_format_rar_ppmd_use_after_free2)
+ assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
+
+ /* Test EOF */
+- assertA(1 == archive_read_next_header(a, &ae));
++ assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
diff --git a/meta/recipes-extended/libarchive/libarchive_3.6.2.bb b/meta/recipes-extended/libarchive/libarchive_3.6.2.bb
index 3937bfb82d..bfd4df8ad1 100644
--- a/meta/recipes-extended/libarchive/libarchive_3.6.2.bb
+++ b/meta/recipes-extended/libarchive/libarchive_3.6.2.bb
@@ -39,6 +39,9 @@ SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \
file://CVE-2025-5915.patch \
file://CVE-2025-5916.patch \
file://CVE-2025-5917.patch \
+ file://0001-FILE-seeking-support-2539.patch \
+ file://0001-Improve-lseek-handling-2564.patch \
+ file://CVE-2025-5918.patch \
"
UPSTREAM_CHECK_URI = "http://libarchive.org/"
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [OE-core][kirkstone 6/8] libxslt: fix CVE-2023-40403
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
` (4 preceding siblings ...)
2025-08-13 21:28 ` [OE-core][kirkstone 5/8] libarchive: patch CVE-2025-5918 Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 7/8] gnupg: disable tests to avoid running target binaries at build time Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 8/8] go-helloworld: fix license Steve Sakoman
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Hitendra Prajapati <hprajapati@mvista.com>
Upstream-Status: Backport from https://gitlab.gnome.org/GNOME/libxslt/-/commit/adebe45f6ef9f9d036acacd8aec7411d4ea84e25 && https://gitlab.gnome.org/GNOME/libxslt/-/commit/1d9820635c271b35f88431f33ea78dc8be349e5b && https://gitlab.gnome.org/GNOME/libxslt/-/commit/ccec6fa31d11ab0a5299f15ea184c7a457e92940 && https://gitlab.gnome.org/GNOME/libxslt/-/commit/82f6cbf8ca61b1f9e00dc04aa3b15d563e7bbc6d && https://gitlab.gnome.org/GNOME/libxslt/-/commit/452fb4ca9b9803448826008b9573987c615912a1
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
.../libxslt/libxslt/CVE-2023-40403-001.patch | 257 +++++++++++++
.../libxslt/libxslt/CVE-2023-40403-002.patch | 147 ++++++++
.../libxslt/libxslt/CVE-2023-40403-003.patch | 231 ++++++++++++
.../libxslt/libxslt/CVE-2023-40403-004.patch | 349 ++++++++++++++++++
.../libxslt/libxslt/CVE-2023-40403-005.patch | 55 +++
.../recipes-support/libxslt/libxslt_1.1.35.bb | 5 +
6 files changed, 1044 insertions(+)
create mode 100644 meta/recipes-support/libxslt/libxslt/CVE-2023-40403-001.patch
create mode 100644 meta/recipes-support/libxslt/libxslt/CVE-2023-40403-002.patch
create mode 100644 meta/recipes-support/libxslt/libxslt/CVE-2023-40403-003.patch
create mode 100644 meta/recipes-support/libxslt/libxslt/CVE-2023-40403-004.patch
create mode 100644 meta/recipes-support/libxslt/libxslt/CVE-2023-40403-005.patch
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-001.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-001.patch
new file mode 100644
index 0000000000..044e100373
--- /dev/null
+++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-001.patch
@@ -0,0 +1,257 @@
+From 4f26166f9e253aa62f8c121a6a25c76df5aa8142 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Wed, 31 Aug 2022 15:29:57 +0200
+Subject: [PATCH] Infrastructure to store extra data in source nodes
+
+Provide a mechanism to store bit flags in nodes from the source
+document. This will later be used to store key and id status.
+
+Provide a function to find the psvi member of a node.
+
+Revert any changes to the source document after the transformation.
+
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/adebe45f6ef9f9d036acacd8aec7411d4ea84e25]
+CVE: CVE-2023-40403
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+
+---
+ libxslt/transform.c | 34 ++++++++++
+ libxslt/xsltInternals.h | 1 +
+ libxslt/xsltutils.c | 135 ++++++++++++++++++++++++++++++++++++++++
+ libxslt/xsltutils.h | 13 ++++
+ 4 files changed, 183 insertions(+)
+
+diff --git a/libxslt/transform.c b/libxslt/transform.c
+index 57f05bf..40ab810 100644
+--- a/libxslt/transform.c
++++ b/libxslt/transform.c
+@@ -5747,6 +5747,37 @@ xsltCountKeys(xsltTransformContextPtr ctxt)
+ return(ctxt->nbKeys);
+ }
+
++/**
++ * xsltCleanupSourceDoc:
++ * @doc: Document
++ *
++ * Resets source node flags and ids stored in 'psvi' member.
++ */
++static void
++xsltCleanupSourceDoc(xmlDocPtr doc) {
++ xmlNodePtr cur = (xmlNodePtr) doc;
++ void **psviPtr;
++
++ while (1) {
++ xsltClearSourceNodeFlags(cur, XSLT_SOURCE_NODE_MASK);
++ psviPtr = xsltGetPSVIPtr(cur);
++ if (psviPtr)
++ *psviPtr = NULL;
++
++ if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) {
++ cur = cur->children;
++ } else {
++ while (cur->next == NULL) {
++ cur = cur->parent;
++ if (cur == (xmlNodePtr) doc)
++ return;
++ }
++
++ cur = cur->next;
++ }
++ }
++}
++
+ /**
+ * xsltApplyStylesheetInternal:
+ * @style: a parsed XSLT stylesheet
+@@ -6145,6 +6176,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
+ printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars);
+ #endif
+
++ if (ctxt->sourceDocDirty)
++ xsltCleanupSourceDoc(doc);
++
+ if ((ctxt != NULL) && (userCtxt == NULL))
+ xsltFreeTransformContext(ctxt);
+
+diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
+index 14343d2..b0125c2 100644
+--- a/libxslt/xsltInternals.h
++++ b/libxslt/xsltInternals.h
+@@ -1786,6 +1786,7 @@ struct _xsltTransformContext {
+ int maxTemplateVars;
+ unsigned long opLimit;
+ unsigned long opCount;
++ int sourceDocDirty;
+ };
+
+ /**
+diff --git a/libxslt/xsltutils.c b/libxslt/xsltutils.c
+index 9faa6b2..a879aa8 100644
+--- a/libxslt/xsltutils.c
++++ b/libxslt/xsltutils.c
+@@ -1835,6 +1835,141 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
+ return 0;
+ }
+
++/**
++ * xsltGetSourceNodeFlags:
++ * @node: Node from source document
++ *
++ * Returns the flags for a source node.
++ */
++int
++xsltGetSourceNodeFlags(xmlNodePtr node) {
++ /*
++ * Squeeze the bit flags into the upper bits of
++ *
++ * - 'int properties' member in struct _xmlDoc
++ * - 'xmlAttributeType atype' member in struct _xmlAttr
++ * - 'unsigned short extra' member in struct _xmlNode
++ */
++ switch (node->type) {
++ case XML_DOCUMENT_NODE:
++ case XML_HTML_DOCUMENT_NODE:
++ return ((xmlDocPtr) node)->properties >> 27;
++
++ case XML_ATTRIBUTE_NODE:
++ return ((xmlAttrPtr) node)->atype >> 27;
++
++ case XML_ELEMENT_NODE:
++ case XML_TEXT_NODE:
++ case XML_CDATA_SECTION_NODE:
++ case XML_PI_NODE:
++ case XML_COMMENT_NODE:
++ return node->extra >> 12;
++
++ default:
++ return 0;
++ }
++}
++
++/**
++ * xsltSetSourceNodeFlags:
++ * @node: Node from source document
++ * @flags: Flags
++ *
++ * Sets the specified flags to 1.
++ *
++ * Returns 0 on success, -1 on error.
++ */
++int
++xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
++ int flags) {
++ if (node->doc == ctxt->initialContextDoc)
++ ctxt->sourceDocDirty = 1;
++
++ switch (node->type) {
++ case XML_DOCUMENT_NODE:
++ case XML_HTML_DOCUMENT_NODE:
++ ((xmlDocPtr) node)->properties |= flags << 27;
++ return 0;
++
++ case XML_ATTRIBUTE_NODE:
++ ((xmlAttrPtr) node)->atype |= flags << 27;
++ return 0;
++
++ case XML_ELEMENT_NODE:
++ case XML_TEXT_NODE:
++ case XML_CDATA_SECTION_NODE:
++ case XML_PI_NODE:
++ case XML_COMMENT_NODE:
++ node->extra |= flags << 12;
++ return 0;
++
++ default:
++ return -1;
++ }
++}
++
++/**
++ * xsltClearSourceNodeFlags:
++ * @node: Node from source document
++ * @flags: Flags
++ *
++ * Sets the specified flags to 0.
++ *
++ * Returns 0 on success, -1 on error.
++ */
++int
++xsltClearSourceNodeFlags(xmlNodePtr node, int flags) {
++ switch (node->type) {
++ case XML_DOCUMENT_NODE:
++ case XML_HTML_DOCUMENT_NODE:
++ ((xmlDocPtr) node)->properties &= ~(flags << 27);
++ return 0;
++
++ case XML_ATTRIBUTE_NODE:
++ ((xmlAttrPtr) node)->atype &= ~(flags << 27);
++ return 0;
++
++ case XML_ELEMENT_NODE:
++ case XML_TEXT_NODE:
++ case XML_CDATA_SECTION_NODE:
++ case XML_PI_NODE:
++ case XML_COMMENT_NODE:
++ node->extra &= ~(flags << 12);
++ return 0;
++
++ default:
++ return -1;
++ }
++}
++
++/**
++ * xsltGetPSVIPtr:
++ * @cur: Node
++ *
++ * Returns a pointer to the psvi member of a node or NULL on error.
++ */
++void **
++xsltGetPSVIPtr(xmlNodePtr cur) {
++ switch (cur->type) {
++ case XML_DOCUMENT_NODE:
++ case XML_HTML_DOCUMENT_NODE:
++ return &((xmlDocPtr) cur)->psvi;
++
++ case XML_ATTRIBUTE_NODE:
++ return &((xmlAttrPtr) cur)->psvi;
++
++ case XML_ELEMENT_NODE:
++ case XML_TEXT_NODE:
++ case XML_CDATA_SECTION_NODE:
++ case XML_PI_NODE:
++ case XML_COMMENT_NODE:
++ return &cur->psvi;
++
++ default:
++ return NULL;
++ }
++}
++
+ #ifdef WITH_PROFILER
+
+ /************************************************************************
+diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
+index ea6c374..202694f 100644
+--- a/libxslt/xsltutils.h
++++ b/libxslt/xsltutils.h
+@@ -247,6 +247,19 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
+ const xmlChar *str,
+ int flags);
+
++#ifdef IN_LIBXSLT
++#define XSLT_SOURCE_NODE_MASK 15
++int
++xsltGetSourceNodeFlags(xmlNodePtr node);
++int
++xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
++ int flags);
++int
++xsltClearSourceNodeFlags(xmlNodePtr node, int flags);
++void **
++xsltGetPSVIPtr(xmlNodePtr cur);
++#endif
++
+ /*
+ * Profiling.
+ */
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-002.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-002.patch
new file mode 100644
index 0000000000..0d815c1090
--- /dev/null
+++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-002.patch
@@ -0,0 +1,147 @@
+From b392a3d0265f190d86cc122d86769a23ddb1fe66 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Wed, 31 Aug 2022 15:34:47 +0200
+Subject: [PATCH] Store key status of source nodes as bit flag
+
+This frees up the psvi member.
+
+CVE: CVE-2023-40403
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/1d9820635c271b35f88431f33ea78dc8be349e5b]
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+
+---
+ libxslt/keys.c | 19 +------------------
+ libxslt/pattern.c | 37 ++-----------------------------------
+ libxslt/xsltutils.h | 1 +
+ 3 files changed, 4 insertions(+), 53 deletions(-)
+
+diff --git a/libxslt/keys.c b/libxslt/keys.c
+index ecef538..3a134ab 100644
+--- a/libxslt/keys.c
++++ b/libxslt/keys.c
+@@ -834,24 +834,7 @@ fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel);
+ */
+ xmlXPathNodeSetAdd(keylist, cur);
+ }
+- switch (cur->type) {
+- case XML_ELEMENT_NODE:
+- case XML_TEXT_NODE:
+- case XML_CDATA_SECTION_NODE:
+- case XML_PI_NODE:
+- case XML_COMMENT_NODE:
+- cur->psvi = keyDef;
+- break;
+- case XML_ATTRIBUTE_NODE:
+- ((xmlAttrPtr) cur)->psvi = keyDef;
+- break;
+- case XML_DOCUMENT_NODE:
+- case XML_HTML_DOCUMENT_NODE:
+- ((xmlDocPtr) cur)->psvi = keyDef;
+- break;
+- default:
+- break;
+- }
++ xsltSetSourceNodeFlags(ctxt, cur, XSLT_SOURCE_NODE_HAS_KEY);
+ xmlFree(str);
+ str = NULL;
+
+diff --git a/libxslt/pattern.c b/libxslt/pattern.c
+index 1944661..9372bc3 100644
+--- a/libxslt/pattern.c
++++ b/libxslt/pattern.c
+@@ -2283,7 +2283,6 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
+ const xmlChar *name = NULL;
+ xsltCompMatchPtr list = NULL;
+ float priority;
+- int keyed = 0;
+
+ if ((ctxt == NULL) || (node == NULL))
+ return(NULL);
+@@ -2361,37 +2360,25 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
+ list = curstyle->rootMatch;
+ else
+ list = curstyle->elemMatch;
+- if (node->psvi != NULL) keyed = 1;
+ break;
+ case XML_ATTRIBUTE_NODE: {
+- xmlAttrPtr attr;
+-
+ list = curstyle->attrMatch;
+- attr = (xmlAttrPtr) node;
+- if (attr->psvi != NULL) keyed = 1;
+ break;
+ }
+ case XML_PI_NODE:
+ list = curstyle->piMatch;
+- if (node->psvi != NULL) keyed = 1;
+ break;
+ case XML_DOCUMENT_NODE:
+ case XML_HTML_DOCUMENT_NODE: {
+- xmlDocPtr doc;
+-
+ list = curstyle->rootMatch;
+- doc = (xmlDocPtr) node;
+- if (doc->psvi != NULL) keyed = 1;
+ break;
+ }
+ case XML_TEXT_NODE:
+ case XML_CDATA_SECTION_NODE:
+ list = curstyle->textMatch;
+- if (node->psvi != NULL) keyed = 1;
+ break;
+ case XML_COMMENT_NODE:
+ list = curstyle->commentMatch;
+- if (node->psvi != NULL) keyed = 1;
+ break;
+ case XML_ENTITY_REF_NODE:
+ case XML_ENTITY_NODE:
+@@ -2461,7 +2448,7 @@ xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
+ }
+
+ keyed_match:
+- if (keyed) {
++ if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY) {
+ list = curstyle->keyMatch;
+ while ((list != NULL) &&
+ ((ret == NULL) ||
+@@ -2489,27 +2476,7 @@ keyed_match:
+ if (xsltComputeAllKeys(ctxt, node) == -1)
+ goto error;
+
+- switch (node->type) {
+- case XML_ELEMENT_NODE:
+- if (node->psvi != NULL) keyed = 1;
+- break;
+- case XML_ATTRIBUTE_NODE:
+- if (((xmlAttrPtr) node)->psvi != NULL) keyed = 1;
+- break;
+- case XML_TEXT_NODE:
+- case XML_CDATA_SECTION_NODE:
+- case XML_COMMENT_NODE:
+- case XML_PI_NODE:
+- if (node->psvi != NULL) keyed = 1;
+- break;
+- case XML_DOCUMENT_NODE:
+- case XML_HTML_DOCUMENT_NODE:
+- if (((xmlDocPtr) node)->psvi != NULL) keyed = 1;
+- break;
+- default:
+- break;
+- }
+- if (keyed)
++ if (xsltGetSourceNodeFlags(node) & XSLT_SOURCE_NODE_HAS_KEY)
+ goto keyed_match;
+ }
+ if (ret != NULL)
+diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
+index 202694f..dcfd139 100644
+--- a/libxslt/xsltutils.h
++++ b/libxslt/xsltutils.h
+@@ -249,6 +249,7 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
+
+ #ifdef IN_LIBXSLT
+ #define XSLT_SOURCE_NODE_MASK 15
++#define XSLT_SOURCE_NODE_HAS_KEY 1
+ int
+ xsltGetSourceNodeFlags(xmlNodePtr node);
+ int
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-003.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-003.patch
new file mode 100644
index 0000000000..0b9ab5829e
--- /dev/null
+++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-003.patch
@@ -0,0 +1,231 @@
+From 8986995b07126852762e8a59eaee83be0b8de9a3 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Wed, 31 Aug 2022 15:35:37 +0200
+Subject: [PATCH] Store RVT ownership in 'compression' member
+
+'compression' is another unused member in struct _xmlDoc which is even
+better suited to store ownership status. More importantly, this frees up
+the 'psvi' member.
+
+This changes the public API but this feature is only required to
+implement EXSLT functions.
+
+CVE: CVE-2023-40403
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/ccec6fa31d11ab0a5299f15ea184c7a457e92940]
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+
+---
+ libexslt/functions.c | 2 +-
+ libxslt/transform.c | 8 ++++----
+ libxslt/variables.c | 44 ++++++++++++++++++++---------------------
+ libxslt/variables.h | 6 +++---
+ libxslt/xsltInternals.h | 2 +-
+ 5 files changed, 31 insertions(+), 31 deletions(-)
+
+diff --git a/libexslt/functions.c b/libexslt/functions.c
+index 958bf60..859a992 100644
+--- a/libexslt/functions.c
++++ b/libexslt/functions.c
+@@ -775,7 +775,7 @@ exsltFuncResultElem (xsltTransformContextPtr ctxt,
+ }
+ /* Mark as function result. */
+ xsltRegisterLocalRVT(ctxt, container);
+- container->psvi = XSLT_RVT_FUNC_RESULT;
++ container->compression = XSLT_RVT_FUNC_RESULT;
+
+ oldInsert = ctxt->insert;
+ ctxt->insert = (xmlNodePtr) container;
+diff --git a/libxslt/transform.c b/libxslt/transform.c
+index 40ab810..19d7326 100644
+--- a/libxslt/transform.c
++++ b/libxslt/transform.c
+@@ -2276,17 +2276,17 @@ xsltReleaseLocalRVTs(xsltTransformContextPtr ctxt, xmlDocPtr base)
+ do {
+ tmp = cur;
+ cur = (xmlDocPtr) cur->next;
+- if (tmp->psvi == XSLT_RVT_LOCAL) {
++ if (tmp->compression == XSLT_RVT_LOCAL) {
+ xsltReleaseRVT(ctxt, tmp);
+- } else if (tmp->psvi == XSLT_RVT_GLOBAL) {
++ } else if (tmp->compression == XSLT_RVT_GLOBAL) {
+ xsltRegisterPersistRVT(ctxt, tmp);
+- } else if (tmp->psvi == XSLT_RVT_FUNC_RESULT) {
++ } else if (tmp->compression == XSLT_RVT_FUNC_RESULT) {
+ /*
+ * This will either register the RVT again or move it to the
+ * context variable.
+ */
+ xsltRegisterLocalRVT(ctxt, tmp);
+- tmp->psvi = XSLT_RVT_FUNC_RESULT;
++ tmp->compression = XSLT_RVT_FUNC_RESULT;
+ } else {
+ xmlGenericError(xmlGenericErrorContext,
+ "xsltReleaseLocalRVTs: Unexpected RVT flag %p\n",
+diff --git a/libxslt/variables.c b/libxslt/variables.c
+index 4c972a4..dab0bab 100644
+--- a/libxslt/variables.c
++++ b/libxslt/variables.c
+@@ -123,7 +123,7 @@ xsltRegisterTmpRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
+ return(-1);
+
+ RVT->prev = NULL;
+- RVT->psvi = XSLT_RVT_LOCAL;
++ RVT->compression = XSLT_RVT_LOCAL;
+
+ /*
+ * We'll restrict the lifetime of user-created fragments
+@@ -163,7 +163,7 @@ xsltRegisterLocalRVT(xsltTransformContextPtr ctxt,
+ return(-1);
+
+ RVT->prev = NULL;
+- RVT->psvi = XSLT_RVT_LOCAL;
++ RVT->compression = XSLT_RVT_LOCAL;
+
+ /*
+ * When evaluating "select" expressions of xsl:variable
+@@ -255,7 +255,7 @@ xsltExtensionInstructionResultRegister(
+ * Returns 0 in case of success and -1 in case of error.
+ */
+ int
+-xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) {
++xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, int val) {
+ int i;
+ xmlNodePtr cur;
+ xmlDocPtr doc;
+@@ -302,34 +302,34 @@ xsltFlagRVTs(xsltTransformContextPtr ctxt, xmlXPathObjectPtr obj, void *val) {
+ return(-1);
+ }
+ if (doc->name && (doc->name[0] == ' ') &&
+- doc->psvi != XSLT_RVT_GLOBAL) {
++ doc->compression != XSLT_RVT_GLOBAL) {
+ /*
+ * This is a result tree fragment.
+- * We store ownership information in the @psvi field.
++ * We store ownership information in the @compression field.
+ * TODO: How do we know if this is a doc acquired via the
+ * document() function?
+ */
+ #ifdef WITH_XSLT_DEBUG_VARIABLE
+ XSLT_TRACE(ctxt,XSLT_TRACE_VARIABLES,xsltGenericDebug(xsltGenericDebugContext,
+- "Flagging RVT %p: %p -> %p\n", doc, doc->psvi, val));
++ "Flagging RVT %p: %d -> %d\n", doc, doc->compression, val));
+ #endif
+
+ if (val == XSLT_RVT_LOCAL) {
+- if (doc->psvi == XSLT_RVT_FUNC_RESULT)
+- doc->psvi = XSLT_RVT_LOCAL;
++ if (doc->compression == XSLT_RVT_FUNC_RESULT)
++ doc->compression = XSLT_RVT_LOCAL;
+ } else if (val == XSLT_RVT_GLOBAL) {
+- if (doc->psvi != XSLT_RVT_LOCAL) {
++ if (doc->compression != XSLT_RVT_LOCAL) {
+ xmlGenericError(xmlGenericErrorContext,
+- "xsltFlagRVTs: Invalid transition %p => GLOBAL\n",
+- doc->psvi);
+- doc->psvi = XSLT_RVT_GLOBAL;
++ "xsltFlagRVTs: Invalid transition %d => GLOBAL\n",
++ doc->compression);
++ doc->compression = XSLT_RVT_GLOBAL;
+ return(-1);
+ }
+
+ /* Will be registered as persistant in xsltReleaseLocalRVTs. */
+- doc->psvi = XSLT_RVT_GLOBAL;
++ doc->compression = XSLT_RVT_GLOBAL;
+ } else if (val == XSLT_RVT_FUNC_RESULT) {
+- doc->psvi = val;
++ doc->compression = val;
+ }
+ }
+ }
+@@ -382,7 +382,7 @@ xsltReleaseRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
+ /*
+ * Reset the ownership information.
+ */
+- RVT->psvi = NULL;
++ RVT->compression = 0;
+
+ RVT->next = (xmlNodePtr) ctxt->cache->RVT;
+ ctxt->cache->RVT = RVT;
+@@ -421,7 +421,7 @@ xsltRegisterPersistRVT(xsltTransformContextPtr ctxt, xmlDocPtr RVT)
+ {
+ if ((ctxt == NULL) || (RVT == NULL)) return(-1);
+
+- RVT->psvi = XSLT_RVT_GLOBAL;
++ RVT->compression = XSLT_RVT_GLOBAL;
+ RVT->prev = NULL;
+ RVT->next = (xmlNodePtr) ctxt->persistRVT;
+ if (ctxt->persistRVT != NULL)
+@@ -580,15 +580,15 @@ xsltFreeStackElem(xsltStackElemPtr elem) {
+ cur = elem->fragment;
+ elem->fragment = (xmlDocPtr) cur->next;
+
+- if (cur->psvi == XSLT_RVT_LOCAL) {
++ if (cur->compression == XSLT_RVT_LOCAL) {
+ xsltReleaseRVT(elem->context, cur);
+- } else if (cur->psvi == XSLT_RVT_FUNC_RESULT) {
++ } else if (cur->compression == XSLT_RVT_FUNC_RESULT) {
+ xsltRegisterLocalRVT(elem->context, cur);
+- cur->psvi = XSLT_RVT_FUNC_RESULT;
++ cur->compression = XSLT_RVT_FUNC_RESULT;
+ } else {
+ xmlGenericError(xmlGenericErrorContext,
+- "xsltFreeStackElem: Unexpected RVT flag %p\n",
+- cur->psvi);
++ "xsltFreeStackElem: Unexpected RVT flag %d\n",
++ cur->compression);
+ }
+ }
+ }
+@@ -989,7 +989,7 @@ xsltEvalVariable(xsltTransformContextPtr ctxt, xsltStackElemPtr variable,
+ * the Result Tree Fragment.
+ */
+ variable->fragment = container;
+- container->psvi = XSLT_RVT_LOCAL;
++ container->compression = XSLT_RVT_LOCAL;
+
+ oldOutput = ctxt->output;
+ oldInsert = ctxt->insert;
+diff --git a/libxslt/variables.h b/libxslt/variables.h
+index 039288f..e2adee0 100644
+--- a/libxslt/variables.h
++++ b/libxslt/variables.h
+@@ -43,7 +43,7 @@ extern "C" {
+ *
+ * RVT is destroyed after the current instructions ends.
+ */
+-#define XSLT_RVT_LOCAL ((void *)1)
++#define XSLT_RVT_LOCAL 1
+
+ /**
+ * XSLT_RVT_FUNC_RESULT:
+@@ -52,14 +52,14 @@ extern "C" {
+ * destroyed after exiting a template and will be reset to XSLT_RVT_LOCAL or
+ * XSLT_RVT_VARIABLE in the template that receives the return value.
+ */
+-#define XSLT_RVT_FUNC_RESULT ((void *)2)
++#define XSLT_RVT_FUNC_RESULT 2
+
+ /**
+ * XSLT_RVT_GLOBAL:
+ *
+ * RVT is part of a global variable.
+ */
+-#define XSLT_RVT_GLOBAL ((void *)3)
++#define XSLT_RVT_GLOBAL 3
+
+ /*
+ * Interfaces for the variable module.
+diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
+index b0125c2..74a2b64 100644
+--- a/libxslt/xsltInternals.h
++++ b/libxslt/xsltInternals.h
+@@ -1916,7 +1916,7 @@ XSLTPUBFUN int XSLTCALL
+ xsltFlagRVTs(
+ xsltTransformContextPtr ctxt,
+ xmlXPathObjectPtr obj,
+- void *val);
++ int val);
+ XSLTPUBFUN void XSLTCALL
+ xsltFreeRVTs (xsltTransformContextPtr ctxt);
+ XSLTPUBFUN void XSLTCALL
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-004.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-004.patch
new file mode 100644
index 0000000000..59e7c1bad3
--- /dev/null
+++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-004.patch
@@ -0,0 +1,349 @@
+From 91c9c56dcca01bfe3f9dae74fb75dcf792ebe58b Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Wed, 31 Aug 2022 13:35:23 +0200
+Subject: [PATCH] Make generate-id() deterministic
+
+Rework the generate-id() function to return deterministic values. We use
+a simple incrementing counter and store ids in the 'psvi' member of
+nodes which was freed up by previous commits. The presence of an id is
+indicated by a new "source node" flag.
+
+This fixes long-standing problems with reproducible builds, see
+https://bugzilla.gnome.org/show_bug.cgi?id=751621
+
+This also hardens security, as the old implementation leaked the
+difference between a heap and a global pointer, see
+https://bugs.chromium.org/p/chromium/issues/detail?id=1356211
+
+The old implementation could also generate the same id for dynamically
+created nodes which happened to reuse the same memory. Ids for namespace
+nodes were completely broken. They now use the id of the parent element
+together with the hex-encoded namespace prefix.
+
+CVE: CVE-2023-40403
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/82f6cbf8ca61b1f9e00dc04aa3b15d563e7bbc6d]
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+
+---
+ libxslt/functions.c | 107 +++++++++++++++++++++++++-----
+ libxslt/xsltInternals.h | 1 +
+ libxslt/xsltutils.h | 1 +
+ tests/REC/test-12.4-1.out | 11 +++
+ tests/REC/test-12.4-1.xml | 6 ++
+ tests/REC/test-12.4-1.xsl | 38 +++++++++++
+ tests/exslt/common/dynamic-id.out | 13 ++++
+ tests/exslt/common/dynamic-id.xml | 1 +
+ tests/exslt/common/dynamic-id.xsl | 29 ++++++++
+ 9 files changed, 191 insertions(+), 16 deletions(-)
+ create mode 100644 tests/REC/test-12.4-1.out
+ create mode 100644 tests/REC/test-12.4-1.xml
+ create mode 100644 tests/REC/test-12.4-1.xsl
+ create mode 100644 tests/exslt/common/dynamic-id.out
+ create mode 100644 tests/exslt/common/dynamic-id.xml
+ create mode 100644 tests/exslt/common/dynamic-id.xsl
+
+diff --git a/libxslt/functions.c b/libxslt/functions.c
+index 7887dda..da25c24 100644
+--- a/libxslt/functions.c
++++ b/libxslt/functions.c
+@@ -693,11 +693,16 @@ xsltFormatNumberFunction(xmlXPathParserContextPtr ctxt, int nargs)
+ */
+ void
+ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
+- static char base_address;
++ xsltTransformContextPtr tctxt;
+ xmlNodePtr cur = NULL;
+ xmlXPathObjectPtr obj = NULL;
+- long val;
+- xmlChar str[30];
++ char *str;
++ const xmlChar *nsPrefix = NULL;
++ void **psviPtr;
++ unsigned long id;
++ size_t size, nsPrefixSize;
++
++ tctxt = xsltXPathGetTransformContext(ctxt);
+
+ if (nargs == 0) {
+ cur = ctxt->context->node;
+@@ -707,16 +712,15 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
+
+ if ((ctxt->value == NULL) || (ctxt->value->type != XPATH_NODESET)) {
+ ctxt->error = XPATH_INVALID_TYPE;
+- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
++ xsltTransformError(tctxt, NULL, NULL,
+ "generate-id() : invalid arg expecting a node-set\n");
+- return;
++ goto out;
+ }
+ obj = valuePop(ctxt);
+ nodelist = obj->nodesetval;
+ if ((nodelist == NULL) || (nodelist->nodeNr <= 0)) {
+- xmlXPathFreeObject(obj);
+ valuePush(ctxt, xmlXPathNewCString(""));
+- return;
++ goto out;
+ }
+ cur = nodelist->nodeTab[0];
+ for (i = 1;i < nodelist->nodeNr;i++) {
+@@ -725,22 +729,93 @@ xsltGenerateIdFunction(xmlXPathParserContextPtr ctxt, int nargs){
+ cur = nodelist->nodeTab[i];
+ }
+ } else {
+- xsltTransformError(xsltXPathGetTransformContext(ctxt), NULL, NULL,
++ xsltTransformError(tctxt, NULL, NULL,
+ "generate-id() : invalid number of args %d\n", nargs);
+ ctxt->error = XPATH_INVALID_ARITY;
+- return;
++ goto out;
++ }
++
++ size = 30; /* for "id%lu" */
++
++ if (cur->type == XML_NAMESPACE_DECL) {
++ xmlNsPtr ns = (xmlNsPtr) cur;
++
++ nsPrefix = ns->prefix;
++ if (nsPrefix == NULL)
++ nsPrefix = BAD_CAST "";
++ nsPrefixSize = xmlStrlen(nsPrefix);
++ /* For "ns" and hex-encoded string */
++ size += nsPrefixSize * 2 + 2;
++
++ /* Parent is stored in 'next'. */
++ cur = (xmlNodePtr) ns->next;
++ }
++
++ psviPtr = xsltGetPSVIPtr(cur);
++ if (psviPtr == NULL) {
++ xsltTransformError(tctxt, NULL, NULL,
++ "generate-id(): invalid node type %d\n", cur->type);
++ ctxt->error = XPATH_INVALID_TYPE;
++ goto out;
+ }
+
+- if (obj)
+- xmlXPathFreeObject(obj);
++ if (xsltGetSourceNodeFlags(cur) & XSLT_SOURCE_NODE_HAS_ID) {
++ id = (unsigned long) *psviPtr;
++ } else {
++ if (cur->type == XML_TEXT_NODE && cur->line == USHRT_MAX) {
++ /* Text nodes store big line numbers in psvi. */
++ cur->line = 0;
++ } else if (*psviPtr != NULL) {
++ xsltTransformError(tctxt, NULL, NULL,
++ "generate-id(): psvi already set\n");
++ ctxt->error = XPATH_MEMORY_ERROR;
++ goto out;
++ }
++
++ if (tctxt->currentId == ULONG_MAX) {
++ xsltTransformError(tctxt, NULL, NULL,
++ "generate-id(): id overflow\n");
++ ctxt->error = XPATH_MEMORY_ERROR;
++ goto out;
++ }
++
++ id = ++tctxt->currentId;
++ *psviPtr = (void *) id;
++ xsltSetSourceNodeFlags(tctxt, cur, XSLT_SOURCE_NODE_HAS_ID);
++ }
+
+- val = (long)((char *)cur - (char *)&base_address);
+- if (val >= 0) {
+- snprintf((char *)str, sizeof(str), "idp%ld", val);
++ str = xmlMalloc(size);
++ if (str == NULL) {
++ xsltTransformError(tctxt, NULL, NULL,
++ "generate-id(): out of memory\n");
++ ctxt->error = XPATH_MEMORY_ERROR;
++ goto out;
++ }
++ if (nsPrefix == NULL) {
++ snprintf(str, size, "id%lu", id);
+ } else {
+- snprintf((char *)str, sizeof(str), "idm%ld", -val);
++ size_t i, j;
++
++ snprintf(str, size, "id%luns", id);
++
++ /*
++ * Only ASCII alphanumerics are allowed, so we hex-encode the prefix.
++ */
++ j = strlen(str);
++ for (i = 0; i < nsPrefixSize; i++) {
++ int v;
++
++ v = nsPrefix[i] >> 4;
++ str[j++] = v < 10 ? '0' + v : 'A' + (v - 10);
++ v = nsPrefix[i] & 15;
++ str[j++] = v < 10 ? '0' + v : 'A' + (v - 10);
++ }
++ str[j] = '\0';
+ }
+- valuePush(ctxt, xmlXPathNewString(str));
++ valuePush(ctxt, xmlXPathWrapString(BAD_CAST str));
++
++out:
++ xmlXPathFreeObject(obj);
+ }
+
+ /**
+diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
+index 74a2b64..2fd1f68 100644
+--- a/libxslt/xsltInternals.h
++++ b/libxslt/xsltInternals.h
+@@ -1787,6 +1787,7 @@ struct _xsltTransformContext {
+ unsigned long opLimit;
+ unsigned long opCount;
+ int sourceDocDirty;
++ unsigned long currentId; /* For generate-id() */
+ };
+
+ /**
+diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
+index dcfd139..6c14ecf 100644
+--- a/libxslt/xsltutils.h
++++ b/libxslt/xsltutils.h
+@@ -250,6 +250,7 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
+ #ifdef IN_LIBXSLT
+ #define XSLT_SOURCE_NODE_MASK 15
+ #define XSLT_SOURCE_NODE_HAS_KEY 1
++#define XSLT_SOURCE_NODE_HAS_ID 2
+ int
+ xsltGetSourceNodeFlags(xmlNodePtr node);
+ int
+diff --git a/tests/REC/test-12.4-1.out b/tests/REC/test-12.4-1.out
+new file mode 100644
+index 0000000..237a9f2
+--- /dev/null
++++ b/tests/REC/test-12.4-1.out
+@@ -0,0 +1,11 @@
++<?xml version="1.0"?>
++<result>
++ <document>id1</document>
++ <element>id2</element>
++ <attribute>id3</attribute>
++ <namespace>id2ns</namespace>
++ <namespace>id2nsC3A4C3B6C3BC</namespace>
++ <text>id4</text>
++ <comment>id5</comment>
++ <processing-instruction>id6</processing-instruction>
++</result>
+diff --git a/tests/REC/test-12.4-1.xml b/tests/REC/test-12.4-1.xml
+new file mode 100644
+index 0000000..84484f6
+--- /dev/null
++++ b/tests/REC/test-12.4-1.xml
+@@ -0,0 +1,6 @@
++<doc xmlns="s:def">
++ <elem attr="value" xmlns:äöü="uri"/>
++ <text>text</text>
++ <!-- comment -->
++ <?pi content?>
++</doc>
+diff --git a/tests/REC/test-12.4-1.xsl b/tests/REC/test-12.4-1.xsl
+new file mode 100644
+index 0000000..5cf5dd3
+--- /dev/null
++++ b/tests/REC/test-12.4-1.xsl
+@@ -0,0 +1,38 @@
++<xsl:stylesheet
++ version="1.0"
++ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
++ xmlns:d="s:def"
++ exclude-result-prefixes="d">
++
++<xsl:output indent="yes"/>
++
++<xsl:template match="/">
++ <result>
++ <document>
++ <xsl:value-of select="generate-id(/)"/>
++ </document>
++ <element>
++ <xsl:value-of select="generate-id(/d:doc/d:elem)"/>
++ </element>
++ <attribute>
++ <xsl:value-of select="generate-id(d:doc/d:elem/@attr)"/>
++ </attribute>
++ <namespace>
++ <xsl:value-of select="generate-id(d:doc/d:elem/namespace::*[local-name()=''])"/>
++ </namespace>
++ <namespace>
++ <xsl:value-of select="generate-id(d:doc/d:elem/namespace::äöü)"/>
++ </namespace>
++ <text>
++ <xsl:value-of select="generate-id(d:doc/d:text/text())"/>
++ </text>
++ <comment>
++ <xsl:value-of select="generate-id(d:doc/comment())"/>
++ </comment>
++ <processing-instruction>
++ <xsl:value-of select="generate-id(d:doc/processing-instruction())"/>
++ </processing-instruction>
++ </result>
++</xsl:template>
++
++</xsl:stylesheet>
+diff --git a/tests/exslt/common/dynamic-id.out b/tests/exslt/common/dynamic-id.out
+new file mode 100644
+index 0000000..1b7b7ba
+--- /dev/null
++++ b/tests/exslt/common/dynamic-id.out
+@@ -0,0 +1,13 @@
++<?xml version="1.0"?>
++<result xmlns:exsl="http://exslt.org/common">
++ <id>id1</id>
++ <id>id2</id>
++ <id>id3</id>
++ <id>id4</id>
++ <id>id5</id>
++ <id>id6</id>
++ <id>id7</id>
++ <id>id8</id>
++ <id>id9</id>
++ <id>id10</id>
++</result>
+diff --git a/tests/exslt/common/dynamic-id.xml b/tests/exslt/common/dynamic-id.xml
+new file mode 100644
+index 0000000..69d62f2
+--- /dev/null
++++ b/tests/exslt/common/dynamic-id.xml
+@@ -0,0 +1 @@
++<doc/>
+diff --git a/tests/exslt/common/dynamic-id.xsl b/tests/exslt/common/dynamic-id.xsl
+new file mode 100644
+index 0000000..8478f6a
+--- /dev/null
++++ b/tests/exslt/common/dynamic-id.xsl
+@@ -0,0 +1,29 @@
++<xsl:stylesheet
++ version="1.0"
++ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
++ xmlns:exsl="http://exslt.org/common">
++
++<xsl:output indent="yes"/>
++
++<xsl:template name="dynamic-id">
++ <id>
++ <xsl:value-of select="generate-id(exsl:node-set('string'))"/>
++ </id>
++</xsl:template>
++
++<xsl:template match="/">
++ <result>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ <xsl:call-template name="dynamic-id"/>
++ </result>
++</xsl:template>
++
++</xsl:stylesheet>
diff --git a/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-005.patch b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-005.patch
new file mode 100644
index 0000000000..e27034a0ec
--- /dev/null
+++ b/meta/recipes-support/libxslt/libxslt/CVE-2023-40403-005.patch
@@ -0,0 +1,55 @@
+From 3014af50b22f1be89b5514faea284de7b63fa5dc Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Wed, 31 Aug 2022 21:37:44 +0200
+Subject: [PATCH] Clean up attributes in source doc
+
+Also make bit flag constants unsigned to avoid implicit-conversion
+warnings.
+
+CVE: CVE-2023-40403
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxslt/-/commit/452fb4ca9b9803448826008b9573987c615912a1]
+Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
+
+---
+ libxslt/transform.c | 10 ++++++++++
+ libxslt/xsltutils.h | 6 +++---
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/libxslt/transform.c b/libxslt/transform.c
+index 19d7326..7299eb5 100644
+--- a/libxslt/transform.c
++++ b/libxslt/transform.c
+@@ -5764,6 +5764,16 @@ xsltCleanupSourceDoc(xmlDocPtr doc) {
+ if (psviPtr)
+ *psviPtr = NULL;
+
++ if (cur->type == XML_ELEMENT_NODE) {
++ xmlAttrPtr prop = cur->properties;
++
++ while (prop) {
++ prop->atype &= ~(XSLT_SOURCE_NODE_MASK << 27);
++ prop->psvi = NULL;
++ prop = prop->next;
++ }
++ }
++
+ if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) {
+ cur = cur->children;
+ } else {
+diff --git a/libxslt/xsltutils.h b/libxslt/xsltutils.h
+index 6c14ecf..2af4282 100644
+--- a/libxslt/xsltutils.h
++++ b/libxslt/xsltutils.h
+@@ -248,9 +248,9 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
+ int flags);
+
+ #ifdef IN_LIBXSLT
+-#define XSLT_SOURCE_NODE_MASK 15
+-#define XSLT_SOURCE_NODE_HAS_KEY 1
+-#define XSLT_SOURCE_NODE_HAS_ID 2
++#define XSLT_SOURCE_NODE_MASK 15u
++#define XSLT_SOURCE_NODE_HAS_KEY 1u
++#define XSLT_SOURCE_NODE_HAS_ID 2u
+ int
+ xsltGetSourceNodeFlags(xmlNodePtr node);
+ int
diff --git a/meta/recipes-support/libxslt/libxslt_1.1.35.bb b/meta/recipes-support/libxslt/libxslt_1.1.35.bb
index 3df372b267..2291ed2cad 100644
--- a/meta/recipes-support/libxslt/libxslt_1.1.35.bb
+++ b/meta/recipes-support/libxslt/libxslt_1.1.35.bb
@@ -16,6 +16,11 @@ DEPENDS = "libxml2"
SRC_URI = "https://download.gnome.org/sources/libxslt/1.1/libxslt-${PV}.tar.xz \
file://CVE-2024-55549.patch \
file://CVE-2025-24855.patch \
+ file://CVE-2023-40403-001.patch \
+ file://CVE-2023-40403-002.patch \
+ file://CVE-2023-40403-003.patch \
+ file://CVE-2023-40403-004.patch \
+ file://CVE-2023-40403-005.patch \
"
SRC_URI[sha256sum] = "8247f33e9a872c6ac859aa45018bc4c4d00b97e2feac9eebc10c93ce1f34dd79"
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [OE-core][kirkstone 7/8] gnupg: disable tests to avoid running target binaries at build time
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
` (5 preceding siblings ...)
2025-08-13 21:28 ` [OE-core][kirkstone 6/8] libxslt: fix CVE-2023-40403 Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
2025-08-13 21:28 ` [OE-core][kirkstone 8/8] go-helloworld: fix license Steve Sakoman
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Guocai He <guocai.he.cn@windriver.com>
By default, the tests are built and run at do_compile and we can see
errors like below in log.do_compile:
gnupg-2.3.7/tests/cms/inittests: line 99: ../../sm/gpgsm: cannot execute binary file: Exec format error
Note that the do_compile process still succeeds. However, we'd better avoid
executing these target binaries at build time.
Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(master rev: 74d48497470ce209bc6bdf49c2e2cfda67dce6ae)
Signed-off-by: Guocai He <guocai.he.cn@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
meta/recipes-support/gnupg/gnupg_2.3.7.bb | 1 +
1 file changed, 1 insertion(+)
diff --git a/meta/recipes-support/gnupg/gnupg_2.3.7.bb b/meta/recipes-support/gnupg/gnupg_2.3.7.bb
index 461ec6687c..27b2d3682a 100644
--- a/meta/recipes-support/gnupg/gnupg_2.3.7.bb
+++ b/meta/recipes-support/gnupg/gnupg_2.3.7.bb
@@ -37,6 +37,7 @@ EXTRA_OECONF = "--disable-ldap \
--with-readline=${STAGING_LIBDIR}/.. \
--with-mailprog=${sbindir}/sendmail \
--enable-gpg-is-gpg2 \
+ --disable-tests \
"
# A minimal package containing just enough to run gpg+gpgagent (E.g. use gpgme in opkg)
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread* [OE-core][kirkstone 8/8] go-helloworld: fix license
2025-08-13 21:28 [OE-core][kirkstone 0/8] Patch review Steve Sakoman
` (6 preceding siblings ...)
2025-08-13 21:28 ` [OE-core][kirkstone 7/8] gnupg: disable tests to avoid running target binaries at build time Steve Sakoman
@ 2025-08-13 21:28 ` Steve Sakoman
7 siblings, 0 replies; 24+ messages in thread
From: Steve Sakoman @ 2025-08-13 21:28 UTC (permalink / raw)
To: openembedded-core
From: Quentin Schulz <quentin.schulz@cherry.de>
The example repo doesn't seem to have ever been under MIT to begin with
but rather Apache-2.0.
The license file exists in the sources, so use that one instead of
taking it from the OE-Core license directory.
License-Update: Incorrect license is now proper
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
meta/recipes-extended/go-examples/go-helloworld_0.1.bb | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/meta/recipes-extended/go-examples/go-helloworld_0.1.bb b/meta/recipes-extended/go-examples/go-helloworld_0.1.bb
index 0055b32d60..5a9d138b9c 100644
--- a/meta/recipes-extended/go-examples/go-helloworld_0.1.bb
+++ b/meta/recipes-extended/go-examples/go-helloworld_0.1.bb
@@ -2,8 +2,8 @@ DESCRIPTION = "This is a simple example recipe that cross-compiles a Go program.
SECTION = "examples"
HOMEPAGE = "https://golang.org/"
-LICENSE = "MIT"
-LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://src/${GO_IMPORT}/LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
SRC_URI = "git://go.googlesource.com/example;branch=master;protocol=https"
SRCREV = "787a929d5a0dfb8bbfcdd2c4a62e0fd89466113f"
--
2.43.0
^ permalink raw reply related [flat|nested] 24+ messages in thread