mirror of
https://git.yoctoproject.org/poky
synced 2026-02-21 00:49:41 +01:00
Compare commits
85 Commits
yocto-4.0.
...
yocto-4.0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04b39e5b7e | ||
|
|
8d5cd4a310 | ||
|
|
59579acac7 | ||
|
|
56aa9e3241 | ||
|
|
ea90d0a5b1 | ||
|
|
9e1c28514a | ||
|
|
24772dd301 | ||
|
|
5f0dcc1dc6 | ||
|
|
8d8972d1b4 | ||
|
|
9626809dce | ||
|
|
3fe029171f | ||
|
|
9a4c708aa5 | ||
|
|
2442316a1e | ||
|
|
48ab50b55c | ||
|
|
bee2fe9cc5 | ||
|
|
d0f445a1e2 | ||
|
|
0118bd1e10 | ||
|
|
7ca21c761a | ||
|
|
4e75dd0f5f | ||
|
|
75cb79eaf5 | ||
|
|
5abe7f3283 | ||
|
|
9a1d2ff9d0 | ||
|
|
2b691e84d8 | ||
|
|
41ae63737b | ||
|
|
ca6745e603 | ||
|
|
d847c8aac1 | ||
|
|
1bf7d50410 | ||
|
|
b48d3ea982 | ||
|
|
42b3adafcc | ||
|
|
2105de9c82 | ||
|
|
dd624cec3b | ||
|
|
2fdbec72e5 | ||
|
|
7b6bc5b49c | ||
|
|
0c1db5ac27 | ||
|
|
8f20ad5f77 | ||
|
|
74672d72c0 | ||
|
|
f245c680a8 | ||
|
|
2325a1dbc5 | ||
|
|
2952d99f0f | ||
|
|
962d08fb40 | ||
|
|
425363de54 | ||
|
|
e5fb48f371 | ||
|
|
259d81175f | ||
|
|
eca1e13385 | ||
|
|
e46adde7bb | ||
|
|
d34a0bd00b | ||
|
|
11f3763b0f | ||
|
|
89a78911d7 | ||
|
|
673b839a6b | ||
|
|
f63f49bdea | ||
|
|
7a5c6b3e18 | ||
|
|
5d1ccbd52f | ||
|
|
c95f2e55ac | ||
|
|
02148028a0 | ||
|
|
093e91d190 | ||
|
|
0163ca382a | ||
|
|
0adb465b9e | ||
|
|
ca3783f70d | ||
|
|
b5a57a04eb | ||
|
|
ed56389e82 | ||
|
|
4a1254610c | ||
|
|
4ef41425c6 | ||
|
|
db50dd87bc | ||
|
|
2b82706dc5 | ||
|
|
bc7377a239 | ||
|
|
7f12221f49 | ||
|
|
11d8b290dd | ||
|
|
55c58356f1 | ||
|
|
3c3b5d0fe9 | ||
|
|
3ff44348f7 | ||
|
|
1f6c798015 | ||
|
|
fd0df2cb78 | ||
|
|
ffd5cd98d6 | ||
|
|
794b42f01a | ||
|
|
11999973cb | ||
|
|
49a5ab4d5f | ||
|
|
d153a3dc36 | ||
|
|
2399c63ca5 | ||
|
|
866395041f | ||
|
|
6303a9d5b5 | ||
|
|
1811a2d13e | ||
|
|
15dd68bda1 | ||
|
|
9c9c706252 | ||
|
|
d2a96dd89c | ||
|
|
9ae3736eb4 |
@@ -123,110 +123,116 @@ to add the upgraded version.
|
||||
|
||||
$ git commit -s file1 file2 dir1 dir2 ...
|
||||
|
||||
To include **a**\ ll staged files::
|
||||
To include all staged files::
|
||||
|
||||
$ git commit -sa
|
||||
|
||||
- The ``-s`` option of ``git commit`` adds a "Signed-off-by:" line
|
||||
to your commit message. There is the same requirement for contributing
|
||||
to the Linux kernel. Adding such a line signifies that you, the
|
||||
submitter, have agreed to the `Developer's Certificate of Origin 1.1
|
||||
<https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin>`__
|
||||
as follows:
|
||||
#. The ``-s`` option of ``git commit`` adds a "Signed-off-by:" line
|
||||
to your commit message. There is the same requirement for contributing
|
||||
to the Linux kernel. Adding such a line signifies that you, the
|
||||
submitter, have agreed to the `Developer's Certificate of Origin 1.1
|
||||
<https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin>`__
|
||||
as follows:
|
||||
|
||||
.. code-block:: none
|
||||
.. code-block:: none
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
|
||||
- Provide a single-line summary of the change and, if more
|
||||
explanation is needed, provide more detail in the body of the
|
||||
commit. This summary is typically viewable in the "shortlist" of
|
||||
changes. Thus, providing something short and descriptive that
|
||||
gives the reader a summary of the change is useful when viewing a
|
||||
list of many commits. You should prefix this short description
|
||||
with the recipe name (if changing a recipe), or else with the
|
||||
short form path to the file being changed.
|
||||
#. Provide a single-line summary of the change and, if more
|
||||
explanation is needed, provide more detail in the description of the
|
||||
commit. This summary is typically viewable in the "shortlist" of
|
||||
changes. Thus, providing something short and descriptive that
|
||||
gives the reader a summary of the change is useful when viewing a
|
||||
list of many commits. You should prefix this short description
|
||||
with the recipe name (if changing a recipe), or else with the
|
||||
short form path to the file being changed.
|
||||
|
||||
.. note::
|
||||
|
||||
To find a suitable prefix for the commit summary, a good idea
|
||||
is to look for prefixes used in previous commits touching the
|
||||
same files or directories::
|
||||
|
||||
git log --oneline <paths>
|
||||
|
||||
#. For the commit description, provide detailed information
|
||||
that describes what you changed, why you made the change, and the
|
||||
approach you used. It might also be helpful if you mention how you
|
||||
tested the change. Provide as much detail as you can in the commit
|
||||
description.
|
||||
|
||||
.. note::
|
||||
|
||||
If the single line summary is enough to describe a simple
|
||||
change, the commit description can be left empty.
|
||||
|
||||
#. If the change addresses a specific bug or issue that is associated
|
||||
with a bug-tracking ID, include a reference to that ID in the body of the
|
||||
commit message. For example, the Yocto Project uses a
|
||||
specific convention for bug references --- any commit that addresses
|
||||
a specific bug should use the following form for the body of the commit
|
||||
message. Be sure to use the actual bug-tracking ID from
|
||||
Bugzilla for bug-id::
|
||||
|
||||
single-line summary of change
|
||||
|
||||
Fixes [YOCTO #bug-id]
|
||||
|
||||
detailed description of change
|
||||
|
||||
#. If other people participated in this patch, add some tags to the commit
|
||||
description to credit other contributors to the change:
|
||||
|
||||
- ``Reported-by``: name and email of a person reporting a bug
|
||||
that your commit is trying to fix. This is a good practice
|
||||
to encourage people to go on reporting bugs and let them
|
||||
know that their reports are taken into account.
|
||||
|
||||
- ``Suggested-by``: name and email of a person to credit for the
|
||||
idea of making the change.
|
||||
|
||||
- ``Tested-by``, ``Reviewed-by``: name and email for people having
|
||||
tested your changes or reviewed their code. These fields are
|
||||
usually added by the maintainer accepting a patch, or by
|
||||
yourself if you submitted your patches to early reviewers,
|
||||
or are submitting an unmodified patch again as part of a
|
||||
new iteration of your patch series.
|
||||
|
||||
- ``Cc``: name and email of people you want to send a copy
|
||||
of your changes to. This field will be used by ``git send-email``.
|
||||
|
||||
See `more guidance about using such tags
|
||||
<https://www.kernel.org/doc/html/latest/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes>`__
|
||||
in the Linux kernel documentation.
|
||||
|
||||
.. note::
|
||||
|
||||
To find a suitable prefix for the commit summary, a good idea
|
||||
is to look for prefixes used in previous commits touching the
|
||||
same files or directories::
|
||||
|
||||
git log --oneline <paths>
|
||||
|
||||
- For the body of the commit message, provide detailed information
|
||||
that describes what you changed, why you made the change, and the
|
||||
approach you used. It might also be helpful if you mention how you
|
||||
tested the change. Provide as much detail as you can in the body
|
||||
of the commit message.
|
||||
|
||||
.. note::
|
||||
|
||||
If the single line summary is enough to describe a simple
|
||||
change, the body of the commit message can be left empty.
|
||||
|
||||
- If the change addresses a specific bug or issue that is associated
|
||||
with a bug-tracking ID, include a reference to that ID in your
|
||||
detailed description. For example, the Yocto Project uses a
|
||||
specific convention for bug references --- any commit that addresses
|
||||
a specific bug should use the following form for the detailed
|
||||
description. Be sure to use the actual bug-tracking ID from
|
||||
Bugzilla for bug-id::
|
||||
|
||||
Fixes [YOCTO #bug-id]
|
||||
|
||||
detailed description of change
|
||||
|
||||
#. *Crediting contributors:* By using the ``git commit --amend`` command,
|
||||
you can add some tags to the commit description to credit other contributors
|
||||
to the change:
|
||||
|
||||
- ``Reported-by``: name and email of a person reporting a bug
|
||||
that your commit is trying to fix. This is a good practice
|
||||
to encourage people to go on reporting bugs and let them
|
||||
know that their reports are taken into account.
|
||||
|
||||
- ``Suggested-by``: name and email of a person to credit for the
|
||||
idea of making the change.
|
||||
|
||||
- ``Tested-by``, ``Reviewed-by``: name and email for people having
|
||||
tested your changes or reviewed their code. These fields are
|
||||
usually added by the maintainer accepting a patch, or by
|
||||
yourself if you submitted your patches to early reviewers,
|
||||
or are submitting an unmodified patch again as part of a
|
||||
new iteration of your patch series.
|
||||
|
||||
- ``CC:`` Name and email of people you want to send a copy
|
||||
of your changes to. This field will be used by ``git send-email``.
|
||||
|
||||
See `more guidance about using such tags
|
||||
<https://www.kernel.org/doc/html/latest/process/submitting-patches.html#using-reported-by-tested-by-reviewed-by-suggested-by-and-fixes>`__
|
||||
in the Linux kernel documentation.
|
||||
One can amend an existing git commit message to add missing tags for
|
||||
contributors with the ``git commit --amend`` command.
|
||||
|
||||
Test your changes
|
||||
-----------------
|
||||
|
||||
@@ -909,6 +909,11 @@ to point to that directory::
|
||||
|
||||
EXTERNALSRC_BUILD:pn-myrecipe = "path-to-your-source-tree"
|
||||
|
||||
.. note::
|
||||
|
||||
The values of :term:`EXTERNALSRC` and :term:`EXTERNALSRC_BUILD`
|
||||
must be absolute paths.
|
||||
|
||||
Replicating a Build Offline
|
||||
===========================
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ known security vulnerabilities, as tracked by the public
|
||||
database.
|
||||
|
||||
The Yocto Project maintains a `list of known vulnerabilities
|
||||
<https://autobuilder.yocto.io/pub/non-release/patchmetrics/>`__
|
||||
<https://valkyrie.yocto.io/pub/non-release/patchmetrics/>`__
|
||||
for packages in Poky and OE-Core, tracking the evolution of the number of
|
||||
unpatched CVEs and the status of patches. Such information is available for
|
||||
the current development version and for each supported release.
|
||||
@@ -235,7 +235,7 @@ products defined in :term:`CVE_PRODUCT`. Then, for each found CVE:
|
||||
The CVE database is stored in :term:`DL_DIR` and can be inspected using
|
||||
``sqlite3`` command as follows::
|
||||
|
||||
sqlite3 downloads/CVE_CHECK/nvdcve_1.1.db .dump | grep CVE-2021-37462
|
||||
sqlite3 downloads/CVE_CHECK/nvd*.db .dump | grep CVE-2021-37462
|
||||
|
||||
When analyzing CVEs, it is recommended to:
|
||||
|
||||
|
||||
@@ -724,13 +724,9 @@ a Raspberry Pi 2, which is based on the Broadcom 2708/2709 chipset::
|
||||
|
||||
KBUILD_DEFCONFIG:raspberrypi2 ?= "bcm2709_defconfig"
|
||||
|
||||
Aside from modifying your kernel recipe and providing your own
|
||||
``defconfig`` file, you need to be sure no files or statements set
|
||||
:term:`SRC_URI` to use a ``defconfig`` other than your "in-tree" file (e.g.
|
||||
a kernel's ``linux-``\ `machine`\ ``.inc`` file). In other words, if the
|
||||
build system detects a statement that identifies an "out-of-tree"
|
||||
``defconfig`` file, that statement will override your
|
||||
:term:`KBUILD_DEFCONFIG` variable.
|
||||
If the build system detects a statement that identifies an "out-of-tree"
|
||||
``defconfig`` file, your :term:`KBUILD_DEFCONFIG` variable will take precedence
|
||||
over it.
|
||||
|
||||
See the
|
||||
:term:`KBUILD_DEFCONFIG`
|
||||
|
||||
@@ -36,3 +36,4 @@ Release 4.0 (kirkstone)
|
||||
release-notes-4.0.27
|
||||
release-notes-4.0.28
|
||||
release-notes-4.0.29
|
||||
release-notes-4.0.30
|
||||
|
||||
170
documentation/migration-guides/release-notes-4.0.30.rst
Normal file
170
documentation/migration-guides/release-notes-4.0.30.rst
Normal file
@@ -0,0 +1,170 @@
|
||||
Release notes for Yocto-4.0.30 (Kirkstone)
|
||||
------------------------------------------
|
||||
|
||||
Security Fixes in Yocto-4.0.30
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- cups: Fix :cve_nist:`2025-58060` and :cve_nist:`2025-58364`
|
||||
- dpkg: Fix :cve_nist:`2025-6297`
|
||||
- ffmpeg: Fix :cve_nist:`2023-6602`, :cve_nist:`2023-6604`, :cve_nist:`2023-6605`,
|
||||
:cve_nist:`2025-1594` and CVE-2025-7700
|
||||
- git: Fix :cve_nist:`2025-27613`, :cve_nist:`2025-27614`, :cve_nist:`2025-46334`,
|
||||
:cve_nist:`2025-46835` and :cve_nist:`2025-48384`
|
||||
- glib-2.0: Fix :cve_nist:`2025-7039`
|
||||
- glib-2.0: Ignore :cve_nist:`2025-4056`
|
||||
- go: Ignore :cve_nist:`2024-24790` and :cve_nist:`2025-0913`
|
||||
- gstreamer1.0-plugins-base: Fix :cve_nist:`2025-47806`, :cve_nist:`2025-47807` and
|
||||
:cve_nist:`2025-47808`
|
||||
- gstreamer1.0-plugins-good: Fix :cve_nist:`2025-47183` and :cve_nist:`2025-47219`
|
||||
- libarchive: Fix :cve_nist:`2025-5918`
|
||||
- libxslt: Fix :cve_nist:`2023-40403`
|
||||
- openssl: Fix :cve_nist:`2023-50781`
|
||||
- python3: Fix :cve_nist:`2025-8194`
|
||||
- qemu: Ignore :cve_nist:`2024-7730`
|
||||
- sqlite3: Revert "sqlite3: patch CVE-2025-7458"
|
||||
- tiff: Fix :cve_nist:`2024-13978`, :cve_nist:`2025-8176`, :cve_nist:`2025-8177`,
|
||||
:cve_nist:`2025-8534` and :cve_nist:`2025-8851`
|
||||
- vim: Fix :cve_nist:`2025-53905` and :cve_nist:`2025-53906`
|
||||
- wpa-supplicant: Fix :cve_nist:`2022-37660`
|
||||
- xserver-xorg: Fix :cve_nist:`2025-49175`, :cve_nist:`2025-49176`, :cve_nist:`2025-49177`,
|
||||
:cve_nist:`2025-49178`, :cve_nist:`2025-49179` and :cve_nist:`2025-49180`
|
||||
|
||||
|
||||
Fixes in Yocto-4.0.30
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- build-appliance-image: Update to kirkstone head revision
|
||||
- default-distrovars.inc: Fix CONNECTIVITY_CHECK_URIS redirect issue
|
||||
- dev-manual/security-subjects.rst: update mailing lists
|
||||
- gnupg: disable tests to avoid running target binaries at build time
|
||||
- go-helloworld: fix license
|
||||
- insane: Ensure that `src-uri-bad` fails correctly
|
||||
- insane: Improve patch warning/error handling
|
||||
- libubootenv: backport patch to fix unknown type name 'size_t'
|
||||
- llvm: fix typo in CVE-2024-0151.patch
|
||||
- migration-guides: add release notes for 4.0.29
|
||||
- overview-manual/yp-intro.rst: fix broken link to article
|
||||
- poky.conf: bump version for 4.0.30
|
||||
- pulseaudio: Add audio group explicitly
|
||||
- ref-manual/classes.rst: document the testexport class
|
||||
- ref-manual/system-requirements.rst: update supported distributions
|
||||
- ref-manual/variables.rst: document :term:`FIT_CONF_PREFIX` :term:`SPL_DTB_BINARY` variable
|
||||
- ref-manual/variables.rst: expand :term:`IMAGE_OVERHEAD_FACTOR` glossary entry
|
||||
- sdk: The main in the C example should return an int
|
||||
- sudo: remove devtool FIXME comment
|
||||
- systemd: Fix manpage build after :cve_nist:`2025-4598`
|
||||
- vim: not adjust script pathnames for native scripts either
|
||||
- vim: upgrade to 9.1.1652
|
||||
|
||||
|
||||
Known Issues in Yocto-4.0.30
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- N/A
|
||||
|
||||
Contributors to Yocto-4.0.30
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Antonin Godard
|
||||
- Archana Polampalli
|
||||
- Dan McGregor
|
||||
- Deepak Rathore
|
||||
- Divya Chellam
|
||||
- Erik Lindsten
|
||||
- Guocai He
|
||||
- Gyorgy Sarvari
|
||||
- Hitendra Prajapati
|
||||
- Jan Vermaete
|
||||
- Jiaying Song
|
||||
- Joao Marcos Costa
|
||||
- Kyungjik Min
|
||||
- Lee Chee Yang
|
||||
- Mingli Yu
|
||||
- Peter Marko
|
||||
- Philip Lorenz
|
||||
- Praveen Kumar
|
||||
- Quentin Schulz
|
||||
- Richard Purdie
|
||||
- Steve Sakoman
|
||||
- Vijay Anusuri
|
||||
- Yogita Urade
|
||||
- Youngseok Jeong
|
||||
|
||||
|
||||
Repositories / Downloads for Yocto-4.0.30
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
poky
|
||||
|
||||
- Repository Location: :yocto_git:`/poky`
|
||||
- Branch: :yocto_git:`kirkstone </poky/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.30 </poky/log/?h=yocto-4.0.30>`
|
||||
- Git Revision: :yocto_git:`51dc9c464de0703bfbc6f1ee71ac9bea20933a45 </poky/commit/?id=51dc9c464de0703bfbc6f1ee71ac9bea20933a45>`
|
||||
- Release Artefact: poky-51dc9c464de0703bfbc6f1ee71ac9bea20933a45
|
||||
- sha: 2b5db0a07598df7684975c0839e6f31515a8e78d366503feb9917ef1ca56c0b2
|
||||
- Download Locations:
|
||||
https://downloads.yoctoproject.org/releases/yocto/yocto-4.0.30/poky-51dc9c464de0703bfbc6f1ee71ac9bea20933a45.tar.bz2
|
||||
https://mirrors.kernel.org/yocto/yocto/yocto-4.0.30/poky-51dc9c464de0703bfbc6f1ee71ac9bea20933a45.tar.bz2
|
||||
|
||||
openembedded-core
|
||||
|
||||
- Repository Location: :oe_git:`/openembedded-core`
|
||||
- Branch: :oe_git:`kirkstone </openembedded-core/log/?h=kirkstone>`
|
||||
- Tag: :oe_git:`yocto-4.0.30 </openembedded-core/log/?h=yocto-4.0.30>`
|
||||
- Git Revision: :oe_git:`d381eeb5e70bd0ce9e78032c909e4a23564f4dd7 </openembedded-core/commit/?id=d381eeb5e70bd0ce9e78032c909e4a23564f4dd7>`
|
||||
- Release Artefact: oecore-d381eeb5e70bd0ce9e78032c909e4a23564f4dd7
|
||||
- sha: 022ab4ef5ac59ac3f01a9dacd8b1d6310cc117c6bed2e86e195ced88e0689c85
|
||||
- Download Locations:
|
||||
https://downloads.yoctoproject.org/releases/yocto/yocto-4.0.30/oecore-d381eeb5e70bd0ce9e78032c909e4a23564f4dd7.tar.bz2
|
||||
https://mirrors.kernel.org/yocto/yocto/yocto-4.0.30/oecore-d381eeb5e70bd0ce9e78032c909e4a23564f4dd7.tar.bz2
|
||||
|
||||
meta-mingw
|
||||
|
||||
- Repository Location: :yocto_git:`/meta-mingw`
|
||||
- Branch: :yocto_git:`kirkstone </meta-mingw/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.30 </meta-mingw/log/?h=yocto-4.0.30>`
|
||||
- Git Revision: :yocto_git:`87c22abb1f11be430caf4372e6b833dc7d77564e </meta-mingw/commit/?id=87c22abb1f11be430caf4372e6b833dc7d77564e>`
|
||||
- Release Artefact: meta-mingw-87c22abb1f11be430caf4372e6b833dc7d77564e
|
||||
- sha: f0bc4873e2e0319fb9d6d6ab9b98eb3f89664d4339a167d2db6a787dd12bc1a8
|
||||
- Download Locations:
|
||||
https://downloads.yoctoproject.org/releases/yocto/yocto-4.0.30/meta-mingw-87c22abb1f11be430caf4372e6b833dc7d77564e.tar.bz2
|
||||
https://mirrors.kernel.org/yocto/yocto/yocto-4.0.30/meta-mingw-87c22abb1f11be430caf4372e6b833dc7d77564e.tar.bz2
|
||||
|
||||
meta-gplv2
|
||||
|
||||
- Repository Location: :yocto_git:`/meta-gplv2`
|
||||
- Branch: :yocto_git:`kirkstone </meta-gplv2/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.30 </meta-gplv2/log/?h=yocto-4.0.30>`
|
||||
- Git Revision: :yocto_git:`d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a </meta-gplv2/commit/?id=d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a>`
|
||||
- Release Artefact: meta-gplv2-d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a
|
||||
- sha: c386f59f8a672747dc3d0be1d4234b6039273d0e57933eb87caa20f56b9cca6d
|
||||
- Download Locations:
|
||||
https://downloads.yoctoproject.org/releases/yocto/yocto-4.0.30/meta-gplv2-d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a.tar.bz2
|
||||
https://mirrors.kernel.org/yocto/yocto/yocto-4.0.30/meta-gplv2-d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a.tar.bz2
|
||||
|
||||
bitbake
|
||||
|
||||
- Repository Location: :oe_git:`/bitbake`
|
||||
- Branch: :oe_git:`2.0 </bitbake/log/?h=2.0>`
|
||||
- Tag: :oe_git:`yocto-4.0.30 </bitbake/log/?h=yocto-4.0.30>`
|
||||
- Git Revision: :oe_git:`8e2d1f8de055549b2101614d85454fcd1d0f94b2 </bitbake/commit/?id=8e2d1f8de055549b2101614d85454fcd1d0f94b2>`
|
||||
- Release Artefact: bitbake-8e2d1f8de055549b2101614d85454fcd1d0f94b2
|
||||
- sha: fad4e7699bae62082118e89785324b031b0af0743064caee87c91ba28549afb0
|
||||
- Download Locations:
|
||||
https://downloads.yoctoproject.org/releases/yocto/yocto-4.0.30/bitbake-8e2d1f8de055549b2101614d85454fcd1d0f94b2.tar.bz2
|
||||
https://mirrors.kernel.org/yocto/yocto/yocto-4.0.30/bitbake-8e2d1f8de055549b2101614d85454fcd1d0f94b2.tar.bz2
|
||||
|
||||
meta-yocto
|
||||
|
||||
- Repository Location: :yocto_git:`/meta-yocto`
|
||||
- Branch: :yocto_git:`kirkstone </meta-yocto/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.30 </meta-yocto/log/?h=yocto-4.0.30>`
|
||||
- Git Revision: :yocto_git:`edf7950e4d81dd31f29a58acdd8022dabd2be494 </meta-yocto/commit/?id=edf7950e4d81dd31f29a58acdd8022dabd2be494>`
|
||||
|
||||
yocto-docs
|
||||
|
||||
- Repository Location: :yocto_git:`/yocto-docs`
|
||||
- Branch: :yocto_git:`kirkstone </yocto-docs/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.30 </yocto-docs/log/?h=yocto-4.0.30>`
|
||||
- Git Revision: :yocto_git:`71a3933c609ce73ff07e5be48d9e7b03f22ef8d7 </yocto-docs/commit/?id=71a3933c609ce73ff07e5be48d9e7b03f22ef8d7>`
|
||||
|
||||
@@ -309,8 +309,12 @@ file for details about how to enable this mechanism in your configuration
|
||||
file, how to disable it for specific recipes, and how to share ``ccache``
|
||||
files between builds.
|
||||
|
||||
However, using the class can lead to unexpected side-effects. Thus, using
|
||||
this class is not recommended.
|
||||
Recipes can also explicitly disable `Ccache` support even when the
|
||||
:ref:`ref-classes-ccache` class is enabled, by setting the
|
||||
:term:`CCACHE_DISABLE` variable to "1".
|
||||
|
||||
Using the :ref:`ref-classes-ccache` class can lead to unexpected side-effects.
|
||||
Using this class is not recommended.
|
||||
|
||||
.. _ref-classes-chrpath:
|
||||
|
||||
@@ -825,6 +829,14 @@ software that uses the GNU ``gettext`` internationalization and localization
|
||||
system. All recipes building software that use ``gettext`` should inherit this
|
||||
class.
|
||||
|
||||
This class will configure recipes to build translations *unless*:
|
||||
|
||||
- the :term:`USE_NLS` variable is set to ``no``, or
|
||||
|
||||
- the :term:`INHIBIT_DEFAULT_DEPS` variable is set and the recipe inheriting
|
||||
the :ref:`ref-classes-gettext` class does not also inherit the
|
||||
:ref:`ref-classes-cross-canadian` class.
|
||||
|
||||
.. _ref-classes-gnomebase:
|
||||
|
||||
``gnomebase``
|
||||
@@ -2544,6 +2556,25 @@ The :ref:`ref-classes-recipe_sanity` class checks for the presence of any host s
|
||||
recipe prerequisites that might affect the build (e.g. variables that
|
||||
are set or software that is present).
|
||||
|
||||
.. _ref-classes-relative_symlinks:
|
||||
|
||||
``relative_symlinks``
|
||||
=====================
|
||||
|
||||
The :ref:`ref-classes-relative_symlinks` class walks the symbolic links in the
|
||||
:term:`D` directory and replaces links pointing to absolute paths to relative
|
||||
paths. This is occasionally used in some recipes that create wrong symbolic
|
||||
links when their :ref:`ref-classes-native` version is built, and/or would cause
|
||||
breakage in the :ref:`overview-manual/concepts:shared state cache`.
|
||||
|
||||
For example, if the following symbolic link is found in :term:`D`::
|
||||
|
||||
/usr/bin/foo -> /sbin/bar
|
||||
|
||||
It is replaced by::
|
||||
|
||||
/usr/bin/foo -> ../../sbin/bar
|
||||
|
||||
.. _ref-classes-relocatable:
|
||||
|
||||
``relocatable``
|
||||
@@ -3214,22 +3245,51 @@ imitates.
|
||||
``uninative``
|
||||
=============
|
||||
|
||||
Attempts to isolate the build system from the host distribution's C
|
||||
library in order to make re-use of native shared state artifacts across
|
||||
different host distributions practical. With this class enabled, a
|
||||
tarball containing a pre-built C library is downloaded at the start of
|
||||
the build. In the Poky reference distribution this is enabled by default
|
||||
through ``meta/conf/distro/include/yocto-uninative.inc``. Other
|
||||
distributions that do not derive from poky can also
|
||||
"``require conf/distro/include/yocto-uninative.inc``" to use this.
|
||||
Alternatively if you prefer, you can build the uninative-tarball recipe
|
||||
yourself, publish the resulting tarball (e.g. via HTTP) and set
|
||||
``UNINATIVE_URL`` and ``UNINATIVE_CHECKSUM`` appropriately. For an
|
||||
example, see the ``meta/conf/distro/include/yocto-uninative.inc``.
|
||||
The :ref:`ref-classes-uninative` class allows binaries to run on systems with
|
||||
older or newer :wikipedia:`Glibc <Glibc>` versions. This means
|
||||
:ref:`ref-classes-native` recipe :ref:`overview-manual/concepts:shared state
|
||||
cache` can be shared among different host distributions of different versions,
|
||||
i.e. the :ref:`overview-manual/concepts:shared state cache` is "universal".
|
||||
|
||||
The :ref:`ref-classes-uninative` class is also used unconditionally by the extensible
|
||||
SDK. When building the extensible SDK, ``uninative-tarball`` is built
|
||||
and the resulting tarball is included within the SDK.
|
||||
To allow this to work, the dynamic loader is changed to our own :manpage:`ld.so
|
||||
<ld.so.8>` when binaries are compiled using the
|
||||
``--dynamic-linker`` option. This means when the binary is executed, it finds
|
||||
our own :manpage:`ld.so <ld.so.8>` and that loader has a modified search path
|
||||
which finds a newer Glibc version.
|
||||
|
||||
The linking of the binaries is not changed at link time since the
|
||||
headers on the system wouldn't match the newer Glibc and this causes
|
||||
obtuse failures. Changing the loader is effectively the same as if the
|
||||
system had a Glibc upgrade after the binary was compiled, so it is a
|
||||
mechanism supported by upstream.
|
||||
|
||||
One caveat to this approach is that the uninative Glibc binary must be
|
||||
equal to or newer in version to the versions on all the systems using
|
||||
the common :ref:`overview-manual/concepts:shared state cache`. This is why
|
||||
:ref:`ref-classes-uninative` is regularly changed on the development and stable
|
||||
branches.
|
||||
|
||||
Another potential issue is static linking: static libraries created on
|
||||
a system with a new Glibc version may have symbols not present in older
|
||||
versions, which would then fail during linking on older systems. This
|
||||
is one reason we don't use static linking for our :ref:`ref-classes-native`
|
||||
binaries.
|
||||
|
||||
With this class enabled, a tarball containing a pre-built C library is
|
||||
downloaded at the start of the build. In the Poky reference distribution this is
|
||||
enabled by default through :oe_git:`meta/conf/distro/include/yocto-uninative.inc
|
||||
</openembedded-core/tree/meta/conf/distro/include/yocto-uninative.inc>`. Other distributions that do
|
||||
not derive from Poky can also "``require conf/distro/include/yocto-uninative.inc``"
|
||||
to use this. Alternatively if you prefer, you can build the uninative-tarball
|
||||
recipe yourself, publish the resulting tarball (e.g. via HTTP) and set
|
||||
:term:`UNINATIVE_URL` and :term:`UNINATIVE_CHECKSUM` appropriately. For an
|
||||
example, see :oe_git:`meta/conf/distro/include/yocto-uninative.inc
|
||||
</openembedded-core/tree/meta/conf/distro/include/yocto-uninative.inc>`.
|
||||
|
||||
The :ref:`ref-classes-uninative` class is also used unconditionally by the
|
||||
:doc:`extensible SDK </sdk-manual/extensible>`. When building the extensible
|
||||
SDK, ``uninative-tarball`` is built and the resulting tarball is included within
|
||||
the SDK.
|
||||
|
||||
.. _ref-classes-update-alternatives:
|
||||
|
||||
|
||||
@@ -328,6 +328,15 @@ Once the build process gets the sample file, it uses ``sed`` to substitute final
|
||||
This file indicates the state of the sanity checks and is created during
|
||||
the build.
|
||||
|
||||
.. _structure-build-conf-auto.conf:
|
||||
|
||||
``build/conf/auto.conf``
|
||||
------------------------
|
||||
|
||||
This file contains configuration variables that are automatically modified by
|
||||
tools such as :oe_git:`bitbake-config-build </bitbake/tree/bin/bitbake-config-build>`.
|
||||
This file should not be modified manually.
|
||||
|
||||
.. _structure-build-downloads:
|
||||
|
||||
``build/downloads/``
|
||||
|
||||
@@ -1097,6 +1097,11 @@ system and gives an overview of their function and contents.
|
||||
:term:`CC`
|
||||
The minimal command and arguments used to run the C compiler.
|
||||
|
||||
:term:`CCACHE_DISABLE`
|
||||
When inheriting the :ref:`ref-classes-ccache` class, the
|
||||
:term:`CCACHE_DISABLE` variable can be set to "1" in a recipe to disable
|
||||
`Ccache` support. This is useful when the recipe is known to not support it.
|
||||
|
||||
:term:`CFLAGS`
|
||||
Specifies the flags to pass to the C compiler. This variable is
|
||||
exported to an environment variable and thus made visible to the
|
||||
@@ -4251,8 +4256,7 @@ system and gives an overview of their function and contents.
|
||||
would place patch files and configuration fragment files (i.e.
|
||||
"out-of-tree"). However, if you want to use a ``defconfig`` file that
|
||||
is part of the kernel tree (i.e. "in-tree"), you can use the
|
||||
:term:`KBUILD_DEFCONFIG` variable and append the
|
||||
:term:`KMACHINE` variable to point to the
|
||||
:term:`KBUILD_DEFCONFIG` variable to point to the
|
||||
``defconfig`` file.
|
||||
|
||||
To use the variable, set it in the append file for your kernel recipe
|
||||
@@ -4688,7 +4692,7 @@ system and gives an overview of their function and contents.
|
||||
information on how this variable is used.
|
||||
|
||||
:term:`LAYERDEPENDS`
|
||||
Lists the layers, separated by spaces, on which this recipe depends.
|
||||
Lists the layers, separated by spaces, on which this layer depends.
|
||||
Optionally, you can specify a specific layer version for a dependency
|
||||
by adding it to the end of the layer name. Here is an example::
|
||||
|
||||
@@ -6822,6 +6826,16 @@ system and gives an overview of their function and contents.
|
||||
:term:`REPODIR`
|
||||
See :term:`bitbake:REPODIR` in the BitBake manual.
|
||||
|
||||
:term:`REQUIRED_COMBINED_FEATURES`
|
||||
When inheriting the :ref:`ref-classes-features_check` class, this variable
|
||||
identifies combined features (the intersection of :term:`MACHINE_FEATURES`
|
||||
and :term:`DISTRO_FEATURES`) that must exist in the current configuration
|
||||
in order for the :term:`OpenEmbedded Build System` to build the recipe. In
|
||||
other words, if the :term:`REQUIRED_COMBINED_FEATURES` variable lists a
|
||||
feature that does not appear in :term:`COMBINED_FEATURES` within the
|
||||
current configuration, then the recipe will be skipped, and if the build
|
||||
system attempts to build the recipe then an error will be triggered.
|
||||
|
||||
:term:`REQUIRED_DISTRO_FEATURES`
|
||||
When inheriting the
|
||||
:ref:`features_check <ref-classes-features_check>`
|
||||
@@ -6833,6 +6847,32 @@ system and gives an overview of their function and contents.
|
||||
the recipe will be skipped, and if the build system attempts to build
|
||||
the recipe then an error will be triggered.
|
||||
|
||||
:term:`REQUIRED_IMAGE_FEATURES`
|
||||
When inheriting the :ref:`ref-classes-features_check` class, this variable
|
||||
identifies image features that must exist in the current
|
||||
configuration in order for the :term:`OpenEmbedded Build System` to build
|
||||
the recipe. In other words, if the :term:`REQUIRED_IMAGE_FEATURES` variable
|
||||
lists a feature that does not appear in :term:`IMAGE_FEATURES` within the
|
||||
current configuration, then the recipe will be skipped, and if the build
|
||||
system attempts to build the recipe then an error will be triggered.
|
||||
|
||||
Compared to other ``REQUIRED_*_FEATURES`` variables, the
|
||||
:term:`REQUIRED_IMAGE_FEATURES` varible only targets image recipes, as the
|
||||
:term:`IMAGE_FEATURES` variable is handled by the :ref:`ref-classes-core-image`
|
||||
class). However, the :term:`REQUIRED_IMAGE_FEATURES` varible can also be
|
||||
set from a :term:`Configuration File`, such as a distro
|
||||
configuration file, if the list of required image features should apply to
|
||||
all images using this :term:`DISTRO`.
|
||||
|
||||
:term:`REQUIRED_MACHINE_FEATURES`
|
||||
When inheriting the :ref:`ref-classes-features_check` class, this variable
|
||||
identifies :term:`MACHINE_FEATURES` that must exist in the current
|
||||
configuration in order for the :term:`OpenEmbedded Build System` to build
|
||||
the recipe. In other words, if the :term:`REQUIRED_MACHINE_FEATURES` variable
|
||||
lists a feature that does not appear in :term:`MACHINE_FEATURES` within the
|
||||
current configuration, then the recipe will be skipped, and if the build
|
||||
system attempts to build the recipe then an error will be triggered.
|
||||
|
||||
:term:`REQUIRED_VERSION`
|
||||
If there are multiple versions of a recipe available, this variable
|
||||
determines which version should be given preference.
|
||||
@@ -8174,7 +8214,7 @@ system and gives an overview of their function and contents.
|
||||
directory for the build host.
|
||||
|
||||
:term:`STAGING_DIR`
|
||||
Helps construct the ``recipe-sysroots`` directory, which is used
|
||||
Helps construct the ``recipe-sysroot*`` directories, which are used
|
||||
during packaging.
|
||||
|
||||
For information on how staging for recipe-specific sysroots occurs,
|
||||
@@ -9422,6 +9462,22 @@ system and gives an overview of their function and contents.
|
||||
passes and uses "all" for the target during the U-Boot building
|
||||
process.
|
||||
|
||||
:term:`UNINATIVE_CHECKSUM`
|
||||
When inheriting the :ref:`ref-classes-uninative` class, the
|
||||
:term:`UNINATIVE_CHECKSUM` variable flags contain the checksums of the
|
||||
uninative tarball as specified by the :term:`UNINATIVE_URL` variable.
|
||||
There should be one checksum per tarballs published at
|
||||
:term:`UNINATIVE_URL`, which match architectures. For example::
|
||||
|
||||
UNINATIVE_CHECKSUM[aarch64] ?= "812045d826b7fda88944055e8526b95a5a9440bfef608d5b53fd52faab49bf85"
|
||||
UNINATIVE_CHECKSUM[i686] ?= "5cc28efd0c15a75de4bcb147c6cce65f1c1c9d442173a220f08427f40a3ffa09"
|
||||
UNINATIVE_CHECKSUM[x86_64] ?= "4c03d1ed2b7b4e823aca4a1a23d8f2e322f1770fc10e859adcede5777aff4f3a"
|
||||
|
||||
:term:`UNINATIVE_URL`
|
||||
When inheriting the :ref:`ref-classes-uninative` class, the
|
||||
:term:`UNINATIVE_URL` variable contains the URL where the uninative
|
||||
tarballs are published.
|
||||
|
||||
:term:`UNKNOWN_CONFIGURE_OPT_IGNORE`
|
||||
Specifies a list of options that, if reported by the configure script
|
||||
as being invalid, should not generate a warning during the
|
||||
@@ -9517,6 +9573,18 @@ system and gives an overview of their function and contents.
|
||||
the Yocto Project Development Tasks Manual for information on how to
|
||||
use this variable.
|
||||
|
||||
:term:`USE_NLS`
|
||||
Determine if language translations should be built for recipes that can
|
||||
build them. This variable can be equal to:
|
||||
|
||||
- ``yes``: translations are enabled.
|
||||
- ``no``: translation are disabled.
|
||||
|
||||
Recipes can use the value of this variable to enable language
|
||||
translations in their build. Classes such as :ref:`ref-classes-gettext`
|
||||
use the value of this variable to enable :wikipedia:`Gettext <Gettext>`
|
||||
support.
|
||||
|
||||
:term:`USE_VT`
|
||||
When using
|
||||
:ref:`SysVinit <dev-manual/new-recipe:enabling system services>`,
|
||||
|
||||
@@ -113,7 +113,7 @@ If ``OEQA_DEBUGGING_SAVED_OUTPUT`` is set, any differing packages will be saved
|
||||
here. The test is also able to run the ``diffoscope`` command on the output to
|
||||
generate HTML files showing the differences between the packages, to aid
|
||||
debugging. On the Autobuilder, these appear under
|
||||
https://autobuilder.yocto.io/pub/repro-fail/ in the form ``oe-reproducible +
|
||||
https://valkyrie.yocto.io/pub/repro-fail/ in the form ``oe-reproducible +
|
||||
<date> + <random ID>``, e.g. ``oe-reproducible-20200202-1lm8o1th``.
|
||||
|
||||
The project's current reproducibility status can be seen at
|
||||
|
||||
@@ -69,7 +69,7 @@ box to "generate an email to QA" is also checked.
|
||||
When the build completes, an email is sent out using the ``send-qa-email``
|
||||
script in the :yocto_git:`yocto-autobuilder-helper </yocto-autobuilder-helper>`
|
||||
repository to the list of people configured for that release. Release builds
|
||||
are placed into a directory in https://autobuilder.yocto.io/pub/releases on the
|
||||
are placed into a directory in https://valkyrie.yocto.io/pub/releases on the
|
||||
Autobuilder which is included in the email. The process from here is
|
||||
more manual and control is effectively passed to release engineering.
|
||||
The next steps include:
|
||||
|
||||
@@ -38,7 +38,7 @@ Benefits
|
||||
and flexible: it gives users the ultimate power to change pretty much any
|
||||
aspect of the system but as with most things, power comes with responsibility.
|
||||
The Yocto Project would like to see people able to mix and match BSPs with
|
||||
distro configs or software stacks and be able to merge succesfully.
|
||||
distro configs or software stacks and be able to merge successfully.
|
||||
Over time, the project identified characteristics in layers that allow them
|
||||
to operate well together. "anti-patterns" were also found, preventing layers
|
||||
from working well together.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
DISTRO = "poky"
|
||||
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
|
||||
#DISTRO_VERSION = "3.4+snapshot-${METADATA_REVISION}"
|
||||
DISTRO_VERSION = "4.0.30"
|
||||
DISTRO_VERSION = "4.0.31"
|
||||
DISTRO_CODENAME = "kirkstone"
|
||||
SDK_VENDOR = "-pokysdk"
|
||||
SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${METADATA_REVISION}', 'snapshot')}"
|
||||
|
||||
@@ -690,7 +690,7 @@ DEBIAN_MIRROR = "http://ftp.debian.org/debian/pool"
|
||||
GENTOO_MIRROR = "http://distfiles.gentoo.org/distfiles"
|
||||
GNOME_GIT = "git://gitlab.gnome.org/GNOME"
|
||||
GNOME_MIRROR = "https://download.gnome.org/sources/"
|
||||
GNU_MIRROR = "https://ftp.gnu.org/gnu"
|
||||
GNU_MIRROR = "https://ftpmirror.gnu.org/gnu"
|
||||
GNUPG_MIRROR = "https://www.gnupg.org/ftp/gcrypt"
|
||||
GPE_MIRROR = "http://gpe.linuxtogo.org/download/source"
|
||||
KERNELORG_MIRROR = "https://cdn.kernel.org/pub"
|
||||
|
||||
@@ -17,7 +17,7 @@ class BuildCpioTest(OESDKTestCase):
|
||||
"""
|
||||
def test_cpio(self):
|
||||
with tempfile.TemporaryDirectory(prefix="cpio-", dir=self.tc.sdk_dir) as testdir:
|
||||
tarball = self.fetch(testdir, self.td["DL_DIR"], "https://ftp.gnu.org/gnu/cpio/cpio-2.13.tar.gz")
|
||||
tarball = self.fetch(testdir, self.td["DL_DIR"], "https://ftpmirror.gnu.org/gnu/cpio/cpio-2.13.tar.gz")
|
||||
|
||||
dirs = {}
|
||||
dirs["source"] = os.path.join(testdir, "cpio-2.13")
|
||||
|
||||
@@ -40,7 +40,7 @@ class MetaIDE(OESelftestTestCase):
|
||||
def test_meta_ide_can_build_cpio_project(self):
|
||||
dl_dir = self.td.get('DL_DIR', None)
|
||||
self.project = SDKBuildProject(self.tmpdir_metaideQA + "/cpio/", self.environment_script_path,
|
||||
"https://ftp.gnu.org/gnu/cpio/cpio-2.13.tar.gz",
|
||||
"https://ftpmirror.gnu.org/gnu/cpio/cpio-2.13.tar.gz",
|
||||
self.tmpdir_metaideQA, self.td['DATETIME'], dl_dir=dl_dir)
|
||||
self.project.download_archive()
|
||||
self.assertEqual(self.project.run_configure('$CONFIGURE_FLAGS --disable-maintainer-mode','sed -i -e "/char \*program_name/d" src/global.c;'), 0,
|
||||
|
||||
75
meta/recipes-bsp/grub/files/CVE-2024-56738.patch
Normal file
75
meta/recipes-bsp/grub/files/CVE-2024-56738.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
From 4cef2fc7308b2132317ad166939994f098b41561 Mon Sep 17 00:00:00 2001
|
||||
From: Ross Burton <ross.burton@arm.com>
|
||||
Date: Tue, 9 Sep 2025 14:23:14 +0100
|
||||
Subject: [PATCH] CVE-2024-56738
|
||||
|
||||
Backport an algorithmic change to grub_crypto_memcmp() so that it completes in
|
||||
constant time and thus isn't susceptible to side-channel attacks.
|
||||
|
||||
This is a partial backport of grub 0739d24cd
|
||||
("libgcrypt: Adjust import script, definitions and API users for libgcrypt 1.11")
|
||||
|
||||
CVE: CVE-2024-56738
|
||||
Upstream-Status: Backport [0739d24cd]
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
grub-core/lib/crypto.c | 23 ++++++++++++++++-------
|
||||
include/grub/crypto.h | 2 +-
|
||||
2 files changed, 17 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c
|
||||
index ca334d5..1bfa922 100644
|
||||
--- a/grub-core/lib/crypto.c
|
||||
+++ b/grub-core/lib/crypto.c
|
||||
@@ -433,19 +433,28 @@ grub_crypto_gcry_error (gcry_err_code_t in)
|
||||
return GRUB_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Compare byte arrays of length LEN, return 1 if it's not same,
|
||||
+ * 0, otherwise.
|
||||
+ */
|
||||
int
|
||||
-grub_crypto_memcmp (const void *a, const void *b, grub_size_t n)
|
||||
+grub_crypto_memcmp (const void *b1, const void *b2, grub_size_t len)
|
||||
{
|
||||
- register grub_size_t counter = 0;
|
||||
- const grub_uint8_t *pa, *pb;
|
||||
+ const grub_uint8_t *a = b1;
|
||||
+ const grub_uint8_t *b = b2;
|
||||
+ int ab, ba;
|
||||
+ grub_size_t i;
|
||||
|
||||
- for (pa = a, pb = b; n; pa++, pb++, n--)
|
||||
+ /* Constant-time compare. */
|
||||
+ for (i = 0, ab = 0, ba = 0; i < len; i++)
|
||||
{
|
||||
- if (*pa != *pb)
|
||||
- counter++;
|
||||
+ /* If a[i] != b[i], either ab or ba will be negative. */
|
||||
+ ab |= a[i] - b[i];
|
||||
+ ba |= b[i] - a[i];
|
||||
}
|
||||
|
||||
- return !!counter;
|
||||
+ /* 'ab | ba' is negative when buffers are not equal, extract sign bit. */
|
||||
+ return ((unsigned int)(ab | ba) >> (sizeof(unsigned int) * 8 - 1)) & 1;
|
||||
}
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
diff --git a/include/grub/crypto.h b/include/grub/crypto.h
|
||||
index 21cd1f7..432912b 100644
|
||||
--- a/include/grub/crypto.h
|
||||
+++ b/include/grub/crypto.h
|
||||
@@ -393,7 +393,7 @@ grub_crypto_pbkdf2 (const struct gcry_md_spec *md,
|
||||
grub_uint8_t *DK, grub_size_t dkLen);
|
||||
|
||||
int
|
||||
-grub_crypto_memcmp (const void *a, const void *b, grub_size_t n);
|
||||
+grub_crypto_memcmp (const void *b1, const void *b2, grub_size_t len);
|
||||
|
||||
int
|
||||
grub_password_get (char buf[], unsigned buf_size);
|
||||
--
|
||||
2.40.0
|
||||
@@ -59,6 +59,7 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \
|
||||
file://CVE-2025-0678_CVE-2025-1125.patch \
|
||||
file://CVE-2025-0690.patch \
|
||||
file://CVE-2025-1118.patch \
|
||||
file://CVE-2024-56738.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "23b64b4c741569f9426ed2e3d0e6780796fca081bee4c99f62aa3f53ae803f5f"
|
||||
@@ -69,6 +70,8 @@ CVE_CHECK_IGNORE += "CVE-2019-14865"
|
||||
CVE_CHECK_IGNORE += "CVE-2021-46705"
|
||||
# not-applicable-platform: Applies only to RHEL/Fedora
|
||||
CVE_CHECK_IGNORE += "CVE-2024-1048 CVE-2023-4001"
|
||||
# not-applicable-platform: Applies only to Ubuntu
|
||||
CVE_CHECK_IGNORE += "CVE-2024-2312"
|
||||
|
||||
DEPENDS = "flex-native bison-native gettext-native"
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ SRC_URI:append:class-nativesdk = " \
|
||||
file://environment.d-openssl.sh \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "dfdd77e4ea1b57ff3a6dbde6b0bdc3f31db5ac99e7fdd4eaf9e1fbb6ec2db8ce"
|
||||
SRC_URI[sha256sum] = "d80c34f5cf902dccf1f1b5df5ebb86d0392e37049e5d73df1b3abae72e4ffe8b"
|
||||
|
||||
inherit lib_package multilib_header multilib_script ptest perlnative
|
||||
MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash"
|
||||
57
meta/recipes-core/busybox/busybox/CVE-2025-46394-01.patch
Normal file
57
meta/recipes-core/busybox/busybox/CVE-2025-46394-01.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From f5e1bf966b19ea1821f00a8c9ecd7774598689b4 Mon Sep 17 00:00:00 2001
|
||||
From: Denys Vlasenko <vda.linux@googlemail.com>
|
||||
Date: Wed, 24 Sep 2025 03:28:47 +0200
|
||||
Subject: [PATCH] archival/libarchive: sanitize filenames on output (prevent
|
||||
control sequence attacks
|
||||
|
||||
This fixes CVE-2025-46394 (terminal escape sequence injection)
|
||||
|
||||
Original credit: Ian.Norton at entrust.com
|
||||
|
||||
function old new delta
|
||||
header_list 9 15 +6
|
||||
header_verbose_list 239 244 +5
|
||||
------------------------------------------------------------------------------
|
||||
(add/remove: 0/0 grow/shrink: 2/0 up/down: 11/0) Total: 11 bytes
|
||||
|
||||
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
||||
|
||||
CVE: CVE-2025-46394
|
||||
Upstream-Status: Backport [https://git.busybox.net/busybox/commit/?id=f5e1bf966b19ea1821f00a8c9ecd7774598689b4]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
archival/libarchive/header_list.c | 2 +-
|
||||
archival/libarchive/header_verbose_list.c | 4 ++--
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/archival/libarchive/header_list.c b/archival/libarchive/header_list.c
|
||||
index 0621aa406..9490b3635 100644
|
||||
--- a/archival/libarchive/header_list.c
|
||||
+++ b/archival/libarchive/header_list.c
|
||||
@@ -8,5 +8,5 @@
|
||||
void FAST_FUNC header_list(const file_header_t *file_header)
|
||||
{
|
||||
//TODO: cpio -vp DIR should output "DIR/NAME", not just "NAME" */
|
||||
- puts(file_header->name);
|
||||
+ puts(printable_string(file_header->name));
|
||||
}
|
||||
diff --git a/archival/libarchive/header_verbose_list.c b/archival/libarchive/header_verbose_list.c
|
||||
index a575a08a0..e7a09430d 100644
|
||||
--- a/archival/libarchive/header_verbose_list.c
|
||||
+++ b/archival/libarchive/header_verbose_list.c
|
||||
@@ -57,13 +57,13 @@ void FAST_FUNC header_verbose_list(const file_header_t *file_header)
|
||||
ptm->tm_hour,
|
||||
ptm->tm_min,
|
||||
ptm->tm_sec,
|
||||
- file_header->name);
|
||||
+ printable_string(file_header->name));
|
||||
|
||||
#endif /* FEATURE_TAR_UNAME_GNAME */
|
||||
|
||||
/* NB: GNU tar shows "->" for symlinks and "link to" for hardlinks */
|
||||
if (file_header->link_target) {
|
||||
- printf(" -> %s", file_header->link_target);
|
||||
+ printf(" -> %s", printable_string(file_header->link_target));
|
||||
}
|
||||
bb_putchar('\n');
|
||||
}
|
||||
32
meta/recipes-core/busybox/busybox/CVE-2025-46394-02.patch
Normal file
32
meta/recipes-core/busybox/busybox/CVE-2025-46394-02.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From 7378db981d87b4a2264e14d60340a7fb5c67ae59 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Marko <peter.marko@siemens.com>
|
||||
Date: Fri, 3 Oct 2025 16:12:56 +0200
|
||||
Subject: [PATCH] testsuite/tar.tests: fix test after CVE-2025-46394
|
||||
|
||||
tar now sanitizes output and this test needs to expect that.
|
||||
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
|
||||
CVE: CVE-2025-46394
|
||||
Upstream-Status: Submitted [https://lists.busybox.net/pipermail/busybox/2025-October/091743.html]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
testsuite/tar.tests | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/testsuite/tar.tests b/testsuite/tar.tests
|
||||
index 0f2e89112..48fc38114 100755
|
||||
--- a/testsuite/tar.tests
|
||||
+++ b/testsuite/tar.tests
|
||||
@@ -325,9 +325,9 @@ unset LANG
|
||||
rm -rf etc usr
|
||||
' "\
|
||||
etc/ssl/certs/3b2716e5.0
|
||||
-etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
|
||||
+etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sa??lay??c??s??.pem
|
||||
etc/ssl/certs/f80cc7f6.0
|
||||
-usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt
|
||||
+usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sa??lay??c??s??.crt
|
||||
0
|
||||
etc/ssl/certs/3b2716e5.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
|
||||
etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem -> /usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt
|
||||
@@ -59,6 +59,8 @@ SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \
|
||||
file://CVE-2023-42366.patch \
|
||||
file://0001-cut-Fix-s-flag-to-omit-blank-lines.patch \
|
||||
file://CVE-2023-39810.patch \
|
||||
file://CVE-2025-46394-01.patch \
|
||||
file://CVE-2025-46394-02.patch \
|
||||
"
|
||||
SRC_URI:append:libc-musl = " file://musl.cfg "
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
From 4dd540505d40babe488404f3174ec39f49a84485 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Catanzaro <mcatanzaro@redhat.com>
|
||||
Date: Mon, 4 Aug 2025 15:10:21 -0500
|
||||
Subject: [PATCH] openssl: properly check return value when writing to BIO
|
||||
objects
|
||||
|
||||
In particular, we will read out of bounds, and then write the invalid
|
||||
memory, if BIO_write() fails when getting the PROP_CERTIFICATE_PEM
|
||||
property. Here we attempt to check the return value, but the check is
|
||||
not correct.
|
||||
|
||||
This also fixes a leak of the BIO in the same place.
|
||||
|
||||
Also add error checking to PROP_SUBJECT_NAME and PROP_ISSUER_NAME, for
|
||||
good measure.
|
||||
|
||||
Fixes #226
|
||||
|
||||
CVE: CVE-2025-60018
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib-networking/-/commit/4dd540505d40babe488404f3174ec39f49a84485]
|
||||
|
||||
Signed-off-by: Rajeshkumar Ramasamy <rajeshkumar.ramasamy@windriver.com>
|
||||
---
|
||||
tls/openssl/gtlscertificate-openssl.c | 25 +++++++++++++++----------
|
||||
1 file changed, 15 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/tls/openssl/gtlscertificate-openssl.c b/tls/openssl/gtlscertificate-openssl.c
|
||||
index 648f3e8..b536559 100644
|
||||
--- a/tls/openssl/gtlscertificate-openssl.c
|
||||
+++ b/tls/openssl/gtlscertificate-openssl.c
|
||||
@@ -362,15 +362,12 @@ g_tls_certificate_openssl_get_property (GObject *object,
|
||||
case PROP_CERTIFICATE_PEM:
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
|
||||
- if (!PEM_write_bio_X509 (bio, openssl->cert) || !BIO_write (bio, "\0", 1))
|
||||
- certificate_pem = NULL;
|
||||
- else
|
||||
+ if (PEM_write_bio_X509 (bio, openssl->cert) == 1 && BIO_write (bio, "\0", 1) == 1)
|
||||
{
|
||||
BIO_get_mem_data (bio, &certificate_pem);
|
||||
g_value_set_string (value, certificate_pem);
|
||||
-
|
||||
- BIO_free_all (bio);
|
||||
}
|
||||
+ BIO_free_all (bio);
|
||||
break;
|
||||
|
||||
case PROP_PRIVATE_KEY:
|
||||
@@ -411,8 +408,12 @@ g_tls_certificate_openssl_get_property (GObject *object,
|
||||
case PROP_SUBJECT_NAME:
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
name = X509_get_subject_name (openssl->cert);
|
||||
- X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS);
|
||||
- BIO_write (bio, "\0", 1);
|
||||
+ if (X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0 ||
|
||||
+ BIO_write (bio, "\0", 1) != 1)
|
||||
+ {
|
||||
+ BIO_free_all (bio);
|
||||
+ break;
|
||||
+ }
|
||||
BIO_get_mem_data (bio, (char **)&name_string);
|
||||
g_value_set_string (value, name_string);
|
||||
BIO_free_all (bio);
|
||||
@@ -421,9 +422,13 @@ g_tls_certificate_openssl_get_property (GObject *object,
|
||||
case PROP_ISSUER_NAME:
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
name = X509_get_issuer_name (openssl->cert);
|
||||
- X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS);
|
||||
- BIO_write (bio, "\0", 1);
|
||||
- BIO_get_mem_data (bio, &name_string);
|
||||
+ if (X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0 ||
|
||||
+ BIO_write (bio, "\0", 1) != 1)
|
||||
+ {
|
||||
+ BIO_free_all (bio);
|
||||
+ break;
|
||||
+ }
|
||||
+ BIO_get_mem_data (bio, (char **)&name_string);
|
||||
g_value_set_string (value, name_string);
|
||||
BIO_free_all (bio);
|
||||
break;
|
||||
--
|
||||
2.48.1
|
||||
@@ -0,0 +1,137 @@
|
||||
From 70df675dd4f5e4a593b2f95406c1aac031aa8bc7 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Catanzaro <mcatanzaro@redhat.com>
|
||||
Date: Thu, 21 Aug 2025 17:21:01 -0500
|
||||
Subject: [PATCH] openssl: check return values of BIO_new()
|
||||
|
||||
We probably need to check even more return values of even more OpenSSL
|
||||
functions, but these ones allocate memory and that's particularly
|
||||
important to get right.
|
||||
|
||||
CVE: CVE-2025-60019
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib-networking/-/commit/70df675dd4f5e4a593b2f95406c1aac031aa8bc7]
|
||||
|
||||
Signed-off-by: Rajeshkumar Ramasamy <rajeshkumar.ramasamy@windriver.com>
|
||||
---
|
||||
tls/openssl/gtlscertificate-openssl.c | 39 ++++++++++++++++++++-------
|
||||
1 file changed, 29 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/tls/openssl/gtlscertificate-openssl.c b/tls/openssl/gtlscertificate-openssl.c
|
||||
index 8f828a7..f7fde51 100644
|
||||
--- a/tls/openssl/gtlscertificate-openssl.c
|
||||
+++ b/tls/openssl/gtlscertificate-openssl.c
|
||||
@@ -156,6 +156,9 @@ export_privkey_to_der (GTlsCertificateOpenssl *openssl,
|
||||
goto err;
|
||||
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
+ if (!bio)
|
||||
+ goto err;
|
||||
+
|
||||
if (i2d_PKCS8_PRIV_KEY_INFO_bio (bio, pkcs8) == 0)
|
||||
goto err;
|
||||
|
||||
@@ -189,6 +192,9 @@ export_privkey_to_pem (GTlsCertificateOpenssl *openssl)
|
||||
return NULL;
|
||||
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
+ if (!bio)
|
||||
+ goto out;
|
||||
+
|
||||
ret = PEM_write_bio_PKCS8PrivateKey (bio, openssl->key, NULL, NULL, 0, NULL, NULL);
|
||||
if (ret == 0)
|
||||
goto out;
|
||||
@@ -201,7 +207,7 @@ export_privkey_to_pem (GTlsCertificateOpenssl *openssl)
|
||||
result = g_strdup (data);
|
||||
|
||||
out:
|
||||
- BIO_free_all (bio);
|
||||
+ g_clear_pointer (&bio, BIO_free_all);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -216,7 +222,7 @@ g_tls_certificate_openssl_get_property (GObject *object,
|
||||
guint8 *data;
|
||||
BIO *bio;
|
||||
GByteArray *byte_array;
|
||||
- char *certificate_pem;
|
||||
+ const char *certificate_pem;
|
||||
long size;
|
||||
|
||||
const ASN1_TIME *time_asn1;
|
||||
@@ -251,12 +257,12 @@ g_tls_certificate_openssl_get_property (GObject *object,
|
||||
case PROP_CERTIFICATE_PEM:
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
|
||||
- if (PEM_write_bio_X509 (bio, openssl->cert) == 1 && BIO_write (bio, "\0", 1) == 1)
|
||||
+ if (bio && PEM_write_bio_X509 (bio, openssl->cert) == 1 && BIO_write (bio, "\0", 1) == 1)
|
||||
{
|
||||
BIO_get_mem_data (bio, &certificate_pem);
|
||||
g_value_set_string (value, certificate_pem);
|
||||
}
|
||||
- BIO_free_all (bio);
|
||||
+ g_clear_pointer (&bio, BIO_free_all);
|
||||
break;
|
||||
|
||||
case PROP_PRIVATE_KEY:
|
||||
@@ -296,6 +302,8 @@ g_tls_certificate_openssl_get_property (GObject *object,
|
||||
|
||||
case PROP_SUBJECT_NAME:
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
+ if (!bio)
|
||||
+ break;
|
||||
name = X509_get_subject_name (openssl->cert);
|
||||
if (X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0 ||
|
||||
BIO_write (bio, "\0", 1) != 1)
|
||||
@@ -310,6 +318,8 @@ g_tls_certificate_openssl_get_property (GObject *object,
|
||||
|
||||
case PROP_ISSUER_NAME:
|
||||
bio = BIO_new (BIO_s_mem ());
|
||||
+ if (!bio)
|
||||
+ break;
|
||||
name = X509_get_issuer_name (openssl->cert);
|
||||
if (X509_NAME_print_ex (bio, name, 0, XN_FLAG_SEP_COMMA_PLUS) < 0 ||
|
||||
BIO_write (bio, "\0", 1) != 1)
|
||||
@@ -377,8 +387,11 @@ g_tls_certificate_openssl_set_property (GObject *object,
|
||||
break;
|
||||
g_return_if_fail (openssl->have_cert == FALSE);
|
||||
bio = BIO_new_mem_buf ((gpointer)string, -1);
|
||||
- openssl->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
|
||||
- BIO_free (bio);
|
||||
+ if (bio)
|
||||
+ {
|
||||
+ openssl->cert = PEM_read_bio_X509 (bio, NULL, NULL, NULL);
|
||||
+ BIO_free (bio);
|
||||
+ }
|
||||
if (openssl->cert)
|
||||
openssl->have_cert = TRUE;
|
||||
else if (!openssl->construct_error)
|
||||
@@ -397,8 +410,11 @@ g_tls_certificate_openssl_set_property (GObject *object,
|
||||
break;
|
||||
g_return_if_fail (openssl->have_key == FALSE);
|
||||
bio = BIO_new_mem_buf (bytes->data, bytes->len);
|
||||
- openssl->key = d2i_PrivateKey_bio (bio, NULL);
|
||||
- BIO_free (bio);
|
||||
+ if (bio)
|
||||
+ {
|
||||
+ openssl->key = d2i_PrivateKey_bio (bio, NULL);
|
||||
+ BIO_free (bio);
|
||||
+ }
|
||||
if (openssl->key)
|
||||
openssl->have_key = TRUE;
|
||||
else if (!openssl->construct_error)
|
||||
@@ -417,8 +433,11 @@ g_tls_certificate_openssl_set_property (GObject *object,
|
||||
break;
|
||||
g_return_if_fail (openssl->have_key == FALSE);
|
||||
bio = BIO_new_mem_buf ((gpointer)string, -1);
|
||||
- openssl->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
|
||||
- BIO_free (bio);
|
||||
+ if (bio)
|
||||
+ {
|
||||
+ openssl->key = PEM_read_bio_PrivateKey (bio, NULL, NULL, NULL);
|
||||
+ BIO_free (bio);
|
||||
+ }
|
||||
if (openssl->key)
|
||||
openssl->have_key = TRUE;
|
||||
else if (!openssl->construct_error)
|
||||
--
|
||||
2.48.1
|
||||
@@ -24,6 +24,8 @@ GNOMEBASEBUILDCLASS = "meson"
|
||||
inherit gnomebase gettext upstream-version-is-even gio-module-cache ptest-gnome
|
||||
|
||||
SRC_URI += "file://run-ptest"
|
||||
SRC_URI += "file://CVE-2025-60018.patch"
|
||||
SRC_URI += "file://CVE-2025-60019.patch"
|
||||
|
||||
FILES:${PN} += "\
|
||||
${libdir}/gio/modules/libgio*.so \
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SRCBRANCH ?= "release/2.35/master"
|
||||
PV = "2.35"
|
||||
SRCREV_glibc ?= "a66bc3941ff298e474d5f02d0c3303401951141f"
|
||||
SRCREV_glibc ?= "4e50046821f05ada5f14c76803845125ddb3ed7d"
|
||||
SRCREV_localedef ?= "794da69788cbf9bf57b59a852f9f11307663fa87"
|
||||
|
||||
GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
From 31d9848830e496f57d4182b518467c4c63bfd4bd Mon Sep 17 00:00:00 2001
|
||||
From 0402999b82f697011de388f61bad68da26060bef Mon Sep 17 00:00:00 2001
|
||||
From: Frank Barrus <frankbarrus_sw@shaggy.cc>
|
||||
Date: Mon, 16 Jun 2025 22:37:54 -0700
|
||||
Date: Tue, 14 Oct 2025 03:55:17 -0700
|
||||
Subject: [PATCH] pthreads NPTL: lost wakeup fix 2
|
||||
|
||||
This fixes the lost wakeup (from a bug in signal stealing) with a change
|
||||
@@ -65,18 +65,19 @@ full wakeup from a G1/G2 switch.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
Commit : 1db84775f831a1494993ce9c118deaf9537cc50a
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=1db84775f831a1494993ce9c118deaf9537cc50a]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002277.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
nptl/pthread_cond_common.c | 106 +++++++++------------------
|
||||
nptl/pthread_cond_common.c | 105 +++++++++------------------
|
||||
nptl/pthread_cond_wait.c | 144 ++++++++++++-------------------------
|
||||
2 files changed, 81 insertions(+), 169 deletions(-)
|
||||
2 files changed, 81 insertions(+), 168 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index fb035f72c3..8dd7037923 100644
|
||||
index fb035f72..a55eee3e 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -201,7 +201,6 @@ static bool __attribute__ ((unused))
|
||||
@@ -87,7 +88,7 @@ index fb035f72c3..8dd7037923 100644
|
||||
unsigned int g1 = *g1index;
|
||||
|
||||
/* If there is no waiter in G2, we don't do anything. The expression may
|
||||
@@ -222,85 +221,46 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
@@ -222,84 +221,46 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
* New waiters arriving concurrently with the group switching will all go
|
||||
into G2 until we atomically make the switch. Waiters existing in G2
|
||||
are not affected.
|
||||
@@ -176,7 +177,6 @@ index fb035f72c3..8dd7037923 100644
|
||||
- that this is now a new group (see __pthread_cond_wait_common for the
|
||||
- matching acquire MO loads). */
|
||||
- atomic_store_release (cond->__data.__g_signals + g1, 0);
|
||||
-
|
||||
+ unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||
+
|
||||
+ /* If any waiters still hold group references (and thus could be blocked),
|
||||
@@ -201,10 +201,10 @@ index fb035f72c3..8dd7037923 100644
|
||||
+
|
||||
+ futex_wake (cond->__data.__g_signals + g1, INT_MAX, private);
|
||||
+ }
|
||||
|
||||
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||
No old waiter can neither grab a signal nor acquire a reference without
|
||||
noticing that __g1_start is larger.
|
||||
@@ -311,6 +271,10 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
@@ -311,6 +272,10 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
g1 ^= 1;
|
||||
*g1index ^= 1;
|
||||
|
||||
@@ -216,7 +216,7 @@ index fb035f72c3..8dd7037923 100644
|
||||
lock. */
|
||||
unsigned int orig_size = wseq - (old_g1_start + old_orig_size);
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 20c348a503..1cb3dbf7b0 100644
|
||||
index 20c348a5..1cb3dbf7 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -238,9 +238,7 @@ __condvar_cleanup_waiting (void *arg)
|
||||
|
||||
54
meta/recipes-core/glibc/glibc/0026-PR25847-10.patch
Normal file
54
meta/recipes-core/glibc/glibc/0026-PR25847-10.patch
Normal file
@@ -0,0 +1,54 @@
|
||||
From 4f78382dd671f381db6d1f452e6f1593d17b177e Mon Sep 17 00:00:00 2001
|
||||
From: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue, 14 Oct 2025 06:53:40 -0700
|
||||
Subject: [PATCH] nptl: PTHREAD_COND_INITIALIZER compatibility with pre-2.41
|
||||
versions (bug 32786)
|
||||
|
||||
The new initializer and struct layout does not initialize the
|
||||
__g_signals field in the old struct layout before the change in
|
||||
commit c36fc50781995e6758cae2b6927839d0157f213c ("nptl: Remove
|
||||
g_refs from condition variables"). Bring back fields at the end
|
||||
of struct __pthread_cond_s, so that they are again zero-initialized.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: dbc5a50d12eff4cb3f782129029d04b8a76f58e7
|
||||
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002282.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
sysdeps/nptl/bits/thread-shared-types.h | 2 ++
|
||||
sysdeps/nptl/pthread.h | 2 +-
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
index 6f17afa4..2354ea21 100644
|
||||
--- a/sysdeps/nptl/bits/thread-shared-types.h
|
||||
+++ b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
@@ -99,6 +99,8 @@ struct __pthread_cond_s
|
||||
unsigned int __g1_orig_size;
|
||||
unsigned int __wrefs;
|
||||
unsigned int __g_signals[2];
|
||||
+ unsigned int __unused_initialized_1;
|
||||
+ unsigned int __unused_initialized_2;
|
||||
};
|
||||
|
||||
typedef unsigned int __tss_t;
|
||||
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
|
||||
index bbb36540..8d6d24ff 100644
|
||||
--- a/sysdeps/nptl/pthread.h
|
||||
+++ b/sysdeps/nptl/pthread.h
|
||||
@@ -152,7 +152,7 @@ enum
|
||||
|
||||
|
||||
/* Conditional variable handling. */
|
||||
-#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, 0, 0, {0, 0} } }
|
||||
+#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, 0, 0, {0, 0}, 0, 0 } }
|
||||
|
||||
|
||||
/* Cleanup buffers */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
From 6aab1191e35a3da66e8c49d95178a9d77c119a1f Mon Sep 17 00:00:00 2001
|
||||
From 306ea7810f5f6709ef3942a7be75077203b5d201 Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Mon, 16 Jun 2025 23:17:53 -0700
|
||||
Date: Tue, 14 Oct 2025 04:27:19 -0700
|
||||
Subject: [PATCH] nptl: Update comments and indentation for new condvar
|
||||
implementation
|
||||
|
||||
@@ -9,9 +9,10 @@ Also fixing indentation where it was using spaces instead of tabs.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: 0cc973160c23bb67f895bc887dd6942d29f8fee3
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=0cc973160c23bb67f895bc887dd6942d29f8fee3]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002275.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
@@ -20,7 +21,7 @@ Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
2 files changed, 22 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index 8dd7037923..306a207dd6 100644
|
||||
index a55eee3e..350a16fa 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -221,8 +221,9 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
@@ -36,7 +37,7 @@ index 8dd7037923..306a207dd6 100644
|
||||
__g_signals since it provides enough signals for all possible
|
||||
remaining waiters. As a result, they can each consume a signal
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 1cb3dbf7b0..cee1968756 100644
|
||||
index 1cb3dbf7..cee19687 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -249,7 +249,7 @@ __condvar_cleanup_waiting (void *arg)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
From 28a5082045429fdc5a4744d45fdc5b5202528eaa Mon Sep 17 00:00:00 2001
|
||||
From 5f22e8cf95cf6b3b2e16ddb03820ae3e77fd420d Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Mon, 16 Jun 2025 23:29:49 -0700
|
||||
Date: Tue, 14 Oct 2025 04:47:48 -0700
|
||||
Subject: [PATCH] nptl: Remove unnecessary catch-all-wake in condvar group
|
||||
switch
|
||||
|
||||
@@ -15,17 +15,18 @@ switch g1 when it should, so we wouldn't even have entered this code path.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: b42cc6af11062c260c7dfa91f1c89891366fed3e
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=b42cc6af11062c260c7dfa91f1c89891366fed3e]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002274.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
nptl/pthread_cond_common.c | 30 +-----------------------------
|
||||
1 file changed, 1 insertion(+), 29 deletions(-)
|
||||
nptl/pthread_cond_common.c | 31 +------------------------------
|
||||
1 file changed, 1 insertion(+), 30 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index 306a207dd6..f976a533a1 100644
|
||||
index 350a16fa..f976a533 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -221,13 +221,7 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
@@ -43,7 +44,7 @@ index 306a207dd6..f976a533a1 100644
|
||||
|
||||
/* Update __g1_start, which finishes closing this group. The value we add
|
||||
will never be negative because old_orig_size can only be zero when we
|
||||
@@ -240,28 +234,6 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
@@ -240,29 +234,6 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
|
||||
unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||
|
||||
@@ -69,6 +70,7 @@ index 306a207dd6..f976a533a1 100644
|
||||
-
|
||||
- futex_wake (cond->__data.__g_signals + g1, INT_MAX, private);
|
||||
- }
|
||||
-
|
||||
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||
No old waiter can neither grab a signal nor acquire a reference without
|
||||
noticing that __g1_start is larger.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
From 16b9af737c77b153fca4f36cbdbe94f7416c0b42 Mon Sep 17 00:00:00 2001
|
||||
From d714165c8bb3cac420077cfa61e3df87ea7f8b2c Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Mon, 16 Jun 2025 23:38:40 -0700
|
||||
Date: Tue, 14 Oct 2025 05:34:06 -0700
|
||||
Subject: [PATCH] nptl: Remove unnecessary quadruple check in pthread_cond_wait
|
||||
|
||||
pthread_cond_wait was checking whether it was in a closed group no less than
|
||||
@@ -22,9 +22,10 @@ Removing the duplicate checks clarifies the code.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: 4f7b051f8ee3feff1b53b27a906f245afaa9cee1
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=4f7b051f8ee3feff1b53b27a906f245afaa9cee1]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002276.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
@@ -32,7 +33,7 @@ Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
1 file changed, 49 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index cee1968756..47e834cade 100644
|
||||
index cee19687..47e834ca 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -366,7 +366,6 @@ static __always_inline int
|
||||
|
||||
@@ -1,105 +1,188 @@
|
||||
From d9ffb50dc55f77e584a5d0275eea758c7a6b04e3 Mon Sep 17 00:00:00 2001
|
||||
From f904a81ff8d0469ceaf3220329e716c03fcbd2d3 Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Mon, 16 Jun 2025 23:53:35 -0700
|
||||
Subject: [PATCH] nptl: Use a single loop in pthread_cond_wait instaed of a
|
||||
nested loop
|
||||
Date: Tue, 14 Oct 2025 05:59:02 -0700
|
||||
Subject: [PATCH] nptl: Remove g_refs from condition variables
|
||||
|
||||
The loop was a little more complicated than necessary. There was only one
|
||||
break statement out of the inner loop, and the outer loop was nearly empty.
|
||||
So just remove the outer loop, moving its code to the one break statement in
|
||||
the inner loop. This allows us to replace all gotos with break statements.
|
||||
This variable used to be needed to wait in group switching until all sleepers
|
||||
have confirmed that they have woken. This is no longer needed. Nothing waits
|
||||
on this variable so there is no need to track how many threads are currently
|
||||
asleep in each group.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
cmmit: c36fc50781995e6758cae2b6927839d0157f213c
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=929a4764ac90382616b6a21f099192b2475da674]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002278.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
nptl/pthread_cond_wait.c | 41 +++++++++++++++++++---------------------
|
||||
1 file changed, 19 insertions(+), 22 deletions(-)
|
||||
nptl/pthread_cond_wait.c | 52 +------------------------
|
||||
nptl/tst-cond22.c | 12 +++---
|
||||
sysdeps/nptl/bits/thread-shared-types.h | 3 +-
|
||||
sysdeps/nptl/pthread.h | 2 +-
|
||||
4 files changed, 9 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 47e834cade..5c86880105 100644
|
||||
index 47e834ca..8a9219e0 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -410,17 +410,15 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
return err;
|
||||
@@ -143,23 +143,6 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
|
||||
}
|
||||
}
|
||||
|
||||
- /* Now wait until a signal is available in our group or it is closed.
|
||||
- Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
- unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
-
|
||||
- do
|
||||
-/* Wake up any signalers that might be waiting. */
|
||||
-static void
|
||||
-__condvar_dec_grefs (pthread_cond_t *cond, unsigned int g, int private)
|
||||
-{
|
||||
- /* Release MO to synchronize-with the acquire load in
|
||||
- __condvar_quiesce_and_switch_g1. */
|
||||
- if (atomic_fetch_add_release (cond->__data.__g_refs + g, -2) == 3)
|
||||
- {
|
||||
+
|
||||
while (1)
|
||||
{
|
||||
+ /* Now wait until a signal is available in our group or it is closed.
|
||||
+ Acquire MO so that if we observe (signals == lowseq) after group
|
||||
+ switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
+ store and will see the prior update of __g1_start done while switching
|
||||
+ groups too. */
|
||||
+ unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
@@ -429,7 +427,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
/* If the group is closed already,
|
||||
then this waiter originally had enough extra signals to
|
||||
consume, up until the time its group was closed. */
|
||||
- goto done;
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* If there is an available signal, don't block.
|
||||
@@ -438,8 +436,16 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
G2, but in either case we're allowed to consume the available
|
||||
signal and should not block anymore. */
|
||||
if ((int)(signals - lowseq) >= 2)
|
||||
- break;
|
||||
- /* Clear the wake-up request flag before waking up. We do not need more
|
||||
- than relaxed MO and it doesn't matter if we apply this for an aliased
|
||||
- group because we wake all futex waiters right after clearing the
|
||||
- flag. */
|
||||
- atomic_fetch_and_relaxed (cond->__data.__g_refs + g, ~(unsigned int) 1);
|
||||
- futex_wake (cond->__data.__g_refs + g, INT_MAX, private);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
+ {
|
||||
+ /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
+ iteration we need to see the correct value of g1_start) */
|
||||
+ if (atomic_compare_exchange_weak_acquire (
|
||||
+ cond->__data.__g_signals + g,
|
||||
+ &signals, signals - 2))
|
||||
+ break;
|
||||
+ else
|
||||
+ continue;
|
||||
+ }
|
||||
/* No signals available after spinning, so prepare to block.
|
||||
We first acquire a group reference and use acquire MO for that so
|
||||
that we synchronize with the dummy read-modify-write in
|
||||
@@ -479,21 +485,12 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
the lock during cancellation is not possible. */
|
||||
/* Clean-up for cancellation of waiters waiting for normal signals. We cancel
|
||||
our registration as a waiter, confirm we have woken up, and re-acquire the
|
||||
mutex. */
|
||||
@@ -171,8 +154,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
pthread_cond_t *cond = cbuffer->cond;
|
||||
unsigned g = cbuffer->wseq & 1;
|
||||
|
||||
- __condvar_dec_grefs (cond, g, cbuffer->private);
|
||||
-
|
||||
__condvar_cancel_waiting (cond, cbuffer->wseq >> 1, g, cbuffer->private);
|
||||
/* FIXME With the current cancellation implementation, it is possible that
|
||||
a thread is cancelled after it has returned from a syscall. This could
|
||||
@@ -327,15 +308,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
sufficient because if a waiter can see a sufficiently large value, it could
|
||||
have also consume a signal in the waiters group.
|
||||
|
||||
- It is essential that the last field in pthread_cond_t is __g_signals[1]:
|
||||
- The previous condvar used a pointer-sized field in pthread_cond_t, so a
|
||||
- PTHREAD_COND_INITIALIZER from that condvar implementation might only
|
||||
- initialize 4 bytes to zero instead of the 8 bytes we need (i.e., 44 bytes
|
||||
- in total instead of the 48 we need). __g_signals[1] is not accessed before
|
||||
- the first group switch (G2 starts at index 0), which will set its value to
|
||||
- zero after a harmless fetch-or whose return value is ignored. This
|
||||
- effectively completes initialization.
|
||||
-
|
||||
|
||||
Limitations:
|
||||
* This condvar isn't designed to allow for more than
|
||||
@@ -440,21 +412,6 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
if ((int)(signals - lowseq) >= 2)
|
||||
break;
|
||||
|
||||
- /* No signals available after spinning, so prepare to block.
|
||||
- We first acquire a group reference and use acquire MO for that so
|
||||
- that we synchronize with the dummy read-modify-write in
|
||||
- __condvar_quiesce_and_switch_g1 if we read from that. In turn,
|
||||
- in this case this will make us see the advancement of __g_signals
|
||||
- to the upcoming new g1_start that occurs with a concurrent
|
||||
- attempt to reuse the group's slot.
|
||||
- We use acquire MO for the __g_signals check to make the
|
||||
- __g1_start check work (see spinning above).
|
||||
- Note that the group reference acquisition will not mask the
|
||||
- release MO when decrementing the reference count because we use
|
||||
- an atomic read-modify-write operation and thus extend the release
|
||||
- sequence. */
|
||||
- atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
|
||||
-
|
||||
// Now block.
|
||||
struct _pthread_cleanup_buffer buffer;
|
||||
struct _condvar_cleanup_buffer cbuffer;
|
||||
@@ -471,18 +428,11 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
|
||||
if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
{
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
- /* If we timed out, we effectively cancel waiting. Note that
|
||||
- we have decremented __g_refs before cancellation, so that a
|
||||
- deadlock between waiting for quiescence of our group in
|
||||
- __condvar_quiesce_and_switch_g1 and us trying to acquire
|
||||
- the lock during cancellation is not possible. */
|
||||
+ /* If we timed out, we effectively cancel waiting. */
|
||||
__condvar_cancel_waiting (cond, seq, g, private);
|
||||
result = err;
|
||||
- goto done;
|
||||
+ break;
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
__condvar_dec_grefs (cond, g, private);
|
||||
- else
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
|
||||
- /* Reload signals. See above for MO. */
|
||||
- signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
}
|
||||
- }
|
||||
- /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
- iteration we need to see the correct value of g1_start) */
|
||||
- while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
|
||||
- &signals, signals - 2));
|
||||
-
|
||||
- done:
|
||||
/* Reload signals. See above for MO. */
|
||||
signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
diff --git a/nptl/tst-cond22.c b/nptl/tst-cond22.c
|
||||
index 1336e9c7..bdcb45c5 100644
|
||||
--- a/nptl/tst-cond22.c
|
||||
+++ b/nptl/tst-cond22.c
|
||||
@@ -106,13 +106,13 @@ do_test (void)
|
||||
status = 1;
|
||||
}
|
||||
|
||||
/* Confirm that we have been woken. We do that before acquiring the mutex
|
||||
to allow for execution of pthread_cond_destroy while having acquired the
|
||||
- printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
|
||||
+ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n",
|
||||
c.__data.__wseq.__value32.__high,
|
||||
c.__data.__wseq.__value32.__low,
|
||||
c.__data.__g1_start.__value32.__high,
|
||||
c.__data.__g1_start.__value32.__low,
|
||||
- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
|
||||
- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
|
||||
+ c.__data.__g_signals[0], c.__data.__g_size[0],
|
||||
+ c.__data.__g_signals[1], c.__data.__g_size[1],
|
||||
c.__data.__g1_orig_size, c.__data.__wrefs);
|
||||
|
||||
if (pthread_create (&th, NULL, tf, (void *) 1l) != 0)
|
||||
@@ -152,13 +152,13 @@ do_test (void)
|
||||
status = 1;
|
||||
}
|
||||
|
||||
- printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u/%u, %u/%u/%u, %u, %u }\n",
|
||||
+ printf ("cond = { 0x%x:%x, 0x%x:%x, %u/%u, %u/%u, %u, %u }\n",
|
||||
c.__data.__wseq.__value32.__high,
|
||||
c.__data.__wseq.__value32.__low,
|
||||
c.__data.__g1_start.__value32.__high,
|
||||
c.__data.__g1_start.__value32.__low,
|
||||
- c.__data.__g_signals[0], c.__data.__g_refs[0], c.__data.__g_size[0],
|
||||
- c.__data.__g_signals[1], c.__data.__g_refs[1], c.__data.__g_size[1],
|
||||
+ c.__data.__g_signals[0], c.__data.__g_size[0],
|
||||
+ c.__data.__g_signals[1], c.__data.__g_size[1],
|
||||
c.__data.__g1_orig_size, c.__data.__wrefs);
|
||||
|
||||
return status;
|
||||
diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
index 5653507e..6f17afa4 100644
|
||||
--- a/sysdeps/nptl/bits/thread-shared-types.h
|
||||
+++ b/sysdeps/nptl/bits/thread-shared-types.h
|
||||
@@ -95,8 +95,7 @@ struct __pthread_cond_s
|
||||
{
|
||||
__atomic_wide_counter __wseq;
|
||||
__atomic_wide_counter __g1_start;
|
||||
- unsigned int __g_refs[2] __LOCK_ALIGNMENT;
|
||||
- unsigned int __g_size[2];
|
||||
+ unsigned int __g_size[2] __LOCK_ALIGNMENT;
|
||||
unsigned int __g1_orig_size;
|
||||
unsigned int __wrefs;
|
||||
unsigned int __g_signals[2];
|
||||
diff --git a/sysdeps/nptl/pthread.h b/sysdeps/nptl/pthread.h
|
||||
index dedad4ec..bbb36540 100644
|
||||
--- a/sysdeps/nptl/pthread.h
|
||||
+++ b/sysdeps/nptl/pthread.h
|
||||
@@ -152,7 +152,7 @@ enum
|
||||
|
||||
|
||||
/* Conditional variable handling. */
|
||||
-#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, {0, 0}, 0, 0, {0, 0} } }
|
||||
+#define PTHREAD_COND_INITIALIZER { { {0}, {0}, {0, 0}, 0, 0, {0, 0} } }
|
||||
|
||||
|
||||
/* Cleanup buffers */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
||||
@@ -1,166 +1,100 @@
|
||||
From a2faee6d0dac6e5232255da9afda4d9ed6cfb6e5 Mon Sep 17 00:00:00 2001
|
||||
From bbd7c84a1a14bf93bf1e5976d8a1540aabbf901b Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Tue, 17 Jun 2025 01:37:12 -0700
|
||||
Subject: [PATCH] nptl: Fix indentation
|
||||
Date: Tue, 14 Oct 2025 06:19:02 -0700
|
||||
Subject: [PATCH] nptl: Use a single loop in pthread_cond_wait instaed of a
|
||||
nested loop
|
||||
|
||||
In my previous change I turned a nested loop into a simple loop. I'm doing
|
||||
the resulting indentation changes in a separate commit to make the diff on
|
||||
the previous commit easier to review.
|
||||
The loop was a little more complicated than necessary. There was only one
|
||||
break statement out of the inner loop, and the outer loop was nearly empty.
|
||||
So just remove the outer loop, moving its code to the one break statement in
|
||||
the inner loop. This allows us to replace all gotos with break statements.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: 929a4764ac90382616b6a21f099192b2475da674
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=ee6c14ed59d480720721aaacc5fb03213dc153da]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002279.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
nptl/pthread_cond_wait.c | 132 ++++++++++++++++-----------------------
|
||||
1 file changed, 54 insertions(+), 78 deletions(-)
|
||||
nptl/pthread_cond_wait.c | 41 +++++++++++++++++++---------------------
|
||||
1 file changed, 19 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 5c86880105..104ebd48ca 100644
|
||||
index 8a9219e0..c8c99bbf 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -410,87 +410,63 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
@@ -382,17 +382,15 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
return err;
|
||||
}
|
||||
|
||||
- /* Now wait until a signal is available in our group or it is closed.
|
||||
- Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
- unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
-
|
||||
- while (1)
|
||||
- {
|
||||
- /* Now wait until a signal is available in our group or it is closed.
|
||||
- Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
- unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
-
|
||||
- if (seq < (g1_start >> 1))
|
||||
- {
|
||||
- /* If the group is closed already,
|
||||
- then this waiter originally had enough extra signals to
|
||||
- consume, up until the time its group was closed. */
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* If there is an available signal, don't block.
|
||||
- If __g1_start has advanced at all, then we must be in G1
|
||||
- by now, perhaps in the process of switching back to an older
|
||||
- G2, but in either case we're allowed to consume the available
|
||||
- signal and should not block anymore. */
|
||||
- if ((int)(signals - lowseq) >= 2)
|
||||
- {
|
||||
- /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
- iteration we need to see the correct value of g1_start) */
|
||||
- if (atomic_compare_exchange_weak_acquire (
|
||||
- cond->__data.__g_signals + g,
|
||||
+ while (1)
|
||||
+ {
|
||||
+ /* Now wait until a signal is available in our group or it is closed.
|
||||
+ Acquire MO so that if we observe (signals == lowseq) after group
|
||||
+ switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
+ store and will see the prior update of __g1_start done while switching
|
||||
+ groups too. */
|
||||
+ unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
- do
|
||||
- {
|
||||
+
|
||||
+ if (seq < (g1_start >> 1))
|
||||
+ {
|
||||
+ /* If the group is closed already,
|
||||
+ then this waiter originally had enough extra signals to
|
||||
+ consume, up until the time its group was closed. */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* If there is an available signal, don't block.
|
||||
+ If __g1_start has advanced at all, then we must be in G1
|
||||
+ by now, perhaps in the process of switching back to an older
|
||||
+ G2, but in either case we're allowed to consume the available
|
||||
+ signal and should not block anymore. */
|
||||
+ if ((int)(signals - lowseq) >= 2)
|
||||
+ {
|
||||
+ /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
+ iteration we need to see the correct value of g1_start) */
|
||||
+ if (atomic_compare_exchange_weak_acquire (
|
||||
+ cond->__data.__g_signals + g,
|
||||
&signals, signals - 2))
|
||||
- break;
|
||||
- else
|
||||
- continue;
|
||||
- }
|
||||
- /* No signals available after spinning, so prepare to block.
|
||||
- We first acquire a group reference and use acquire MO for that so
|
||||
- that we synchronize with the dummy read-modify-write in
|
||||
- __condvar_quiesce_and_switch_g1 if we read from that. In turn,
|
||||
- in this case this will make us see the advancement of __g_signals
|
||||
- to the upcoming new g1_start that occurs with a concurrent
|
||||
- attempt to reuse the group's slot.
|
||||
- We use acquire MO for the __g_signals check to make the
|
||||
- __g1_start check work (see spinning above).
|
||||
- Note that the group reference acquisition will not mask the
|
||||
- release MO when decrementing the reference count because we use
|
||||
- an atomic read-modify-write operation and thus extend the release
|
||||
- sequence. */
|
||||
- atomic_fetch_add_acquire (cond->__data.__g_refs + g, 2);
|
||||
while (1)
|
||||
{
|
||||
+ /* Now wait until a signal is available in our group or it is closed.
|
||||
+ Acquire MO so that if we observe (signals == lowseq) after group
|
||||
+ switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
+ store and will see the prior update of __g1_start done while switching
|
||||
+ groups too. */
|
||||
+ unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
@@ -401,7 +399,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
/* If the group is closed already,
|
||||
then this waiter originally had enough extra signals to
|
||||
consume, up until the time its group was closed. */
|
||||
- goto done;
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* If there is an available signal, don't block.
|
||||
@@ -410,7 +408,16 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
G2, but in either case we're allowed to consume the available
|
||||
signal and should not block anymore. */
|
||||
if ((int)(signals - lowseq) >= 2)
|
||||
- break;
|
||||
+ {
|
||||
+ /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
+ iteration we need to see the correct value of g1_start) */
|
||||
+ if (atomic_compare_exchange_weak_acquire (
|
||||
+ cond->__data.__g_signals + g,
|
||||
+ &signals, signals - 2))
|
||||
+ break;
|
||||
+ else
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
// Now block.
|
||||
struct _pthread_cleanup_buffer buffer;
|
||||
@@ -431,19 +438,9 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
/* If we timed out, we effectively cancel waiting. */
|
||||
__condvar_cancel_waiting (cond, seq, g, private);
|
||||
result = err;
|
||||
- goto done;
|
||||
+ break;
|
||||
}
|
||||
-
|
||||
- // Now block.
|
||||
- struct _pthread_cleanup_buffer buffer;
|
||||
- struct _condvar_cleanup_buffer cbuffer;
|
||||
- cbuffer.wseq = wseq;
|
||||
- cbuffer.cond = cond;
|
||||
- cbuffer.mutex = mutex;
|
||||
- cbuffer.private = private;
|
||||
- __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
|
||||
-
|
||||
- err = __futex_abstimed_wait_cancelable64 (
|
||||
- cond->__data.__g_signals + g, signals, clockid, abstime, private);
|
||||
-
|
||||
- __pthread_cleanup_pop (&buffer, 0);
|
||||
-
|
||||
- if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
- {
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
- /* If we timed out, we effectively cancel waiting. Note that
|
||||
- we have decremented __g_refs before cancellation, so that a
|
||||
- deadlock between waiting for quiescence of our group in
|
||||
- __condvar_quiesce_and_switch_g1 and us trying to acquire
|
||||
- the lock during cancellation is not possible. */
|
||||
- __condvar_cancel_waiting (cond, seq, g, private);
|
||||
- result = err;
|
||||
break;
|
||||
- }
|
||||
- else
|
||||
- __condvar_dec_grefs (cond, g, private);
|
||||
-
|
||||
+ else
|
||||
+ continue;
|
||||
- /* Reload signals. See above for MO. */
|
||||
- signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
}
|
||||
+ // Now block.
|
||||
+ struct _pthread_cleanup_buffer buffer;
|
||||
+ struct _condvar_cleanup_buffer cbuffer;
|
||||
+ cbuffer.wseq = wseq;
|
||||
+ cbuffer.cond = cond;
|
||||
+ cbuffer.mutex = mutex;
|
||||
+ cbuffer.private = private;
|
||||
+ __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
|
||||
+
|
||||
+ err = __futex_abstimed_wait_cancelable64 (
|
||||
+ cond->__data.__g_signals + g, signals, clockid, abstime, private);
|
||||
+
|
||||
+ __pthread_cleanup_pop (&buffer, 0);
|
||||
+
|
||||
+ if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
+ {
|
||||
+ /* If we timed out, we effectively cancel waiting. */
|
||||
+ __condvar_cancel_waiting (cond, seq, g, private);
|
||||
+ result = err;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
- }
|
||||
- /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
- iteration we need to see the correct value of g1_start) */
|
||||
- while (!atomic_compare_exchange_weak_acquire (cond->__data.__g_signals + g,
|
||||
- &signals, signals - 2));
|
||||
-
|
||||
- done:
|
||||
|
||||
/* Confirm that we have been woken. We do that before acquiring the mutex
|
||||
to allow for execution of pthread_cond_destroy while having acquired the
|
||||
|
||||
@@ -1,160 +1,149 @@
|
||||
From 2a601ac9041e2ca645acad2c174b1c545cfceafe Mon Sep 17 00:00:00 2001
|
||||
From 1077953950d1e8864c63222967141c67f51297f8 Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Tue, 17 Jun 2025 01:53:25 -0700
|
||||
Subject: [PATCH] nptl: rename __condvar_quiesce_and_switch_g1
|
||||
Date: Tue, 14 Oct 2025 06:27:04 -0700
|
||||
Subject: [PATCH] nptl: Fix indentation
|
||||
|
||||
This function no longer waits for threads to leave g1, so rename it to
|
||||
__condvar_switch_g1
|
||||
In my previous change I turned a nested loop into a simple loop. I'm doing
|
||||
the resulting indentation changes in a separate commit to make the diff on
|
||||
the previous commit easier to review.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: ee6c14ed59d480720721aaacc5fb03213dc153da
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=4b79e27a5073c02f6bff9aa8f4791230a0ab1867]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002280.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
nptl/pthread_cond_broadcast.c | 4 ++--
|
||||
nptl/pthread_cond_common.c | 26 ++++++++++++--------------
|
||||
nptl/pthread_cond_signal.c | 17 ++++++++---------
|
||||
nptl/pthread_cond_wait.c | 9 ++++-----
|
||||
4 files changed, 26 insertions(+), 30 deletions(-)
|
||||
nptl/pthread_cond_wait.c | 110 +++++++++++++++++++--------------------
|
||||
1 file changed, 55 insertions(+), 55 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
|
||||
index 5ae141ac81..a07435589a 100644
|
||||
--- a/nptl/pthread_cond_broadcast.c
|
||||
+++ b/nptl/pthread_cond_broadcast.c
|
||||
@@ -60,7 +60,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
cond->__data.__g_size[g1] << 1);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
|
||||
- /* We need to wake G1 waiters before we quiesce G1 below. */
|
||||
+ /* We need to wake G1 waiters before we switch G1 below. */
|
||||
/* TODO Only set it if there are indeed futex waiters. We could
|
||||
also try to move this out of the critical section in cases when
|
||||
G2 is empty (and we don't need to quiesce). */
|
||||
@@ -69,7 +69,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
|
||||
/* G1 is complete. Step (2) is next unless there are no waiters in G2, in
|
||||
which case we can stop. */
|
||||
- if (__condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
|
||||
+ if (__condvar_switch_g1 (cond, wseq, &g1, private))
|
||||
{
|
||||
/* Step (3): Send signals to all waiters in the old G2 / new G1. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index f976a533a1..3baac4dabc 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -189,16 +189,15 @@ __condvar_get_private (int flags)
|
||||
return FUTEX_SHARED;
|
||||
}
|
||||
|
||||
-/* This closes G1 (whose index is in G1INDEX), waits for all futex waiters to
|
||||
- leave G1, converts G1 into a fresh G2, and then switches group roles so that
|
||||
- the former G2 becomes the new G1 ending at the current __wseq value when we
|
||||
- eventually make the switch (WSEQ is just an observation of __wseq by the
|
||||
- signaler).
|
||||
+/* This closes G1 (whose index is in G1INDEX), converts G1 into a fresh G2,
|
||||
+ and then switches group roles so that the former G2 becomes the new G1
|
||||
+ ending at the current __wseq value when we eventually make the switch
|
||||
+ (WSEQ is just an observation of __wseq by the signaler).
|
||||
If G2 is empty, it will not switch groups because then it would create an
|
||||
empty G1 which would require switching groups again on the next signal.
|
||||
Returns false iff groups were not switched because G2 was empty. */
|
||||
static bool __attribute__ ((unused))
|
||||
-__condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
+__condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
unsigned int *g1index, int private)
|
||||
{
|
||||
unsigned int g1 = *g1index;
|
||||
@@ -214,8 +213,7 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
+ cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
return false;
|
||||
|
||||
- /* Now try to close and quiesce G1. We have to consider the following kinds
|
||||
- of waiters:
|
||||
+ /* We have to consider the following kinds of waiters:
|
||||
* Waiters from less recent groups than G1 are not affected because
|
||||
nothing will change for them apart from __g1_start getting larger.
|
||||
* New waiters arriving concurrently with the group switching will all go
|
||||
@@ -223,12 +221,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
are not affected.
|
||||
* Waiters in G1 have already received a signal and been woken. */
|
||||
|
||||
- /* Update __g1_start, which finishes closing this group. The value we add
|
||||
- will never be negative because old_orig_size can only be zero when we
|
||||
- switch groups the first time after a condvar was initialized, in which
|
||||
- case G1 will be at index 1 and we will add a value of 1.
|
||||
- Relaxed MO is fine because the change comes with no additional
|
||||
- constraints that others would have to observe. */
|
||||
+ /* Update __g1_start, which closes this group. The value we add will never
|
||||
+ be negative because old_orig_size can only be zero when we switch groups
|
||||
+ the first time after a condvar was initialized, in which case G1 will be
|
||||
+ at index 1 and we will add a value of 1. Relaxed MO is fine because the
|
||||
+ change comes with no additional constraints that others would have to
|
||||
+ observe. */
|
||||
__condvar_add_g1_start_relaxed (cond,
|
||||
(old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
|
||||
|
||||
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
|
||||
index 14800ba00b..a9bc10dcca 100644
|
||||
--- a/nptl/pthread_cond_signal.c
|
||||
+++ b/nptl/pthread_cond_signal.c
|
||||
@@ -69,18 +69,17 @@ ___pthread_cond_signal (pthread_cond_t *cond)
|
||||
bool do_futex_wake = false;
|
||||
|
||||
/* If G1 is still receiving signals, we put the signal there. If not, we
|
||||
- check if G2 has waiters, and if so, quiesce and switch G1 to the former
|
||||
- G2; if this results in a new G1 with waiters (G2 might have cancellations
|
||||
- already, see __condvar_quiesce_and_switch_g1), we put the signal in the
|
||||
- new G1. */
|
||||
+ check if G2 has waiters, and if so, switch G1 to the former G2; if this
|
||||
+ results in a new G1 with waiters (G2 might have cancellations already,
|
||||
+ see __condvar_switch_g1), we put the signal in the new G1. */
|
||||
if ((cond->__data.__g_size[g1] != 0)
|
||||
- || __condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
|
||||
+ || __condvar_switch_g1 (cond, wseq, &g1, private))
|
||||
{
|
||||
/* Add a signal. Relaxed MO is fine because signaling does not need to
|
||||
- establish a happens-before relation (see above). We do not mask the
|
||||
- release-MO store when initializing a group in
|
||||
- __condvar_quiesce_and_switch_g1 because we use an atomic
|
||||
- read-modify-write and thus extend that store's release sequence. */
|
||||
+ establish a happens-before relation (see above). We do not mask the
|
||||
+ release-MO store when initializing a group in __condvar_switch_g1
|
||||
+ because we use an atomic read-modify-write and thus extend that
|
||||
+ store's release sequence. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
|
||||
cond->__data.__g_size[g1]--;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 104ebd48ca..bb46f3605d 100644
|
||||
index c8c99bbf..adf26a80 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -382,8 +382,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
because we do not need to establish any happens-before relation with
|
||||
signalers (see __pthread_cond_signal); modification order alone
|
||||
establishes a total order of waiters/signals. We do need acquire MO
|
||||
- to synchronize with group reinitialization in
|
||||
- __condvar_quiesce_and_switch_g1. */
|
||||
+ to synchronize with group reinitialization in __condvar_switch_g1. */
|
||||
uint64_t wseq = __condvar_fetch_add_wseq_acquire (cond, 2);
|
||||
/* Find our group's index. We always go into what was G2 when we acquired
|
||||
our position. */
|
||||
@@ -414,9 +413,9 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
{
|
||||
/* Now wait until a signal is available in our group or it is closed.
|
||||
Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
+ switching in __condvar_switch_g1, we synchronize with that store and
|
||||
+ will see the prior update of __g1_start done while switching groups
|
||||
+ too. */
|
||||
unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
@@ -383,65 +383,65 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
}
|
||||
|
||||
|
||||
- while (1)
|
||||
- {
|
||||
- /* Now wait until a signal is available in our group or it is closed.
|
||||
- Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
- unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
-
|
||||
- if (seq < (g1_start >> 1))
|
||||
- {
|
||||
- /* If the group is closed already,
|
||||
- then this waiter originally had enough extra signals to
|
||||
- consume, up until the time its group was closed. */
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- /* If there is an available signal, don't block.
|
||||
- If __g1_start has advanced at all, then we must be in G1
|
||||
- by now, perhaps in the process of switching back to an older
|
||||
- G2, but in either case we're allowed to consume the available
|
||||
- signal and should not block anymore. */
|
||||
- if ((int)(signals - lowseq) >= 2)
|
||||
- {
|
||||
- /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
- iteration we need to see the correct value of g1_start) */
|
||||
- if (atomic_compare_exchange_weak_acquire (
|
||||
- cond->__data.__g_signals + g,
|
||||
+ while (1)
|
||||
+ {
|
||||
+ /* Now wait until a signal is available in our group or it is closed.
|
||||
+ Acquire MO so that if we observe (signals == lowseq) after group
|
||||
+ switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
+ store and will see the prior update of __g1_start done while switching
|
||||
+ groups too. */
|
||||
+ unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
+
|
||||
+ if (seq < (g1_start >> 1))
|
||||
+ {
|
||||
+ /* If the group is closed already,
|
||||
+ then this waiter originally had enough extra signals to
|
||||
+ consume, up until the time its group was closed. */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* If there is an available signal, don't block.
|
||||
+ If __g1_start has advanced at all, then we must be in G1
|
||||
+ by now, perhaps in the process of switching back to an older
|
||||
+ G2, but in either case we're allowed to consume the available
|
||||
+ signal and should not block anymore. */
|
||||
+ if ((int)(signals - lowseq) >= 2)
|
||||
+ {
|
||||
+ /* Try to grab a signal. See above for MO. (if we do another loop
|
||||
+ iteration we need to see the correct value of g1_start) */
|
||||
+ if (atomic_compare_exchange_weak_acquire (
|
||||
+ cond->__data.__g_signals + g,
|
||||
&signals, signals - 2))
|
||||
- break;
|
||||
- else
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- // Now block.
|
||||
- struct _pthread_cleanup_buffer buffer;
|
||||
- struct _condvar_cleanup_buffer cbuffer;
|
||||
- cbuffer.wseq = wseq;
|
||||
- cbuffer.cond = cond;
|
||||
- cbuffer.mutex = mutex;
|
||||
- cbuffer.private = private;
|
||||
- __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
|
||||
-
|
||||
- err = __futex_abstimed_wait_cancelable64 (
|
||||
- cond->__data.__g_signals + g, signals, clockid, abstime, private);
|
||||
-
|
||||
- __pthread_cleanup_pop (&buffer, 0);
|
||||
-
|
||||
- if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
- {
|
||||
- /* If we timed out, we effectively cancel waiting. */
|
||||
- __condvar_cancel_waiting (cond, seq, g, private);
|
||||
- result = err;
|
||||
break;
|
||||
- }
|
||||
+ else
|
||||
+ continue;
|
||||
}
|
||||
|
||||
+ // Now block.
|
||||
+ struct _pthread_cleanup_buffer buffer;
|
||||
+ struct _condvar_cleanup_buffer cbuffer;
|
||||
+ cbuffer.wseq = wseq;
|
||||
+ cbuffer.cond = cond;
|
||||
+ cbuffer.mutex = mutex;
|
||||
+ cbuffer.private = private;
|
||||
+ __pthread_cleanup_push (&buffer, __condvar_cleanup_waiting, &cbuffer);
|
||||
+
|
||||
+ err = __futex_abstimed_wait_cancelable64 (
|
||||
+ cond->__data.__g_signals + g, signals, clockid, abstime, private);
|
||||
+
|
||||
+ __pthread_cleanup_pop (&buffer, 0);
|
||||
+
|
||||
+ if (__glibc_unlikely (err == ETIMEDOUT || err == EOVERFLOW))
|
||||
+ {
|
||||
+ /* If we timed out, we effectively cancel waiting. */
|
||||
+ __condvar_cancel_waiting (cond, seq, g, private);
|
||||
+ result = err;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* Confirm that we have been woken. We do that before acquiring the mutex
|
||||
to allow for execution of pthread_cond_destroy while having acquired the
|
||||
mutex. */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
||||
@@ -1,192 +1,161 @@
|
||||
From fc074de88796eb2036fbe9bade638e00adfd5cb2 Mon Sep 17 00:00:00 2001
|
||||
From 20d84dfa0b9a32f88259269bbeaae588744ae4ae Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Tue, 17 Jun 2025 02:08:36 -0700
|
||||
Subject: [PATCH] nptl: Use all of g1_start and g_signals
|
||||
Date: Tue, 14 Oct 2025 06:33:50 -0700
|
||||
Subject: [PATCH] nptl: rename __condvar_quiesce_and_switch_g1
|
||||
|
||||
The LSB of g_signals was unused. The LSB of g1_start was used to indicate
|
||||
which group is G2. This was used to always go to sleep in pthread_cond_wait
|
||||
if a waiter is in G2. A comment earlier in the file says that this is not
|
||||
correct to do:
|
||||
|
||||
"Waiters cannot determine whether they are currently in G2 or G1 -- but they
|
||||
do not have to because all they are interested in is whether there are
|
||||
available signals"
|
||||
|
||||
I either would have had to update the comment, or get rid of the check. I
|
||||
chose to get rid of the check. In fact I don't quite know why it was there.
|
||||
There will never be available signals for group G2, so we didn't need the
|
||||
special case. Even if there were, this would just be a spurious wake. This
|
||||
might have caught some cases where the count has wrapped around, but it
|
||||
wouldn't reliably do that, (and even if it did, why would you want to force a
|
||||
sleep in that case?) and we don't support that many concurrent waiters
|
||||
anyway. Getting rid of it allows us to use one more bit, making us more
|
||||
robust to wraparound.
|
||||
This function no longer waits for threads to leave g1, so rename it to
|
||||
__condvar_switch_g1
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: 4b79e27a5073c02f6bff9aa8f4791230a0ab1867
|
||||
|
||||
Upstream-Status: Backport
|
||||
[https://sourceware.org/git/?p=glibc.git;a=commit;h=91bb902f58264a2fd50fbce8f39a9a290dd23706]
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002281.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
nptl/pthread_cond_broadcast.c | 4 ++--
|
||||
nptl/pthread_cond_common.c | 26 ++++++++++----------------
|
||||
nptl/pthread_cond_signal.c | 2 +-
|
||||
nptl/pthread_cond_wait.c | 14 +++++---------
|
||||
4 files changed, 18 insertions(+), 28 deletions(-)
|
||||
nptl/pthread_cond_common.c | 26 ++++++++++++--------------
|
||||
nptl/pthread_cond_signal.c | 17 ++++++++---------
|
||||
nptl/pthread_cond_wait.c | 9 ++++-----
|
||||
4 files changed, 26 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
|
||||
index a07435589a..ef0943cdc5 100644
|
||||
index 5ae141ac..a0743558 100644
|
||||
--- a/nptl/pthread_cond_broadcast.c
|
||||
+++ b/nptl/pthread_cond_broadcast.c
|
||||
@@ -57,7 +57,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
{
|
||||
/* Add as many signals as the remaining size of the group. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
- cond->__data.__g_size[g1] << 1);
|
||||
+ cond->__data.__g_size[g1]);
|
||||
@@ -60,7 +60,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
cond->__data.__g_size[g1] << 1);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
|
||||
/* We need to wake G1 waiters before we switch G1 below. */
|
||||
@@ -73,7 +73,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
- /* We need to wake G1 waiters before we quiesce G1 below. */
|
||||
+ /* We need to wake G1 waiters before we switch G1 below. */
|
||||
/* TODO Only set it if there are indeed futex waiters. We could
|
||||
also try to move this out of the critical section in cases when
|
||||
G2 is empty (and we don't need to quiesce). */
|
||||
@@ -69,7 +69,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
|
||||
/* G1 is complete. Step (2) is next unless there are no waiters in G2, in
|
||||
which case we can stop. */
|
||||
- if (__condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
|
||||
+ if (__condvar_switch_g1 (cond, wseq, &g1, private))
|
||||
{
|
||||
/* Step (3): Send signals to all waiters in the old G2 / new G1. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
- cond->__data.__g_size[g1] << 1);
|
||||
+ cond->__data.__g_size[g1]);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
do_futex_wake = true;
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index 3baac4dabc..e48f914321 100644
|
||||
index f976a533..3baac4da 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -208,9 +208,9 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
behavior.
|
||||
Note that this works correctly for a zero-initialized condvar too. */
|
||||
unsigned int old_orig_size = __condvar_get_orig_size (cond);
|
||||
- uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
|
||||
- if (((unsigned) (wseq - old_g1_start - old_orig_size)
|
||||
- + cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
+ uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ uint64_t new_g1_start = old_g1_start + old_orig_size;
|
||||
+ if (((unsigned) (wseq - new_g1_start) + cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
@@ -189,16 +189,15 @@ __condvar_get_private (int flags)
|
||||
return FUTEX_SHARED;
|
||||
}
|
||||
|
||||
-/* This closes G1 (whose index is in G1INDEX), waits for all futex waiters to
|
||||
- leave G1, converts G1 into a fresh G2, and then switches group roles so that
|
||||
- the former G2 becomes the new G1 ending at the current __wseq value when we
|
||||
- eventually make the switch (WSEQ is just an observation of __wseq by the
|
||||
- signaler).
|
||||
+/* This closes G1 (whose index is in G1INDEX), converts G1 into a fresh G2,
|
||||
+ and then switches group roles so that the former G2 becomes the new G1
|
||||
+ ending at the current __wseq value when we eventually make the switch
|
||||
+ (WSEQ is just an observation of __wseq by the signaler).
|
||||
If G2 is empty, it will not switch groups because then it would create an
|
||||
empty G1 which would require switching groups again on the next signal.
|
||||
Returns false iff groups were not switched because G2 was empty. */
|
||||
static bool __attribute__ ((unused))
|
||||
-__condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
+__condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
unsigned int *g1index, int private)
|
||||
{
|
||||
unsigned int g1 = *g1index;
|
||||
@@ -214,8 +213,7 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
+ cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
return false;
|
||||
|
||||
/* We have to consider the following kinds of waiters:
|
||||
@@ -221,16 +221,10 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
- /* Now try to close and quiesce G1. We have to consider the following kinds
|
||||
- of waiters:
|
||||
+ /* We have to consider the following kinds of waiters:
|
||||
* Waiters from less recent groups than G1 are not affected because
|
||||
nothing will change for them apart from __g1_start getting larger.
|
||||
* New waiters arriving concurrently with the group switching will all go
|
||||
@@ -223,12 +221,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
are not affected.
|
||||
* Waiters in G1 have already received a signal and been woken. */
|
||||
|
||||
- /* Update __g1_start, which closes this group. The value we add will never
|
||||
- be negative because old_orig_size can only be zero when we switch groups
|
||||
- the first time after a condvar was initialized, in which case G1 will be
|
||||
- at index 1 and we will add a value of 1. Relaxed MO is fine because the
|
||||
- change comes with no additional constraints that others would have to
|
||||
- observe. */
|
||||
- __condvar_add_g1_start_relaxed (cond,
|
||||
- (old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
|
||||
-
|
||||
- unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||
+ /* Update __g1_start, which closes this group. Relaxed MO is fine because
|
||||
+ the change comes with no additional constraints that others would have
|
||||
+ to observe. */
|
||||
+ __condvar_add_g1_start_relaxed (cond, old_orig_size);
|
||||
- /* Update __g1_start, which finishes closing this group. The value we add
|
||||
- will never be negative because old_orig_size can only be zero when we
|
||||
- switch groups the first time after a condvar was initialized, in which
|
||||
- case G1 will be at index 1 and we will add a value of 1.
|
||||
- Relaxed MO is fine because the change comes with no additional
|
||||
- constraints that others would have to observe. */
|
||||
+ /* Update __g1_start, which closes this group. The value we add will never
|
||||
+ be negative because old_orig_size can only be zero when we switch groups
|
||||
+ the first time after a condvar was initialized, in which case G1 will be
|
||||
+ at index 1 and we will add a value of 1. Relaxed MO is fine because the
|
||||
+ change comes with no additional constraints that others would have to
|
||||
+ observe. */
|
||||
__condvar_add_g1_start_relaxed (cond,
|
||||
(old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
|
||||
|
||||
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||
No old waiter can neither grab a signal nor acquire a reference without
|
||||
@@ -242,13 +236,13 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
g1 ^= 1;
|
||||
*g1index ^= 1;
|
||||
|
||||
- /* Now advance the new G1 g_signals to the new lowseq, giving it
|
||||
+ /* Now advance the new G1 g_signals to the new g1_start, giving it
|
||||
an effective signal count of 0 to start. */
|
||||
- atomic_store_release (cond->__data.__g_signals + g1, lowseq);
|
||||
+ atomic_store_release (cond->__data.__g_signals + g1, (unsigned)new_g1_start);
|
||||
|
||||
/* These values are just observed by signalers, and thus protected by the
|
||||
lock. */
|
||||
- unsigned int orig_size = wseq - (old_g1_start + old_orig_size);
|
||||
+ unsigned int orig_size = wseq - new_g1_start;
|
||||
__condvar_set_orig_size (cond, orig_size);
|
||||
/* Use and addition to not loose track of cancellations in what was
|
||||
previously G2. */
|
||||
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
|
||||
index a9bc10dcca..07427369aa 100644
|
||||
index 14800ba0..a9bc10dc 100644
|
||||
--- a/nptl/pthread_cond_signal.c
|
||||
+++ b/nptl/pthread_cond_signal.c
|
||||
@@ -80,7 +80,7 @@ ___pthread_cond_signal (pthread_cond_t *cond)
|
||||
release-MO store when initializing a group in __condvar_switch_g1
|
||||
because we use an atomic read-modify-write and thus extend that
|
||||
store's release sequence. */
|
||||
- atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
|
||||
+ atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 1);
|
||||
@@ -69,18 +69,17 @@ ___pthread_cond_signal (pthread_cond_t *cond)
|
||||
bool do_futex_wake = false;
|
||||
|
||||
/* If G1 is still receiving signals, we put the signal there. If not, we
|
||||
- check if G2 has waiters, and if so, quiesce and switch G1 to the former
|
||||
- G2; if this results in a new G1 with waiters (G2 might have cancellations
|
||||
- already, see __condvar_quiesce_and_switch_g1), we put the signal in the
|
||||
- new G1. */
|
||||
+ check if G2 has waiters, and if so, switch G1 to the former G2; if this
|
||||
+ results in a new G1 with waiters (G2 might have cancellations already,
|
||||
+ see __condvar_switch_g1), we put the signal in the new G1. */
|
||||
if ((cond->__data.__g_size[g1] != 0)
|
||||
- || __condvar_quiesce_and_switch_g1 (cond, wseq, &g1, private))
|
||||
+ || __condvar_switch_g1 (cond, wseq, &g1, private))
|
||||
{
|
||||
/* Add a signal. Relaxed MO is fine because signaling does not need to
|
||||
- establish a happens-before relation (see above). We do not mask the
|
||||
- release-MO store when initializing a group in
|
||||
- __condvar_quiesce_and_switch_g1 because we use an atomic
|
||||
- read-modify-write and thus extend that store's release sequence. */
|
||||
+ establish a happens-before relation (see above). We do not mask the
|
||||
+ release-MO store when initializing a group in __condvar_switch_g1
|
||||
+ because we use an atomic read-modify-write and thus extend that
|
||||
+ store's release sequence. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
|
||||
cond->__data.__g_size[g1]--;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
do_futex_wake = true;
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index bb46f3605d..430cbe8a35 100644
|
||||
index adf26a80..40a74342 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -84,7 +84,7 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
|
||||
not hold a reference on the group. */
|
||||
__condvar_acquire_lock (cond, private);
|
||||
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
if (g1_start > seq)
|
||||
@@ -354,8 +354,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
because we do not need to establish any happens-before relation with
|
||||
signalers (see __pthread_cond_signal); modification order alone
|
||||
establishes a total order of waiters/signals. We do need acquire MO
|
||||
- to synchronize with group reinitialization in
|
||||
- __condvar_quiesce_and_switch_g1. */
|
||||
+ to synchronize with group reinitialization in __condvar_switch_g1. */
|
||||
uint64_t wseq = __condvar_fetch_add_wseq_acquire (cond, 2);
|
||||
/* Find our group's index. We always go into what was G2 when we acquired
|
||||
our position. */
|
||||
@@ -387,9 +386,9 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
{
|
||||
/* Our group is closed, so someone provided enough signals for it.
|
||||
@@ -278,7 +278,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
* Waiters fetch-add while having acquire the mutex associated with the
|
||||
condvar. Signalers load it and fetch-xor it concurrently.
|
||||
__g1_start: Starting position of G1 (inclusive)
|
||||
- * LSB is index of current G2.
|
||||
* Modified by signalers while having acquired the condvar-internal lock
|
||||
and observed concurrently by waiters.
|
||||
__g1_orig_size: Initial size of G1
|
||||
@@ -299,11 +298,9 @@ __condvar_cleanup_waiting (void *arg)
|
||||
* Reference count used by waiters concurrently with signalers that have
|
||||
acquired the condvar-internal lock.
|
||||
__g_signals: The number of signals that can still be consumed, relative to
|
||||
- the current g1_start. (i.e. bits 31 to 1 of __g_signals are bits
|
||||
- 31 to 1 of g1_start with the signal count added)
|
||||
+ the current g1_start. (i.e. g1_start with the signal count added)
|
||||
* Used as a futex word by waiters. Used concurrently by waiters and
|
||||
signalers.
|
||||
- * LSB is currently reserved and 0.
|
||||
__g_size: Waiters remaining in this group (i.e., which have not been
|
||||
signaled yet.
|
||||
* Accessed by signalers and waiters that cancel waiting (both do so only
|
||||
@@ -418,9 +415,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
too. */
|
||||
/* Now wait until a signal is available in our group or it is closed.
|
||||
Acquire MO so that if we observe (signals == lowseq) after group
|
||||
- switching in __condvar_quiesce_and_switch_g1, we synchronize with that
|
||||
- store and will see the prior update of __g1_start done while switching
|
||||
- groups too. */
|
||||
+ switching in __condvar_switch_g1, we synchronize with that store and
|
||||
+ will see the prior update of __g1_start done while switching groups
|
||||
+ too. */
|
||||
unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
- if (seq < (g1_start >> 1))
|
||||
+ if (seq < g1_start)
|
||||
{
|
||||
/* If the group is closed already,
|
||||
then this waiter originally had enough extra signals to
|
||||
@@ -433,13 +429,13 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
by now, perhaps in the process of switching back to an older
|
||||
G2, but in either case we're allowed to consume the available
|
||||
signal and should not block anymore. */
|
||||
- if ((int)(signals - lowseq) >= 2)
|
||||
+ if ((int)(signals - (unsigned int)g1_start) > 0)
|
||||
{
|
||||
/* Try to grab a signal. See above for MO. (if we do another loop
|
||||
iteration we need to see the correct value of g1_start) */
|
||||
if (atomic_compare_exchange_weak_acquire (
|
||||
cond->__data.__g_signals + g,
|
||||
- &signals, signals - 2))
|
||||
+ &signals, signals - 1))
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
|
||||
193
meta/recipes-core/glibc/glibc/0026-PR25847-9.patch
Normal file
193
meta/recipes-core/glibc/glibc/0026-PR25847-9.patch
Normal file
@@ -0,0 +1,193 @@
|
||||
From c2677e68956bb9677d8de4ee6c5341b1a744d490 Mon Sep 17 00:00:00 2001
|
||||
From: Malte Skarupke <malteskarupke@fastmail.fm>
|
||||
Date: Tue, 14 Oct 2025 06:40:57 -0700
|
||||
Subject: [PATCH] nptl: Use all of g1_start and g_signals
|
||||
|
||||
The LSB of g_signals was unused. The LSB of g1_start was used to indicate
|
||||
which group is G2. This was used to always go to sleep in pthread_cond_wait
|
||||
if a waiter is in G2. A comment earlier in the file says that this is not
|
||||
correct to do:
|
||||
|
||||
"Waiters cannot determine whether they are currently in G2 or G1 -- but they
|
||||
do not have to because all they are interested in is whether there are
|
||||
available signals"
|
||||
|
||||
I either would have had to update the comment, or get rid of the check. I
|
||||
chose to get rid of the check. In fact I don't quite know why it was there.
|
||||
There will never be available signals for group G2, so we didn't need the
|
||||
special case. Even if there were, this would just be a spurious wake. This
|
||||
might have caught some cases where the count has wrapped around, but it
|
||||
wouldn't reliably do that, (and even if it did, why would you want to force a
|
||||
sleep in that case?) and we don't support that many concurrent waiters
|
||||
anyway. Getting rid of it allows us to use one more bit, making us more
|
||||
robust to wraparound.
|
||||
|
||||
The following commits have been cherry-picked from Glibc master branch:
|
||||
Bug : https://sourceware.org/bugzilla/show_bug.cgi?id=25847
|
||||
commit: 91bb902f58264a2fd50fbce8f39a9a290dd23706
|
||||
|
||||
Upstream-Status: Submitted
|
||||
[https://sourceware.org/pipermail/libc-stable/2025-July/002283.html]
|
||||
|
||||
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
|
||||
---
|
||||
nptl/pthread_cond_broadcast.c | 4 ++--
|
||||
nptl/pthread_cond_common.c | 26 ++++++++++----------------
|
||||
nptl/pthread_cond_signal.c | 2 +-
|
||||
nptl/pthread_cond_wait.c | 14 +++++---------
|
||||
4 files changed, 18 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c
|
||||
index a0743558..ef0943cd 100644
|
||||
--- a/nptl/pthread_cond_broadcast.c
|
||||
+++ b/nptl/pthread_cond_broadcast.c
|
||||
@@ -57,7 +57,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
{
|
||||
/* Add as many signals as the remaining size of the group. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
- cond->__data.__g_size[g1] << 1);
|
||||
+ cond->__data.__g_size[g1]);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
|
||||
/* We need to wake G1 waiters before we switch G1 below. */
|
||||
@@ -73,7 +73,7 @@ ___pthread_cond_broadcast (pthread_cond_t *cond)
|
||||
{
|
||||
/* Step (3): Send signals to all waiters in the old G2 / new G1. */
|
||||
atomic_fetch_add_relaxed (cond->__data.__g_signals + g1,
|
||||
- cond->__data.__g_size[g1] << 1);
|
||||
+ cond->__data.__g_size[g1]);
|
||||
cond->__data.__g_size[g1] = 0;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
do_futex_wake = true;
|
||||
diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
|
||||
index 3baac4da..e48f9143 100644
|
||||
--- a/nptl/pthread_cond_common.c
|
||||
+++ b/nptl/pthread_cond_common.c
|
||||
@@ -208,9 +208,9 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
behavior.
|
||||
Note that this works correctly for a zero-initialized condvar too. */
|
||||
unsigned int old_orig_size = __condvar_get_orig_size (cond);
|
||||
- uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
|
||||
- if (((unsigned) (wseq - old_g1_start - old_orig_size)
|
||||
- + cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
+ uint64_t old_g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
+ uint64_t new_g1_start = old_g1_start + old_orig_size;
|
||||
+ if (((unsigned) (wseq - new_g1_start) + cond->__data.__g_size[g1 ^ 1]) == 0)
|
||||
return false;
|
||||
|
||||
/* We have to consider the following kinds of waiters:
|
||||
@@ -221,16 +221,10 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
are not affected.
|
||||
* Waiters in G1 have already received a signal and been woken. */
|
||||
|
||||
- /* Update __g1_start, which closes this group. The value we add will never
|
||||
- be negative because old_orig_size can only be zero when we switch groups
|
||||
- the first time after a condvar was initialized, in which case G1 will be
|
||||
- at index 1 and we will add a value of 1. Relaxed MO is fine because the
|
||||
- change comes with no additional constraints that others would have to
|
||||
- observe. */
|
||||
- __condvar_add_g1_start_relaxed (cond,
|
||||
- (old_orig_size << 1) + (g1 == 1 ? 1 : - 1));
|
||||
-
|
||||
- unsigned int lowseq = ((old_g1_start + old_orig_size) << 1) & ~1U;
|
||||
+ /* Update __g1_start, which closes this group. Relaxed MO is fine because
|
||||
+ the change comes with no additional constraints that others would have
|
||||
+ to observe. */
|
||||
+ __condvar_add_g1_start_relaxed (cond, old_orig_size);
|
||||
|
||||
/* At this point, the old G1 is now a valid new G2 (but not in use yet).
|
||||
No old waiter can neither grab a signal nor acquire a reference without
|
||||
@@ -242,13 +236,13 @@ __condvar_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
|
||||
g1 ^= 1;
|
||||
*g1index ^= 1;
|
||||
|
||||
- /* Now advance the new G1 g_signals to the new lowseq, giving it
|
||||
+ /* Now advance the new G1 g_signals to the new g1_start, giving it
|
||||
an effective signal count of 0 to start. */
|
||||
- atomic_store_release (cond->__data.__g_signals + g1, lowseq);
|
||||
+ atomic_store_release (cond->__data.__g_signals + g1, (unsigned)new_g1_start);
|
||||
|
||||
/* These values are just observed by signalers, and thus protected by the
|
||||
lock. */
|
||||
- unsigned int orig_size = wseq - (old_g1_start + old_orig_size);
|
||||
+ unsigned int orig_size = wseq - new_g1_start;
|
||||
__condvar_set_orig_size (cond, orig_size);
|
||||
/* Use and addition to not loose track of cancellations in what was
|
||||
previously G2. */
|
||||
diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c
|
||||
index a9bc10dc..07427369 100644
|
||||
--- a/nptl/pthread_cond_signal.c
|
||||
+++ b/nptl/pthread_cond_signal.c
|
||||
@@ -80,7 +80,7 @@ ___pthread_cond_signal (pthread_cond_t *cond)
|
||||
release-MO store when initializing a group in __condvar_switch_g1
|
||||
because we use an atomic read-modify-write and thus extend that
|
||||
store's release sequence. */
|
||||
- atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 2);
|
||||
+ atomic_fetch_add_relaxed (cond->__data.__g_signals + g1, 1);
|
||||
cond->__data.__g_size[g1]--;
|
||||
/* TODO Only set it if there are indeed futex waiters. */
|
||||
do_futex_wake = true;
|
||||
diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
|
||||
index 40a74342..d7e073ab 100644
|
||||
--- a/nptl/pthread_cond_wait.c
|
||||
+++ b/nptl/pthread_cond_wait.c
|
||||
@@ -84,7 +84,7 @@ __condvar_cancel_waiting (pthread_cond_t *cond, uint64_t seq, unsigned int g,
|
||||
not hold a reference on the group. */
|
||||
__condvar_acquire_lock (cond, private);
|
||||
|
||||
- uint64_t g1_start = __condvar_load_g1_start_relaxed (cond) >> 1;
|
||||
+ uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
if (g1_start > seq)
|
||||
{
|
||||
/* Our group is closed, so someone provided enough signals for it.
|
||||
@@ -259,7 +259,6 @@ __condvar_cleanup_waiting (void *arg)
|
||||
* Waiters fetch-add while having acquire the mutex associated with the
|
||||
condvar. Signalers load it and fetch-xor it concurrently.
|
||||
__g1_start: Starting position of G1 (inclusive)
|
||||
- * LSB is index of current G2.
|
||||
* Modified by signalers while having acquired the condvar-internal lock
|
||||
and observed concurrently by waiters.
|
||||
__g1_orig_size: Initial size of G1
|
||||
@@ -280,11 +279,9 @@ __condvar_cleanup_waiting (void *arg)
|
||||
* Reference count used by waiters concurrently with signalers that have
|
||||
acquired the condvar-internal lock.
|
||||
__g_signals: The number of signals that can still be consumed, relative to
|
||||
- the current g1_start. (i.e. bits 31 to 1 of __g_signals are bits
|
||||
- 31 to 1 of g1_start with the signal count added)
|
||||
+ the current g1_start. (i.e. g1_start with the signal count added)
|
||||
* Used as a futex word by waiters. Used concurrently by waiters and
|
||||
signalers.
|
||||
- * LSB is currently reserved and 0.
|
||||
__g_size: Waiters remaining in this group (i.e., which have not been
|
||||
signaled yet.
|
||||
* Accessed by signalers and waiters that cancel waiting (both do so only
|
||||
@@ -391,9 +388,8 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
too. */
|
||||
unsigned int signals = atomic_load_acquire (cond->__data.__g_signals + g);
|
||||
uint64_t g1_start = __condvar_load_g1_start_relaxed (cond);
|
||||
- unsigned int lowseq = (g1_start & 1) == g ? signals : g1_start & ~1U;
|
||||
|
||||
- if (seq < (g1_start >> 1))
|
||||
+ if (seq < g1_start)
|
||||
{
|
||||
/* If the group is closed already,
|
||||
then this waiter originally had enough extra signals to
|
||||
@@ -406,13 +402,13 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
by now, perhaps in the process of switching back to an older
|
||||
G2, but in either case we're allowed to consume the available
|
||||
signal and should not block anymore. */
|
||||
- if ((int)(signals - lowseq) >= 2)
|
||||
+ if ((int)(signals - (unsigned int)g1_start) > 0)
|
||||
{
|
||||
/* Try to grab a signal. See above for MO. (if we do another loop
|
||||
iteration we need to see the correct value of g1_start) */
|
||||
if (atomic_compare_exchange_weak_acquire (
|
||||
cond->__data.__g_signals + g,
|
||||
- &signals, signals - 2))
|
||||
+ &signals, signals - 1))
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@@ -70,6 +70,8 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
|
||||
file://0026-PR25847-6.patch \
|
||||
file://0026-PR25847-7.patch \
|
||||
file://0026-PR25847-8.patch \
|
||||
file://0026-PR25847-9.patch \
|
||||
file://0026-PR25847-10.patch \
|
||||
\
|
||||
file://0001-Revert-Linux-Implement-a-useful-version-of-_startup_.patch \
|
||||
file://0002-get_nscd_addresses-Fix-subscript-typos-BZ-29605.patch \
|
||||
|
||||
@@ -24,7 +24,7 @@ IMAGE_FSTYPES = "wic.vmdk wic.vhd wic.vhdx"
|
||||
|
||||
inherit core-image setuptools3
|
||||
|
||||
SRCREV ?= "49e837cefaa0d1844b32ff788c6e9de246a3a739"
|
||||
SRCREV ?= "8d5cd4a310e1807e841b25aaa46261dc24cea1eb"
|
||||
SRC_URI = "git://git.yoctoproject.org/poky;branch=kirkstone \
|
||||
file://Yocto_Build_Appliance.vmx \
|
||||
file://Yocto_Build_Appliance.vmxf \
|
||||
|
||||
117
meta/recipes-core/libxml/libxml2/CVE-2025-9714.patch
Normal file
117
meta/recipes-core/libxml/libxml2/CVE-2025-9714.patch
Normal file
@@ -0,0 +1,117 @@
|
||||
From 6ef8b9f05cc21d3fc28156fe5d1251834c29c7d7 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 28 Jul 2022 20:21:24 +0200
|
||||
Subject: [PATCH] Make XPath depth check work with recursive invocations
|
||||
|
||||
EXSLT functions like dyn:map or dyn:evaluate invoke xmlXPathRunEval
|
||||
recursively. Don't set depth to zero but keep and restore the original
|
||||
value to avoid stack overflows when abusing these functions.
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/677a42645ef22b5a50741bad5facf9d8a8bc6d21]
|
||||
CVE: CVE-2025-9714
|
||||
|
||||
Signed-off-by: Theo GAIGE <tgaige.opensource@witekio.com>
|
||||
---
|
||||
xpath.c | 23 +++++++++++++++++------
|
||||
1 file changed, 17 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index c2d845888..028471d53 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -13883,12 +13883,11 @@ static int
|
||||
xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
|
||||
{
|
||||
xmlXPathCompExprPtr comp;
|
||||
+ int oldDepth;
|
||||
|
||||
if ((ctxt == NULL) || (ctxt->comp == NULL))
|
||||
return(-1);
|
||||
|
||||
- ctxt->context->depth = 0;
|
||||
-
|
||||
if (ctxt->valueTab == NULL) {
|
||||
/* Allocate the value stack */
|
||||
ctxt->valueTab = (xmlXPathObjectPtr *)
|
||||
@@ -13942,11 +13941,13 @@ xmlXPathRunEval(xmlXPathParserContextPtr ctxt, int toBool)
|
||||
"xmlXPathRunEval: last is less than zero\n");
|
||||
return(-1);
|
||||
}
|
||||
+ oldDepth = ctxt->context->depth;
|
||||
if (toBool)
|
||||
return(xmlXPathCompOpEvalToBoolean(ctxt,
|
||||
&comp->steps[comp->last], 0));
|
||||
else
|
||||
xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
|
||||
+ ctxt->context->depth = oldDepth;
|
||||
|
||||
return(0);
|
||||
}
|
||||
@@ -14217,6 +14218,7 @@ xmlXPathCompExprPtr
|
||||
xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
|
||||
xmlXPathParserContextPtr pctxt;
|
||||
xmlXPathCompExprPtr comp;
|
||||
+ int oldDepth = 0;
|
||||
|
||||
#ifdef XPATH_STREAMING
|
||||
comp = xmlXPathTryStreamCompile(ctxt, str);
|
||||
@@ -14230,8 +14232,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
|
||||
if (pctxt == NULL)
|
||||
return NULL;
|
||||
if (ctxt != NULL)
|
||||
- ctxt->depth = 0;
|
||||
+ oldDepth = ctxt->depth;
|
||||
xmlXPathCompileExpr(pctxt, 1);
|
||||
+ if (ctxt != NULL)
|
||||
+ ctxt->depth = oldDepth;
|
||||
|
||||
if( pctxt->error != XPATH_EXPRESSION_OK )
|
||||
{
|
||||
@@ -14252,8 +14256,10 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
|
||||
comp = pctxt->comp;
|
||||
if ((comp->nbStep > 1) && (comp->last >= 0)) {
|
||||
if (ctxt != NULL)
|
||||
- ctxt->depth = 0;
|
||||
+ oldDepth = ctxt->depth;
|
||||
xmlXPathOptimizeExpression(pctxt, &comp->steps[comp->last]);
|
||||
+ if (ctxt != NULL)
|
||||
+ ctxt->depth = oldDepth;
|
||||
}
|
||||
pctxt->comp = NULL;
|
||||
}
|
||||
@@ -14409,6 +14415,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
|
||||
#ifdef XPATH_STREAMING
|
||||
xmlXPathCompExprPtr comp;
|
||||
#endif
|
||||
+ int oldDepth = 0;
|
||||
|
||||
if (ctxt == NULL) return;
|
||||
|
||||
@@ -14422,8 +14429,10 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
|
||||
#endif
|
||||
{
|
||||
if (ctxt->context != NULL)
|
||||
- ctxt->context->depth = 0;
|
||||
+ oldDepth = ctxt->context->depth;
|
||||
xmlXPathCompileExpr(ctxt, 1);
|
||||
+ if (ctxt->context != NULL)
|
||||
+ ctxt->context->depth = oldDepth;
|
||||
CHECK_ERROR;
|
||||
|
||||
/* Check for trailing characters. */
|
||||
@@ -14432,9 +14441,11 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
|
||||
|
||||
if ((ctxt->comp->nbStep > 1) && (ctxt->comp->last >= 0)) {
|
||||
if (ctxt->context != NULL)
|
||||
- ctxt->context->depth = 0;
|
||||
+ oldDepth = ctxt->context->depth;
|
||||
xmlXPathOptimizeExpression(ctxt,
|
||||
&ctxt->comp->steps[ctxt->comp->last]);
|
||||
+ if (ctxt->context != NULL)
|
||||
+ ctxt->context->depth = oldDepth;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -42,6 +42,7 @@ SRC_URI += "http://www.w3.org/XML/Test/xmlts20080827.tar;subdir=${BP};name=testt
|
||||
file://CVE-2025-6021.patch \
|
||||
file://CVE-2025-49794-CVE-2025-49796.patch \
|
||||
file://CVE-2025-6170.patch \
|
||||
file://CVE-2025-9714.patch \
|
||||
"
|
||||
|
||||
SRC_URI[archive.sha256sum] = "60d74a257d1ccec0475e749cba2f21559e48139efba6ff28224357c7c798dfee"
|
||||
|
||||
@@ -235,6 +235,7 @@ EXTRA_OEMESON += "-Dnobody-user=nobody \
|
||||
-Dmode=release \
|
||||
-Dsystem-alloc-uid-min=101 \
|
||||
-Dsystem-uid-max=999 \
|
||||
-Dtranslations=${@'false' if d.getVar('USE_NLS') == 'no' else 'true'} \
|
||||
-Dsystem-alloc-gid-min=101 \
|
||||
-Dsystem-gid-max=999 \
|
||||
"
|
||||
|
||||
@@ -80,5 +80,9 @@ SRC_URI = "\
|
||||
file://0042-CVE-2025-5245.patch \
|
||||
file://0043-CVE-2025-7546.patch \
|
||||
file://0043-CVE-2025-7545.patch \
|
||||
file://0044-CVE-2025-11082.patch \
|
||||
file://0045-CVE-2025-11083.patch \
|
||||
file://0046-CVE-2025-11081.patch \
|
||||
file://0047-CVE-2025-8225.patch \
|
||||
"
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From ea1a0737c7692737a644af0486b71e4a392cbca8 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Mon, 22 Sep 2025 15:20:34 +0800
|
||||
Subject: [PATCH] elf: Don't read beyond .eh_frame section size
|
||||
|
||||
PR ld/33464
|
||||
* elf-eh-frame.c (_bfd_elf_parse_eh_frame): Don't read beyond
|
||||
.eh_frame section size.
|
||||
|
||||
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
CVE: CVE-2025-11082
|
||||
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ea1a0737c7692737a644af0486b71e4a392cbca8]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
bfd/elf-eh-frame.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
|
||||
index dc0d2e097f5..30bb313489c 100644
|
||||
--- a/bfd/elf-eh-frame.c
|
||||
+++ b/bfd/elf-eh-frame.c
|
||||
@@ -733,6 +733,7 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||
if (hdr_id == 0)
|
||||
{
|
||||
unsigned int initial_insn_length;
|
||||
+ char *null_byte;
|
||||
|
||||
/* CIE */
|
||||
this_inf->cie = 1;
|
||||
@@ -749,10 +750,13 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
|
||||
REQUIRE (cie->version == 1
|
||||
|| cie->version == 3
|
||||
|| cie->version == 4);
|
||||
- REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
|
||||
+ null_byte = memchr ((char *) buf, 0, end - buf);
|
||||
+ REQUIRE (null_byte != NULL);
|
||||
+ REQUIRE ((size_t) (null_byte - (char *) buf)
|
||||
+ < sizeof (cie->augmentation));
|
||||
|
||||
strcpy (cie->augmentation, (char *) buf);
|
||||
- buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
|
||||
+ buf = (bfd_byte *) null_byte + 1;
|
||||
this_inf->u.cie.aug_str_len = buf - start - 1;
|
||||
ENSURE_NO_RELOCS (buf);
|
||||
if (buf[0] == 'e' && buf[1] == 'h')
|
||||
@@ -0,0 +1,77 @@
|
||||
From 9ca499644a21ceb3f946d1c179c38a83be084490 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
Date: Thu, 18 Sep 2025 16:59:25 -0700
|
||||
Subject: [PATCH] elf: Don't match corrupt section header in linker input
|
||||
|
||||
Don't swap in nor match corrupt section header in linker input to avoid
|
||||
linker crash later.
|
||||
|
||||
PR ld/33457
|
||||
* elfcode.h (elf_swap_shdr_in): Changed to return bool. Return
|
||||
false for corrupt section header in linker input.
|
||||
(elf_object_p): Reject if elf_swap_shdr_in returns false.
|
||||
|
||||
Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
CVE: CVE-2025-11083
|
||||
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=9ca499644a21ceb3f946d1c179c38a83be084490]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
bfd/elfcode.h | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
|
||||
index 9c65852e103..5224a1abee6 100644
|
||||
--- a/bfd/elfcode.h
|
||||
+++ b/bfd/elfcode.h
|
||||
@@ -298,7 +298,7 @@ elf_swap_ehdr_out (bfd *abfd,
|
||||
/* Translate an ELF section header table entry in external format into an
|
||||
ELF section header table entry in internal format. */
|
||||
|
||||
-static void
|
||||
+static bool
|
||||
elf_swap_shdr_in (bfd *abfd,
|
||||
const Elf_External_Shdr *src,
|
||||
Elf_Internal_Shdr *dst)
|
||||
@@ -328,6 +328,9 @@ elf_swap_shdr_in (bfd *abfd,
|
||||
if (!abfd->read_only)
|
||||
_bfd_error_handler (_("warning: %pB has a section "
|
||||
"extending past end of file"), abfd);
|
||||
+ /* PR ld/33457: Don't match corrupt section header. */
|
||||
+ if (abfd->is_linker_input)
|
||||
+ return false;
|
||||
abfd->read_only = 1;
|
||||
}
|
||||
}
|
||||
@@ -337,6 +340,7 @@ elf_swap_shdr_in (bfd *abfd,
|
||||
dst->sh_entsize = H_GET_WORD (abfd, src->sh_entsize);
|
||||
dst->bfd_section = NULL;
|
||||
dst->contents = NULL;
|
||||
+ return true;
|
||||
}
|
||||
|
||||
/* Translate an ELF section header table entry in internal format into an
|
||||
@@ -629,9 +633,9 @@ elf_object_p (bfd *abfd)
|
||||
|
||||
/* Read the first section header at index 0, and convert to internal
|
||||
form. */
|
||||
- if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
|
||||
+ if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)
|
||||
+ || !elf_swap_shdr_in (abfd, &x_shdr, &i_shdr))
|
||||
goto got_no_match;
|
||||
- elf_swap_shdr_in (abfd, &x_shdr, &i_shdr);
|
||||
|
||||
/* If the section count is zero, the actual count is in the first
|
||||
section header. */
|
||||
@@ -717,9 +721,9 @@ elf_object_p (bfd *abfd)
|
||||
to internal form. */
|
||||
for (shindex = 1; shindex < i_ehdrp->e_shnum; shindex++)
|
||||
{
|
||||
- if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr))
|
||||
+ if (bfd_bread (&x_shdr, sizeof x_shdr, abfd) != sizeof (x_shdr)
|
||||
+ || !elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex))
|
||||
goto got_no_match;
|
||||
- elf_swap_shdr_in (abfd, &x_shdr, i_shdrp + shindex);
|
||||
|
||||
/* Sanity check sh_link and sh_info. */
|
||||
if (i_shdrp[shindex].sh_link >= num_sec)
|
||||
@@ -0,0 +1,84 @@
|
||||
From f87a66db645caf8cc0e6fc87b0c28c78a38af59b Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Tue, 9 Sep 2025 18:32:09 +0930
|
||||
Subject: [PATCH] PR 33406 SEGV in dump_dwarf_section
|
||||
|
||||
Trying to dump .sframe in a PE file results in a segfault accessing
|
||||
elf_section_data.
|
||||
|
||||
* objdump (dump_sframe_section, dump_dwarf_section): Don't access
|
||||
elf_section_type without first checking the file is ELF.
|
||||
---
|
||||
binutils/objdump.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=f87a66db645caf8cc0e6fc87b0c28c78a38af59b]
|
||||
CVE: CVE-2025-11081
|
||||
|
||||
Signed-off-by: Alan Modra <amodra@gmail.com>
|
||||
Signed-off-by: Yash Shinde <Yash.Shinde@windriver.com>
|
||||
|
||||
diff --git a/binutils/objdump.c b/binutils/objdump.c
|
||||
index 290f7e51f66..ee8823da05a 100644
|
||||
--- a/binutils/objdump.c
|
||||
+++ b/binutils/objdump.c
|
||||
@@ -4418,6 +4418,10 @@
|
||||
else
|
||||
match = name;
|
||||
|
||||
+ if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
|
||||
+ && elf_section_type (section) == SHT_GNU_SFRAME)
|
||||
+ match = ".sframe";
|
||||
+
|
||||
for (i = 0; i < max; i++)
|
||||
if ((strcmp (debug_displays [i].section.uncompressed_name, match) == 0
|
||||
|| strcmp (debug_displays [i].section.compressed_name, match) == 0
|
||||
@@ -4923,6 +4927,36 @@
|
||||
}
|
||||
|
||||
+static void
|
||||
+dump_sframe_section (bfd *abfd, const char *sect_name, bool is_mainfile)
|
||||
+
|
||||
+{
|
||||
+ /* Error checking for user provided SFrame section name, if any. */
|
||||
+ if (sect_name)
|
||||
+ {
|
||||
+ asection *sec = bfd_get_section_by_name (abfd, sect_name);
|
||||
+ if (sec == NULL)
|
||||
+ {
|
||||
+ printf (_("No %s section present\n\n"), sanitize_string (sect_name));
|
||||
+ return;
|
||||
+ }
|
||||
+ /* Starting with Binutils 2.45, SFrame sections have section type
|
||||
+ SHT_GNU_SFRAME. For SFrame sections from Binutils 2.44 or earlier,
|
||||
+ check explcitly for SFrame sections of type SHT_PROGBITS and name
|
||||
+ ".sframe" to allow them. */
|
||||
+ else if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
|
||||
+ || (elf_section_type (sec) != SHT_GNU_SFRAME
|
||||
+ && !(elf_section_type (sec) == SHT_PROGBITS
|
||||
+ && strcmp (sect_name, ".sframe") == 0)))
|
||||
+ {
|
||||
+ printf (_("Section %s does not contain SFrame data\n\n"),
|
||||
+ sanitize_string (sect_name));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ dump_dwarf (abfd, is_mainfile);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dump_target_specific (bfd *abfd)
|
||||
{
|
||||
const struct objdump_private_desc * const *desc;
|
||||
diff --git a/include/elf/common.h b/include/elf/common.h
|
||||
--- a/include/elf/common.h
|
||||
+++ b/include/elf/common.h
|
||||
@@ -528,6 +528,8 @@
|
||||
#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
|
||||
#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
|
||||
|
||||
+#define SHT_GNU_SFRAME 0x6ffffff4 /* SFrame stack trace information. */
|
||||
+
|
||||
#define SHT_GNU_INCREMENTAL_INPUTS 0x6fff4700 /* incremental build data */
|
||||
#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes */
|
||||
#define SHT_GNU_HASH 0x6ffffff6 /* GNU style symbol hash table */
|
||||
@@ -0,0 +1,47 @@
|
||||
From e51fdff7d2e538c0e5accdd65649ac68e6e0ddd4 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Wed, 19 Feb 2025 22:45:29 +1030
|
||||
Subject: [PATCH] binutils/dwarf.c debug_information leak
|
||||
|
||||
It is possible with fuzzed files to have num_debug_info_entries zero
|
||||
after allocating space for debug_information, leading to multiple
|
||||
allocations.
|
||||
|
||||
* dwarf.c (process_debug_info): Don't test num_debug_info_entries
|
||||
to determine whether debug_information has been allocated,
|
||||
test alloc_num_debug_info_entries.
|
||||
---
|
||||
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=e51fdff7d2e538c0e5accdd65649ac68e6e0ddd4]
|
||||
CVE: CVE-2025-8225
|
||||
|
||||
binutils/dwarf.c | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
Signed-off-by: Alan Modra <amodra@gmail.com>
|
||||
Signed-off-by: Yash Shinde <Yash.Shinde@windriver.com>
|
||||
|
||||
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
|
||||
index 8e004cea839..bfbf83ec9f4 100644
|
||||
--- a/binutils/dwarf.c
|
||||
+++ b/binutils/dwarf.c
|
||||
@@ -3807,13 +3807,11 @@ process_debug_info (struct dwarf_section * section,
|
||||
}
|
||||
|
||||
if ((do_loc || do_debug_loc || do_debug_ranges || do_debug_info)
|
||||
- && num_debug_info_entries == 0
|
||||
- && ! do_types)
|
||||
+ && alloc_num_debug_info_entries == 0
|
||||
+ && !do_types)
|
||||
{
|
||||
-
|
||||
/* Then allocate an array to hold the information. */
|
||||
- debug_information = (debug_info *) cmalloc (num_units,
|
||||
- sizeof (* debug_information));
|
||||
+ debug_information = cmalloc (num_units, sizeof (*debug_information));
|
||||
if (debug_information == NULL)
|
||||
{
|
||||
error (_("Not enough memory for a debug info array of %u entries\n"),
|
||||
--
|
||||
2.43.7
|
||||
|
||||
71
meta/recipes-devtools/cmake/cmake/CVE-2025-9301.patch
Normal file
71
meta/recipes-devtools/cmake/cmake/CVE-2025-9301.patch
Normal file
@@ -0,0 +1,71 @@
|
||||
From 37e27f71bc356d880c908040cd0cb68fa2c371b8 Mon Sep 17 00:00:00 2001
|
||||
From: Tyler Yankee <tyler.yankee@kitware.com>
|
||||
Date: Wed, 13 Aug 2025 15:22:28 -0400
|
||||
Subject: [PATCH] foreach: Explicitly skip replay without iterations
|
||||
|
||||
As written, foreach loops with a trailing `IN` (i.e., no loop
|
||||
variable(s) given) lead to an assertion error. Handle this case by
|
||||
exiting early when we know the loop won't execute anything.
|
||||
|
||||
Fixes: #27135
|
||||
|
||||
CVE: CVE-2025-9301
|
||||
|
||||
Upstream-Status: Backport
|
||||
https://gitlab.kitware.com/cmake/cmake/-/commit/37e27f71bc356d880c908040cd0cb68fa2c371b8
|
||||
|
||||
Signed-off-by: Tyler Yankee <tyler.yankee@kitware.com>
|
||||
Signed-off-by: Saravanan <saravanan.kadambathursubramaniyam@windriver.com>
|
||||
---
|
||||
Source/cmForEachCommand.cxx | 3 +++
|
||||
Tests/RunCMake/foreach/RunCMakeTest.cmake | 1 +
|
||||
Tests/RunCMake/foreach/TrailingIn-result.txt | 1 +
|
||||
Tests/RunCMake/foreach/TrailingIn.cmake | 5 +++++
|
||||
4 files changed, 10 insertions(+)
|
||||
create mode 100644 Tests/RunCMake/foreach/TrailingIn-result.txt
|
||||
create mode 100644 Tests/RunCMake/foreach/TrailingIn.cmake
|
||||
|
||||
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
|
||||
index dcb36265..35b59960 100644
|
||||
--- a/Source/cmForEachCommand.cxx
|
||||
+++ b/Source/cmForEachCommand.cxx
|
||||
@@ -100,6 +100,9 @@ bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
|
||||
bool cmForEachFunctionBlocker::Replay(
|
||||
std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus)
|
||||
{
|
||||
+ if (this->Args.size() == this->IterationVarsCount) {
|
||||
+ return true;
|
||||
+ }
|
||||
return this->ZipLists ? this->ReplayZipLists(functions, inStatus)
|
||||
: this->ReplayItems(functions, inStatus);
|
||||
}
|
||||
diff --git a/Tests/RunCMake/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake
|
||||
index 15ca4770..acfc742e 100644
|
||||
--- a/Tests/RunCMake/foreach/RunCMakeTest.cmake
|
||||
+++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake
|
||||
@@ -22,3 +22,4 @@ run_cmake(foreach-RANGE-invalid-test)
|
||||
run_cmake(foreach-RANGE-out-of-range-test)
|
||||
run_cmake(foreach-var-scope-CMP0124-OLD)
|
||||
run_cmake(foreach-var-scope-CMP0124-NEW)
|
||||
+run_cmake(TrailingIn)
|
||||
diff --git a/Tests/RunCMake/foreach/TrailingIn-result.txt b/Tests/RunCMake/foreach/TrailingIn-result.txt
|
||||
new file mode 100644
|
||||
index 00000000..573541ac
|
||||
--- /dev/null
|
||||
+++ b/Tests/RunCMake/foreach/TrailingIn-result.txt
|
||||
@@ -0,0 +1 @@
|
||||
+0
|
||||
diff --git a/Tests/RunCMake/foreach/TrailingIn.cmake b/Tests/RunCMake/foreach/TrailingIn.cmake
|
||||
new file mode 100644
|
||||
index 00000000..e2b5b2f2
|
||||
--- /dev/null
|
||||
+++ b/Tests/RunCMake/foreach/TrailingIn.cmake
|
||||
@@ -0,0 +1,5 @@
|
||||
+foreach(v IN)
|
||||
+endforeach()
|
||||
+
|
||||
+foreach(v1 v2 IN)
|
||||
+endforeach()
|
||||
--
|
||||
2.35.5
|
||||
|
||||
@@ -12,6 +12,7 @@ SRC_URI:append:class-nativesdk = " \
|
||||
file://0001-CMakeDetermineSystem-use-oe-environment-vars-to-load.patch \
|
||||
file://0001-ctest-Allow-arbitrary-characters-in-test-names-of-CT.patch \
|
||||
"
|
||||
SRC_URI += "file://CVE-2025-9301.patch"
|
||||
|
||||
LICENSE:append = " & BSD-1-Clause & MIT"
|
||||
LIC_FILES_CHKSUM:append = " \
|
||||
|
||||
97
meta/recipes-devtools/git/git/CVE-2025-48386.patch
Normal file
97
meta/recipes-devtools/git/git/CVE-2025-48386.patch
Normal file
@@ -0,0 +1,97 @@
|
||||
From 9de345cb273cc7faaeda279c7e07149d8a15a319 Mon Sep 17 00:00:00 2001
|
||||
From: Taylor Blau <me@ttaylorr.com>
|
||||
Date: Mon, 19 May 2025 18:30:29 -0400
|
||||
Subject: [PATCH] wincred: avoid buffer overflow in wcsncat()
|
||||
|
||||
The wincred credential helper uses a static buffer ("target") as a
|
||||
unique key for storing and comparing against internal storage. It does
|
||||
this by building up a string is supposed to look like:
|
||||
|
||||
git:$PROTOCOL://$USERNAME@$HOST/@path
|
||||
|
||||
However, the static "target" buffer is declared as a wide string with no
|
||||
more than 1,024 wide characters. The first call to wcsncat() is almost
|
||||
correct (it copies no more than ARRAY_SIZE(target) wchar_t's), but does
|
||||
not account for the trailing NUL, introducing an off-by-one error.
|
||||
|
||||
But subsequent calls to wcsncat() have an additional problem on top of
|
||||
the off-by-one. They do not account for the length of the existing
|
||||
wide string being built up in 'target'. So the following:
|
||||
|
||||
$ perl -e '
|
||||
my $x = "x" x 1_000;
|
||||
print "protocol=$x\nhost=$x\nusername=$x\npath=$x\n"
|
||||
' |
|
||||
C\:/Program\ Files/Git/mingw64/libexec/git-core/git-credential-wincred.exe get
|
||||
|
||||
will result in a segmentation fault from over-filling buffer.
|
||||
|
||||
This bug is as old as the wincred helper itself, dating back to
|
||||
a6253da (contrib: add win32 credential-helper, 2012-07-27). Commit
|
||||
8b2d219 (wincred: improve compatibility with windows versions,
|
||||
2013-01-10) replaced the use of strncat() with wcsncat(), but retained
|
||||
the buggy behavior.
|
||||
|
||||
Fix this by using a "target_append()" helper which accounts for both the
|
||||
length of the existing string within the buffer, as well as the trailing
|
||||
NUL character.
|
||||
|
||||
Reported-by: David Leadbeater <dgl@dgl.cx>
|
||||
Helped-by: David Leadbeater <dgl@dgl.cx>
|
||||
Helped-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Taylor Blau <me@ttaylorr.com>
|
||||
|
||||
CVE: CVE-2025-48386
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/9de345cb273cc7faaeda279c7e07149d8a15a319]
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
.../wincred/git-credential-wincred.c | 22 +++++++++++++------
|
||||
1 file changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c
|
||||
index 5091048..00ecd87 100644
|
||||
--- a/contrib/credential/wincred/git-credential-wincred.c
|
||||
+++ b/contrib/credential/wincred/git-credential-wincred.c
|
||||
@@ -93,6 +93,14 @@ static void load_cred_funcs(void)
|
||||
|
||||
static WCHAR *wusername, *password, *protocol, *host, *path, target[1024];
|
||||
|
||||
+static void target_append(const WCHAR *src)
|
||||
+{
|
||||
+ size_t avail = ARRAY_SIZE(target) - wcslen(target) - 1; /* -1 for NUL */
|
||||
+ if (avail < wcslen(src))
|
||||
+ die("target buffer overflow");
|
||||
+ wcsncat(target, src, avail);
|
||||
+}
|
||||
+
|
||||
static void write_item(const char *what, LPCWSTR wbuf, int wlen)
|
||||
{
|
||||
char *buf;
|
||||
@@ -304,17 +312,17 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* prepare 'target', the unique key for the credential */
|
||||
wcscpy(target, L"git:");
|
||||
- wcsncat(target, protocol, ARRAY_SIZE(target));
|
||||
- wcsncat(target, L"://", ARRAY_SIZE(target));
|
||||
+ target_append(protocol);
|
||||
+ target_append(L"://");
|
||||
if (wusername) {
|
||||
- wcsncat(target, wusername, ARRAY_SIZE(target));
|
||||
- wcsncat(target, L"@", ARRAY_SIZE(target));
|
||||
+ target_append(wusername);
|
||||
+ target_append(L"@");
|
||||
}
|
||||
if (host)
|
||||
- wcsncat(target, host, ARRAY_SIZE(target));
|
||||
+ target_append(host);
|
||||
if (path) {
|
||||
- wcsncat(target, L"/", ARRAY_SIZE(target));
|
||||
- wcsncat(target, path, ARRAY_SIZE(target));
|
||||
+ target_append(L"/");
|
||||
+ target_append(path);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "get"))
|
||||
--
|
||||
2.50.1
|
||||
|
||||
@@ -28,6 +28,7 @@ SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \
|
||||
file://CVE-2024-52006.patch \
|
||||
file://CVE-2025-27614-CVE-2025-27613-CVE-2025-46334-CVE-2025-46835.patch \
|
||||
file://CVE-2025-48384.patch \
|
||||
file://CVE-2025-48386.patch \
|
||||
"
|
||||
|
||||
S = "${WORKDIR}/git-${PV}"
|
||||
|
||||
@@ -4,67 +4,71 @@ FILESEXTRAPATHS:prepend := "${FILE_DIRNAME}/go-1.21:${FILE_DIRNAME}/go-1.20:${FI
|
||||
|
||||
LIC_FILES_CHKSUM = "file://LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707"
|
||||
|
||||
SRC_URI += "\
|
||||
file://0001-allow-CC-and-CXX-to-have-multiple-words.patch \
|
||||
file://0002-cmd-go-make-content-based-hash-generation-less-pedan.patch \
|
||||
file://0003-allow-GOTOOLDIR-to-be-overridden-in-the-environment.patch \
|
||||
file://0004-ld-add-soname-to-shareable-objects.patch \
|
||||
file://0005-make.bash-override-CC-when-building-dist-and-go_boot.patch \
|
||||
file://0006-cmd-dist-separate-host-and-target-builds.patch \
|
||||
file://0007-cmd-go-make-GOROOT-precious-by-default.patch \
|
||||
file://0008-use-GOBUILDMODE-to-set-buildmode.patch \
|
||||
file://0009-Revert-cmd-go-make-sure-CC-and-CXX-are-absolute.patch \
|
||||
file://0001-exec.go-do-not-write-linker-flags-into-buildids.patch \
|
||||
file://0001-src-cmd-dist-buildgo.go-do-not-hardcode-host-compile.patch \
|
||||
file://0010-net-Fix-issue-with-DNS-not-being-updated.patch \
|
||||
file://CVE-2022-27664.patch \
|
||||
file://0001-net-http-httputil-avoid-query-parameter-smuggling.patch \
|
||||
file://CVE-2022-41715.patch \
|
||||
file://CVE-2022-41717.patch \
|
||||
file://CVE-2022-2879.patch \
|
||||
file://CVE-2022-41720.patch \
|
||||
file://CVE-2022-41723.patch \
|
||||
file://cve-2022-41724.patch \
|
||||
file://add_godebug.patch \
|
||||
file://cve-2022-41725.patch \
|
||||
file://CVE-2022-41722.patch \
|
||||
file://CVE-2023-24537.patch \
|
||||
file://CVE-2023-24534.patch \
|
||||
file://CVE-2023-24538_1.patch \
|
||||
file://CVE-2023-24538_2.patch \
|
||||
file://CVE-2023-24540.patch \
|
||||
file://CVE-2023-24539.patch \
|
||||
file://CVE-2023-29404.patch \
|
||||
file://CVE-2023-29405.patch \
|
||||
file://CVE-2023-29402.patch \
|
||||
file://CVE-2023-29400.patch \
|
||||
file://CVE-2023-29406-1.patch \
|
||||
file://CVE-2023-29406-2.patch \
|
||||
file://CVE-2023-24536_1.patch \
|
||||
file://CVE-2023-24536_2.patch \
|
||||
file://CVE-2023-24536_3.patch \
|
||||
file://CVE-2023-24531_1.patch \
|
||||
file://CVE-2023-24531_2.patch \
|
||||
file://CVE-2023-29409.patch \
|
||||
file://CVE-2023-39319.patch \
|
||||
file://CVE-2023-39318.patch \
|
||||
file://CVE-2023-39326.patch \
|
||||
file://CVE-2023-45285.patch \
|
||||
file://CVE-2023-45287.patch \
|
||||
file://CVE-2023-45289.patch \
|
||||
file://CVE-2023-45290.patch \
|
||||
file://CVE-2024-24784.patch \
|
||||
file://CVE-2024-24785.patch \
|
||||
file://CVE-2023-45288.patch \
|
||||
file://CVE-2024-24789.patch \
|
||||
file://CVE-2024-24791.patch \
|
||||
file://CVE-2024-34155.patch \
|
||||
file://CVE-2024-34156.patch \
|
||||
file://CVE-2024-34158.patch \
|
||||
file://CVE-2024-45336.patch \
|
||||
file://CVE-2025-22871.patch \
|
||||
file://CVE-2025-4673.patch \
|
||||
"
|
||||
SRC_URI = "https://golang.org/dl/go${PV}.src.tar.gz;name=main \
|
||||
file://0001-allow-CC-and-CXX-to-have-multiple-words.patch \
|
||||
file://0002-cmd-go-make-content-based-hash-generation-less-pedan.patch \
|
||||
file://0003-allow-GOTOOLDIR-to-be-overridden-in-the-environment.patch \
|
||||
file://0004-ld-add-soname-to-shareable-objects.patch \
|
||||
file://0005-make.bash-override-CC-when-building-dist-and-go_boot.patch \
|
||||
file://0006-cmd-dist-separate-host-and-target-builds.patch \
|
||||
file://0007-cmd-go-make-GOROOT-precious-by-default.patch \
|
||||
file://0008-use-GOBUILDMODE-to-set-buildmode.patch \
|
||||
file://0009-Revert-cmd-go-make-sure-CC-and-CXX-are-absolute.patch \
|
||||
file://0001-exec.go-do-not-write-linker-flags-into-buildids.patch \
|
||||
file://0001-src-cmd-dist-buildgo.go-do-not-hardcode-host-compile.patch \
|
||||
file://0010-net-Fix-issue-with-DNS-not-being-updated.patch \
|
||||
file://CVE-2022-27664.patch \
|
||||
file://0001-net-http-httputil-avoid-query-parameter-smuggling.patch \
|
||||
file://CVE-2022-41715.patch \
|
||||
file://CVE-2022-41717.patch \
|
||||
file://CVE-2022-2879.patch \
|
||||
file://CVE-2022-41720.patch \
|
||||
file://CVE-2022-41723.patch \
|
||||
file://cve-2022-41724.patch \
|
||||
file://add_godebug.patch \
|
||||
file://cve-2022-41725.patch \
|
||||
file://CVE-2022-41722.patch \
|
||||
file://CVE-2023-24537.patch \
|
||||
file://CVE-2023-24534.patch \
|
||||
file://CVE-2023-24538_1.patch \
|
||||
file://CVE-2023-24538_2.patch \
|
||||
file://CVE-2023-24540.patch \
|
||||
file://CVE-2023-24539.patch \
|
||||
file://CVE-2023-29404.patch \
|
||||
file://CVE-2023-29405.patch \
|
||||
file://CVE-2023-29402.patch \
|
||||
file://CVE-2023-29400.patch \
|
||||
file://CVE-2023-29406-1.patch \
|
||||
file://CVE-2023-29406-2.patch \
|
||||
file://CVE-2023-24536_1.patch \
|
||||
file://CVE-2023-24536_2.patch \
|
||||
file://CVE-2023-24536_3.patch \
|
||||
file://CVE-2023-24531_1.patch \
|
||||
file://CVE-2023-24531_2.patch \
|
||||
file://CVE-2023-29409.patch \
|
||||
file://CVE-2023-39319.patch \
|
||||
file://CVE-2023-39318.patch \
|
||||
file://CVE-2023-39326.patch \
|
||||
file://CVE-2023-45285.patch \
|
||||
file://CVE-2023-45287.patch \
|
||||
file://CVE-2023-45289.patch \
|
||||
file://CVE-2023-45290.patch \
|
||||
file://CVE-2024-24784.patch \
|
||||
file://CVE-2024-24785.patch \
|
||||
file://CVE-2023-45288.patch \
|
||||
file://CVE-2024-24789.patch \
|
||||
file://CVE-2024-24791.patch \
|
||||
file://CVE-2024-34155.patch \
|
||||
file://CVE-2024-34156.patch \
|
||||
file://CVE-2024-34158.patch \
|
||||
file://CVE-2024-45336.patch \
|
||||
file://CVE-2025-22871.patch \
|
||||
file://CVE-2025-4673.patch \
|
||||
file://CVE-2025-47907-pre-0001.patch \
|
||||
file://CVE-2025-47907-pre-0002.patch \
|
||||
file://CVE-2025-47907.patch \
|
||||
file://CVE-2025-47906.patch \
|
||||
"
|
||||
SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd"
|
||||
|
||||
# Upstream don't believe it is a signifiant real world issue and will only
|
||||
|
||||
171
meta/recipes-devtools/go/go-1.21/CVE-2025-47906.patch
Normal file
171
meta/recipes-devtools/go/go-1.21/CVE-2025-47906.patch
Normal file
@@ -0,0 +1,171 @@
|
||||
From 8fa31a2d7d9e60c50a3a94080c097b6e65773f4b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= <olivier.mengue@gmail.com>
|
||||
Date: Mon, 30 Jun 2025 16:58:59 +0200
|
||||
Subject: [PATCH] [release-branch.go1.23] os/exec: fix incorrect expansion of
|
||||
"", "." and ".." in LookPath Fix incorrect expansion of "" and "." when $PATH
|
||||
contains an executable file or, on Windows, a parent directory of a %PATH%
|
||||
element contains an file with the same name as the %PATH% element but with
|
||||
one of the %PATHEXT% extension (ex: C:\utils\bin is in PATH, and
|
||||
C:\utils\bin.exe exists).
|
||||
|
||||
Fix incorrect expansion of ".." when $PATH contains an element which is
|
||||
an the concatenation of the path to an executable file (or on Windows
|
||||
a path that can be expanded to an executable by appending a %PATHEXT%
|
||||
extension), a path separator and a name.
|
||||
|
||||
"", "." and ".." are now rejected early with ErrNotFound.
|
||||
|
||||
Fixes CVE-2025-47906
|
||||
Fixes #74803
|
||||
|
||||
Change-Id: Ie50cc0a660fce8fbdc952a7f2e05c36062dcb50e
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/685755
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
Auto-Submit: Damien Neil <dneil@google.com>
|
||||
Reviewed-by: Roland Shoemaker <roland@golang.org>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
(cherry picked from commit e0b07dc)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/691855
|
||||
Reviewed-by: Michael Knyszek <mknyszek@google.com>
|
||||
|
||||
CVE: CVE-2025-47906
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/8fa31a2d7d9e60c50a3a94080c097b6e65773f4b]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
src/internal/execabs/execabs_test.go | 55 ++++++++++++++++++++++++++++
|
||||
src/os/exec/exec.go | 9 +++++
|
||||
src/os/exec/lp_plan9.go | 4 ++
|
||||
src/os/exec/lp_unix.go | 4 ++
|
||||
src/os/exec/lp_windows.go | 4 ++
|
||||
5 files changed, 76 insertions(+)
|
||||
|
||||
diff --git a/src/internal/execabs/execabs_test.go b/src/internal/execabs/execabs_test.go
|
||||
index 97a3f39..99fd64b 100644
|
||||
--- a/src/internal/execabs/execabs_test.go
|
||||
+++ b/src/internal/execabs/execabs_test.go
|
||||
@@ -100,4 +100,59 @@ func TestLookPath(t *testing.T) {
|
||||
} else if err.Error() != expectedErr {
|
||||
t.Errorf("LookPath returned unexpected error: want %q, got %q", expectedErr, err.Error())
|
||||
}
|
||||
+ checker := func(test string) func(t *testing.T) {
|
||||
+ return func(t *testing.T) {
|
||||
+ t.Helper()
|
||||
+ t.Logf("PATH=%s", os.Getenv("PATH"))
|
||||
+ p, err := LookPath(test)
|
||||
+ if err == nil {
|
||||
+ t.Errorf("%q: error expected, got nil", test)
|
||||
+ }
|
||||
+ if p != "" {
|
||||
+ t.Errorf("%q: path returned should be \"\". Got %q", test, p)
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Reference behavior for the next test
|
||||
+ t.Run(pathVar+"=$OTHER2", func(t *testing.T) {
|
||||
+ t.Run("empty", checker(""))
|
||||
+ t.Run("dot", checker("."))
|
||||
+ t.Run("dotdot1", checker("abc/.."))
|
||||
+ t.Run("dotdot2", checker(".."))
|
||||
+ })
|
||||
+
|
||||
+ // Test the behavior when PATH contains an executable file which is not a directory
|
||||
+ t.Run(pathVar+"=exe", func(t *testing.T) {
|
||||
+ // Inject an executable file (not a directory) in PATH.
|
||||
+ // Use our own binary os.Args[0].
|
||||
+ testenv.MustHaveExec(t)
|
||||
+ exe, err := os.Executable()
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+
|
||||
+ t.Setenv(pathVar, exe)
|
||||
+ t.Run("empty", checker(""))
|
||||
+ t.Run("dot", checker("."))
|
||||
+ t.Run("dotdot1", checker("abc/.."))
|
||||
+ t.Run("dotdot2", checker(".."))
|
||||
+ })
|
||||
+
|
||||
+ // Test the behavior when PATH contains an executable file which is not a directory
|
||||
+ t.Run(pathVar+"=exe/xx", func(t *testing.T) {
|
||||
+ // Inject an executable file (not a directory) in PATH.
|
||||
+ // Use our own binary os.Args[0].
|
||||
+ testenv.MustHaveExec(t)
|
||||
+ exe, err := os.Executable()
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+
|
||||
+ t.Setenv(pathVar, filepath.Join(exe, "xx"))
|
||||
+ t.Run("empty", checker(""))
|
||||
+ t.Run("dot", checker("."))
|
||||
+ t.Run("dotdot1", checker("abc/.."))
|
||||
+ t.Run("dotdot2", checker(".."))
|
||||
+ })
|
||||
}
|
||||
diff --git a/src/os/exec/exec.go b/src/os/exec/exec.go
|
||||
index 505de58..84fd82f 100644
|
||||
--- a/src/os/exec/exec.go
|
||||
+++ b/src/os/exec/exec.go
|
||||
@@ -790,3 +790,12 @@ func addCriticalEnv(env []string) []string {
|
||||
}
|
||||
return append(env, "SYSTEMROOT="+os.Getenv("SYSTEMROOT"))
|
||||
}
|
||||
+// validateLookPath excludes paths that can't be valid
|
||||
+// executable names. See issue #74466 and CVE-2025-47906.
|
||||
+func validateLookPath(s string) error {
|
||||
+ switch s {
|
||||
+ case "", ".", "..":
|
||||
+ return ErrNotFound
|
||||
+ }
|
||||
+ return nil
|
||||
+}
|
||||
diff --git a/src/os/exec/lp_plan9.go b/src/os/exec/lp_plan9.go
|
||||
index e8826a5..ed9f6e3 100644
|
||||
--- a/src/os/exec/lp_plan9.go
|
||||
+++ b/src/os/exec/lp_plan9.go
|
||||
@@ -33,6 +33,10 @@ func findExecutable(file string) error {
|
||||
// The result may be an absolute path or a path relative to the current directory.
|
||||
func LookPath(file string) (string, error) {
|
||||
// skip the path lookup for these prefixes
|
||||
+ if err := validateLookPath(file); err != nil {
|
||||
+ return "", &Error{file, err}
|
||||
+ }
|
||||
+
|
||||
skip := []string{"/", "#", "./", "../"}
|
||||
|
||||
for _, p := range skip {
|
||||
diff --git a/src/os/exec/lp_unix.go b/src/os/exec/lp_unix.go
|
||||
index d1d246a..1b27f2b 100644
|
||||
--- a/src/os/exec/lp_unix.go
|
||||
+++ b/src/os/exec/lp_unix.go
|
||||
@@ -38,6 +38,10 @@ func LookPath(file string) (string, error) {
|
||||
// (only bypass the path if file begins with / or ./ or ../)
|
||||
// but that would not match all the Unix shells.
|
||||
|
||||
+ if err := validateLookPath(file); err != nil {
|
||||
+ return "", &Error{file, err}
|
||||
+ }
|
||||
+
|
||||
if strings.Contains(file, "/") {
|
||||
err := findExecutable(file)
|
||||
if err == nil {
|
||||
diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
|
||||
index e7a2cdf..7a1d6fb 100644
|
||||
--- a/src/os/exec/lp_windows.go
|
||||
+++ b/src/os/exec/lp_windows.go
|
||||
@@ -58,6 +58,10 @@ func findExecutable(file string, exts []string) (string, error) {
|
||||
// a suitable candidate.
|
||||
// The result may be an absolute path or a path relative to the current directory.
|
||||
func LookPath(file string) (string, error) {
|
||||
+ if err := validateLookPath(file); err != nil {
|
||||
+ return "", &Error{file, err}
|
||||
+ }
|
||||
+
|
||||
var exts []string
|
||||
x := os.Getenv(`PATHEXT`)
|
||||
if x != "" {
|
||||
--
|
||||
2.40.0
|
||||
354
meta/recipes-devtools/go/go-1.21/CVE-2025-47907-pre-0001.patch
Normal file
354
meta/recipes-devtools/go/go-1.21/CVE-2025-47907-pre-0001.patch
Normal file
@@ -0,0 +1,354 @@
|
||||
From 298fe517a9333c05143a8a8e1f9d5499f0c6e59b Mon Sep 17 00:00:00 2001
|
||||
From: Brad Fitzpatrick <bradfitz@golang.org>
|
||||
Date: Tue, 23 May 2023 15:12:47 -0700
|
||||
Subject: [PATCH] database/sql: make RawBytes safely usable with contexts
|
||||
|
||||
sql.RawBytes was added the very first Go release, Go 1. Its docs
|
||||
say:
|
||||
|
||||
> RawBytes is a byte slice that holds a reference to memory owned by
|
||||
> the database itself. After a Scan into a RawBytes, the slice is only
|
||||
> valid until the next call to Next, Scan, or Close.
|
||||
|
||||
That "only valid until the next call" bit was true at the time,
|
||||
until contexts were added to database/sql in Go 1.8.
|
||||
|
||||
In the past ~dozen releases it's been unsafe to use QueryContext with
|
||||
a context that might become Done to get an *sql.Rows that's scanning
|
||||
into a RawBytes. The Scan can succeed, but then while the caller's
|
||||
reading the memory, a database/sql-managed goroutine can see the
|
||||
context becoming done and call Close on the database/sql/driver and
|
||||
make the caller's view of the RawBytes memory no longer valid,
|
||||
introducing races, crashes, or database corruption. See #60304
|
||||
and #53970 for details.
|
||||
|
||||
This change does the minimal surgery on database/sql to make it safe
|
||||
again: Rows.Scan was already acquiring a mutex to check whether the
|
||||
rows had been closed, so this change make Rows.Scan notice whether
|
||||
*RawBytes was used and, if so, doesn't release the mutex on exit
|
||||
before returning. That mean it's still locked while the user code
|
||||
operates on the RawBytes memory and the concurrent context-watching
|
||||
goroutine to close the database still runs, but if it fires, it then
|
||||
gets blocked on the mutex until the next call to a Rows method (Next,
|
||||
NextResultSet, Err, Close).
|
||||
|
||||
Updates #60304
|
||||
Updates #53970 (earlier one I'd missed)
|
||||
|
||||
Change-Id: Ie41c0c6f32c24887b2f53ec3686c2aab73a1bfff
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/497675
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Reviewed-by: Ian Lance Taylor <iant@google.com>
|
||||
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
|
||||
Auto-Submit: Ian Lance Taylor <iant@google.com>
|
||||
Reviewed-by: Russ Cox <rsc@golang.org>
|
||||
|
||||
CVE: CVE-2025-47907
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/298fe517a9333c05143a8a8e1f9d5499f0c6e59b]
|
||||
|
||||
Signed-off-by: Praveen Kumar <praveen.kumar@windriver.com>
|
||||
---
|
||||
src/database/sql/fakedb_test.go | 13 +++++-
|
||||
src/database/sql/sql.go | 72 ++++++++++++++++++++++++++++++++-
|
||||
src/database/sql/sql_test.go | 58 ++++++++++++++++++++++++++
|
||||
3 files changed, 141 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/database/sql/fakedb_test.go b/src/database/sql/fakedb_test.go
|
||||
index 4b68f1c..33c57b9 100644
|
||||
--- a/src/database/sql/fakedb_test.go
|
||||
+++ b/src/database/sql/fakedb_test.go
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
+ "sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -90,6 +91,8 @@ func (cc *fakeDriverCtx) OpenConnector(name string) (driver.Connector, error) {
|
||||
type fakeDB struct {
|
||||
name string
|
||||
|
||||
+ useRawBytes atomic.Bool
|
||||
+
|
||||
mu sync.Mutex
|
||||
tables map[string]*table
|
||||
badConn bool
|
||||
@@ -680,6 +683,8 @@ func (c *fakeConn) PrepareContext(ctx context.Context, query string) (driver.Stm
|
||||
switch cmd {
|
||||
case "WIPE":
|
||||
// Nothing
|
||||
+ case "USE_RAWBYTES":
|
||||
+ c.db.useRawBytes.Store(true)
|
||||
case "SELECT":
|
||||
stmt, err = c.prepareSelect(stmt, parts)
|
||||
case "CREATE":
|
||||
@@ -783,6 +788,9 @@ func (s *fakeStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (d
|
||||
case "WIPE":
|
||||
db.wipe()
|
||||
return driver.ResultNoRows, nil
|
||||
+ case "USE_RAWBYTES":
|
||||
+ s.c.db.useRawBytes.Store(true)
|
||||
+ return driver.ResultNoRows, nil
|
||||
case "CREATE":
|
||||
if err := db.createTable(s.table, s.colName, s.colType); err != nil {
|
||||
return nil, err
|
||||
@@ -912,6 +920,7 @@ func (s *fakeStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (
|
||||
txStatus = "transaction"
|
||||
}
|
||||
cursor := &rowsCursor{
|
||||
+ db: s.c.db,
|
||||
parentMem: s.c,
|
||||
posRow: -1,
|
||||
rows: [][]*row{
|
||||
@@ -1008,6 +1017,7 @@ func (s *fakeStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (
|
||||
}
|
||||
|
||||
cursor := &rowsCursor{
|
||||
+ db: s.c.db,
|
||||
parentMem: s.c,
|
||||
posRow: -1,
|
||||
rows: setMRows,
|
||||
@@ -1050,6 +1060,7 @@ func (tx *fakeTx) Rollback() error {
|
||||
}
|
||||
|
||||
type rowsCursor struct {
|
||||
+ db *fakeDB
|
||||
parentMem memToucher
|
||||
cols [][]string
|
||||
colType [][]string
|
||||
@@ -1121,7 +1132,7 @@ func (rc *rowsCursor) Next(dest []driver.Value) error {
|
||||
// messing up conversions or doing them differently.
|
||||
dest[i] = v
|
||||
|
||||
- if bs, ok := v.([]byte); ok {
|
||||
+ if bs, ok := v.([]byte); ok && !rc.db.useRawBytes.Load() {
|
||||
if rc.bytesClone == nil {
|
||||
rc.bytesClone = make(map[*byte][]byte)
|
||||
}
|
||||
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
|
||||
index 68fb392..ef49e70 100644
|
||||
--- a/src/database/sql/sql.go
|
||||
+++ b/src/database/sql/sql.go
|
||||
@@ -2879,6 +2879,8 @@ type Rows struct {
|
||||
cancel func() // called when Rows is closed, may be nil.
|
||||
closeStmt *driverStmt // if non-nil, statement to Close on close
|
||||
|
||||
+ contextDone atomic.Value // error that awaitDone saw; set before close attempt
|
||||
+
|
||||
// closemu prevents Rows from closing while there
|
||||
// is an active streaming result. It is held for read during non-close operations
|
||||
// and exclusively during close.
|
||||
@@ -2891,6 +2893,15 @@ type Rows struct {
|
||||
// lastcols is only used in Scan, Next, and NextResultSet which are expected
|
||||
// not to be called concurrently.
|
||||
lastcols []driver.Value
|
||||
+
|
||||
+ // closemuScanHold is whether the previous call to Scan kept closemu RLock'ed
|
||||
+ // without unlocking it. It does that when the user passes a *RawBytes scan
|
||||
+ // target. In that case, we need to prevent awaitDone from closing the Rows
|
||||
+ // while the user's still using the memory. See go.dev/issue/60304.
|
||||
+ //
|
||||
+ // It is only used by Scan, Next, and NextResultSet which are expected
|
||||
+ // not to be called concurrently.
|
||||
+ closemuScanHold bool
|
||||
}
|
||||
|
||||
// lasterrOrErrLocked returns either lasterr or the provided err.
|
||||
@@ -2928,7 +2939,11 @@ func (rs *Rows) awaitDone(ctx, txctx context.Context) {
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
+ err := ctx.Err()
|
||||
+ rs.contextDone.Store(&err)
|
||||
case <-txctxDone:
|
||||
+ err := txctx.Err()
|
||||
+ rs.contextDone.Store(&err)
|
||||
}
|
||||
rs.close(ctx.Err())
|
||||
}
|
||||
@@ -2940,6 +2955,15 @@ func (rs *Rows) awaitDone(ctx, txctx context.Context) {
|
||||
//
|
||||
// Every call to Scan, even the first one, must be preceded by a call to Next.
|
||||
func (rs *Rows) Next() bool {
|
||||
+ // If the user's calling Next, they're done with their previous row's Scan
|
||||
+ // results (any RawBytes memory), so we can release the read lock that would
|
||||
+ // be preventing awaitDone from calling close.
|
||||
+ rs.closemuRUnlockIfHeldByScan()
|
||||
+
|
||||
+ if rs.contextDone.Load() != nil {
|
||||
+ return false
|
||||
+ }
|
||||
+
|
||||
var doClose, ok bool
|
||||
withLock(rs.closemu.RLocker(), func() {
|
||||
doClose, ok = rs.nextLocked()
|
||||
@@ -2994,6 +3018,11 @@ func (rs *Rows) nextLocked() (doClose, ok bool) {
|
||||
// scanning. If there are further result sets they may not have rows in the result
|
||||
// set.
|
||||
func (rs *Rows) NextResultSet() bool {
|
||||
+ // If the user's calling NextResultSet, they're done with their previous
|
||||
+ // row's Scan results (any RawBytes memory), so we can release the read lock
|
||||
+ // that would be preventing awaitDone from calling close.
|
||||
+ rs.closemuRUnlockIfHeldByScan()
|
||||
+
|
||||
var doClose bool
|
||||
defer func() {
|
||||
if doClose {
|
||||
@@ -3030,6 +3059,10 @@ func (rs *Rows) NextResultSet() bool {
|
||||
// Err returns the error, if any, that was encountered during iteration.
|
||||
// Err may be called after an explicit or implicit Close.
|
||||
func (rs *Rows) Err() error {
|
||||
+ if errp := rs.contextDone.Load(); errp != nil {
|
||||
+ return *(errp.(*error))
|
||||
+ }
|
||||
+
|
||||
rs.closemu.RLock()
|
||||
defer rs.closemu.RUnlock()
|
||||
return rs.lasterrOrErrLocked(nil)
|
||||
@@ -3223,6 +3256,11 @@ func rowsColumnInfoSetupConnLocked(rowsi driver.Rows) []*ColumnType {
|
||||
// If any of the first arguments implementing Scanner returns an error,
|
||||
// that error will be wrapped in the returned error
|
||||
func (rs *Rows) Scan(dest ...interface{}) error {
|
||||
+ if rs.closemuScanHold {
|
||||
+ // This should only be possible if the user calls Scan twice in a row
|
||||
+ // without calling Next.
|
||||
+ return fmt.Errorf("sql: Scan called without calling Next (closemuScanHold)")
|
||||
+ }
|
||||
rs.closemu.RLock()
|
||||
|
||||
if rs.lasterr != nil && rs.lasterr != io.EOF {
|
||||
@@ -3234,23 +3272,50 @@ func (rs *Rows) Scan(dest ...interface{}) error {
|
||||
rs.closemu.RUnlock()
|
||||
return err
|
||||
}
|
||||
- rs.closemu.RUnlock()
|
||||
+
|
||||
+ if scanArgsContainRawBytes(dest) {
|
||||
+ rs.closemuScanHold = true
|
||||
+ } else {
|
||||
+ rs.closemu.RUnlock()
|
||||
+ }
|
||||
|
||||
if rs.lastcols == nil {
|
||||
+ rs.closemuRUnlockIfHeldByScan()
|
||||
return errors.New("sql: Scan called without calling Next")
|
||||
}
|
||||
if len(dest) != len(rs.lastcols) {
|
||||
+ rs.closemuRUnlockIfHeldByScan()
|
||||
return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
|
||||
}
|
||||
+
|
||||
for i, sv := range rs.lastcols {
|
||||
err := convertAssignRows(dest[i], sv, rs)
|
||||
if err != nil {
|
||||
+ rs.closemuRUnlockIfHeldByScan()
|
||||
return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+// closemuRUnlockIfHeldByScan releases any closemu.RLock held open by a previous
|
||||
+// call to Scan with *RawBytes.
|
||||
+func (rs *Rows) closemuRUnlockIfHeldByScan() {
|
||||
+ if rs.closemuScanHold {
|
||||
+ rs.closemuScanHold = false
|
||||
+ rs.closemu.RUnlock()
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func scanArgsContainRawBytes(args []interface{}) bool {
|
||||
+ for _, a := range args {
|
||||
+ if _, ok := a.(*RawBytes); ok {
|
||||
+ return true
|
||||
+ }
|
||||
+ }
|
||||
+ return false
|
||||
+}
|
||||
+
|
||||
// rowsCloseHook returns a function so tests may install the
|
||||
// hook through a test only mutex.
|
||||
var rowsCloseHook = func() func(*Rows, *error) { return nil }
|
||||
@@ -3260,6 +3325,11 @@ var rowsCloseHook = func() func(*Rows, *error) { return nil }
|
||||
// the Rows are closed automatically and it will suffice to check the
|
||||
// result of Err. Close is idempotent and does not affect the result of Err.
|
||||
func (rs *Rows) Close() error {
|
||||
+ // If the user's calling Close, they're done with their previous row's Scan
|
||||
+ // results (any RawBytes memory), so we can release the read lock that would
|
||||
+ // be preventing awaitDone from calling the unexported close before we do so.
|
||||
+ rs.closemuRUnlockIfHeldByScan()
|
||||
+
|
||||
return rs.close(nil)
|
||||
}
|
||||
|
||||
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
|
||||
index f771dee..53b38d1 100644
|
||||
--- a/src/database/sql/sql_test.go
|
||||
+++ b/src/database/sql/sql_test.go
|
||||
@@ -4255,6 +4255,64 @@ func TestRowsScanProperlyWrapsErrors(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+// From go.dev/issue/60304
|
||||
+func TestContextCancelDuringRawBytesScan(t *testing.T) {
|
||||
+ db := newTestDB(t, "people")
|
||||
+ defer closeDB(t, db)
|
||||
+
|
||||
+ if _, err := db.Exec("USE_RAWBYTES"); err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+
|
||||
+ ctx, cancel := context.WithCancel(context.Background())
|
||||
+ defer cancel()
|
||||
+
|
||||
+ r, err := db.QueryContext(ctx, "SELECT|people|name|")
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ numRows := 0
|
||||
+ var sink byte
|
||||
+ for r.Next() {
|
||||
+ numRows++
|
||||
+ var s RawBytes
|
||||
+ err = r.Scan(&s)
|
||||
+ if !r.closemuScanHold {
|
||||
+ t.Errorf("expected closemu to be held")
|
||||
+ }
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ t.Logf("read %q", s)
|
||||
+ if numRows == 2 {
|
||||
+ cancel() // invalidate the context, which used to call close asynchronously
|
||||
+ }
|
||||
+ for _, b := range s { // some operation reading from the raw memory
|
||||
+ sink += b
|
||||
+ }
|
||||
+ }
|
||||
+ if r.closemuScanHold {
|
||||
+ t.Errorf("closemu held; should not be")
|
||||
+ }
|
||||
+
|
||||
+ // There are 3 rows. We canceled after reading 2 so we expect either
|
||||
+ // 2 or 3 depending on how the awaitDone goroutine schedules.
|
||||
+ switch numRows {
|
||||
+ case 0, 1:
|
||||
+ t.Errorf("got %d rows; want 2+", numRows)
|
||||
+ case 2:
|
||||
+ if err := r.Err(); err != context.Canceled {
|
||||
+ t.Errorf("unexpected error: %v (%T)", err, err)
|
||||
+ }
|
||||
+ default:
|
||||
+ // Made it to the end. This is rare, but fine. Permit it.
|
||||
+ }
|
||||
+
|
||||
+ if err := r.Close(); err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// badConn implements a bad driver.Conn, for TestBadDriver.
|
||||
// The Exec method panics.
|
||||
type badConn struct{}
|
||||
232
meta/recipes-devtools/go/go-1.21/CVE-2025-47907-pre-0002.patch
Normal file
232
meta/recipes-devtools/go/go-1.21/CVE-2025-47907-pre-0002.patch
Normal file
@@ -0,0 +1,232 @@
|
||||
From c23579f031ecd09bf37c644723b33736dffa8b92 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Tue, 23 Jan 2024 15:59:47 -0800
|
||||
Subject: [PATCH] database/sql: avoid clobbering driver-owned memory in
|
||||
RawBytes
|
||||
|
||||
Depending on the query, a RawBytes can contain memory owned by the
|
||||
driver or by database/sql:
|
||||
|
||||
If the driver provides the column as a []byte,
|
||||
RawBytes aliases that []byte.
|
||||
|
||||
If the driver provides the column as any other type,
|
||||
RawBytes contains memory allocated by database/sql.
|
||||
Prior to this CL, Rows.Scan will reuse existing capacity in a
|
||||
RawBytes to permit a single allocation to be reused across rows.
|
||||
|
||||
When a RawBytes is reused across queries, this can result
|
||||
in database/sql writing to driver-owned memory.
|
||||
|
||||
Add a buffer to Rows to store RawBytes data, and reuse this
|
||||
buffer across calls to Rows.Scan.
|
||||
|
||||
Fixes #65201
|
||||
|
||||
Change-Id: Iac640174c7afa97eeb39496f47dec202501b2483
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/557917
|
||||
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
|
||||
Reviewed-by: Roland Shoemaker <roland@golang.org>
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
|
||||
CVE: CVE-2025-47907
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/c23579f031ecd09bf37c644723b33736dffa8b92]
|
||||
|
||||
Signed-off-by: Praveen Kumar <praveen.kumar@windriver.com>
|
||||
---
|
||||
src/database/sql/convert.go | 8 +++---
|
||||
src/database/sql/convert_test.go | 14 +++++++---
|
||||
src/database/sql/sql.go | 34 +++++++++++++++++++++++
|
||||
src/database/sql/sql_test.go | 47 ++++++++++++++++++++++++++++++++
|
||||
4 files changed, 95 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/database/sql/convert.go b/src/database/sql/convert.go
|
||||
index b966ef9..3a581f6 100644
|
||||
--- a/src/database/sql/convert.go
|
||||
+++ b/src/database/sql/convert.go
|
||||
@@ -237,7 +237,7 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
- *d = append((*d)[:0], s...)
|
||||
+ *d = rows.setrawbuf(append(rows.rawbuf(), s...))
|
||||
return nil
|
||||
}
|
||||
case []byte:
|
||||
@@ -285,7 +285,7 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
|
||||
if d == nil {
|
||||
return errNilPtr
|
||||
}
|
||||
- *d = s.AppendFormat((*d)[:0], time.RFC3339Nano)
|
||||
+ *d = rows.setrawbuf(s.AppendFormat(rows.rawbuf(), time.RFC3339Nano))
|
||||
return nil
|
||||
}
|
||||
case decimalDecompose:
|
||||
@@ -366,8 +366,8 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
|
||||
}
|
||||
case *RawBytes:
|
||||
sv = reflect.ValueOf(src)
|
||||
- if b, ok := asBytes([]byte(*d)[:0], sv); ok {
|
||||
- *d = RawBytes(b)
|
||||
+ if b, ok := asBytes(rows.rawbuf(), sv); ok {
|
||||
+ *d = rows.setrawbuf(b)
|
||||
return nil
|
||||
}
|
||||
case *bool:
|
||||
diff --git a/src/database/sql/convert_test.go b/src/database/sql/convert_test.go
|
||||
index 2668a5e..23a70bf 100644
|
||||
--- a/src/database/sql/convert_test.go
|
||||
+++ b/src/database/sql/convert_test.go
|
||||
@@ -357,9 +357,10 @@ func TestRawBytesAllocs(t *testing.T) {
|
||||
{"time", time.Unix(2, 5).UTC(), "1970-01-01T00:00:02.000000005Z"},
|
||||
}
|
||||
|
||||
- buf := make(RawBytes, 10)
|
||||
- test := func(name string, in interface{}, want string) {
|
||||
- if err := convertAssign(&buf, in); err != nil {
|
||||
+ var buf RawBytes
|
||||
+ rows := &Rows{}
|
||||
+ test := func(name string, in interface{}, want string) {
|
||||
+ if err := convertAssignRows(&buf, in, rows); err != nil {
|
||||
t.Fatalf("%s: convertAssign = %v", name, err)
|
||||
}
|
||||
match := len(buf) == len(want)
|
||||
@@ -378,6 +379,7 @@ func TestRawBytesAllocs(t *testing.T) {
|
||||
|
||||
n := testing.AllocsPerRun(100, func() {
|
||||
for _, tt := range tests {
|
||||
+ rows.raw = rows.raw[:0]
|
||||
test(tt.name, tt.in, tt.want)
|
||||
}
|
||||
})
|
||||
@@ -386,7 +388,11 @@ func TestRawBytesAllocs(t *testing.T) {
|
||||
// and gc. With 32-bit words there are more convT2E allocs, and
|
||||
// with gccgo, only pointers currently go in interface data.
|
||||
// So only care on amd64 gc for now.
|
||||
- measureAllocs := runtime.GOARCH == "amd64" && runtime.Compiler == "gc"
|
||||
+ measureAllocs := false
|
||||
+ switch runtime.GOARCH {
|
||||
+ case "amd64", "arm64":
|
||||
+ measureAllocs = runtime.Compiler == "gc"
|
||||
+ }
|
||||
|
||||
if n > 0.5 && measureAllocs {
|
||||
t.Fatalf("allocs = %v; want 0", n)
|
||||
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
|
||||
index ef49e70..e25447c 100644
|
||||
--- a/src/database/sql/sql.go
|
||||
+++ b/src/database/sql/sql.go
|
||||
@@ -2894,6 +2894,13 @@ type Rows struct {
|
||||
// not to be called concurrently.
|
||||
lastcols []driver.Value
|
||||
|
||||
+ // raw is a buffer for RawBytes that persists between Scan calls.
|
||||
+ // This is used when the driver returns a mismatched type that requires
|
||||
+ // a cloning allocation. For example, if the driver returns a *string and
|
||||
+ // the user is scanning into a *RawBytes, we need to copy the string.
|
||||
+ // The raw buffer here lets us reuse the memory for that copy across Scan calls.
|
||||
+ raw []byte
|
||||
+
|
||||
// closemuScanHold is whether the previous call to Scan kept closemu RLock'ed
|
||||
// without unlocking it. It does that when the user passes a *RawBytes scan
|
||||
// target. In that case, we need to prevent awaitDone from closing the Rows
|
||||
@@ -3068,6 +3075,32 @@ func (rs *Rows) Err() error {
|
||||
return rs.lasterrOrErrLocked(nil)
|
||||
}
|
||||
|
||||
+// rawbuf returns the buffer to append RawBytes values to.
|
||||
+// This buffer is reused across calls to Rows.Scan.
|
||||
+//
|
||||
+// Usage:
|
||||
+//
|
||||
+// rawBytes = rows.setrawbuf(append(rows.rawbuf(), value...))
|
||||
+func (rs *Rows) rawbuf() []byte {
|
||||
+ if rs == nil {
|
||||
+ // convertAssignRows can take a nil *Rows; for simplicity handle it here
|
||||
+ return nil
|
||||
+ }
|
||||
+ return rs.raw
|
||||
+}
|
||||
+
|
||||
+// setrawbuf updates the RawBytes buffer with the result of appending a new value to it.
|
||||
+// It returns the new value.
|
||||
+func (rs *Rows) setrawbuf(b []byte) RawBytes {
|
||||
+ if rs == nil {
|
||||
+ // convertAssignRows can take a nil *Rows; for simplicity handle it here
|
||||
+ return RawBytes(b)
|
||||
+ }
|
||||
+ off := len(rs.raw)
|
||||
+ rs.raw = b
|
||||
+ return RawBytes(rs.raw[off:])
|
||||
+}
|
||||
+
|
||||
var errRowsClosed = errors.New("sql: Rows are closed")
|
||||
var errNoRows = errors.New("sql: no Rows available")
|
||||
|
||||
@@ -3275,6 +3308,7 @@ func (rs *Rows) Scan(dest ...interface{}) error {
|
||||
|
||||
if scanArgsContainRawBytes(dest) {
|
||||
rs.closemuScanHold = true
|
||||
+ rs.raw = rs.raw[:0]
|
||||
} else {
|
||||
rs.closemu.RUnlock()
|
||||
}
|
||||
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
|
||||
index 53b38d1..6aa9bf0 100644
|
||||
--- a/src/database/sql/sql_test.go
|
||||
+++ b/src/database/sql/sql_test.go
|
||||
@@ -4313,6 +4313,53 @@ func TestContextCancelDuringRawBytesScan(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+// Issue #65201.
|
||||
+//
|
||||
+// If a RawBytes is reused across multiple queries,
|
||||
+// subsequent queries shouldn't overwrite driver-owned memory from previous queries.
|
||||
+func TestRawBytesReuse(t *testing.T) {
|
||||
+ db := newTestDB(t, "people")
|
||||
+ defer closeDB(t, db)
|
||||
+
|
||||
+ if _, err := db.Exec("USE_RAWBYTES"); err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+
|
||||
+ var raw RawBytes
|
||||
+
|
||||
+ // The RawBytes in this query aliases driver-owned memory.
|
||||
+ rows, err := db.Query("SELECT|people|name|")
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ rows.Next()
|
||||
+ rows.Scan(&raw) // now raw is pointing to driver-owned memory
|
||||
+ name1 := string(raw)
|
||||
+ rows.Close()
|
||||
+
|
||||
+ // The RawBytes in this query does not alias driver-owned memory.
|
||||
+ rows, err = db.Query("SELECT|people|age|")
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ rows.Next()
|
||||
+ rows.Scan(&raw) // this must not write to the driver-owned memory in raw
|
||||
+ rows.Close()
|
||||
+
|
||||
+ // Repeat the first query. Nothing should have changed.
|
||||
+ rows, err = db.Query("SELECT|people|name|")
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ rows.Next()
|
||||
+ rows.Scan(&raw) // raw points to driver-owned memory again
|
||||
+ name2 := string(raw)
|
||||
+ rows.Close()
|
||||
+ if name1 != name2 {
|
||||
+ t.Fatalf("Scan read name %q, want %q", name2, name1)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// badConn implements a bad driver.Conn, for TestBadDriver.
|
||||
// The Exec method panics.
|
||||
type badConn struct{}
|
||||
327
meta/recipes-devtools/go/go-1.21/CVE-2025-47907.patch
Normal file
327
meta/recipes-devtools/go/go-1.21/CVE-2025-47907.patch
Normal file
@@ -0,0 +1,327 @@
|
||||
From 8a924caaf348fdc366bab906424616b2974ad4e9 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Wed, 23 Jul 2025 14:26:54 -0700
|
||||
Subject: [PATCH] database/sql: avoid closing Rows while scan is in progress
|
||||
|
||||
A database/sql/driver.Rows can return database-owned data
|
||||
from Rows.Next. The driver.Rows documentation doesn't explicitly
|
||||
document the lifetime guarantees for this data, but a reasonable
|
||||
expectation is that the caller of Next should only access it
|
||||
until the next call to Rows.Close or Rows.Next.
|
||||
|
||||
Avoid violating that constraint when a query is cancelled while
|
||||
a call to database/sql.Rows.Scan (note the difference between
|
||||
the two different Rows types!) is in progress. We previously
|
||||
took care to avoid closing a driver.Rows while the user has
|
||||
access to driver-owned memory via a RawData, but we could still
|
||||
close a driver.Rows while a Scan call was in the process of
|
||||
reading previously-returned driver-owned data.
|
||||
|
||||
Update the fake DB used in database/sql tests to invalidate
|
||||
returned data to help catch other places we might be
|
||||
incorrectly retaining it.
|
||||
|
||||
Updates #74831
|
||||
Fixes #74832
|
||||
|
||||
Change-Id: Ice45b5fad51b679c38e3e1d21ef39156b56d6037
|
||||
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2540
|
||||
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||
Reviewed-by: Neal Patel <nealpatel@google.com>
|
||||
Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/2601
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/693558
|
||||
TryBot-Bypass: Dmitri Shuralyov <dmitshur@golang.org>
|
||||
Reviewed-by: Mark Freeman <markfreeman@google.com>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
|
||||
|
||||
CVE: CVE-2025-47907
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/8a924caaf348fdc366bab906424616b2974ad4e9]
|
||||
|
||||
Signed-off-by: Praveen Kumar <praveen.kumar@windriver.com>
|
||||
---
|
||||
src/database/sql/convert.go | 2 --
|
||||
src/database/sql/fakedb_test.go | 47 ++++++++++++--------------
|
||||
src/database/sql/sql.go | 26 +++++++-------
|
||||
src/database/sql/sql_test.go | 60 ++++++++++++++++++++++++++++++---
|
||||
4 files changed, 90 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/src/database/sql/convert.go b/src/database/sql/convert.go
|
||||
index 3a581f6..5b0c6f0 100644
|
||||
--- a/src/database/sql/convert.go
|
||||
+++ b/src/database/sql/convert.go
|
||||
@@ -324,7 +324,6 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
|
||||
if rows == nil {
|
||||
return errors.New("invalid context to convert cursor rows, missing parent *Rows")
|
||||
}
|
||||
- rows.closemu.Lock()
|
||||
*d = Rows{
|
||||
dc: rows.dc,
|
||||
releaseConn: func(error) {},
|
||||
@@ -340,7 +339,6 @@ func convertAssignRows(dest, src interface{}, rows *Rows) error {
|
||||
parentCancel()
|
||||
}
|
||||
}
|
||||
- rows.closemu.Unlock()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
diff --git a/src/database/sql/fakedb_test.go b/src/database/sql/fakedb_test.go
|
||||
index 33c57b9..9f3d517 100644
|
||||
--- a/src/database/sql/fakedb_test.go
|
||||
+++ b/src/database/sql/fakedb_test.go
|
||||
@@ -5,6 +5,7 @@
|
||||
package sql
|
||||
|
||||
import (
|
||||
+ "bytes"
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
@@ -15,7 +16,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
- "sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -91,8 +91,6 @@ func (cc *fakeDriverCtx) OpenConnector(name string) (driver.Connector, error) {
|
||||
type fakeDB struct {
|
||||
name string
|
||||
|
||||
- useRawBytes atomic.Bool
|
||||
-
|
||||
mu sync.Mutex
|
||||
tables map[string]*table
|
||||
badConn bool
|
||||
@@ -683,8 +681,6 @@ func (c *fakeConn) PrepareContext(ctx context.Context, query string) (driver.Stm
|
||||
switch cmd {
|
||||
case "WIPE":
|
||||
// Nothing
|
||||
- case "USE_RAWBYTES":
|
||||
- c.db.useRawBytes.Store(true)
|
||||
case "SELECT":
|
||||
stmt, err = c.prepareSelect(stmt, parts)
|
||||
case "CREATE":
|
||||
@@ -788,9 +784,6 @@ func (s *fakeStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (d
|
||||
case "WIPE":
|
||||
db.wipe()
|
||||
return driver.ResultNoRows, nil
|
||||
- case "USE_RAWBYTES":
|
||||
- s.c.db.useRawBytes.Store(true)
|
||||
- return driver.ResultNoRows, nil
|
||||
case "CREATE":
|
||||
if err := db.createTable(s.table, s.colName, s.colType); err != nil {
|
||||
return nil, err
|
||||
@@ -1073,10 +1066,9 @@ type rowsCursor struct {
|
||||
errPos int
|
||||
err error
|
||||
|
||||
- // a clone of slices to give out to clients, indexed by the
|
||||
- // original slice's first byte address. we clone them
|
||||
- // just so we're able to corrupt them on close.
|
||||
- bytesClone map[*byte][]byte
|
||||
+ // Data returned to clients.
|
||||
+ // We clone and stash it here so it can be invalidated by Close and Next.
|
||||
+ driverOwnedMemory [][]byte
|
||||
|
||||
// Every operation writes to line to enable the race detector
|
||||
// check for data races.
|
||||
@@ -1090,9 +1082,19 @@ func (rc *rowsCursor) touchMem() {
|
||||
rc.line++
|
||||
}
|
||||
|
||||
+func (rc *rowsCursor) invalidateDriverOwnedMemory() {
|
||||
+ for _, buf := range rc.driverOwnedMemory {
|
||||
+ for i := range buf {
|
||||
+ buf[i] = 'x'
|
||||
+ }
|
||||
+ }
|
||||
+ rc.driverOwnedMemory = nil
|
||||
+}
|
||||
+
|
||||
func (rc *rowsCursor) Close() error {
|
||||
rc.touchMem()
|
||||
rc.parentMem.touchMem()
|
||||
+ rc.invalidateDriverOwnedMemory()
|
||||
rc.closed = true
|
||||
return nil
|
||||
}
|
||||
@@ -1123,6 +1125,8 @@ func (rc *rowsCursor) Next(dest []driver.Value) error {
|
||||
if rc.posRow >= len(rc.rows[rc.posSet]) {
|
||||
return io.EOF // per interface spec
|
||||
}
|
||||
+ // Corrupt any previously returned bytes.
|
||||
+ rc.invalidateDriverOwnedMemory()
|
||||
for i, v := range rc.rows[rc.posSet][rc.posRow].cols {
|
||||
// TODO(bradfitz): convert to subset types? naah, I
|
||||
// think the subset types should only be input to
|
||||
@@ -1130,20 +1134,13 @@ func (rc *rowsCursor) Next(dest []driver.Value) error {
|
||||
// a wider range of types coming out of drivers. all
|
||||
// for ease of drivers, and to prevent drivers from
|
||||
// messing up conversions or doing them differently.
|
||||
- dest[i] = v
|
||||
-
|
||||
- if bs, ok := v.([]byte); ok && !rc.db.useRawBytes.Load() {
|
||||
- if rc.bytesClone == nil {
|
||||
- rc.bytesClone = make(map[*byte][]byte)
|
||||
- }
|
||||
- clone, ok := rc.bytesClone[&bs[0]]
|
||||
- if !ok {
|
||||
- clone = make([]byte, len(bs))
|
||||
- copy(clone, bs)
|
||||
- rc.bytesClone[&bs[0]] = clone
|
||||
- }
|
||||
- dest[i] = clone
|
||||
+ if bs, ok := v.([]byte); ok {
|
||||
+ // Clone []bytes and stash for later invalidation.
|
||||
+ bs = bytes.Clone(bs)
|
||||
+ rc.driverOwnedMemory = append(rc.driverOwnedMemory, bs)
|
||||
+ v = bs
|
||||
}
|
||||
+ dest[i] = v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
|
||||
index e25447c..a428e29 100644
|
||||
--- a/src/database/sql/sql.go
|
||||
+++ b/src/database/sql/sql.go
|
||||
@@ -3294,38 +3294,36 @@ func (rs *Rows) Scan(dest ...interface{}) error {
|
||||
// without calling Next.
|
||||
return fmt.Errorf("sql: Scan called without calling Next (closemuScanHold)")
|
||||
}
|
||||
+
|
||||
rs.closemu.RLock()
|
||||
+ rs.raw = rs.raw[:0]
|
||||
+ err := rs.scanLocked(dest...)
|
||||
+ if err == nil && scanArgsContainRawBytes(dest) {
|
||||
+ rs.closemuScanHold = true
|
||||
+ } else {
|
||||
+ rs.closemu.RUnlock()
|
||||
+ }
|
||||
+ return err
|
||||
+}
|
||||
|
||||
+func (rs *Rows) scanLocked(dest ...interface{}) error {
|
||||
if rs.lasterr != nil && rs.lasterr != io.EOF {
|
||||
- rs.closemu.RUnlock()
|
||||
return rs.lasterr
|
||||
}
|
||||
if rs.closed {
|
||||
- err := rs.lasterrOrErrLocked(errRowsClosed)
|
||||
- rs.closemu.RUnlock()
|
||||
- return err
|
||||
- }
|
||||
-
|
||||
- if scanArgsContainRawBytes(dest) {
|
||||
- rs.closemuScanHold = true
|
||||
- rs.raw = rs.raw[:0]
|
||||
- } else {
|
||||
- rs.closemu.RUnlock()
|
||||
+ return rs.lasterrOrErrLocked(errRowsClosed)
|
||||
}
|
||||
|
||||
if rs.lastcols == nil {
|
||||
- rs.closemuRUnlockIfHeldByScan()
|
||||
return errors.New("sql: Scan called without calling Next")
|
||||
}
|
||||
if len(dest) != len(rs.lastcols) {
|
||||
- rs.closemuRUnlockIfHeldByScan()
|
||||
return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
|
||||
}
|
||||
|
||||
for i, sv := range rs.lastcols {
|
||||
err := convertAssignRows(dest[i], sv, rs)
|
||||
if err != nil {
|
||||
- rs.closemuRUnlockIfHeldByScan()
|
||||
return fmt.Errorf(`sql: Scan error on column index %d, name %q: %w`, i, rs.rowsi.Columns()[i], err)
|
||||
}
|
||||
}
|
||||
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
|
||||
index 6aa9bf0..6aec7ec 100644
|
||||
--- a/src/database/sql/sql_test.go
|
||||
+++ b/src/database/sql/sql_test.go
|
||||
@@ -5,6 +5,7 @@
|
||||
package sql
|
||||
|
||||
import (
|
||||
+ "bytes"
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
@@ -4321,10 +4322,6 @@ func TestRawBytesReuse(t *testing.T) {
|
||||
db := newTestDB(t, "people")
|
||||
defer closeDB(t, db)
|
||||
|
||||
- if _, err := db.Exec("USE_RAWBYTES"); err != nil {
|
||||
- t.Fatal(err)
|
||||
- }
|
||||
-
|
||||
var raw RawBytes
|
||||
|
||||
// The RawBytes in this query aliases driver-owned memory.
|
||||
@@ -4469,6 +4466,61 @@ func TestTypedString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+type testScanner struct {
|
||||
+ scanf func(src any) error
|
||||
+}
|
||||
+
|
||||
+func (ts testScanner) Scan(src any) error { return ts.scanf(src) }
|
||||
+
|
||||
+func TestContextCancelDuringScan(t *testing.T) {
|
||||
+ db := newTestDB(t, "people")
|
||||
+ defer closeDB(t, db)
|
||||
+
|
||||
+ ctx, cancel := context.WithCancel(context.Background())
|
||||
+ defer cancel()
|
||||
+
|
||||
+ scanStart := make(chan any)
|
||||
+ scanEnd := make(chan error)
|
||||
+ scanner := &testScanner{
|
||||
+ scanf: func(src any) error {
|
||||
+ scanStart <- src
|
||||
+ return <-scanEnd
|
||||
+ },
|
||||
+ }
|
||||
+
|
||||
+ // Start a query, and pause it mid-scan.
|
||||
+ want := []byte("Alice")
|
||||
+ r, err := db.QueryContext(ctx, "SELECT|people|name|name=?", string(want))
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ if !r.Next() {
|
||||
+ t.Fatalf("r.Next() = false, want true")
|
||||
+ }
|
||||
+ go func() {
|
||||
+ r.Scan(scanner)
|
||||
+ }()
|
||||
+ got := <-scanStart
|
||||
+ defer close(scanEnd)
|
||||
+ gotBytes, ok := got.([]byte)
|
||||
+ if !ok {
|
||||
+ t.Fatalf("r.Scan returned %T, want []byte", got)
|
||||
+ }
|
||||
+ if !bytes.Equal(gotBytes, want) {
|
||||
+ t.Fatalf("before cancel: r.Scan returned %q, want %q", gotBytes, want)
|
||||
+ }
|
||||
+
|
||||
+ // Cancel the query.
|
||||
+ // Sleep to give it a chance to finish canceling.
|
||||
+ cancel()
|
||||
+ time.Sleep(10 * time.Millisecond)
|
||||
+
|
||||
+ // Cancelling the query should not have changed the result.
|
||||
+ if !bytes.Equal(gotBytes, want) {
|
||||
+ t.Fatalf("after cancel: r.Scan result is now %q, want %q", gotBytes, want)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
func BenchmarkConcurrentDBExec(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
ct := new(concurrentDBExecTest)
|
||||
@@ -4,7 +4,7 @@ HOMEPAGE = "https://pypi.org/project/Jinja2/"
|
||||
LICENSE = "BSD-3-Clause"
|
||||
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=5dc88300786f1c214c1e9827a5229462"
|
||||
|
||||
SRC_URI[sha256sum] = "4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"
|
||||
SRC_URI[sha256sum] = "0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"
|
||||
|
||||
PYPI_PACKAGE = "jinja2"
|
||||
|
||||
@@ -22,6 +22,9 @@ SRC_URI += " \
|
||||
do_install_ptest() {
|
||||
install -d ${D}${PTEST_PATH}/tests
|
||||
cp -rf ${S}/tests/* ${D}${PTEST_PATH}/tests/
|
||||
|
||||
# test_async items require trio module
|
||||
rm -f ${D}${PTEST_PATH}/tests/test_async.py ${D}${PTEST_PATH}/tests/test_async_filters.py
|
||||
}
|
||||
|
||||
RDEPENDS:${PN}-ptest += " \
|
||||
@@ -16,7 +16,7 @@ diff --git a/Lib/tarfile.py b/Lib/tarfile.py
|
||||
index 3bbbcaa..473167d 100755
|
||||
--- a/Lib/tarfile.py
|
||||
+++ b/Lib/tarfile.py
|
||||
@@ -2675,7 +2675,8 @@ class TarFile(object):
|
||||
@@ -2678,7 +2678,8 @@ class TarFile(object):
|
||||
os.lchown(targetpath, u, g)
|
||||
else:
|
||||
os.chown(targetpath, u, g)
|
||||
|
||||
@@ -1,219 +0,0 @@
|
||||
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`.)
|
||||
@@ -37,7 +37,6 @@ 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 = " \
|
||||
@@ -46,7 +45,7 @@ SRC_URI:append:class-native = " \
|
||||
file://12-distutils-prefix-is-inside-staging-area.patch \
|
||||
file://0001-Don-t-search-system-for-headers-libraries.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "ae665bc678abd9ab6a6e1573d2481625a53719bc517e9a634ed2b9fefae3817f"
|
||||
SRC_URI[sha256sum] = "c8f4a596572201d81dd7df91f70e177e19a70f1d489968b54b5fbbf29a97c076"
|
||||
|
||||
# exclude pre-releases for both python 2.x and 3.x
|
||||
UPSTREAM_CHECK_REGEX = "[Pp]ython-(?P<pver>\d+(\.\d+)+).tar"
|
||||
@@ -128,6 +128,7 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
|
||||
file://CVE-2024-3446-0005.patch \
|
||||
file://CVE-2024-3446-0006.patch \
|
||||
file://CVE-2024-3447.patch \
|
||||
file://CVE-2024-8354.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
|
||||
|
||||
|
||||
75
meta/recipes-devtools/qemu/qemu/CVE-2024-8354.patch
Normal file
75
meta/recipes-devtools/qemu/qemu/CVE-2024-8354.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
From 746269eaae16423572ae7c0dfeb66140fa882149 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Maydell <peter.maydell@linaro.org>
|
||||
Date: Mon, 15 Sep 2025 14:29:10 +0100
|
||||
Subject: [PATCH] hw/usb/hcd-uhci: don't assert for SETUP to non-0 endpoint
|
||||
|
||||
If the guest feeds invalid data to the UHCI controller, we
|
||||
can assert:
|
||||
qemu-system-x86_64: ../../hw/usb/core.c:744: usb_ep_get: Assertion `pid == USB_TOKEN_IN || pid == USB_TOKEN_OUT' failed.
|
||||
|
||||
(see issue 2548 for the repro case). This happens because the guest
|
||||
attempts USB_TOKEN_SETUP to an endpoint other than 0, which is not
|
||||
valid. The controller code doesn't catch this guest error, so
|
||||
instead we hit the assertion in the USB core code.
|
||||
|
||||
Catch the case of SETUP to non-zero endpoint, and treat it as a fatal
|
||||
error in the TD, in the same way we do for an invalid PID value in
|
||||
the TD.
|
||||
|
||||
This is the UHCI equivalent of the same bug in OHCI that we fixed in
|
||||
commit 3c3c233677 ("hw/usb/hcd-ohci: Fix #1510, #303: pid not IN or
|
||||
OUT").
|
||||
|
||||
This bug has been tracked as CVE-2024-8354.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/2548
|
||||
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
|
||||
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
(cherry picked from commit d0af3cd0274e265435170a583c72b9f0a4100dff)
|
||||
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
|
||||
CVE: CVE-2024-8354
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/746269eaae16423572ae7c0dfeb66140fa882149]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
hw/usb/hcd-uhci.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
|
||||
index 0561a6d801..8f4d6a0f71 100644
|
||||
--- a/hw/usb/hcd-uhci.c
|
||||
+++ b/hw/usb/hcd-uhci.c
|
||||
@@ -724,6 +724,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
|
||||
bool spd;
|
||||
bool queuing = (q != NULL);
|
||||
uint8_t pid = td->token & 0xff;
|
||||
+ uint8_t ep_id = (td->token >> 15) & 0xf;
|
||||
UHCIAsync *async;
|
||||
|
||||
async = uhci_async_find_td(s, td_addr);
|
||||
@@ -767,9 +768,14 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
|
||||
|
||||
switch (pid) {
|
||||
case USB_TOKEN_OUT:
|
||||
- case USB_TOKEN_SETUP:
|
||||
case USB_TOKEN_IN:
|
||||
break;
|
||||
+ case USB_TOKEN_SETUP:
|
||||
+ /* SETUP is only valid to endpoint 0 */
|
||||
+ if (ep_id == 0) {
|
||||
+ break;
|
||||
+ }
|
||||
+ /* fallthrough */
|
||||
default:
|
||||
/* invalid pid : frame interrupted */
|
||||
s->status |= UHCI_STS_HCPERR;
|
||||
@@ -816,7 +822,7 @@ static int uhci_handle_td(UHCIState *s, UHCIQueue *q, uint32_t qh_addr,
|
||||
return uhci_handle_td_error(s, td, td_addr, USB_RET_NODEV,
|
||||
int_mask);
|
||||
}
|
||||
- ep = usb_ep_get(dev, pid, (td->token >> 15) & 0xf);
|
||||
+ ep = usb_ep_get(dev, pid, ep_id);
|
||||
q = uhci_queue_new(s, qh_addr, td, ep);
|
||||
}
|
||||
async = uhci_async_alloc(q, td_addr);
|
||||
@@ -0,0 +1,134 @@
|
||||
From 0cae41b23a9669e801211dd4cf97b6dadd6dbdd7 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Thu, 22 May 2025 12:25:41 +0100
|
||||
Subject: [PATCH] pdfwrite - avoid buffer overrun
|
||||
|
||||
Bug #708539 "Buffer overflow in pdf_write_cmap"
|
||||
|
||||
The proposed fix in the report solves the buffer overrun, but does not
|
||||
tackle a number of other problems.
|
||||
|
||||
This commit checks the result of stream_puts() in
|
||||
pdf_write_cid_system_info_to_stream() and correctly signals an error to
|
||||
the caller if that fails.
|
||||
|
||||
In pdf_write_cid_system_info we replace a (rather small!) fixed size
|
||||
buffer with a dynamically allocated one using the lengths of the strings
|
||||
which pdf_write_cid_system_info_to_stream() will write, and a small
|
||||
fixed overhead to deal with the keys and initial byte '/'.
|
||||
|
||||
Because 'buf' is used in the stream 's', if it is too small to hold all
|
||||
the CIDSystemInfo then we would get an error which was simply discarded
|
||||
previously.
|
||||
|
||||
We now should avoid the potential error by ensuring the buffer is large
|
||||
enough for all the information, and if we do get an error we no longer
|
||||
silently ignore it, which would write an invalid PDF file.
|
||||
|
||||
CVE: CVE-2025-59798
|
||||
Upstream-Status: Backport [https://github.com/ArtifexSoftware/ghostpdl/commit/0cae41b23a9669e801211dd4cf97b6dadd6dbdd7]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
devices/vector/gdevpdtw.c | 52 ++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 41 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/devices/vector/gdevpdtw.c b/devices/vector/gdevpdtw.c
|
||||
index ced15c9b2..fe24dd73a 100644
|
||||
--- a/devices/vector/gdevpdtw.c
|
||||
+++ b/devices/vector/gdevpdtw.c
|
||||
@@ -694,7 +694,8 @@ static int
|
||||
pdf_write_cid_system_info_to_stream(gx_device_pdf *pdev, stream *s,
|
||||
const gs_cid_system_info_t *pcidsi, gs_id object_id)
|
||||
{
|
||||
- byte *Registry, *Ordering;
|
||||
+ byte *Registry = NULL, *Ordering = NULL;
|
||||
+ int code = 0;
|
||||
|
||||
Registry = gs_alloc_bytes(pdev->pdf_memory, pcidsi->Registry.size, "temporary buffer for Registry");
|
||||
if (!Registry)
|
||||
@@ -725,14 +726,19 @@ pdf_write_cid_system_info_to_stream(gx_device_pdf *pdev, stream *s,
|
||||
}
|
||||
s_arcfour_process_buffer(&sarc4, Ordering, pcidsi->Ordering.size);
|
||||
}
|
||||
- stream_puts(s, "<<\n/Registry");
|
||||
+ code = stream_puts(s, "<<\n/Registry");
|
||||
+ if (code < 0)
|
||||
+ goto error;
|
||||
s_write_ps_string(s, Registry, pcidsi->Registry.size, PRINT_HEX_NOT_OK);
|
||||
- stream_puts(s, "\n/Ordering");
|
||||
+ code = stream_puts(s, "\n/Ordering");
|
||||
+ if(code < 0)
|
||||
+ goto error;
|
||||
s_write_ps_string(s, Ordering, pcidsi->Ordering.size, PRINT_HEX_NOT_OK);
|
||||
+error:
|
||||
pprintd1(s, "\n/Supplement %d\n>>\n", pcidsi->Supplement);
|
||||
gs_free_object(pdev->pdf_memory, Registry, "free temporary Registry buffer");
|
||||
gs_free_object(pdev->pdf_memory, Ordering, "free temporary Ordering buffer");
|
||||
- return 0;
|
||||
+ return code;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -777,31 +783,55 @@ pdf_write_cmap(gx_device_pdf *pdev, const gs_cmap_t *pcmap,
|
||||
*ppres = writer.pres;
|
||||
writer.pres->where_used = 0; /* CMap isn't a PDF resource. */
|
||||
if (!pcmap->ToUnicode) {
|
||||
- byte buf[200];
|
||||
+ byte *buf = NULL;
|
||||
+ uint64_t buflen = 0;
|
||||
cos_dict_t *pcd = (cos_dict_t *)writer.pres->object;
|
||||
stream s;
|
||||
|
||||
+ /* We use 'buf' for the stream 's' below and that needs to have some extra
|
||||
+ * space for the CIDSystemInfo. We also need an extra byte for the leading '/'
|
||||
+ * 100 bytes is ample for the overhead.
|
||||
+ */
|
||||
+ buflen = pcmap->CIDSystemInfo->Registry.size + pcmap->CIDSystemInfo->Ordering.size + pcmap->CMapName.size + 100;
|
||||
+ if (buflen > max_uint)
|
||||
+ return_error(gs_error_limitcheck);
|
||||
+
|
||||
+ buf = gs_alloc_bytes(pdev->memory, buflen, "pdf_write_cmap");
|
||||
+ if (buf == NULL)
|
||||
+ return_error(gs_error_VMerror);
|
||||
+
|
||||
code = cos_dict_put_c_key_int(pcd, "/WMode", pcmap->WMode);
|
||||
- if (code < 0)
|
||||
+ if (code < 0) {
|
||||
+ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
|
||||
return code;
|
||||
+ }
|
||||
buf[0] = '/';
|
||||
memcpy(buf + 1, pcmap->CMapName.data, pcmap->CMapName.size);
|
||||
code = cos_dict_put_c_key_string(pcd, "/CMapName",
|
||||
buf, pcmap->CMapName.size + 1);
|
||||
- if (code < 0)
|
||||
+ if (code < 0) {
|
||||
+ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
|
||||
return code;
|
||||
+ }
|
||||
s_init(&s, pdev->memory);
|
||||
- swrite_string(&s, buf, sizeof(buf));
|
||||
+ swrite_string(&s, buf, buflen);
|
||||
code = pdf_write_cid_system_info_to_stream(pdev, &s, pcmap->CIDSystemInfo, 0);
|
||||
- if (code < 0)
|
||||
+ if (code < 0) {
|
||||
+ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
|
||||
return code;
|
||||
+ }
|
||||
code = cos_dict_put_c_key_string(pcd, "/CIDSystemInfo",
|
||||
buf, stell(&s));
|
||||
- if (code < 0)
|
||||
+ if (code < 0) {
|
||||
+ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
|
||||
return code;
|
||||
+ }
|
||||
code = cos_dict_put_string_copy(pcd, "/Type", "/CMap");
|
||||
- if (code < 0)
|
||||
+ if (code < 0) {
|
||||
+ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
|
||||
return code;
|
||||
+ }
|
||||
+ gs_free_object(pdev->memory, buf, "pdf_write_cmap");
|
||||
}
|
||||
if (pcmap->CMapName.size == 0) {
|
||||
/* Create an arbitrary name (for ToUnicode CMap). */
|
||||
@@ -0,0 +1,41 @@
|
||||
From 6dab38fb211f15226c242ab7a83fa53e4b0ff781 Mon Sep 17 00:00:00 2001
|
||||
From: Piotr Kajda <petermasterperfect@gmail.com>
|
||||
Date: Thu, 8 May 2025 11:37:09 +0100
|
||||
Subject: [PATCH] pdfwrite - bounds check some strings
|
||||
|
||||
Bug #708517
|
||||
|
||||
This differs very slightly from the proposed patch in the bug report, I
|
||||
had a quick scout through the C file and found another similar case.
|
||||
|
||||
Both fixed here.
|
||||
|
||||
CVE: CVE-2025-59799
|
||||
Upstream-Status: Backport [https://github.com/ArtifexSoftware/ghostpdl/commit/6dab38fb211f15226c242ab7a83fa53e4b0ff781]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
devices/vector/gdevpdfm.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/devices/vector/gdevpdfm.c b/devices/vector/gdevpdfm.c
|
||||
index 5aa3644e2..4b1d7d89c 100644
|
||||
--- a/devices/vector/gdevpdfm.c
|
||||
+++ b/devices/vector/gdevpdfm.c
|
||||
@@ -199,6 +199,8 @@ pdfmark_coerce_dest(gs_param_string *dstr, char dest[MAX_DEST_STRING])
|
||||
{
|
||||
const byte *data = dstr->data;
|
||||
uint size = dstr->size;
|
||||
+ if (size > MAX_DEST_STRING)
|
||||
+ return_error(gs_error_limitcheck);
|
||||
if (size == 0 || data[0] != '(')
|
||||
return 0;
|
||||
/****** HANDLE ESCAPES ******/
|
||||
@@ -848,6 +850,8 @@ pdfmark_put_ao_pairs(gx_device_pdf * pdev, cos_dict_t *pcd,
|
||||
char buf[30];
|
||||
int d0, d1;
|
||||
|
||||
+ if (Action[1].size > 29)
|
||||
+ return_error(gs_error_rangecheck);
|
||||
memcpy(buf, Action[1].data, Action[1].size);
|
||||
buf[Action[1].size] = 0;
|
||||
if (sscanf(buf, "%d %d R", &d0, &d1) == 2)
|
||||
@@ -0,0 +1,36 @@
|
||||
From 176cf0188a2294bc307b8caec876f39412e58350 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Tue, 1 Jul 2025 10:31:17 +0100
|
||||
Subject: [PATCH] PDF OCR 8 bit device - avoid overflow
|
||||
|
||||
Bug 708602 "Heap overflow in ocr_line8"
|
||||
|
||||
Make sure the calculation of the required raster size does not overflow
|
||||
an int.
|
||||
|
||||
CVE: CVE-2025-59800
|
||||
Upstream-Status: Backport [https://github.com/ArtifexSoftware/ghostpdl/commit/176cf0188a2294bc307b8caec876f39412e58350]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
devices/gdevpdfocr.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/devices/gdevpdfocr.c b/devices/gdevpdfocr.c
|
||||
index f27dc11db..6362f4104 100644
|
||||
--- a/devices/gdevpdfocr.c
|
||||
+++ b/devices/gdevpdfocr.c
|
||||
@@ -521,9 +521,12 @@ ocr_line32(gx_device_pdf_image *dev, void *row)
|
||||
static int
|
||||
ocr_begin_page(gx_device_pdf_image *dev, int w, int h, int bpp)
|
||||
{
|
||||
- int raster = (w+3)&~3;
|
||||
+ int64_t raster = (w + 3) & ~3;
|
||||
|
||||
- dev->ocr.data = gs_alloc_bytes(dev->memory, raster * h, "ocr_begin_page");
|
||||
+ raster = raster * (int64_t)h;
|
||||
+ if (raster < 0 || raster > max_size_t)
|
||||
+ return gs_note_error(gs_error_VMerror);
|
||||
+ dev->ocr.data = gs_alloc_bytes(dev->memory, raster, "ocr_begin_page");
|
||||
if (dev->ocr.data == NULL)
|
||||
return_error(gs_error_VMerror);
|
||||
dev->ocr.w = w;
|
||||
@@ -76,6 +76,9 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d
|
||||
file://CVE-2025-27836-1.patch \
|
||||
file://CVE-2025-27836-2.patch \
|
||||
file://CVE-2025-48708.patch \
|
||||
file://CVE-2025-59798.patch \
|
||||
file://CVE-2025-59799.patch \
|
||||
file://CVE-2025-59800.patch \
|
||||
"
|
||||
|
||||
SRC_URI = "${SRC_URI_BASE} \
|
||||
|
||||
@@ -9,7 +9,7 @@ BUGTRACKER = "https://gitlab.gnome.org/GNOME/libhandy/-/issues"
|
||||
LICENSE = "LGPL-2.1-only"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=4fbd65380cdd255951079008b364516c"
|
||||
|
||||
SRC_URI = "git://gitlab.gnome.org/GNOME/libhandy.git;protocol=https;branch=master \
|
||||
SRC_URI = "git://gitlab.gnome.org/GNOME/libhandy.git;protocol=https;branch=main \
|
||||
file://0001-Add-private-headers.patch \
|
||||
"
|
||||
SRCREV = "8fa8306a79215fc6ebf2483145da98bf9b2495ab"
|
||||
|
||||
@@ -11,13 +11,13 @@ python () {
|
||||
raise bb.parse.SkipRecipe("Set PREFERRED_PROVIDER_virtual/kernel to linux-yocto-rt to enable it")
|
||||
}
|
||||
|
||||
SRCREV_machine ?= "76da2cf32fe004e10f581744496e71547d0a4361"
|
||||
SRCREV_meta ?= "5932fcfa6982f5b86a13849b84ef3d80a557a030"
|
||||
SRCREV_machine ?= "259f7f9d0bd0df2c3e497395568a655c5745b5ac"
|
||||
SRCREV_meta ?= "578937826ffad97749eba3a5d1b21b37b5cd7bdc"
|
||||
|
||||
SRC_URI = "git://git.yoctoproject.org/linux-yocto.git;branch=${KBRANCH};name=machine \
|
||||
git://git.yoctoproject.org/yocto-kernel-cache;type=kmeta;name=meta;branch=yocto-5.15;destsuffix=${KMETA}"
|
||||
|
||||
LINUX_VERSION ?= "5.15.186"
|
||||
LINUX_VERSION ?= "5.15.194"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ KCONFIG_MODE = "--allnoconfig"
|
||||
|
||||
require recipes-kernel/linux/linux-yocto.inc
|
||||
|
||||
LINUX_VERSION ?= "5.15.186"
|
||||
LINUX_VERSION ?= "5.15.194"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"
|
||||
|
||||
DEPENDS += "${@bb.utils.contains('ARCH', 'x86', 'elfutils-native', '', d)}"
|
||||
@@ -14,8 +14,8 @@ DEPENDS += "openssl-native util-linux-native"
|
||||
KMETA = "kernel-meta"
|
||||
KCONF_BSP_AUDIT_LEVEL = "2"
|
||||
|
||||
SRCREV_machine ?= "4175c60a7b8e282d802be846bae75eeba398969e"
|
||||
SRCREV_meta ?= "5932fcfa6982f5b86a13849b84ef3d80a557a030"
|
||||
SRCREV_machine ?= "57960f78280a75ea48270a3984ac01bd06078b88"
|
||||
SRCREV_meta ?= "578937826ffad97749eba3a5d1b21b37b5cd7bdc"
|
||||
|
||||
PV = "${LINUX_VERSION}+git${SRCPV}"
|
||||
|
||||
|
||||
@@ -14,24 +14,24 @@ KBRANCH:qemux86 ?= "v5.15/standard/base"
|
||||
KBRANCH:qemux86-64 ?= "v5.15/standard/base"
|
||||
KBRANCH:qemumips64 ?= "v5.15/standard/mti-malta64"
|
||||
|
||||
SRCREV_machine:qemuarm ?= "d93c7fcf604b572bf93497e00017f9cf34fa34c7"
|
||||
SRCREV_machine:qemuarm64 ?= "9e9701d7239420165b342f3c363961ee3040a91e"
|
||||
SRCREV_machine:qemumips ?= "be5800a6d9002fd12668c0f8ada68ad7cab4398c"
|
||||
SRCREV_machine:qemuppc ?= "6fa52ff2eb31c6855f51a0d4f96339c50437d139"
|
||||
SRCREV_machine:qemuriscv64 ?= "48702d462c58d69b4b382bb34984f2f0881d0bb1"
|
||||
SRCREV_machine:qemuriscv32 ?= "48702d462c58d69b4b382bb34984f2f0881d0bb1"
|
||||
SRCREV_machine:qemux86 ?= "48702d462c58d69b4b382bb34984f2f0881d0bb1"
|
||||
SRCREV_machine:qemux86-64 ?= "48702d462c58d69b4b382bb34984f2f0881d0bb1"
|
||||
SRCREV_machine:qemumips64 ?= "bb909213f7e13fd17e39d95e5d1b646a7b0bacf2"
|
||||
SRCREV_machine ?= "48702d462c58d69b4b382bb34984f2f0881d0bb1"
|
||||
SRCREV_meta ?= "5932fcfa6982f5b86a13849b84ef3d80a557a030"
|
||||
SRCREV_machine:qemuarm ?= "7b19f872b07703f73c494baa81cd7e984db01336"
|
||||
SRCREV_machine:qemuarm64 ?= "431a37a229ce5be7b6ba116dc7bd282be4a745fa"
|
||||
SRCREV_machine:qemumips ?= "9404d4015b457e7324d5675d3e14f46d84cd8c40"
|
||||
SRCREV_machine:qemuppc ?= "bfd132d4b358cdb5260fccc71eb1e5a09daae033"
|
||||
SRCREV_machine:qemuriscv64 ?= "5df8e23ccadd62ab9945320b6b4327b082870c61"
|
||||
SRCREV_machine:qemuriscv32 ?= "5df8e23ccadd62ab9945320b6b4327b082870c61"
|
||||
SRCREV_machine:qemux86 ?= "5df8e23ccadd62ab9945320b6b4327b082870c61"
|
||||
SRCREV_machine:qemux86-64 ?= "5df8e23ccadd62ab9945320b6b4327b082870c61"
|
||||
SRCREV_machine:qemumips64 ?= "ed52c5eccf0cc2b0da2dd7d13d012c50db78a62a"
|
||||
SRCREV_machine ?= "5df8e23ccadd62ab9945320b6b4327b082870c61"
|
||||
SRCREV_meta ?= "578937826ffad97749eba3a5d1b21b37b5cd7bdc"
|
||||
|
||||
# set your preferred provider of linux-yocto to 'linux-yocto-upstream', and you'll
|
||||
# get the <version>/base branch, which is pure upstream -stable, and the same
|
||||
# meta SRCREV as the linux-yocto-standard builds. Select your version using the
|
||||
# normal PREFERRED_VERSION settings.
|
||||
BBCLASSEXTEND = "devupstream:target"
|
||||
SRCREV_machine:class-devupstream ?= "1c700860e8bc079c5c71d73c55e51865d273943c"
|
||||
SRCREV_machine:class-devupstream ?= "29e53a5b1c4f144301ee36a907e8b03d7733f0b0"
|
||||
PN:class-devupstream = "linux-yocto-upstream"
|
||||
KBRANCH:class-devupstream = "v5.15/base"
|
||||
|
||||
@@ -39,7 +39,7 @@ SRC_URI = "git://git.yoctoproject.org/linux-yocto.git;name=machine;branch=${KBRA
|
||||
git://git.yoctoproject.org/yocto-kernel-cache;type=kmeta;name=meta;branch=yocto-5.15;destsuffix=${KMETA}"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=6bc538ed5bd9a7fc9398086aedcd7e46"
|
||||
LINUX_VERSION ?= "5.15.186"
|
||||
LINUX_VERSION ?= "5.15.194"
|
||||
|
||||
DEPENDS += "${@bb.utils.contains('ARCH', 'x86', 'elfutils-native', '', d)}"
|
||||
DEPENDS += "openssl-native util-linux-native"
|
||||
|
||||
@@ -21,7 +21,7 @@ Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
|
||||
(cherry picked from commit 91d96dc8ddaebe0b6cb393f672085e6bfaf15a31)
|
||||
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
|
||||
|
||||
CVE: CVE-2023-6602 CVE-2023-6604 CVE-2023-6605
|
||||
CVE: CVE-2023-6601 CVE-2023-6602 CVE-2023-6604 CVE-2023-6605
|
||||
|
||||
Upstream-Status: Backport [https://github.com/FFmpeg/FFmpeg/commit/9803800e0e8cd8e1e7695f77cfbf4e0db0abfe57]
|
||||
|
||||
|
||||
@@ -101,6 +101,10 @@ CVE_CHECK_IGNORE += "CVE-2022-3109"
|
||||
# bugfix: https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/481e81be1271ac9a0124ee615700390c2371bd89
|
||||
CVE_CHECK_IGNORE += "CVE-2022-3341"
|
||||
|
||||
# This vulnerability was fixed in 5.0
|
||||
# bugfix: https://github.com/FFmpeg/FFmpeg/commit/28c83584e8f3cd747c1476a74cc2841d3d1fa7f3
|
||||
CVE_CHECK_IGNORE += "CVE-2023-6603"
|
||||
|
||||
# Build fails when thumb is enabled: https://bugzilla.yoctoproject.org/show_bug.cgi?id=7717
|
||||
ARM_INSTRUCTION_SET:armv4 = "arm"
|
||||
ARM_INSTRUCTION_SET:armv5 = "arm"
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From 5463f0e09768ca90aa8c58357c1f4c645db580db Mon Sep 17 00:00:00 2001
|
||||
From: Seungha Yang <seungha@centricular.com>
|
||||
Date: Sat, 15 Mar 2025 22:39:44 +0900
|
||||
Subject: [PATCH 1/2] h265parser: Fix max_dec_pic_buffering_minus1 bound check
|
||||
|
||||
Allowed max value is MaxDpbSize - 1
|
||||
|
||||
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8885>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/5463f0e09768ca90aa8c58357c1f4c645db580db]
|
||||
CVE: CVE-2025-3887
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
gst-libs/gst/codecparsers/gsth265parser.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c
|
||||
index 3db1c38..d02e32d 100644
|
||||
--- a/gst-libs/gst/codecparsers/gsth265parser.c
|
||||
+++ b/gst-libs/gst/codecparsers/gsth265parser.c
|
||||
@@ -72,6 +72,8 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
+#define MAX_DPB_SIZE 16
|
||||
+
|
||||
#ifndef GST_DISABLE_GST_DEBUG
|
||||
#define GST_CAT_DEFAULT gst_h265_debug_category_get()
|
||||
static GstDebugCategory *
|
||||
@@ -1686,7 +1688,7 @@ gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps)
|
||||
for (i =
|
||||
(vps->sub_layer_ordering_info_present_flag ? 0 :
|
||||
vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) {
|
||||
- READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1);
|
||||
+ READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], MAX_DPB_SIZE - 1);
|
||||
READ_UE_MAX (&nr, vps->max_num_reorder_pics[i],
|
||||
vps->max_dec_pic_buffering_minus1[i]);
|
||||
READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
|
||||
@@ -1882,7 +1884,7 @@ gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu,
|
||||
for (i =
|
||||
(sps->sub_layer_ordering_info_present_flag ? 0 :
|
||||
sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) {
|
||||
- READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16);
|
||||
+ READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], MAX_DPB_SIZE - 1);
|
||||
READ_UE_MAX (&nr, sps->max_num_reorder_pics[i],
|
||||
sps->max_dec_pic_buffering_minus1[i]);
|
||||
READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1);
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
From bcaab3609805ea10fb3d9ac0c9d947b4c3563948 Mon Sep 17 00:00:00 2001
|
||||
From: Seungha Yang <seungha@centricular.com>
|
||||
Date: Sat, 15 Mar 2025 23:48:52 +0900
|
||||
Subject: [PATCH 2/2] h265parser: Fix num_long_term_pics bound check
|
||||
|
||||
As defined in the spec 7.4.7.1, calculates allowed maximum
|
||||
value of num_long_term_pics
|
||||
|
||||
Fixes ZDI-CAN-26596
|
||||
|
||||
Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/4285
|
||||
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8885>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/gstreamer/gstreamer/-/commit/bcaab3609805ea10fb3d9ac0c9d947b4c3563948]
|
||||
CVE: CVE-2025-3887
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
gst-libs/gst/codecparsers/gsth265parser.c | 40 +++++++++++++++++++++--
|
||||
1 file changed, 37 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c
|
||||
index d02e32d..ad9751f 100644
|
||||
--- a/gst-libs/gst/codecparsers/gsth265parser.c
|
||||
+++ b/gst-libs/gst/codecparsers/gsth265parser.c
|
||||
@@ -2513,6 +2513,8 @@ gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
|
||||
READ_UINT8 (&nr, slice->colour_plane_id, 2);
|
||||
|
||||
if (!GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
|
||||
+ const GstH265ShortTermRefPicSet *ref_pic_sets = NULL;
|
||||
+
|
||||
READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
|
||||
(sps->log2_max_pic_order_cnt_lsb_minus4 + 4));
|
||||
|
||||
@@ -2525,21 +2527,53 @@ gst_h265_parser_parse_slice_hdr (GstH265Parser * parser,
|
||||
goto error;
|
||||
|
||||
slice->short_term_ref_pic_set_size = nal_reader_get_pos (&nr) - pos;
|
||||
+
|
||||
+ ref_pic_sets = &slice->short_term_ref_pic_sets;
|
||||
} else if (sps->num_short_term_ref_pic_sets > 1) {
|
||||
const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets);
|
||||
READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n);
|
||||
CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx,
|
||||
sps->num_short_term_ref_pic_sets - 1);
|
||||
+ ref_pic_sets =
|
||||
+ &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx];
|
||||
+ } else {
|
||||
+ ref_pic_sets = &sps->short_term_ref_pic_set[0];
|
||||
}
|
||||
|
||||
if (sps->long_term_ref_pics_present_flag) {
|
||||
guint32 limit;
|
||||
+ gint max_num_long_term_pics = 0;
|
||||
+ gint TwoVersionsOfCurrDecPicFlag = 0;
|
||||
|
||||
- if (sps->num_long_term_ref_pics_sps > 0)
|
||||
+ if (sps->num_long_term_ref_pics_sps > 0) {
|
||||
READ_UE_MAX (&nr, slice->num_long_term_sps,
|
||||
sps->num_long_term_ref_pics_sps);
|
||||
-
|
||||
- READ_UE_MAX (&nr, slice->num_long_term_pics, 16);
|
||||
+ }
|
||||
+
|
||||
+ /* 7.4.3.3.3 */
|
||||
+ if (pps->pps_scc_extension_flag &&
|
||||
+ pps->pps_scc_extension_params.pps_curr_pic_ref_enabled_flag &&
|
||||
+ (sps->sample_adaptive_offset_enabled_flag ||
|
||||
+ !pps->deblocking_filter_disabled_flag ||
|
||||
+ pps->deblocking_filter_override_enabled_flag)) {
|
||||
+ TwoVersionsOfCurrDecPicFlag = 1;
|
||||
+ }
|
||||
+
|
||||
+ /* Calculated upper bound num_long_term_pics can have. 7.4.7.1 */
|
||||
+ max_num_long_term_pics =
|
||||
+ /* sps_max_dec_pic_buffering_minus1[TemporalId], allowed max is
|
||||
+ * MaxDpbSize - 1 */
|
||||
+ MAX_DPB_SIZE - 1
|
||||
+ - (gint) slice->num_long_term_sps
|
||||
+ - (gint) ref_pic_sets->NumNegativePics
|
||||
+ - (gint) ref_pic_sets->NumPositivePics -
|
||||
+ TwoVersionsOfCurrDecPicFlag;
|
||||
+ if (max_num_long_term_pics < 0) {
|
||||
+ GST_WARNING ("Invalid stream, too many reference pictures");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ READ_UE_MAX (&nr, slice->num_long_term_pics, max_num_long_term_pics);
|
||||
limit = slice->num_long_term_sps + slice->num_long_term_pics;
|
||||
for (i = 0; i < limit; i++) {
|
||||
if (i < slice->num_long_term_sps) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -17,6 +17,8 @@ SRC_URI = "https://gstreamer.freedesktop.org/src/gst-plugins-bad/gst-plugins-bad
|
||||
file://CVE-2024-0444.patch \
|
||||
file://CVE-2023-44446.patch \
|
||||
file://CVE-2023-50186.patch \
|
||||
file://CVE-2025-3887-1.patch \
|
||||
file://CVE-2025-3887-2.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "87251beebfd1325e5118cc67774061f6e8971761ca65a9e5957919610080d195"
|
||||
|
||||
|
||||
@@ -71,15 +71,24 @@ FILES:${PN}-dbg += "${datadir}/gdb ${datadir}/gstreamer-1.0/gdb"
|
||||
CVE_PRODUCT = "gstreamer"
|
||||
|
||||
# these CVEs are patched in gstreamer1.0-plugins-bad
|
||||
CVE_CHECK_IGNORE += "CVE-2023-40474 CVE-2023-40475 CVE-2023-40476 CVE-2023-44429 CVE-2023-44446 CVE-2023-50186 CVE-2024-0444"
|
||||
CVE_CHECK_IGNORE += "\
|
||||
CVE-2023-40474 CVE-2023-40475 CVE-2023-40476 CVE-2023-44429 CVE-2023-44446 CVE-2023-50186 CVE-2024-0444 \
|
||||
CVE-2025-3887 \
|
||||
"
|
||||
# these CVEs are patched in gstreamer1.0-plugins-base
|
||||
CVE_CHECK_IGNORE += "CVE-2024-47538 CVE-2024-47541 CVE-2024-47542 CVE-2024-47600 CVE-2024-47607 CVE-2024-47615 CVE-2024-47835"
|
||||
CVE_CHECK_IGNORE += " \
|
||||
CVE-2024-47538 CVE-2024-47541 CVE-2024-47542 CVE-2024-47600 CVE-2024-47607 CVE-2024-47615 CVE-2024-47835 \
|
||||
CVE-2025-47806 CVE-2025-47807 CVE-2025-47808 \
|
||||
"
|
||||
# these CVEs are patched in gstreamer1.0-plugins-good
|
||||
CVE_CHECK_IGNORE += " \
|
||||
CVE-2024-47537 CVE-2024-47539 CVE-2024-47540 CVE-2024-47543 CVE-2024-47544 CVE-2024-47545 \
|
||||
CVE-2024-47546 CVE-2024-47596 CVE-2024-47597 CVE-2024-47598 CVE-2024-47599 CVE-2024-47601 \
|
||||
CVE-2024-47602 CVE-2024-47603 CVE-2024-47613 CVE-2024-47774 CVE-2024-47775 CVE-2024-47776 \
|
||||
CVE-2024-47777 CVE-2024-47778 CVE-2024-47834 \
|
||||
CVE-2024-47777 CVE-2024-47778 CVE-2024-47834 CVE-2025-47183 CVE-2025-47219 \
|
||||
"
|
||||
|
||||
# not-applicable-platform: affects installation packages for non Linux OSes
|
||||
CVE_CHECK_IGNORE += "CVE-2025-2759"
|
||||
|
||||
PTEST_BUILD_HOST_FILES = ""
|
||||
|
||||
74
meta/recipes-multimedia/libtiff/tiff/CVE-2025-8961.patch
Normal file
74
meta/recipes-multimedia/libtiff/tiff/CVE-2025-8961.patch
Normal file
@@ -0,0 +1,74 @@
|
||||
From 0ac97aa7a5bffddd88f7cdbe517264e9db3f5bd5 Mon Sep 17 00:00:00 2001
|
||||
From: Lee Howard <faxguy@howardsilvan.com>
|
||||
Date: Fri, 5 Sep 2025 21:42:35 +0000
|
||||
Subject: [PATCH] tiffcrop: fix double-free and memory leak exposed by issue
|
||||
#721
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/0ac97aa7a5bffddd88f7cdbe517264e9db3f5bd5]
|
||||
CVE: CVE-2025-8961
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
tools/tiffcrop.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/tiffcrop.c b/tools/tiffcrop.c
|
||||
index e16bc2d..c7d2553 100644
|
||||
--- a/tools/tiffcrop.c
|
||||
+++ b/tools/tiffcrop.c
|
||||
@@ -929,6 +929,7 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8_t* buf,
|
||||
TIFFError("readContigTilesIntoBuffer",
|
||||
"Unable to extract row %"PRIu32" from tile %"PRIu32,
|
||||
row, TIFFCurrentTile(in));
|
||||
+ _TIFFfree(tilebuf);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -943,6 +944,7 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8_t* buf,
|
||||
TIFFError("readContigTilesIntoBuffer",
|
||||
"Unable to extract row %"PRIu32" from tile %"PRIu32,
|
||||
row, TIFFCurrentTile(in));
|
||||
+ _TIFFfree(tilebuf);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -957,6 +959,7 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8_t* buf,
|
||||
TIFFError("readContigTilesIntoBuffer",
|
||||
"Unable to extract row %"PRIu32" from tile %"PRIu32,
|
||||
row, TIFFCurrentTile(in));
|
||||
+ _TIFFfree(tilebuf);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -969,6 +972,7 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8_t* buf,
|
||||
TIFFError("readContigTilesIntoBuffer",
|
||||
"Unable to extract row %"PRIu32" from tile %"PRIu32,
|
||||
row, TIFFCurrentTile(in));
|
||||
+ _TIFFfree(tilebuf);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
@@ -983,10 +987,12 @@ static int readContigTilesIntoBuffer (TIFF* in, uint8_t* buf,
|
||||
TIFFError("readContigTilesIntoBuffer",
|
||||
"Unable to extract row %"PRIu32" from tile %"PRIu32,
|
||||
row, TIFFCurrentTile(in));
|
||||
+ _TIFFfree(tilebuf);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default: TIFFError("readContigTilesIntoBuffer", "Unsupported bit depth %"PRIu16, bps);
|
||||
+ _TIFFfree(tilebuf);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -2535,7 +2541,7 @@ main(int argc, char* argv[])
|
||||
}
|
||||
|
||||
/* If we did not use the read buffer as the crop buffer */
|
||||
- if (read_buff)
|
||||
+ if (read_buff && read_buff != crop_buff)
|
||||
_TIFFfree(read_buff);
|
||||
|
||||
if (crop_buff)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
32
meta/recipes-multimedia/libtiff/tiff/CVE-2025-9165.patch
Normal file
32
meta/recipes-multimedia/libtiff/tiff/CVE-2025-9165.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From ed141286a37f6e5ddafb5069347ff5d587e7a4e0 Mon Sep 17 00:00:00 2001
|
||||
From: Su_Laus <sulau@freenet.de>
|
||||
Date: Fri, 8 Aug 2025 21:35:30 +0200
|
||||
Subject: [PATCH] tiffcmp: fix memory leak when second file cannot be opened.
|
||||
|
||||
Closes #728, #729
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/ed141286a37f6e5ddafb5069347ff5d587e7a4e0]
|
||||
CVE: CVE-2025-9165
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
tools/tiffcmp.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/tools/tiffcmp.c b/tools/tiffcmp.c
|
||||
index 2a35fe6..f812c7d 100644
|
||||
--- a/tools/tiffcmp.c
|
||||
+++ b/tools/tiffcmp.c
|
||||
@@ -103,7 +103,10 @@ main(int argc, char* argv[])
|
||||
return (2);
|
||||
tif2 = TIFFOpen(argv[optind+1], "r");
|
||||
if (tif2 == NULL)
|
||||
+ {
|
||||
+ TIFFClose(tif1);
|
||||
return (2);
|
||||
+ }
|
||||
dirnum = 0;
|
||||
while (tiffcmp(tif1, tif2)) {
|
||||
if (!TIFFReadDirectory(tif1)) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
57
meta/recipes-multimedia/libtiff/tiff/CVE-2025-9900.patch
Normal file
57
meta/recipes-multimedia/libtiff/tiff/CVE-2025-9900.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From 3e0dcf0ec651638b2bd849b2e6f3124b36890d99 Mon Sep 17 00:00:00 2001
|
||||
From: Su Laus <sulau@freenet.de>
|
||||
Date: Wed, 11 Jun 2025 19:45:19 +0000
|
||||
Subject: [PATCH] tif_getimage.c: Fix buffer underflow crash for less raster
|
||||
rows at TIFFReadRGBAImageOriented()
|
||||
|
||||
CVE: CVE-2025-9900
|
||||
Upstream-Status: Backport [https://gitlab.com/libtiff/libtiff/-/commit/3e0dcf0ec651638b2bd849b2e6f3124b36890d99]
|
||||
|
||||
Changes-
|
||||
- Use old API TIFFWarningExt instead of TIFFWarningExtR.
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
libtiff/tif_getimage.c | 20 +++++++++++++++++---
|
||||
1 file changed, 17 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libtiff/tif_getimage.c b/libtiff/tif_getimage.c
|
||||
index a9cd48f..4c807ad 100644
|
||||
--- a/libtiff/tif_getimage.c
|
||||
+++ b/libtiff/tif_getimage.c
|
||||
@@ -509,6 +509,22 @@ TIFFRGBAImageGet(TIFFRGBAImage* img, uint32_t* raster, uint32_t w, uint32_t h)
|
||||
"No \"put\" routine setupl; probably can not handle image format");
|
||||
return (0);
|
||||
}
|
||||
+ /* Verify raster width and height against image width and height. */
|
||||
+ if (h > img->height)
|
||||
+ {
|
||||
+ /* Adapt parameters to read only available lines and put image at
|
||||
+ * the bottom of the raster. */
|
||||
+ raster += (size_t)(h - img->height) * w;
|
||||
+ h = img->height;
|
||||
+ }
|
||||
+ if (w > img->width)
|
||||
+ {
|
||||
+ TIFFWarningExt(img->tif, TIFFFileName(img->tif),
|
||||
+ "Raster width of %d shall not be larger than image "
|
||||
+ "width of %d -> raster width adapted for reading",
|
||||
+ w, img->width);
|
||||
+ w = img->width;
|
||||
+ }
|
||||
return (*img->get)(img, raster, w, h);
|
||||
}
|
||||
|
||||
@@ -527,9 +543,7 @@ TIFFReadRGBAImageOriented(TIFF* tif,
|
||||
|
||||
if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
|
||||
img.req_orientation = (uint16_t)orientation;
|
||||
- /* XXX verify rwidth and rheight against width and height */
|
||||
- ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
|
||||
- rwidth, img.height);
|
||||
+ ok = TIFFRGBAImageGet(&img, raster, rwidth, rheight);
|
||||
TIFFRGBAImageEnd(&img);
|
||||
} else {
|
||||
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
|
||||
--
|
||||
2.40.0
|
||||
@@ -62,6 +62,9 @@ SRC_URI = "http://download.osgeo.org/libtiff/tiff-${PV}.tar.gz \
|
||||
file://CVE-2024-13978.patch \
|
||||
file://CVE-2025-8534.patch \
|
||||
file://CVE-2025-8851.patch \
|
||||
file://CVE-2025-9900.patch \
|
||||
file://CVE-2025-8961.patch \
|
||||
file://CVE-2025-9165.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "0e46e5acb087ce7d1ac53cf4f56a09b221537fc86dfc5daaad1c2e89e1b37ac8"
|
||||
|
||||
@@ -281,3 +281,6 @@ RDEPENDS:pulseaudio-server += "\
|
||||
RDEPENDS:pulseaudio-server += "${@bb.utils.contains('DISTRO_FEATURES', 'x11', \
|
||||
bb.utils.contains('DISTRO_FEATURES', 'systemd', 'pulseaudio-module-systemd-login', 'pulseaudio-module-console-kit', d), \
|
||||
'', d)}"
|
||||
|
||||
# not-applicable-platform: specific to Ubuntu 16.04
|
||||
CVE_CHECK_IGNORE += "CVE-2024-11586"
|
||||
|
||||
55
meta/recipes-support/curl/curl/CVE-2025-9086.patch
Normal file
55
meta/recipes-support/curl/curl/CVE-2025-9086.patch
Normal file
@@ -0,0 +1,55 @@
|
||||
From c6ae07c6a541e0e96d0040afb62b45dd37711300 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
Date: Mon, 11 Aug 2025 20:23:05 +0200
|
||||
Subject: [PATCH] cookie: don't treat the leading slash as trailing
|
||||
|
||||
If there is only a leading slash in the path, keep that. Also add an
|
||||
assert to make sure the path is never blank.
|
||||
|
||||
Reported-by: Google Big Sleep
|
||||
Closes #18266
|
||||
|
||||
CVE: CVE-2025-9086
|
||||
Upstream-Status: Backport [https://github.com/curl/curl/commit/c6ae07c6a541e0e96d0040afb6]
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
lib/cookie.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/cookie.c b/lib/cookie.c
|
||||
index e287458..ac7d3de 100644
|
||||
--- a/lib/cookie.c
|
||||
+++ b/lib/cookie.c
|
||||
@@ -312,7 +312,7 @@ static char *sanitize_cookie_path(const char *cookie_path)
|
||||
}
|
||||
|
||||
/* convert /hoge/ to /hoge */
|
||||
- if(len && new_path[len - 1] == '/') {
|
||||
+ if(len > 1 && new_path[len - 1] == '/') {
|
||||
new_path[len - 1] = 0x0;
|
||||
}
|
||||
|
||||
@@ -1078,7 +1078,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
if(clist->spath && co->spath) {
|
||||
if(clist->secure && !co->secure && !secure) {
|
||||
size_t cllen;
|
||||
- const char *sep;
|
||||
+ const char *sep = NULL;
|
||||
|
||||
/*
|
||||
* A non-secure cookie may not overlay an existing secure cookie.
|
||||
@@ -1087,8 +1087,9 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||
* "/loginhelper" is ok.
|
||||
*/
|
||||
|
||||
- sep = strchr(clist->spath + 1, '/');
|
||||
-
|
||||
+ DEBUGASSERT(clist->spath[0]);
|
||||
+ if(clist->spath[0])
|
||||
+ sep = strchr(clist->spath + 1, '/');
|
||||
if(sep)
|
||||
cllen = sep - clist->spath;
|
||||
else
|
||||
--
|
||||
2.40.0
|
||||
@@ -66,6 +66,7 @@ SRC_URI = "https://curl.se/download/${BP}.tar.xz \
|
||||
file://CVE-2024-11053-0001.patch \
|
||||
file://CVE-2024-11053-0002.patch \
|
||||
file://CVE-2025-0167.patch \
|
||||
file://CVE-2025-9086.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c"
|
||||
|
||||
|
||||
105
meta/recipes-support/libxslt/libxslt/CVE-2025-7424.patch
Normal file
105
meta/recipes-support/libxslt/libxslt/CVE-2025-7424.patch
Normal file
@@ -0,0 +1,105 @@
|
||||
From 345d6826d0eae6f0a962456b8ed6f6a1bad0877d Mon Sep 17 00:00:00 2001
|
||||
From: David Kilzer <ddkilzer@apple.com>
|
||||
Date: Sat, 24 May 2025 15:06:42 -0700
|
||||
Subject: [PATCH] libxslt: Type confusion in xmlNode.psvi between stylesheet
|
||||
and source nodes
|
||||
|
||||
* libxslt/functions.c:
|
||||
(xsltDocumentFunctionLoadDocument):
|
||||
- Implement fix suggested by Ivan Fratric. This copies the xmlDoc,
|
||||
calls xsltCleanupSourceDoc() to remove pvsi fields, then adds the
|
||||
xmlDoc to tctxt->docList.
|
||||
- Add error handling for functions that may return NULL.
|
||||
* libxslt/transform.c:
|
||||
- Remove static keyword so this can be called from
|
||||
xsltDocumentFunctionLoadDocument().
|
||||
* libxslt/transformInternals.h: Add.
|
||||
(xsltCleanupSourceDoc): Add declaration.
|
||||
|
||||
Fixes #139.
|
||||
|
||||
Origin: https://gitlab.gnome.org/-/project/1762/uploads/627ae84cb0643d9adf6e5c86947f6be6/gnome-libxslt-bug-139-apple-fix.diff
|
||||
|
||||
Upstream-Status: Submitted [https://gitlab.gnome.org/GNOME/libxslt/-/issues/139]
|
||||
CVE: CVE-2025-7424
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
libxslt/functions.c | 16 +++++++++++++++-
|
||||
libxslt/transform.c | 3 ++-
|
||||
libxslt/transformInternals.h | 9 +++++++++
|
||||
3 files changed, 26 insertions(+), 2 deletions(-)
|
||||
create mode 100644 libxslt/transformInternals.h
|
||||
|
||||
diff --git a/libxslt/functions.c b/libxslt/functions.c
|
||||
index da25c24..8a9bdc2 100644
|
||||
--- a/libxslt/functions.c
|
||||
+++ b/libxslt/functions.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "numbersInternals.h"
|
||||
#include "keys.h"
|
||||
#include "documents.h"
|
||||
+#include "transformInternals.h"
|
||||
|
||||
#ifdef WITH_XSLT_DEBUG
|
||||
#define WITH_XSLT_DEBUG_FUNCTION
|
||||
@@ -152,7 +153,20 @@ xsltDocumentFunctionLoadDocument(xmlXPathParserContextPtr ctxt, xmlChar* URI)
|
||||
/*
|
||||
* This selects the stylesheet's doc itself.
|
||||
*/
|
||||
- doc = tctxt->style->doc;
|
||||
+ doc = xmlCopyDoc(tctxt->style->doc, 1);
|
||||
+ if (doc == NULL) {
|
||||
+ xsltTransformError(tctxt, NULL, NULL,
|
||||
+ "document() : failed to copy style doc\n");
|
||||
+ goto out_fragment;
|
||||
+ }
|
||||
+ xsltCleanupSourceDoc(doc); /* Remove psvi fields. */
|
||||
+ idoc = xsltNewDocument(tctxt, doc);
|
||||
+ if (idoc == NULL) {
|
||||
+ xsltTransformError(tctxt, NULL, NULL,
|
||||
+ "document() : failed to create xsltDocument\n");
|
||||
+ xmlFreeDoc(doc);
|
||||
+ goto out_fragment;
|
||||
+ }
|
||||
} else {
|
||||
valuePush(ctxt, xmlXPathNewNodeSet(NULL));
|
||||
|
||||
diff --git a/libxslt/transform.c b/libxslt/transform.c
|
||||
index 7299eb5..6976a04 100644
|
||||
--- a/libxslt/transform.c
|
||||
+++ b/libxslt/transform.c
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "xsltutils.h"
|
||||
#include "pattern.h"
|
||||
#include "transform.h"
|
||||
+#include "transformInternals.h"
|
||||
#include "variables.h"
|
||||
#include "numbersInternals.h"
|
||||
#include "namespaces.h"
|
||||
@@ -5753,7 +5754,7 @@ xsltCountKeys(xsltTransformContextPtr ctxt)
|
||||
*
|
||||
* Resets source node flags and ids stored in 'psvi' member.
|
||||
*/
|
||||
-static void
|
||||
+void
|
||||
xsltCleanupSourceDoc(xmlDocPtr doc) {
|
||||
xmlNodePtr cur = (xmlNodePtr) doc;
|
||||
void **psviPtr;
|
||||
diff --git a/libxslt/transformInternals.h b/libxslt/transformInternals.h
|
||||
new file mode 100644
|
||||
index 0000000..d0f4282
|
||||
--- /dev/null
|
||||
+++ b/libxslt/transformInternals.h
|
||||
@@ -0,0 +1,9 @@
|
||||
+/*
|
||||
+ * Summary: set of internal interfaces for the XSLT engine transformation part.
|
||||
+ *
|
||||
+ * Copy: See Copyright for the status of this software.
|
||||
+ *
|
||||
+ * Author: David Kilzer <ddkilzer@apple.com>
|
||||
+ */
|
||||
+
|
||||
+void xsltCleanupSourceDoc(xmlDocPtr doc);
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -21,6 +21,7 @@ SRC_URI = "https://download.gnome.org/sources/libxslt/1.1/libxslt-${PV}.tar.xz \
|
||||
file://CVE-2023-40403-003.patch \
|
||||
file://CVE-2023-40403-004.patch \
|
||||
file://CVE-2023-40403-005.patch \
|
||||
file://CVE-2025-7424.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "8247f33e9a872c6ac859aa45018bc4c4d00b97e2feac9eebc10c93ce1f34dd79"
|
||||
|
||||
69
meta/recipes-support/lz4/files/CVE-2025-62813.patch
Normal file
69
meta/recipes-support/lz4/files/CVE-2025-62813.patch
Normal file
@@ -0,0 +1,69 @@
|
||||
From f64efec011c058bd70348576438abac222fe6c82 Mon Sep 17 00:00:00 2001
|
||||
From: louislafosse <louis.lafosse@epitech.eu>
|
||||
Date: Mon, 31 Mar 2025 20:48:52 +0200
|
||||
Subject: [PATCH] fix(null) : improve error handlings when passing a null
|
||||
pointer to some functions from lz4frame
|
||||
|
||||
CVE: CVE-2025-62813
|
||||
Upstream-Status: Backport [https://github.com/lz4/lz4/commit/f64efec011c058bd70348576438abac222fe6c82]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
lib/lz4frame.c | 15 +++++++++++++--
|
||||
tests/frametest.c | 9 ++++++---
|
||||
2 files changed, 19 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/lib/lz4frame.c b/lib/lz4frame.c
|
||||
index 85daca7b..c9e4a3cf 100644
|
||||
--- a/lib/lz4frame.c
|
||||
+++ b/lib/lz4frame.c
|
||||
@@ -530,9 +530,16 @@ LZ4F_CDict*
|
||||
LZ4F_createCDict_advanced(LZ4F_CustomMem cmem, const void* dictBuffer, size_t dictSize)
|
||||
{
|
||||
const char* dictStart = (const char*)dictBuffer;
|
||||
- LZ4F_CDict* const cdict = (LZ4F_CDict*)LZ4F_malloc(sizeof(*cdict), cmem);
|
||||
+ LZ4F_CDict* cdict = NULL;
|
||||
+
|
||||
DEBUGLOG(4, "LZ4F_createCDict_advanced");
|
||||
- if (!cdict) return NULL;
|
||||
+
|
||||
+ if (!dictStart)
|
||||
+ return NULL;
|
||||
+ cdict = (LZ4F_CDict*)LZ4F_malloc(sizeof(*cdict), cmem);
|
||||
+ if (!cdict)
|
||||
+ return NULL;
|
||||
+
|
||||
cdict->cmem = cmem;
|
||||
if (dictSize > 64 KB) {
|
||||
dictStart += dictSize - 64 KB;
|
||||
@@ -1429,6 +1436,10 @@ LZ4F_errorCode_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
|
||||
LZ4F_frameInfo_t* frameInfoPtr,
|
||||
const void* srcBuffer, size_t* srcSizePtr)
|
||||
{
|
||||
+ assert(dctx != NULL);
|
||||
+ RETURN_ERROR_IF(frameInfoPtr == NULL, parameter_null);
|
||||
+ RETURN_ERROR_IF(srcSizePtr == NULL, parameter_null);
|
||||
+
|
||||
LZ4F_STATIC_ASSERT(dstage_getFrameHeader < dstage_storeFrameHeader);
|
||||
if (dctx->dStage > dstage_storeFrameHeader) {
|
||||
/* frameInfo already decoded */
|
||||
diff --git a/tests/frametest.c b/tests/frametest.c
|
||||
index de0fe643..90247547 100644
|
||||
--- a/tests/frametest.c
|
||||
+++ b/tests/frametest.c
|
||||
@@ -589,10 +589,13 @@ int basicTests(U32 seed, double compressibility)
|
||||
size_t const srcSize = 65 KB; /* must be > 64 KB to avoid short-size optimizations */
|
||||
size_t const dstCapacity = LZ4F_compressFrameBound(srcSize, NULL);
|
||||
size_t cSizeNoDict, cSizeWithDict;
|
||||
- LZ4F_CDict* const cdict = LZ4F_createCDict(CNBuffer, dictSize);
|
||||
- if (cdict == NULL) goto _output_error;
|
||||
- CHECK( LZ4F_createCompressionContext(&cctx, LZ4F_VERSION) );
|
||||
+ LZ4F_CDict* cdict = NULL;
|
||||
|
||||
+ CHECK( LZ4F_createCompressionContext(&cctx, LZ4F_VERSION) );
|
||||
+ cdict = LZ4F_createCDict(CNBuffer, dictSize);
|
||||
+ if (cdict == NULL)
|
||||
+ goto _output_error;
|
||||
+
|
||||
DISPLAYLEVEL(3, "Testing LZ4F_createCDict_advanced : ");
|
||||
{ LZ4F_CDict* const cda = LZ4F_createCDict_advanced(lz4f_cmem_test, CNBuffer, dictSize);
|
||||
if (cda == NULL) goto _output_error;
|
||||
@@ -12,7 +12,9 @@ PE = "1"
|
||||
|
||||
SRCREV = "5ff839680134437dbf4678f3d0c7b371d84f4964"
|
||||
|
||||
SRC_URI = "git://github.com/lz4/lz4.git;branch=release;protocol=https"
|
||||
SRC_URI = "git://github.com/lz4/lz4.git;branch=release;protocol=https \
|
||||
file://CVE-2025-62813.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_GITTAGREGEX = "v(?P<pver>.*)"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
@@ -18,6 +18,7 @@ PACKAGECONFIG ??= ""
|
||||
PACKAGECONFIG[manpages] = "-Dman=true,-Dman=false,libxslt-native"
|
||||
PACKAGECONFIG[trust-paths] = "-Dtrust_paths=/etc/ssl/certs/ca-certificates.crt,,,ca-certificates"
|
||||
|
||||
EXTRA_OEMESON:append = " -Dnls=${@'false' if d.getVar('USE_NLS') == 'no' else 'true'}"
|
||||
GTKDOC_MESON_OPTION = 'gtk_doc'
|
||||
|
||||
FILES:${PN} += " \
|
||||
|
||||
@@ -18,8 +18,8 @@ SRC_URI = "git://github.com/vim/vim.git;branch=master;protocol=https \
|
||||
file://no-path-adjust.patch \
|
||||
"
|
||||
|
||||
PV .= ".1652"
|
||||
SRCREV = "3e152c76adb9542af86760786d42a0beffe5354b"
|
||||
PV .= ".1683"
|
||||
SRCREV = "b922b30cfe4c044c83bac3cc908084ed20a83598"
|
||||
|
||||
# Do not consider .z in x.y.z, as that is updated with every commit
|
||||
UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+\.\d+)\.0"
|
||||
|
||||
@@ -57,8 +57,8 @@ logger = scriptutils.logger_create(PROGNAME, stream=sys.stdout)
|
||||
|
||||
DEFAULT_INSTALL_DIR = os.path.join(os.path.split(scripts_path)[0],'buildtools')
|
||||
DEFAULT_BASE_URL = 'https://downloads.yoctoproject.org/releases/yocto'
|
||||
DEFAULT_RELEASE = 'yocto-4.0.28'
|
||||
DEFAULT_INSTALLER_VERSION = '4.0.28'
|
||||
DEFAULT_RELEASE = 'yocto-4.0.30'
|
||||
DEFAULT_INSTALLER_VERSION = '4.0.30'
|
||||
DEFAULT_BUILDDATE = '202110XX'
|
||||
|
||||
# Python version sanity check
|
||||
|
||||
Reference in New Issue
Block a user