mirror of
https://git.yoctoproject.org/poky
synced 2026-02-20 08:29:42 +01:00
Compare commits
73 Commits
kirkstone-
...
kirkstone-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4cdc553814 | ||
|
|
940c885c23 | ||
|
|
3dd7b3edae | ||
|
|
62de516d0e | ||
|
|
630e7d6000 | ||
|
|
dd123d8eda | ||
|
|
bf6aca4b29 | ||
|
|
a952dec3e4 | ||
|
|
0ae3b2bd49 | ||
|
|
e9d17c4dee | ||
|
|
e318cce49c | ||
|
|
cada1f30e8 | ||
|
|
92cb089717 | ||
|
|
1f5be803ee | ||
|
|
da07e6ee34 | ||
|
|
2b5ca6638e | ||
|
|
2640cecd2f | ||
|
|
1c798dccd1 | ||
|
|
da71261344 | ||
|
|
784646063b | ||
|
|
0d356a401d | ||
|
|
48ef389f91 | ||
|
|
fbba5a616d | ||
|
|
54d061affe | ||
|
|
7db7a86fbc | ||
|
|
13707e4b1a | ||
|
|
cc7068b99a | ||
|
|
5bdf0b4c3a | ||
|
|
3be2b60b66 | ||
|
|
5c036f07cc | ||
|
|
52cfc78696 | ||
|
|
204b28c419 | ||
|
|
6313a595f9 | ||
|
|
25a9b7b70c | ||
|
|
bba60774f7 | ||
|
|
e932b53647 | ||
|
|
0dfb53c328 | ||
|
|
dd6669d720 | ||
|
|
7397fefc2f | ||
|
|
2ccf694440 | ||
|
|
7506cbff40 | ||
|
|
ae4a66db4b | ||
|
|
93ef091fb2 | ||
|
|
0405a3b4f3 | ||
|
|
2a6c675b9a | ||
|
|
e135227779 | ||
|
|
e781bf1095 | ||
|
|
322d4df8cb | ||
|
|
b1b94b434d | ||
|
|
67e1f5404c | ||
|
|
3242d8234d | ||
|
|
6d58d0c4a2 | ||
|
|
4bad38de6e | ||
|
|
6bd3969d32 | ||
|
|
75ff26ce99 | ||
|
|
be9285cbd9 | ||
|
|
945b58b5ba | ||
|
|
b5381de5ba | ||
|
|
979f68bad0 | ||
|
|
9170d3f0f3 | ||
|
|
14065a801b | ||
|
|
6635675a68 | ||
|
|
cbac0f1bfc | ||
|
|
7c5fc9fedc | ||
|
|
af50c9154c | ||
|
|
940a24ab8b | ||
|
|
14fe1f1319 | ||
|
|
52f1435174 | ||
|
|
064e000b18 | ||
|
|
e2366b9d09 | ||
|
|
f27a1997b6 | ||
|
|
35a517b7bd | ||
|
|
4374c6dfab |
@@ -261,12 +261,9 @@ class VariableHistory(object):
|
||||
return
|
||||
if 'op' not in loginfo or not loginfo['op']:
|
||||
loginfo['op'] = 'set'
|
||||
if 'detail' in loginfo:
|
||||
loginfo['detail'] = str(loginfo['detail'])
|
||||
if 'variable' not in loginfo or 'file' not in loginfo:
|
||||
raise ValueError("record() missing variable or file.")
|
||||
var = loginfo['variable']
|
||||
|
||||
if var not in self.variables:
|
||||
self.variables[var] = []
|
||||
if not isinstance(self.variables[var], list):
|
||||
@@ -325,7 +322,8 @@ class VariableHistory(object):
|
||||
flag = '[%s] ' % (event['flag'])
|
||||
else:
|
||||
flag = ''
|
||||
o.write("# %s %s:%s%s\n# %s\"%s\"\n" % (event['op'], event['file'], event['line'], display_func, flag, re.sub('\n', '\n# ', event['detail'])))
|
||||
o.write("# %s %s:%s%s\n# %s\"%s\"\n" % \
|
||||
(event['op'], event['file'], event['line'], display_func, flag, re.sub('\n', '\n# ', str(event['detail']))))
|
||||
if len(history) > 1:
|
||||
o.write("# pre-expansion value:\n")
|
||||
o.write('# "%s"\n' % (commentVal))
|
||||
@@ -379,7 +377,7 @@ class VariableHistory(object):
|
||||
if isset and event['op'] == 'set?':
|
||||
continue
|
||||
isset = True
|
||||
items = d.expand(event['detail']).split()
|
||||
items = d.expand(str(event['detail'])).split()
|
||||
for item in items:
|
||||
# This is a little crude but is belt-and-braces to avoid us
|
||||
# having to handle every possible operation type specifically
|
||||
|
||||
@@ -1335,7 +1335,7 @@ class FetchLatestVersionTest(FetcherTest):
|
||||
# combination version pattern
|
||||
("sysprof", "git://gitlab.gnome.org/GNOME/sysprof.git;protocol=https;branch=master", "cd44ee6644c3641507fb53b8a2a69137f2971219", "")
|
||||
: "1.2.0",
|
||||
("u-boot-mkimage", "git://git.denx.de/u-boot.git;branch=master;protocol=git", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "")
|
||||
("u-boot-mkimage", "git://source.denx.de/u-boot/u-boot.git;branch=master;protocol=https", "62c175fbb8a0f9a926c88294ea9f7e88eb898f6c", "")
|
||||
: "2014.01",
|
||||
# version pattern "yyyymmdd"
|
||||
("mobile-broadband-provider-info", "git://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git;protocol=https;branch=master", "4ed19e11c2975105b71b956440acdb25d46a347d", "")
|
||||
|
||||
@@ -25,3 +25,6 @@ Release 4.0 (kirkstone)
|
||||
release-notes-4.0.16
|
||||
release-notes-4.0.17
|
||||
release-notes-4.0.18
|
||||
release-notes-4.0.19
|
||||
release-notes-4.0.20
|
||||
|
||||
|
||||
159
documentation/migration-guides/release-notes-4.0.19.rst
Normal file
159
documentation/migration-guides/release-notes-4.0.19.rst
Normal file
File diff suppressed because one or more lines are too long
130
documentation/migration-guides/release-notes-4.0.20.rst
Normal file
130
documentation/migration-guides/release-notes-4.0.20.rst
Normal file
@@ -0,0 +1,130 @@
|
||||
.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
|
||||
|
||||
Release notes for Yocto-4.0.20 (Kirkstone)
|
||||
------------------------------------------
|
||||
|
||||
Security Fixes in Yocto-4.0.20
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- acpica: Fix :cve:`2024-24856`
|
||||
- glib-2.0: Fix :cve:`2024-34397`
|
||||
- gstreamer1.0-plugins-base: Fix :cve:`2024-4453`
|
||||
- libxml2: Fix :cve:`2024-34459`
|
||||
- openssh: fix :cve:`2024-6387`
|
||||
- openssl: Fix :cve_mitre:`2024-4741` and :cve:`2024-5535`
|
||||
- ruby: fix :cve:`2024-27280`
|
||||
- wget: Fix for :cve:`2024-38428`
|
||||
|
||||
|
||||
Fixes in Yocto-4.0.20
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- bitbake: tests/fetch: Tweak test to match upstream repo url change Upstream changed their urls, update our test to match.
|
||||
- build-appliance-image: Update to kirkstone head revision
|
||||
- glibc-tests: Add missing bash ptest dependency
|
||||
- glibc-tests: correctly pull in the actual tests when installing -ptest package
|
||||
- glibc: stable 2.35 branch updates
|
||||
- gobject-introspection: Do not hardcode objdump name
|
||||
- linuxloader: add -armhf on arm only for :term:`TARGET_FPU` 'hard'
|
||||
- man-pages: add an alternative link name for crypt_r.3
|
||||
- man-pages: remove conflict pages
|
||||
- migration-guides: add release notes for 4.0.19
|
||||
- openssl: Upgrade 3.0.13 -> 3.0.14
|
||||
- poky.conf: bump version for 4.0.20
|
||||
|
||||
|
||||
Known Issues in Yocto-4.0.20
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- N/A
|
||||
|
||||
|
||||
Contributors to Yocto-4.0.20
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Archana Polampalli
|
||||
- Changqing Li
|
||||
- Deepthi Hemraj
|
||||
- Jonas Gorski
|
||||
- Jose Quaresma
|
||||
- Khem Raj
|
||||
- Lee Chee Yang
|
||||
- Peter Marko
|
||||
- Poonam Jadhav
|
||||
- Siddharth Doshi
|
||||
- Steve Sakoman
|
||||
- Thomas Perrot
|
||||
- Vijay Anusuri
|
||||
- Yogita Urade
|
||||
|
||||
|
||||
Repositories / Downloads for Yocto-4.0.20
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
poky
|
||||
|
||||
- Repository Location: :yocto_git:`/poky`
|
||||
- Branch: :yocto_git:`kirkstone </poky/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.20 </poky/log/?h=yocto-4.0.20>`
|
||||
- Git Revision: :yocto_git:`6bd3969d32730538608e680653e032e66958fe84 </poky/commit/?id=6bd3969d32730538608e680653e032e66958fe84>`
|
||||
- Release Artefact: poky-6bd3969d32730538608e680653e032e66958fe84
|
||||
- sha: b7ef1bd5ba1af257c4eb07a59b51d69e147723aea010eb2da99ea30dcbbbe2d9
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.20/poky-6bd3969d32730538608e680653e032e66958fe84.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.20/poky-6bd3969d32730538608e680653e032e66958fe84.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.20 </openembedded-core/log/?h=yocto-4.0.20>`
|
||||
- Git Revision: :oe_git:`5d97b0576e98a2cf402abab1a1edcab223545d87 </openembedded-core/commit/?id=5d97b0576e98a2cf402abab1a1edcab223545d87>`
|
||||
- Release Artefact: oecore-5d97b0576e98a2cf402abab1a1edcab223545d87
|
||||
- sha: 4064a32b8ff1ad8a98aa15e75b27585d2b27236c8cdfa4a28af6d6fef99b93c0
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.20/oecore-5d97b0576e98a2cf402abab1a1edcab223545d87.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.20/oecore-5d97b0576e98a2cf402abab1a1edcab223545d87.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.20 </meta-mingw/log/?h=yocto-4.0.20>`
|
||||
- Git Revision: :yocto_git:`f6b38ce3c90e1600d41c2ebb41e152936a0357d7 </meta-mingw/commit/?id=f6b38ce3c90e1600d41c2ebb41e152936a0357d7>`
|
||||
- Release Artefact: meta-mingw-f6b38ce3c90e1600d41c2ebb41e152936a0357d7
|
||||
- sha: 7d57167c19077f4ab95623d55a24c2267a3a3fb5ed83688659b4c03586373b25
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.20/meta-mingw-f6b38ce3c90e1600d41c2ebb41e152936a0357d7.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.20/meta-mingw-f6b38ce3c90e1600d41c2ebb41e152936a0357d7.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.20 </meta-gplv2/log/?h=yocto-4.0.20>`
|
||||
- Git Revision: :yocto_git:`d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a </meta-gplv2/commit/?id=d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a>`
|
||||
- Release Artefact: meta-gplv2-d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a
|
||||
- sha: c386f59f8a672747dc3d0be1d4234b6039273d0e57933eb87caa20f56b9cca6d
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.20/meta-gplv2-d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.20/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.20 </bitbake/log/?h=yocto-4.0.20>`
|
||||
- Git Revision: :oe_git:`734b0ea3dfe45eb16ee60f0c2c388e22af4040e0 </bitbake/commit/?id=734b0ea3dfe45eb16ee60f0c2c388e22af4040e0>`
|
||||
- Release Artefact: bitbake-734b0ea3dfe45eb16ee60f0c2c388e22af4040e0
|
||||
- sha: 99f4c6786fec790fd6c4577b5dea3c97c580cc4815bd409ce554a68ee99b0180
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.20/bitbake-734b0ea3dfe45eb16ee60f0c2c388e22af4040e0.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.20/bitbake-734b0ea3dfe45eb16ee60f0c2c388e22af4040e0.tar.bz2
|
||||
|
||||
yocto-docs
|
||||
|
||||
- Repository Location: :yocto_git:`/yocto-docs`
|
||||
- Branch: :yocto_git:`kirkstone </yocto-docs/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.20 </yocto-docs/log/?h=yocto-4.0.20>`
|
||||
- Git Revision: :yocto_git:`b15b1d369edf33cd91232fefa0278e7e89653a01 </yocto-docs/commit/?id=b15b1d369edf33cd91232fefa0278e7e89653a01>`
|
||||
|
||||
@@ -8123,6 +8123,35 @@ system and gives an overview of their function and contents.
|
||||
/sysroot-only \
|
||||
"
|
||||
|
||||
Consider the following example in which you need to manipulate this variable.
|
||||
Assume you have a recipe ``A`` that provides a shared library ``.so.*`` that is
|
||||
installed into a custom folder other than "``${libdir}``"
|
||||
or "``${base_libdir}``", let's say "``/opt/lib``".
|
||||
|
||||
.. note::
|
||||
|
||||
This is not a recommended way to deal with shared libraries, but this
|
||||
is just to show the usefulness of setting :term:`SYSROOT_DIRS`.
|
||||
|
||||
When a recipe ``B`` :term:`DEPENDS` on ``A``, it means what is in
|
||||
:term:`SYSROOT_DIRS` will be copied from :term:`D` of the recipe ``A``
|
||||
into ``B``'s :term:`SYSROOT_DESTDIR` that is "``${WORKDIR}/sysroot-destdir``".
|
||||
|
||||
Now, since ``/opt/lib`` is not in :term:`SYSROOT_DIRS`, it will never be copied to
|
||||
``A``'s :term:`RECIPE_SYSROOT`, which is "``${WORKDIR}/recipe-sysroot``". So,
|
||||
the linking process will fail.
|
||||
|
||||
To fix this, you need to add ``/opt/lib`` to :term:`SYSROOT_DIRS`::
|
||||
|
||||
SYSROOT_DIRS:append = " /opt/lib"
|
||||
|
||||
.. note::
|
||||
Even after setting ``/opt/lib`` to :term:`SYSROOT_DIRS`, the linking process will still fail
|
||||
because the linker does not know that location, since :term:`TARGET_LDFLAGS`
|
||||
doesn't contain it (if your recipe is for the target). Therefore, so you should add::
|
||||
|
||||
TARGET_LDFLAGS:append = " -L${RECIPE_SYSROOT}/opt/lib"
|
||||
|
||||
:term:`SYSROOT_DIRS_IGNORE`
|
||||
Directories that are not staged into the sysroot by the
|
||||
:ref:`ref-tasks-populate_sysroot` task. You
|
||||
@@ -8146,35 +8175,6 @@ system and gives an overview of their function and contents.
|
||||
${libdir}/${BPN}/ptest \
|
||||
"
|
||||
|
||||
Consider the following example in which you need to manipulate this variable.
|
||||
Assume you have a recipe ``A`` that provides a shared library ``.so.*`` that is
|
||||
installed into a custom folder other than "``${libdir}``"
|
||||
or "``${base_libdir}``", let's say "``/opt/lib``".
|
||||
|
||||
.. note::
|
||||
|
||||
This is not a recommended way to deal with shared libraries, but this
|
||||
is just to show the usefulness of setting :term:`SYSROOT_DIRS`.
|
||||
|
||||
When a recipe ``B`` :term:`DEPENDS` on ``A``, it means what is in
|
||||
:term:`SYSROOT_DIRS` will be copied from :term:`D` of the recipe ``B``
|
||||
into ``B``'s :term:`SYSROOT_DESTDIR` that is "``${WORKDIR}/sysroot-destdir``".
|
||||
|
||||
Now, since ``/opt/lib`` is not in :term:`SYSROOT_DIRS`, it will never be copied to
|
||||
``A``'s :term:`RECIPE_SYSROOT`, which is "``${WORKDIR}/recipe-sysroot``". So,
|
||||
the linking process will fail.
|
||||
|
||||
To fix this, you need to add ``/opt/lib`` to :term:`SYSROOT_DIRS`::
|
||||
|
||||
SYSROOT_DIRS:append = " /opt/lib"
|
||||
|
||||
.. note::
|
||||
Even after setting ``/opt/lib`` to :term:`SYSROOT_DIRS`, the linking process will still fail
|
||||
because the linker does not know that location, since :term:`TARGET_LDFLAGS`
|
||||
doesn't contain it (if your recipe is for the target). Therefore, so you should add::
|
||||
|
||||
TARGET_LDFLAGS:append = " -L${RECIPE_SYSROOT}/opt/lib"
|
||||
|
||||
:term:`SYSROOT_DIRS_NATIVE`
|
||||
Extra directories staged into the sysroot by the
|
||||
:ref:`ref-tasks-populate_sysroot` task for
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
DISTRO = "poky"
|
||||
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
|
||||
#DISTRO_VERSION = "3.4+snapshot-${METADATA_REVISION}"
|
||||
DISTRO_VERSION = "4.0.19"
|
||||
DISTRO_VERSION = "4.0.21"
|
||||
DISTRO_CODENAME = "kirkstone"
|
||||
SDK_VENDOR = "-pokysdk"
|
||||
SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${METADATA_REVISION}', 'snapshot')}"
|
||||
|
||||
@@ -292,8 +292,8 @@ CONVERSION_CMD:lzma = "lzma -k -f -7 ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}"
|
||||
CONVERSION_CMD:gz = "gzip -f -9 -n -c --rsyncable ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type} > ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.gz"
|
||||
CONVERSION_CMD:bz2 = "pbzip2 -f -k ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}"
|
||||
CONVERSION_CMD:xz = "xz -f -k -c ${XZ_COMPRESSION_LEVEL} ${XZ_DEFAULTS} --check=${XZ_INTEGRITY_CHECK} ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type} > ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.xz"
|
||||
CONVERSION_CMD:lz4 = "lz4 -9 -z -l ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type} ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.lz4"
|
||||
CONVERSION_CMD:lzo = "lzop -9 ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}"
|
||||
CONVERSION_CMD:lz4 = "lz4 -f -9 -z -l ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type} ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.lz4"
|
||||
CONVERSION_CMD:lzo = "lzop -f -9 ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}"
|
||||
CONVERSION_CMD:zip = "zip ${ZIP_COMPRESSION_LEVEL} ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.zip ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}"
|
||||
CONVERSION_CMD:zst = "zstd -f -k -T0 -c ${ZSTD_COMPRESSION_LEVEL} ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type} > ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.zst"
|
||||
CONVERSION_CMD:sum = "sumtool -i ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type} -o ${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.${type}.sum ${JFFS2_SUM_EXTRA_ARGS}"
|
||||
|
||||
@@ -49,7 +49,7 @@ def get_glibc_loader(d):
|
||||
elif re.search("i.86", targetarch):
|
||||
dynamic_loader = "${base_libdir}/ld-linux.so.2"
|
||||
elif targetarch == "arm":
|
||||
dynamic_loader = "${base_libdir}/ld-linux${@['-armhf', ''][d.getVar('TARGET_FPU') == 'soft']}.so.3"
|
||||
dynamic_loader = "${base_libdir}/ld-linux${@['', '-armhf'][d.getVar('TARGET_FPU') == 'hard']}.so.3"
|
||||
elif targetarch.startswith("aarch64"):
|
||||
dynamic_loader = "${base_libdir}/ld-linux-aarch64${ARMPKGSFX_ENDIAN_64}.so.1"
|
||||
elif targetarch.startswith("riscv64"):
|
||||
|
||||
@@ -137,8 +137,7 @@ concat_dtb_helper() {
|
||||
|
||||
if [ -n "${UBOOT_CONFIG}" ]
|
||||
then
|
||||
i=0
|
||||
j=0
|
||||
unset i j
|
||||
for config in ${UBOOT_MACHINE}; do
|
||||
i=$(expr $i + 1);
|
||||
for type in ${UBOOT_CONFIG}; do
|
||||
@@ -146,9 +145,12 @@ concat_dtb_helper() {
|
||||
if [ $j -eq $i ]
|
||||
then
|
||||
cp ${UBOOT_IMAGE} ${B}/${CONFIG_B_PATH}/u-boot-$type.${UBOOT_SUFFIX}
|
||||
break
|
||||
fi
|
||||
done
|
||||
unset j
|
||||
done
|
||||
unset i
|
||||
fi
|
||||
else
|
||||
bbwarn "Failure while adding public key to u-boot binary. Verified boot won't be available."
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
From e43f3d93b28cce852c110c7a8e40d8311bcd8bb1 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Fri, 15 Jul 2022 16:13:02 -0400
|
||||
Subject: [PATCH] fs/fat: Don't error when mtime is 0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
In the wild, we occasionally see valid ESPs where some file modification
|
||||
times are 0. For instance:
|
||||
|
||||
├── [Dec 31 1979] EFI
|
||||
│ ├── [Dec 31 1979] BOOT
|
||||
│ │ ├── [Dec 31 1979] BOOTX64.EFI
|
||||
│ │ └── [Dec 31 1979] fbx64.efi
|
||||
│ └── [Jun 27 02:41] fedora
|
||||
│ ├── [Dec 31 1979] BOOTX64.CSV
|
||||
│ ├── [Dec 31 1979] fonts
|
||||
│ ├── [Mar 14 03:35] fw
|
||||
│ │ ├── [Mar 14 03:35] fwupd-359c1169-abd6-4a0d-8bce-e4d4713335c1.cap
|
||||
│ │ ├── [Mar 14 03:34] fwupd-9d255c4b-2d88-4861-860d-7ee52ade9463.cap
|
||||
│ │ └── [Mar 14 03:34] fwupd-b36438d8-9128-49d2-b280-487be02d948b.cap
|
||||
│ ├── [Dec 31 1979] fwupdx64.efi
|
||||
│ ├── [May 10 10:47] grub.cfg
|
||||
│ ├── [Jun 3 12:38] grub.cfg.new.new
|
||||
│ ├── [May 10 10:41] grub.cfg.old
|
||||
│ ├── [Jun 27 02:41] grubenv
|
||||
│ ├── [Dec 31 1979] grubx64.efi
|
||||
│ ├── [Dec 31 1979] mmx64.efi
|
||||
│ ├── [Dec 31 1979] shim.efi
|
||||
│ ├── [Dec 31 1979] shimx64.efi
|
||||
│ └── [Dec 31 1979] shimx64-fedora.efi
|
||||
└── [Dec 31 1979] FSCK0000.REC
|
||||
|
||||
5 directories, 17 files
|
||||
|
||||
This causes grub-probe failure, which in turn causes grub-mkconfig
|
||||
failure. They are valid filesystems that appear intact, and the Linux
|
||||
FAT stack is able to mount and manipulate them without complaint.
|
||||
|
||||
The check for mtime of 0 has been present since
|
||||
20def1a3c3952982395cd7c3ea7e78638527962b (fat: support file
|
||||
modification times).
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?id=e43f3d93b28cce852c110c7a8e40d8311bcd8bb1]
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
|
||||
---
|
||||
grub-core/fs/fat.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c
|
||||
index 0951b2e63..c5efed724 100644
|
||||
--- a/grub-core/fs/fat.c
|
||||
+++ b/grub-core/fs/fat.c
|
||||
@@ -1027,9 +1027,6 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook,
|
||||
grub_le_to_cpu16 (ctxt.dir.w_date),
|
||||
&info.mtime);
|
||||
#endif
|
||||
- if (info.mtimeset == 0)
|
||||
- grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
- "invalid modification timestamp for %s", path);
|
||||
|
||||
if (hook (ctxt.filename, &info, hook_data))
|
||||
break;
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -40,6 +40,7 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \
|
||||
file://CVE-2022-28736-loader-efi-chainloader-Use-grub_loader_set_ex.patch \
|
||||
file://CVE-2023-4692.patch \
|
||||
file://CVE-2023-4693.patch \
|
||||
file://0001-fs-fat-Don-t-error-when-mtime-is-0.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "23b64b4c741569f9426ed2e3d0e6780796fca081bee4c99f62aa3f53ae803f5f"
|
||||
|
||||
@@ -20,7 +20,7 @@ SRC_URI = "https://ftp.isc.org/isc/bind9/${PV}/${BPN}-${PV}.tar.xz \
|
||||
file://0001-avoid-start-failure-with-bind-user.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "709d73023c9115ddad3bab65b6c8c79a590196d0d114f5d0ca2533dbd52ddf66"
|
||||
SRC_URI[sha256sum] = "e7cce9a165f7b619eefc4832f0a8dc16b005d29e3890aed6008c506ea286a5e7"
|
||||
|
||||
UPSTREAM_CHECK_URI = "https://ftp.isc.org/isc/bind9/"
|
||||
# follow the ESV versions divisible by 2
|
||||
@@ -0,0 +1,37 @@
|
||||
From a90421d8e45d63b304dc010baba24633e7869682 Mon Sep 17 00:00:00 2001
|
||||
From: Denis Kenzior <denkenz@gmail.com>
|
||||
Date: Mon, 5 Aug 2024 19:50:04 +0800
|
||||
Subject: [PATCH] smsutil: ensure the address length in bytes <= 10
|
||||
|
||||
If a specially formatted SMS is received, it is conceivable that the
|
||||
address length might overflow the structure it is being parsed into.
|
||||
Ensure that the length in bytes of the address never exceeds 10.
|
||||
|
||||
CVE: CVE-2023-2794
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/network/ofono/ofono.git/commit/?id=a90421d8e45d63b304dc010baba24633e7869682]
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
src/smsutil.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/smsutil.c b/src/smsutil.c
|
||||
index 8dd2126..d8170d1 100644
|
||||
--- a/src/smsutil.c
|
||||
+++ b/src/smsutil.c
|
||||
@@ -643,7 +643,12 @@ gboolean sms_decode_address_field(const unsigned char *pdu, int len,
|
||||
else
|
||||
byte_len = (addr_len + 1) / 2;
|
||||
|
||||
- if ((len - *offset) < byte_len)
|
||||
+ /*
|
||||
+ * 23.040:
|
||||
+ * The maximum length of the full address field
|
||||
+ * (AddressLength, TypeofAddress and AddressValue) is 12 octets.
|
||||
+ */
|
||||
+ if ((len - *offset) < byte_len || byte_len > 10)
|
||||
return FALSE;
|
||||
|
||||
out->number_type = bit_field(addr_type, 4, 3);
|
||||
--
|
||||
2.25.1
|
||||
@@ -0,0 +1,32 @@
|
||||
From 7f2adfa22fbae824f8e2c3ae86a3f51da31ee400 Mon Sep 17 00:00:00 2001
|
||||
From: Denis Kenzior <denkenz@gmail.com>
|
||||
Date: Mon, 5 Aug 2024 20:06:09 +0800
|
||||
Subject: [PATCH] smsutil: Check cbs_dcs_decode return value
|
||||
|
||||
It is better to explicitly check the return value of cbs_dcs_decode
|
||||
instead of relying on udhi not being changed due to side-effects.
|
||||
|
||||
CVE: CVE-2023-2794
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/network/ofono/ofono.git/commit/?id=7f2adfa22fbae824f8e2c3ae86a3f51da31ee400]
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
src/smsutil.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/smsutil.c b/src/smsutil.c
|
||||
index d8170d1..7746a71 100644
|
||||
--- a/src/smsutil.c
|
||||
+++ b/src/smsutil.c
|
||||
@@ -1765,7 +1765,8 @@ gboolean sms_udh_iter_init_from_cbs(const struct cbs *cbs,
|
||||
const guint8 *hdr;
|
||||
guint8 max_ud_len;
|
||||
|
||||
- cbs_dcs_decode(cbs->dcs, &udhi, NULL, NULL, NULL, NULL, NULL);
|
||||
+ if (!cbs_dcs_decode(cbs->dcs, &udhi, NULL, NULL, NULL, NULL, NULL))
|
||||
+ return FALSE;
|
||||
|
||||
if (!udhi)
|
||||
return FALSE;
|
||||
--
|
||||
2.25.1
|
||||
@@ -0,0 +1,44 @@
|
||||
From 07f48b23e3877ef7d15a7b0b8b79d32ad0a3607e Mon Sep 17 00:00:00 2001
|
||||
From: Denis Kenzior <denkenz@gmail.com>
|
||||
Date: Mon, 5 Aug 2024 20:23:38 +0800
|
||||
Subject: [PATCH] simutil: Make sure set_length on the parent succeeds
|
||||
|
||||
CVE: CVE-2023-2794
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/network/ofono/ofono.git/commit/?id=07f48b23e3877ef7d15a7b0b8b79d32ad0a3607e]
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
src/simutil.c | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/simutil.c b/src/simutil.c
|
||||
index 59d8d5d..0e131e8 100644
|
||||
--- a/src/simutil.c
|
||||
+++ b/src/simutil.c
|
||||
@@ -588,8 +588,9 @@ gboolean ber_tlv_builder_set_length(struct ber_tlv_builder *builder,
|
||||
if (new_pos > builder->max)
|
||||
return FALSE;
|
||||
|
||||
- if (builder->parent)
|
||||
- ber_tlv_builder_set_length(builder->parent, new_pos);
|
||||
+ if (builder->parent &&
|
||||
+ !ber_tlv_builder_set_length(builder->parent, new_pos))
|
||||
+ return FALSE;
|
||||
|
||||
builder->len = new_len;
|
||||
|
||||
@@ -730,9 +731,9 @@ gboolean comprehension_tlv_builder_set_length(
|
||||
if (builder->pos + new_ctlv_len > builder->max)
|
||||
return FALSE;
|
||||
|
||||
- if (builder->parent)
|
||||
- ber_tlv_builder_set_length(builder->parent,
|
||||
- builder->pos + new_ctlv_len);
|
||||
+ if (builder->parent && !ber_tlv_builder_set_length(builder->parent,
|
||||
+ builder->pos + new_ctlv_len))
|
||||
+ return FALSE;
|
||||
|
||||
len = MIN(builder->len, new_len);
|
||||
if (len > 0 && new_len_size != len_size)
|
||||
--
|
||||
2.25.1
|
||||
127
meta/recipes-connectivity/ofono/ofono/CVE-2023-2794-0004.patch
Normal file
127
meta/recipes-connectivity/ofono/ofono/CVE-2023-2794-0004.patch
Normal file
@@ -0,0 +1,127 @@
|
||||
From 8fa1fdfcb54e1edb588c6a5e2688880b065a39c9 Mon Sep 17 00:00:00 2001
|
||||
From: Denis Kenzior <denkenz@gmail.com>
|
||||
Date: Mon, 5 Aug 2024 20:38:20 +0800
|
||||
Subject: [PATCH] smsutil: Use a safer strlcpy
|
||||
|
||||
sms_address_from_string is meant as private API, to be used with string
|
||||
form addresses that have already been sanitized. However, to be safe,
|
||||
use a safe version of strcpy to avoid overflowing the buffer in case the
|
||||
input was not sanitized properly. While here, add a '__' prefix to the
|
||||
function name to help make it clearer that this API is private and
|
||||
should be used with more care.
|
||||
|
||||
CVE: CVE-2023-2794
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/network/ofono/ofono.git/commit/?id=8fa1fdfcb54e1edb588c6a5e2688880b065a39c9]
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
src/smsutil.c | 14 +++++++-------
|
||||
src/smsutil.h | 2 +-
|
||||
unit/test-sms.c | 6 +++---
|
||||
3 files changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/smsutil.c b/src/smsutil.c
|
||||
index 7746a71..e073a06 100644
|
||||
--- a/src/smsutil.c
|
||||
+++ b/src/smsutil.c
|
||||
@@ -1887,15 +1887,15 @@ time_t sms_scts_to_time(const struct sms_scts *scts, struct tm *remote)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-void sms_address_from_string(struct sms_address *addr, const char *str)
|
||||
+void __sms_address_from_string(struct sms_address *addr, const char *str)
|
||||
{
|
||||
addr->numbering_plan = SMS_NUMBERING_PLAN_ISDN;
|
||||
if (str[0] == '+') {
|
||||
addr->number_type = SMS_NUMBER_TYPE_INTERNATIONAL;
|
||||
- strcpy(addr->address, str + 1);
|
||||
+ l_strlcpy(addr->address, str + 1, sizeof(addr->address));
|
||||
} else {
|
||||
addr->number_type = SMS_NUMBER_TYPE_UNKNOWN;
|
||||
- strcpy(addr->address, str);
|
||||
+ l_strlcpy(addr->address, str, sizeof(addr->address));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3087,7 +3087,7 @@ gboolean status_report_assembly_report(struct status_report_assembly *assembly,
|
||||
}
|
||||
}
|
||||
|
||||
- sms_address_from_string(&addr, straddr);
|
||||
+ __sms_address_from_string(&addr, straddr);
|
||||
|
||||
if (pending == TRUE && node->deliverable == TRUE) {
|
||||
/*
|
||||
@@ -3180,7 +3180,7 @@ void status_report_assembly_expire(struct status_report_assembly *assembly,
|
||||
while (g_hash_table_iter_next(&iter_addr, (gpointer) &straddr,
|
||||
(gpointer) &id_table)) {
|
||||
|
||||
- sms_address_from_string(&addr, straddr);
|
||||
+ __sms_address_from_string(&addr, straddr);
|
||||
g_hash_table_iter_init(&iter_node, id_table);
|
||||
|
||||
/* Go through different messages. */
|
||||
@@ -3474,7 +3474,7 @@ GSList *sms_datagram_prepare(const char *to,
|
||||
template.submit.vp.relative = 0xA7; /* 24 Hours */
|
||||
template.submit.dcs = 0x04; /* Class Unspecified, 8 Bit */
|
||||
template.submit.udhi = TRUE;
|
||||
- sms_address_from_string(&template.submit.daddr, to);
|
||||
+ __sms_address_from_string(&template.submit.daddr, to);
|
||||
|
||||
offset = 1;
|
||||
|
||||
@@ -3601,7 +3601,7 @@ GSList *sms_text_prepare_with_alphabet(const char *to, const char *utf8,
|
||||
template.submit.srr = use_delivery_reports;
|
||||
template.submit.mr = 0;
|
||||
template.submit.vp.relative = 0xA7; /* 24 Hours */
|
||||
- sms_address_from_string(&template.submit.daddr, to);
|
||||
+ __sms_address_from_string(&template.submit.daddr, to);
|
||||
|
||||
/* There are two enums for the same thing */
|
||||
dialect = (enum gsm_dialect)alphabet;
|
||||
diff --git a/src/smsutil.h b/src/smsutil.h
|
||||
index 01487de..bc21504 100644
|
||||
--- a/src/smsutil.h
|
||||
+++ b/src/smsutil.h
|
||||
@@ -487,7 +487,7 @@ int sms_udl_in_bytes(guint8 ud_len, guint8 dcs);
|
||||
time_t sms_scts_to_time(const struct sms_scts *scts, struct tm *remote);
|
||||
|
||||
const char *sms_address_to_string(const struct sms_address *addr);
|
||||
-void sms_address_from_string(struct sms_address *addr, const char *str);
|
||||
+void __sms_address_from_string(struct sms_address *addr, const char *str);
|
||||
|
||||
const guint8 *sms_extract_common(const struct sms *sms, gboolean *out_udhi,
|
||||
guint8 *out_dcs, guint8 *out_udl,
|
||||
diff --git a/unit/test-sms.c b/unit/test-sms.c
|
||||
index 3bc099b..88293d5 100644
|
||||
--- a/unit/test-sms.c
|
||||
+++ b/unit/test-sms.c
|
||||
@@ -1603,7 +1603,7 @@ static void test_sr_assembly(void)
|
||||
sr3.status_report.mr);
|
||||
}
|
||||
|
||||
- sms_address_from_string(&addr, "+4915259911630");
|
||||
+ __sms_address_from_string(&addr, "+4915259911630");
|
||||
|
||||
sra = status_report_assembly_new(NULL);
|
||||
|
||||
@@ -1626,7 +1626,7 @@ static void test_sr_assembly(void)
|
||||
* Send sms-message in the national address-format,
|
||||
* but receive in the international address-format.
|
||||
*/
|
||||
- sms_address_from_string(&addr, "9911630");
|
||||
+ __sms_address_from_string(&addr, "9911630");
|
||||
status_report_assembly_add_fragment(sra, sha1, &addr, 4, time(NULL), 2);
|
||||
status_report_assembly_add_fragment(sra, sha1, &addr, 5, time(NULL), 2);
|
||||
|
||||
@@ -1641,7 +1641,7 @@ static void test_sr_assembly(void)
|
||||
* Send sms-message in the international address-format,
|
||||
* but receive in the national address-format.
|
||||
*/
|
||||
- sms_address_from_string(&addr, "+358123456789");
|
||||
+ __sms_address_from_string(&addr, "+358123456789");
|
||||
status_report_assembly_add_fragment(sra, sha1, &addr, 6, time(NULL), 1);
|
||||
|
||||
g_assert(status_report_assembly_report(sra, &sr3, id, &delivered));
|
||||
--
|
||||
2.25.1
|
||||
@@ -14,6 +14,10 @@ SRC_URI = "\
|
||||
file://0002-mbim-Fix-build-with-ell-0.39-by-restoring-unlikely-m.patch \
|
||||
file://CVE-2023-4234.patch \
|
||||
file://CVE-2023-4233.patch \
|
||||
file://CVE-2023-2794-0001.patch \
|
||||
file://CVE-2023-2794-0002.patch \
|
||||
file://CVE-2023-2794-0003.patch \
|
||||
file://CVE-2023-2794-0004.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "c0b96d3013447ec2bcb74579bef90e4e59c68dbfa4b9c6fbce5d12401a43aac7"
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
Description: fix signal handler race condition
|
||||
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/2070497
|
||||
|
||||
CVE: CVE-2024-6387
|
||||
|
||||
Upstream-Status: Backport
|
||||
https://git.launchpad.net/ubuntu/+source/openssh/commit/?h=applied/ubuntu/jammy-devel&id=b059bcfa928df4ff2d103ae2e8f4e3136ee03efc
|
||||
|
||||
Signed-off-by: Jose Quaresma <jose.quaresma@foundries.io>
|
||||
|
||||
--- a/log.c
|
||||
+++ b/log.c
|
||||
@@ -452,12 +452,14 @@ void
|
||||
sshsigdie(const char *file, const char *func, int line, int showfunc,
|
||||
LogLevel level, const char *suffix, const char *fmt, ...)
|
||||
{
|
||||
+#if 0
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
sshlogv(file, func, line, showfunc, SYSLOG_LEVEL_FATAL,
|
||||
suffix, fmt, args);
|
||||
va_end(args);
|
||||
+#endif
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar
|
||||
file://CVE-2023-48795.patch \
|
||||
file://CVE-2023-51384.patch \
|
||||
file://CVE-2023-51385.patch \
|
||||
file://CVE-2024-6387.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "fd497654b7ab1686dac672fb83dfb4ba4096e8b5ffcdaccd262380ae58bec5e7"
|
||||
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
From b52867a9f618bb955bed2a3ce3db4d4f97ed8e5d Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Tue, 5 Mar 2024 15:43:53 +0000
|
||||
Subject: [PATCH] Fix unconstrained session cache growth in TLSv1.3
|
||||
|
||||
In TLSv1.3 we create a new session object for each ticket that we send.
|
||||
We do this by duplicating the original session. If SSL_OP_NO_TICKET is in
|
||||
use then the new session will be added to the session cache. However, if
|
||||
early data is not in use (and therefore anti-replay protection is being
|
||||
used), then multiple threads could be resuming from the same session
|
||||
simultaneously. If this happens and a problem occurs on one of the threads,
|
||||
then the original session object could be marked as not_resumable. When we
|
||||
duplicate the session object this not_resumable status gets copied into the
|
||||
new session object. The new session object is then added to the session
|
||||
cache even though it is not_resumable.
|
||||
|
||||
Subsequently, another bug means that the session_id_length is set to 0 for
|
||||
sessions that are marked as not_resumable - even though that session is
|
||||
still in the cache. Once this happens the session can never be removed from
|
||||
the cache. When that object gets to be the session cache tail object the
|
||||
cache never shrinks again and grows indefinitely.
|
||||
|
||||
CVE-2024-2511
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24044)
|
||||
|
||||
(cherry picked from commit 7e4d731b1c07201ad9374c1cd9ac5263bdf35bce)
|
||||
|
||||
CVE: CVE-2024-2511
|
||||
Upstream-Status: Backport [https://github.com/openssl/openssl/commit/b52867a9f618bb955bed2a3ce3db4d4f97ed8e5d]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
ssl/ssl_lib.c | 5 +++--
|
||||
ssl/ssl_sess.c | 28 ++++++++++++++++++++++------
|
||||
ssl/statem/statem_srvr.c | 5 ++---
|
||||
3 files changed, 27 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
|
||||
index 2c8479eb5fc69..eed649c6fdee9 100644
|
||||
--- a/ssl/ssl_lib.c
|
||||
+++ b/ssl/ssl_lib.c
|
||||
@@ -3736,9 +3736,10 @@ void ssl_update_cache(SSL *s, int mode)
|
||||
|
||||
/*
|
||||
* If the session_id_length is 0, we are not supposed to cache it, and it
|
||||
- * would be rather hard to do anyway :-)
|
||||
+ * would be rather hard to do anyway :-). Also if the session has already
|
||||
+ * been marked as not_resumable we should not cache it for later reuse.
|
||||
*/
|
||||
- if (s->session->session_id_length == 0)
|
||||
+ if (s->session->session_id_length == 0 || s->session->not_resumable)
|
||||
return;
|
||||
|
||||
/*
|
||||
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
|
||||
index d836b33ed0e81..75adbd9e52b40 100644
|
||||
--- a/ssl/ssl_sess.c
|
||||
+++ b/ssl/ssl_sess.c
|
||||
@@ -152,16 +152,11 @@ SSL_SESSION *SSL_SESSION_new(void)
|
||||
return ss;
|
||||
}
|
||||
|
||||
-SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
|
||||
-{
|
||||
- return ssl_session_dup(src, 1);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Create a new SSL_SESSION and duplicate the contents of |src| into it. If
|
||||
* ticket == 0 then no ticket information is duplicated, otherwise it is.
|
||||
*/
|
||||
-SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
|
||||
+static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
|
||||
{
|
||||
SSL_SESSION *dest;
|
||||
|
||||
@@ -285,6 +280,27 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
|
||||
+{
|
||||
+ return ssl_session_dup_intern(src, 1);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Used internally when duplicating a session which might be already shared.
|
||||
+ * We will have resumed the original session. Subsequently we might have marked
|
||||
+ * it as non-resumable (e.g. in another thread) - but this copy should be ok to
|
||||
+ * resume from.
|
||||
+ */
|
||||
+SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
|
||||
+{
|
||||
+ SSL_SESSION *sess = ssl_session_dup_intern(src, ticket);
|
||||
+
|
||||
+ if (sess != NULL)
|
||||
+ sess->not_resumable = 0;
|
||||
+
|
||||
+ return sess;
|
||||
+}
|
||||
+
|
||||
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
|
||||
{
|
||||
if (len)
|
||||
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
|
||||
index a9e67f9d32a77..6c942e6bcec29 100644
|
||||
--- a/ssl/statem/statem_srvr.c
|
||||
+++ b/ssl/statem/statem_srvr.c
|
||||
@@ -2338,9 +2338,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
|
||||
* so the following won't overwrite an ID that we're supposed
|
||||
* to send back.
|
||||
*/
|
||||
- if (s->session->not_resumable ||
|
||||
- (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
|
||||
- && !s->hit))
|
||||
+ if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
|
||||
+ && !s->hit)
|
||||
s->session->session_id_length = 0;
|
||||
|
||||
if (usetls13) {
|
||||
@@ -1,180 +0,0 @@
|
||||
From 3559e868e58005d15c6013a0c1fd832e51c73397 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tomas@openssl.org>
|
||||
Date: Wed, 8 May 2024 15:23:45 +0200
|
||||
Subject: [PATCH] Check DSA parameters for excessive sizes before validating
|
||||
|
||||
This avoids overly long computation of various validation
|
||||
checks.
|
||||
|
||||
Fixes CVE-2024-4603
|
||||
|
||||
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
|
||||
Reviewed-by: Matt Caswell <matt@openssl.org>
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24346)
|
||||
|
||||
(cherry picked from commit 85ccbab216da245cf9a6503dd327072f21950d9b)
|
||||
|
||||
<dropped CHANGES.md modifications as it would need backport of all previous changes>
|
||||
|
||||
CVE: CVE-2024-4603
|
||||
Upstream-Status: Backport [https://github.com/openssl/openssl/commit/3559e868e58005d15c6013a0c1fd832e51c73397]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
crypto/dsa/dsa_check.c | 44 ++++++++++++--
|
||||
.../invalid/p10240_q256_too_big.pem | 57 +++++++++++++++++++
|
||||
2 files changed, 97 insertions(+), 4 deletions(-)
|
||||
create mode 100644 test/recipes/15-test_dsaparam_data/invalid/p10240_q256_too_big.pem
|
||||
|
||||
diff --git a/crypto/dsa/dsa_check.c b/crypto/dsa/dsa_check.c
|
||||
index fb0e9129a2..122449a7bf 100644
|
||||
--- a/crypto/dsa/dsa_check.c
|
||||
+++ b/crypto/dsa/dsa_check.c
|
||||
@@ -19,8 +19,34 @@
|
||||
#include "dsa_local.h"
|
||||
#include "crypto/dsa.h"
|
||||
|
||||
+static int dsa_precheck_params(const DSA *dsa, int *ret)
|
||||
+{
|
||||
+ if (dsa->params.p == NULL || dsa->params.q == NULL) {
|
||||
+ ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS);
|
||||
+ *ret = FFC_CHECK_INVALID_PQ;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (BN_num_bits(dsa->params.p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
|
||||
+ ERR_raise(ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE);
|
||||
+ *ret = FFC_CHECK_INVALID_PQ;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (BN_num_bits(dsa->params.q) >= BN_num_bits(dsa->params.p)) {
|
||||
+ ERR_raise(ERR_LIB_DSA, DSA_R_BAD_Q_VALUE);
|
||||
+ *ret = FFC_CHECK_INVALID_PQ;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
int ossl_dsa_check_params(const DSA *dsa, int checktype, int *ret)
|
||||
{
|
||||
+ if (!dsa_precheck_params(dsa, ret))
|
||||
+ return 0;
|
||||
+
|
||||
if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
|
||||
return ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params,
|
||||
FFC_PARAM_TYPE_DSA, ret);
|
||||
@@ -39,6 +65,9 @@ int ossl_dsa_check_params(const DSA *dsa, int checktype, int *ret)
|
||||
*/
|
||||
int ossl_dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret)
|
||||
{
|
||||
+ if (!dsa_precheck_params(dsa, ret))
|
||||
+ return 0;
|
||||
+
|
||||
return ossl_ffc_validate_public_key(&dsa->params, pub_key, ret)
|
||||
&& *ret == 0;
|
||||
}
|
||||
@@ -50,6 +79,9 @@ int ossl_dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret)
|
||||
*/
|
||||
int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, int *ret)
|
||||
{
|
||||
+ if (!dsa_precheck_params(dsa, ret))
|
||||
+ return 0;
|
||||
+
|
||||
return ossl_ffc_validate_public_key_partial(&dsa->params, pub_key, ret)
|
||||
&& *ret == 0;
|
||||
}
|
||||
@@ -58,8 +90,10 @@ int ossl_dsa_check_priv_key(const DSA *dsa, const BIGNUM *priv_key, int *ret)
|
||||
{
|
||||
*ret = 0;
|
||||
|
||||
- return (dsa->params.q != NULL
|
||||
- && ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret));
|
||||
+ if (!dsa_precheck_params(dsa, ret))
|
||||
+ return 0;
|
||||
+
|
||||
+ return ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -72,8 +106,10 @@ int ossl_dsa_check_pairwise(const DSA *dsa)
|
||||
BN_CTX *ctx = NULL;
|
||||
BIGNUM *pub_key = NULL;
|
||||
|
||||
- if (dsa->params.p == NULL
|
||||
- || dsa->params.g == NULL
|
||||
+ if (!dsa_precheck_params(dsa, &ret))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (dsa->params.g == NULL
|
||||
|| dsa->priv_key == NULL
|
||||
|| dsa->pub_key == NULL)
|
||||
return 0;
|
||||
diff --git a/test/recipes/15-test_dsaparam_data/invalid/p10240_q256_too_big.pem b/test/recipes/15-test_dsaparam_data/invalid/p10240_q256_too_big.pem
|
||||
new file mode 100644
|
||||
index 0000000000..e85e2953b7
|
||||
--- /dev/null
|
||||
+++ b/test/recipes/15-test_dsaparam_data/invalid/p10240_q256_too_big.pem
|
||||
@@ -0,0 +1,57 @@
|
||||
+-----BEGIN DSA PARAMETERS-----
|
||||
+MIIKLAKCBQEAym47LzPFZdbz16WvjczLKuzLtsP8yRk/exxL4bBthJhP1qOwctja
|
||||
+p1586SF7gDxCMn7yWVEYdfRbFefGoq0gj1XOE917XqlbnkmZhMgxut2KbNJo/xil
|
||||
+XNFUjGvKs3F413U9rAodC8f07cWHP1iTcWL+vPe6u2yilKWYYfnLWHQH+Z6aPrrF
|
||||
+x/R08LI6DZ6nEsIo+hxaQnEtx+iqNTJC6Q1RIjWDqxQkFVTkJ0Y7miRDXmRdneWk
|
||||
+oLrMZRpaXr5l5tSjEghh1pBgJcdyOv0lh4dlDy/alAiqE2Qlb667yHl6A9dDPlpW
|
||||
+dAntpffy4LwOxfbuEhISvKjjQoBwIvYE4TBPqL0Q6bC6HgQ4+tqd9b44pQjdIQjb
|
||||
+Xcjc6azheITSnPEex3OdKtKoQeRq01qCeLBpMXu1c+CTf4ApKArZvT3vZSg0hM1O
|
||||
+pR71bRZrEEegDj0LH2HCgI5W6H3blOS9A0kUTddCoQXr2lsVdiPtRbPKH1gcd9FQ
|
||||
+P8cGrvbakpTiC0dCczOMDaCteM1QNILlkM7ZoV6VghsKvDnFPxFsiIr5GgjasXP5
|
||||
+hhbn3g7sDoq1LiTEo+IKQY28pBWx7etSOSRuXW/spnvCkivZla7lSEGljoy9QlQ2
|
||||
+UZmsEQI9G3YyzgpxHvKZBK1CiZVTywdYKTZ4TYCxvqzhYhjv2bqbpjI12HRFLojB
|
||||
+koyEmMSp53lldCzp158PrIanqSp2rksMR8SmmCL3FwfAp2OjqFMEglG9DT8x0WaN
|
||||
+TLSkjGC6t2csMte7WyU1ekNoFDKfMjDSAz0+xIx21DEmZtYqFOg1DNPK1xYLS0pl
|
||||
+RSMRRkJVN2mk/G7/1oxlB8Wb9wgi3GKUqqCYT11SnBjzq0NdoJ3E4GMedp5Lx3AZ
|
||||
+4mFuRPUd4iV86tE0XDSHSFE7Y3ZkrOjD7Q/26/L53L/UH5z4HW6CHP5os7QERJjg
|
||||
+c1S3x87wXWo9QXbB9b2xmf+c+aWwAAr1cviw38tru58jF3/IGyduj9H8claKQqBG
|
||||
+cIOUF4aNe1hK2K3ArAOApUxr4KE+tCvrltRfiTmVFip0g9Jt1CPY3Zu7Bd4Z2ZkE
|
||||
+DtSztpwa49HrWF5E9xpquvBL2U8jQ68E7Xd8Wp4orI/TIChriamBmdkgRz3H2LvN
|
||||
+Ozb6+hsnEGrz3sp2RVAToSqA9ysa6nHZdfufPNtMEbQdO/k1ehmGRb0ljBRsO6b2
|
||||
+rsG2eYuC8tg8eCrIkua0TGRI7g6a4K32AJdzaX6NsISaaIW+OYJuoDSscvD3oOg8
|
||||
+PPEhU+zM7xJskTA+jxvPlikKx8V7MNHOCQECldJlUBwzJvqp40JvwfnDsF+8VYwd
|
||||
+UaiieR3pzMzyTjpReXRmZbnRPusRcsVzxb2OhB79wmuy4UPjjQBX+7eD0rs8xxvW
|
||||
+5a5q1Cjq4AvbwmmcA/wDrHDOjcbD/zodad2O1QtBWa/R4xyWea4zKsflgACE1zY9
|
||||
+wW2br7+YQFekcrXkkkEzgxd6zxv8KVEDpXRZjmAM1cI5LvkoN64To4GedN8Qe/G7
|
||||
+R9SZh9gnS17PTP64hK+aYqhFafMdu87q/+qLfxaSux727qE5hiW01u4nnWhACf9s
|
||||
+xuOozowKqxZxkolMIyZv6Lddwy1Zv5qjCyd0DvM/1skpXWkb9kfabYC+OhjsjVhs
|
||||
+0Ktfs6a5B3eixiw5x94hhIcTEcS4hmvhGUL72FiTca6ZeSERTKmNBy8CIQC9/ZUN
|
||||
+uU/V5JTcnYyUGHzm7+XcZBjyGBagBj9rCmW3SQKCBQAJ/k9rb39f1cO+/3XDEMjy
|
||||
+9bIEXSuS48g5RAc1UGd5nrrBQwuDxGWFyz0yvAY7LgyidZuJS21+MAp9EY7AOMmx
|
||||
+TDttifNaBJYt4GZ8of166PcqTKkHQwq5uBpxeSDv/ZE8YbYfaCtLTcUC8KlO+l36
|
||||
+gjJHSkdkflSsGy1yObSNDQDfVAAwQs//TjDMnuEtvlNXZllsTvFFBceXVETn10K2
|
||||
+ZMmdSIJNfLnjReUKEN6PfeGqv7F4xoyGwUybEfRE4u5RmXrqCODaIjY3SNMrOq8B
|
||||
+R3Ata/cCozsM1jIdIW2z+OybDJH+BYsYm2nkSZQjZS6javTYClLrntEKG/hAQwL8
|
||||
+F16YLOQXpHhgiAaWnTZzANtLppB2+5qCVy5ElzKongOwT8JTjTFXOaRnqe/ngm9W
|
||||
+SSbrxfDaoWUOyK9XD8Cydzpv3n4Y8nWNGayi7/yAFCU36Ri040ufgv/TZLuKacnl
|
||||
++3ga3ZUpRlSigzx0kb1+KjTSWeQ8vE/psdWjvBukVEbzdUauMLyRLo/6znSVvvPX
|
||||
+UGhviThE5uhrsUg+wEPFINriSHfF7JDKVhDcJnLBdaXvfN52pkF/naLBF5Rt3Gvq
|
||||
+fjCxjx0Sy9Lag1hDN4dor7dzuO7wmwOS01DJW1PtNLuuH0Bbqh1kYSaQkmyXBZWX
|
||||
+qo8K3nkoDM0niOtJJubOhTNrGmSaZpNXkK3Mcy9rBbdvEs5O0Jmqaax/eOdU0Yot
|
||||
+B3lX+3ddOseT2ZEFjzObqTtkWuFBeBxuYNcRTsu3qMdIBsEb8URQdsTtjoIja2fK
|
||||
+hreVgjK36GW70KXEl8V/vq5qjQulmqkBEjmilcDuiREKqQuyeagUOnhQaBplqVco
|
||||
+4xznh5DMBMRbpGb5lHxKv4cPNi+uNAJ5i98zWUM1JRt6aXnRCuWcll1z8fRZ+5kD
|
||||
+vK9FaZU3VRMK/eknEG49cGr8OuJ6ZRSaC+tKwV1y+amkSZpKPWnk2bUnQI3ApJv3
|
||||
+k1e1EToeECpMUkLMDgNbpKBoz4nqMEvAAlYgw9xKNbLlQlahqTVEAmaJHh4yDMDy
|
||||
+i7IZ9Wrn47IGoR7s3cvhDHUpRPeW4nsmgzj+tf5EAxemI61STZJTTWo0iaPGJxct
|
||||
+9nhOOhw1I38Mvm4vkAbFH7YJ0B6QrjjYL2MbOTp5JiIh4vdOeWwNo9/y4ffyaN5+
|
||||
+ADpxuuIAmcbdr6GPOhkOFFixRJa0B2eP1i032HESlLs8RB9oYtdTXdXQotnIgJGd
|
||||
+Y8tSKOa1zjzeLHn3AVpRZTUW++/BxmApV3GKIeG8fsUjg/df0QRrBcdC/1uccdaG
|
||||
+KKlAOwlywVn5jUlwHkTmDiTM9w5AqVVGHZ2b+4ZgQW8jnPKN0SrKf6U555D+zp7E
|
||||
+x4uXoE8ojN9y8m8UKf0cTLnujH2XgZorjPfuMOt5VZEhQFMS2QaljSeni5CJJ8gk
|
||||
+XtztNqfBlAtWR4V5iAHeQOfIB2YaOy8GESda89tyKraKeaez41VblpTVHTeq9IIF
|
||||
+YB4cQA2PfuNaGVRGLMAgT3Dvl+mxxxeJyxnGAiUcETU/jJJt9QombiuszBlYGQ5d
|
||||
+ELOSm/eQSRARV9zNSt5jaQlMSjMBqenIEM09BzYqa7jDwqoztFxNdO8bcuQPuKwa
|
||||
+4z3bBZ1yYm63WFdNbQqqGEwc0OYmqg1raJ0zltgHyjFyw8IGu4g/wETs+nVQcH7D
|
||||
+vKuje86bePD6kD/LH3wmkA==
|
||||
+-----END DSA PARAMETERS-----
|
||||
--
|
||||
2.30.2
|
||||
|
||||
115
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_1.patch
Normal file
115
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_1.patch
Normal file
@@ -0,0 +1,115 @@
|
||||
From e6190fc977f086428cc7880f95e8bcd5a11ac193 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 31 May 2024 11:14:33 +0100
|
||||
Subject: [PATCH 1/9] Fix SSL_select_next_proto
|
||||
|
||||
Ensure that the provided client list is non-NULL and starts with a valid
|
||||
entry. When called from the ALPN callback the client list should already
|
||||
have been validated by OpenSSL so this should not cause a problem. When
|
||||
called from the NPN callback the client list is locally configured and
|
||||
will not have already been validated. Therefore SSL_select_next_proto
|
||||
should not assume that it is correctly formatted.
|
||||
|
||||
We implement stricter checking of the client protocol list. We also do the
|
||||
same for the server list while we are about it.
|
||||
|
||||
CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit 4ada436a1946cbb24db5ab4ca082b69c1bc10f37)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/cf6f91f6121f4db167405db2f0de410a456f260c]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
ssl/ssl_lib.c | 63 ++++++++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 40 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
|
||||
index cb4e006..e628140 100644
|
||||
--- a/ssl/ssl_lib.c
|
||||
+++ b/ssl/ssl_lib.c
|
||||
@@ -2952,37 +2952,54 @@ int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
|
||||
unsigned int server_len,
|
||||
const unsigned char *client, unsigned int client_len)
|
||||
{
|
||||
- unsigned int i, j;
|
||||
- const unsigned char *result;
|
||||
- int status = OPENSSL_NPN_UNSUPPORTED;
|
||||
+ PACKET cpkt, csubpkt, spkt, ssubpkt;
|
||||
+
|
||||
+ if (!PACKET_buf_init(&cpkt, client, client_len)
|
||||
+ || !PACKET_get_length_prefixed_1(&cpkt, &csubpkt)
|
||||
+ || PACKET_remaining(&csubpkt) == 0) {
|
||||
+ *out = NULL;
|
||||
+ *outlen = 0;
|
||||
+ return OPENSSL_NPN_NO_OVERLAP;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Set the default opportunistic protocol. Will be overwritten if we find
|
||||
+ * a match.
|
||||
+ */
|
||||
+ *out = (unsigned char *)PACKET_data(&csubpkt);
|
||||
+ *outlen = (unsigned char)PACKET_remaining(&csubpkt);
|
||||
|
||||
/*
|
||||
* For each protocol in server preference order, see if we support it.
|
||||
*/
|
||||
- for (i = 0; i < server_len;) {
|
||||
- for (j = 0; j < client_len;) {
|
||||
- if (server[i] == client[j] &&
|
||||
- memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
|
||||
- /* We found a match */
|
||||
- result = &server[i];
|
||||
- status = OPENSSL_NPN_NEGOTIATED;
|
||||
- goto found;
|
||||
+ if (PACKET_buf_init(&spkt, server, server_len)) {
|
||||
+ while (PACKET_get_length_prefixed_1(&spkt, &ssubpkt)) {
|
||||
+ if (PACKET_remaining(&ssubpkt) == 0)
|
||||
+ continue; /* Invalid - ignore it */
|
||||
+ if (PACKET_buf_init(&cpkt, client, client_len)) {
|
||||
+ while (PACKET_get_length_prefixed_1(&cpkt, &csubpkt)) {
|
||||
+ if (PACKET_equal(&csubpkt, PACKET_data(&ssubpkt),
|
||||
+ PACKET_remaining(&ssubpkt))) {
|
||||
+ /* We found a match */
|
||||
+ *out = (unsigned char *)PACKET_data(&ssubpkt);
|
||||
+ *outlen = (unsigned char)PACKET_remaining(&ssubpkt);
|
||||
+ return OPENSSL_NPN_NEGOTIATED;
|
||||
+ }
|
||||
+ }
|
||||
+ /* Ignore spurious trailing bytes in the client list */
|
||||
+ } else {
|
||||
+ /* This should never happen */
|
||||
+ return OPENSSL_NPN_NO_OVERLAP;
|
||||
}
|
||||
- j += client[j];
|
||||
- j++;
|
||||
}
|
||||
- i += server[i];
|
||||
- i++;
|
||||
+ /* Ignore spurious trailing bytes in the server list */
|
||||
}
|
||||
|
||||
- /* There's no overlap between our protocols and the server's list. */
|
||||
- result = client;
|
||||
- status = OPENSSL_NPN_NO_OVERLAP;
|
||||
-
|
||||
- found:
|
||||
- *out = (unsigned char *)result + 1;
|
||||
- *outlen = result[0];
|
||||
- return status;
|
||||
+ /*
|
||||
+ * There's no overlap between our protocols and the server's list. We use
|
||||
+ * the default opportunistic protocol selected earlier
|
||||
+ */
|
||||
+ return OPENSSL_NPN_NO_OVERLAP;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_NEXTPROTONEG
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
From 4a96c6b7265838b044dab4a2a6150c246297bc89 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 31 May 2024 11:18:27 +0100
|
||||
Subject: [PATCH 2/9] More correctly handle a selected_len of 0 when processing
|
||||
NPN
|
||||
|
||||
In the case where the NPN callback returns with SSL_TLEXT_ERR_OK, but
|
||||
the selected_len is 0 we should fail. Previously this would fail with an
|
||||
internal_error alert because calling OPENSSL_malloc(selected_len) will
|
||||
return NULL when selected_len is 0. We make this error detection more
|
||||
explicit and return a handshake failure alert.
|
||||
|
||||
Follow on from CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit 4279c89a726025c758db3dafb263b17e52211304)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/159921152fd4aa91e4c849fd281ad93ac0d0d0ba]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
ssl/statem/extensions_clnt.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
|
||||
index 842be07..a07dc62 100644
|
||||
--- a/ssl/statem/extensions_clnt.c
|
||||
+++ b/ssl/statem/extensions_clnt.c
|
||||
@@ -1536,7 +1536,8 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
PACKET_data(pkt),
|
||||
PACKET_remaining(pkt),
|
||||
s->ctx->ext.npn_select_cb_arg) !=
|
||||
- SSL_TLSEXT_ERR_OK) {
|
||||
+ SSL_TLSEXT_ERR_OK
|
||||
+ || selected_len == 0) {
|
||||
SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_BAD_EXTENSION);
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
From 6887608f77236d14b0789f4b1c14df53dfe2d618 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 31 May 2024 11:46:38 +0100
|
||||
Subject: [PATCH 3/9] Clarify the SSL_select_next_proto() documentation
|
||||
|
||||
We clarify the input preconditions and the expected behaviour in the event
|
||||
of no overlap.
|
||||
|
||||
Follow on from CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit 889ed19ba25abebd2690997acd6d4791cbe5c493)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/7a9f521b1de96e79184948e5813e791e608cc94b]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
doc/man3/SSL_CTX_set_alpn_select_cb.pod | 26 +++++++++++++++++--------
|
||||
1 file changed, 18 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/doc/man3/SSL_CTX_set_alpn_select_cb.pod b/doc/man3/SSL_CTX_set_alpn_select_cb.pod
|
||||
index 102e657..a29557d 100644
|
||||
--- a/doc/man3/SSL_CTX_set_alpn_select_cb.pod
|
||||
+++ b/doc/man3/SSL_CTX_set_alpn_select_cb.pod
|
||||
@@ -52,7 +52,8 @@ SSL_select_next_proto, SSL_get0_alpn_selected, SSL_get0_next_proto_negotiated
|
||||
SSL_CTX_set_alpn_protos() and SSL_set_alpn_protos() are used by the client to
|
||||
set the list of protocols available to be negotiated. The B<protos> must be in
|
||||
protocol-list format, described below. The length of B<protos> is specified in
|
||||
-B<protos_len>.
|
||||
+B<protos_len>. Setting B<protos_len> to 0 clears any existing list of ALPN
|
||||
+protocols and no ALPN extension will be sent to the server.
|
||||
|
||||
SSL_CTX_set_alpn_select_cb() sets the application callback B<cb> used by a
|
||||
server to select which protocol to use for the incoming connection. When B<cb>
|
||||
@@ -73,9 +74,16 @@ B<server_len> and B<client>, B<client_len> must be in the protocol-list format
|
||||
described below. The first item in the B<server>, B<server_len> list that
|
||||
matches an item in the B<client>, B<client_len> list is selected, and returned
|
||||
in B<out>, B<outlen>. The B<out> value will point into either B<server> or
|
||||
-B<client>, so it should be copied immediately. If no match is found, the first
|
||||
-item in B<client>, B<client_len> is returned in B<out>, B<outlen>. This
|
||||
-function can also be used in the NPN callback.
|
||||
+B<client>, so it should be copied immediately. The client list must include at
|
||||
+least one valid (nonempty) protocol entry in the list.
|
||||
+
|
||||
+The SSL_select_next_proto() helper function can be useful from either the ALPN
|
||||
+callback or the NPN callback (described below). If no match is found, the first
|
||||
+item in B<client>, B<client_len> is returned in B<out>, B<outlen> and
|
||||
+B<OPENSSL_NPN_NO_OVERLAP> is returned. This can be useful when implementating
|
||||
+the NPN callback. In the ALPN case, the value returned in B<out> and B<outlen>
|
||||
+must be ignored if B<OPENSSL_NPN_NO_OVERLAP> has been returned from
|
||||
+SSL_select_next_proto().
|
||||
|
||||
SSL_CTX_set_next_proto_select_cb() sets a callback B<cb> that is called when a
|
||||
client needs to select a protocol from the server's provided list, and a
|
||||
@@ -85,9 +93,10 @@ must be set to point to the selected protocol (which may be within B<in>).
|
||||
The length of the protocol name must be written into B<outlen>. The
|
||||
server's advertised protocols are provided in B<in> and B<inlen>. The
|
||||
callback can assume that B<in> is syntactically valid. The client must
|
||||
-select a protocol. It is fatal to the connection if this callback returns
|
||||
-a value other than B<SSL_TLSEXT_ERR_OK>. The B<arg> parameter is the pointer
|
||||
-set via SSL_CTX_set_next_proto_select_cb().
|
||||
+select a protocol (although it may be an empty, zero length protocol). It is
|
||||
+fatal to the connection if this callback returns a value other than
|
||||
+B<SSL_TLSEXT_ERR_OK> or if the zero length protocol is selected. The B<arg>
|
||||
+parameter is the pointer set via SSL_CTX_set_next_proto_select_cb().
|
||||
|
||||
SSL_CTX_set_next_protos_advertised_cb() sets a callback B<cb> that is called
|
||||
when a TLS server needs a list of supported protocols for Next Protocol
|
||||
@@ -149,7 +158,8 @@ A match was found and is returned in B<out>, B<outlen>.
|
||||
=item OPENSSL_NPN_NO_OVERLAP
|
||||
|
||||
No match was found. The first item in B<client>, B<client_len> is returned in
|
||||
-B<out>, B<outlen>.
|
||||
+B<out>, B<outlen> (or B<NULL> and 0 in the case where the first entry in
|
||||
+B<client> is invalid).
|
||||
|
||||
=back
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
178
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_4.patch
Normal file
178
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_4.patch
Normal file
@@ -0,0 +1,178 @@
|
||||
From 6f9e71968f1f5e089bf79b0925e703a16f7bfa19 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 31 May 2024 16:35:16 +0100
|
||||
Subject: [PATCH 4/9] Add a test for SSL_select_next_proto
|
||||
|
||||
Follow on from CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit ad1318efa2cfdf43ed49d23c4a815f4754604b97)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/707c71aa03ba968e09325d72cf1e8dcac70df2df]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
test/sslapitest.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 137 insertions(+)
|
||||
|
||||
diff --git a/test/sslapitest.c b/test/sslapitest.c
|
||||
index 2b1c2fd..3922262 100644
|
||||
--- a/test/sslapitest.c
|
||||
+++ b/test/sslapitest.c
|
||||
@@ -10765,6 +10765,142 @@ static int test_multi_resume(int idx)
|
||||
return testresult;
|
||||
}
|
||||
|
||||
+static struct next_proto_st {
|
||||
+ int serverlen;
|
||||
+ unsigned char server[40];
|
||||
+ int clientlen;
|
||||
+ unsigned char client[40];
|
||||
+ int expected_ret;
|
||||
+ size_t selectedlen;
|
||||
+ unsigned char selected[40];
|
||||
+} next_proto_tests[] = {
|
||||
+ {
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NEGOTIATED,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 7, { 3, 'a', 'b', 'c', 2, 'a', 'b' },
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NEGOTIATED,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c', },
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NEGOTIATED,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ 7, { 3, 'a', 'b', 'c', 2, 'a', 'b', },
|
||||
+ OPENSSL_NPN_NEGOTIATED,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'},
|
||||
+ OPENSSL_NPN_NEGOTIATED,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 7, { 2, 'b', 'c', 3, 'a', 'b', 'c' },
|
||||
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'},
|
||||
+ OPENSSL_NPN_NEGOTIATED,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 10, { 2, 'b', 'c', 3, 'a', 'b', 'c', 2, 'a', 'b' },
|
||||
+ 7, { 2, 'a', 'b', 3, 'a', 'b', 'c'},
|
||||
+ OPENSSL_NPN_NEGOTIATED,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 4, { 3, 'b', 'c', 'd' },
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NO_OVERLAP,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 0, { 0 },
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NO_OVERLAP,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ -1, { 0 },
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NO_OVERLAP,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ 0, { 0 },
|
||||
+ OPENSSL_NPN_NO_OVERLAP,
|
||||
+ 0, { 0 }
|
||||
+ },
|
||||
+ {
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ -1, { 0 },
|
||||
+ OPENSSL_NPN_NO_OVERLAP,
|
||||
+ 0, { 0 }
|
||||
+ },
|
||||
+ {
|
||||
+ 3, { 3, 'a', 'b', 'c' },
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NO_OVERLAP,
|
||||
+ 3, { 'a', 'b', 'c' }
|
||||
+ },
|
||||
+ {
|
||||
+ 4, { 3, 'a', 'b', 'c' },
|
||||
+ 3, { 3, 'a', 'b', 'c' },
|
||||
+ OPENSSL_NPN_NO_OVERLAP,
|
||||
+ 0, { 0 }
|
||||
+ }
|
||||
+};
|
||||
+
|
||||
+static int test_select_next_proto(int idx)
|
||||
+{
|
||||
+ struct next_proto_st *np = &next_proto_tests[idx];
|
||||
+ int ret = 0;
|
||||
+ unsigned char *out, *client, *server;
|
||||
+ unsigned char outlen;
|
||||
+ unsigned int clientlen, serverlen;
|
||||
+
|
||||
+ if (np->clientlen == -1) {
|
||||
+ client = NULL;
|
||||
+ clientlen = 0;
|
||||
+ } else {
|
||||
+ client = np->client;
|
||||
+ clientlen = (unsigned int)np->clientlen;
|
||||
+ }
|
||||
+ if (np->serverlen == -1) {
|
||||
+ server = NULL;
|
||||
+ serverlen = 0;
|
||||
+ } else {
|
||||
+ server = np->server;
|
||||
+ serverlen = (unsigned int)np->serverlen;
|
||||
+ }
|
||||
+
|
||||
+ if (!TEST_int_eq(SSL_select_next_proto(&out, &outlen, server, serverlen,
|
||||
+ client, clientlen),
|
||||
+ np->expected_ret))
|
||||
+ goto err;
|
||||
+
|
||||
+ if (np->selectedlen == 0) {
|
||||
+ if (!TEST_ptr_null(out) || !TEST_uchar_eq(outlen, 0))
|
||||
+ goto err;
|
||||
+ } else {
|
||||
+ if (!TEST_mem_eq(out, outlen, np->selected, np->selectedlen))
|
||||
+ goto err;
|
||||
+ }
|
||||
+
|
||||
+ ret = 1;
|
||||
+ err:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
|
||||
|
||||
int setup_tests(void)
|
||||
@@ -11041,6 +11177,7 @@ int setup_tests(void)
|
||||
#endif
|
||||
ADD_ALL_TESTS(test_handshake_retry, 16);
|
||||
ADD_ALL_TESTS(test_multi_resume, 5);
|
||||
+ ADD_ALL_TESTS(test_select_next_proto, OSSL_NELEM(next_proto_tests));
|
||||
return 1;
|
||||
|
||||
err:
|
||||
--
|
||||
2.25.1
|
||||
|
||||
1175
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_5.patch
Normal file
1175
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_5.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,45 @@
|
||||
From a8c0ee154d212284f82680275de63642d914365e Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 21 Jun 2024 10:41:55 +0100
|
||||
Subject: [PATCH 6/9] Correct return values for
|
||||
tls_construct_stoc_next_proto_neg
|
||||
|
||||
Return EXT_RETURN_NOT_SENT in the event that we don't send the extension,
|
||||
rather than EXT_RETURN_SENT. This actually makes no difference at all to
|
||||
the current control flow since this return value is ignored in this case
|
||||
anyway. But lets make it correct anyway.
|
||||
|
||||
Follow on from CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit 087501b4f572825e27ca8cc2c5874fcf6fd47cf7)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/189a7ed3e380e34ea38fe4190a7c9396bace0fb7]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
ssl/statem/extensions_srvr.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c
|
||||
index 1fab5a3..51ea74b 100644
|
||||
--- a/ssl/statem/extensions_srvr.c
|
||||
+++ b/ssl/statem/extensions_srvr.c
|
||||
@@ -1471,9 +1471,10 @@ EXT_RETURN tls_construct_stoc_next_proto_neg(SSL *s, WPACKET *pkt,
|
||||
return EXT_RETURN_FAIL;
|
||||
}
|
||||
s->s3.npn_seen = 1;
|
||||
+ return EXT_RETURN_SENT;
|
||||
}
|
||||
|
||||
- return EXT_RETURN_SENT;
|
||||
+ return EXT_RETURN_NOT_SENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
From fa5cc5eb58a4c9632929397fc9a6c291fff1b99d Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 21 Jun 2024 11:51:54 +0100
|
||||
Subject: [PATCH 7/9] Add ALPN validation in the client
|
||||
|
||||
The ALPN protocol selected by the server must be one that we originally
|
||||
advertised. We should verify that it is.
|
||||
|
||||
Follow on from CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit 017e54183b95617825fb9316d618c154a34c634e)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/4b375b998798dd516d367036773073e1b88e6433]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
ssl/statem/extensions_clnt.c | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c
|
||||
index a07dc62..b21ccf9 100644
|
||||
--- a/ssl/statem/extensions_clnt.c
|
||||
+++ b/ssl/statem/extensions_clnt.c
|
||||
@@ -1566,6 +1566,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
size_t chainidx)
|
||||
{
|
||||
size_t len;
|
||||
+ PACKET confpkt, protpkt;
|
||||
+ int valid = 0;
|
||||
|
||||
/* We must have requested it. */
|
||||
if (!s->s3.alpn_sent) {
|
||||
@@ -1584,6 +1586,28 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
|
||||
SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+ /* It must be a protocol that we sent */
|
||||
+ if (!PACKET_buf_init(&confpkt, s->ext.alpn, s->ext.alpn_len)) {
|
||||
+ SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ while (PACKET_get_length_prefixed_1(&confpkt, &protpkt)) {
|
||||
+ if (PACKET_remaining(&protpkt) != len)
|
||||
+ continue;
|
||||
+ if (memcmp(PACKET_data(pkt), PACKET_data(&protpkt), len) == 0) {
|
||||
+ /* Valid protocol found */
|
||||
+ valid = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!valid) {
|
||||
+ /* The protocol sent from the server does not match one we advertised */
|
||||
+ SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
OPENSSL_free(s->s3.alpn_selected);
|
||||
s->s3.alpn_selected = OPENSSL_malloc(len);
|
||||
if (s->s3.alpn_selected == NULL) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
273
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_8.patch
Normal file
273
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_8.patch
Normal file
@@ -0,0 +1,273 @@
|
||||
From b898db2b91751a52d2af699e674a80a6b218084d Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 21 Jun 2024 10:09:41 +0100
|
||||
Subject: [PATCH 8/9] Add explicit testing of ALN and NPN in sslapitest
|
||||
|
||||
We already had some tests elsewhere - but this extends that testing with
|
||||
additional tests.
|
||||
|
||||
Follow on from CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit 0453bf5a7ac60ab01c8bb713d8cc2a94324aa88c)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/ca176d7291eb780e4ed2781342f5be5a32210a68]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
test/sslapitest.c | 229 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 229 insertions(+)
|
||||
|
||||
diff --git a/test/sslapitest.c b/test/sslapitest.c
|
||||
index 3922262..171298b 100644
|
||||
--- a/test/sslapitest.c
|
||||
+++ b/test/sslapitest.c
|
||||
@@ -10901,6 +10901,231 @@ static int test_select_next_proto(int idx)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static const unsigned char fooprot[] = {3, 'f', 'o', 'o' };
|
||||
+static const unsigned char barprot[] = {3, 'b', 'a', 'r' };
|
||||
+
|
||||
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG)
|
||||
+static int npn_advert_cb(SSL *ssl, const unsigned char **out,
|
||||
+ unsigned int *outlen, void *arg)
|
||||
+{
|
||||
+ int *idx = (int *)arg;
|
||||
+
|
||||
+ switch (*idx) {
|
||||
+ default:
|
||||
+ case 0:
|
||||
+ *out = fooprot;
|
||||
+ *outlen = sizeof(fooprot);
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ case 1:
|
||||
+ *outlen = 0;
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ case 2:
|
||||
+ return SSL_TLSEXT_ERR_NOACK;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int npn_select_cb(SSL *s, unsigned char **out, unsigned char *outlen,
|
||||
+ const unsigned char *in, unsigned int inlen, void *arg)
|
||||
+{
|
||||
+ int *idx = (int *)arg;
|
||||
+
|
||||
+ switch (*idx) {
|
||||
+ case 0:
|
||||
+ case 1:
|
||||
+ *out = (unsigned char *)(fooprot + 1);
|
||||
+ *outlen = *fooprot;
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ case 3:
|
||||
+ *out = (unsigned char *)(barprot + 1);
|
||||
+ *outlen = *barprot;
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ case 4:
|
||||
+ *outlen = 0;
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ default:
|
||||
+ case 2:
|
||||
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test the NPN callbacks
|
||||
+ * Test 0: advert = foo, select = foo
|
||||
+ * Test 1: advert = <empty>, select = foo
|
||||
+ * Test 2: no advert
|
||||
+ * Test 3: advert = foo, select = bar
|
||||
+ * Test 4: advert = foo, select = <empty> (should fail)
|
||||
+ */
|
||||
+static int test_npn(int idx)
|
||||
+{
|
||||
+ SSL_CTX *sctx = NULL, *cctx = NULL;
|
||||
+ SSL *serverssl = NULL, *clientssl = NULL;
|
||||
+ int testresult = 0;
|
||||
+
|
||||
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
||||
+ TLS_client_method(), 0, TLS1_2_VERSION,
|
||||
+ &sctx, &cctx, cert, privkey)))
|
||||
+ goto end;
|
||||
+
|
||||
+ SSL_CTX_set_next_protos_advertised_cb(sctx, npn_advert_cb, &idx);
|
||||
+ SSL_CTX_set_next_proto_select_cb(cctx, npn_select_cb, &idx);
|
||||
+
|
||||
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
|
||||
+ NULL)))
|
||||
+ goto end;
|
||||
+
|
||||
+ if (idx == 4) {
|
||||
+ /* We don't allow empty selection of NPN, so this should fail */
|
||||
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl,
|
||||
+ SSL_ERROR_NONE)))
|
||||
+ goto end;
|
||||
+ } else {
|
||||
+ const unsigned char *prot;
|
||||
+ unsigned int protlen;
|
||||
+
|
||||
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
||||
+ SSL_ERROR_NONE)))
|
||||
+ goto end;
|
||||
+
|
||||
+ SSL_get0_next_proto_negotiated(serverssl, &prot, &protlen);
|
||||
+ switch (idx) {
|
||||
+ case 0:
|
||||
+ case 1:
|
||||
+ if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot))
|
||||
+ goto end;
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ if (!TEST_uint_eq(protlen, 0))
|
||||
+ goto end;
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ if (!TEST_mem_eq(prot, protlen, barprot + 1, *barprot))
|
||||
+ goto end;
|
||||
+ break;
|
||||
+ default:
|
||||
+ TEST_error("Should not get here");
|
||||
+ goto end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ testresult = 1;
|
||||
+ end:
|
||||
+ SSL_free(serverssl);
|
||||
+ SSL_free(clientssl);
|
||||
+ SSL_CTX_free(sctx);
|
||||
+ SSL_CTX_free(cctx);
|
||||
+
|
||||
+ return testresult;
|
||||
+}
|
||||
+#endif /* !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) */
|
||||
+
|
||||
+static int alpn_select_cb2(SSL *ssl, const unsigned char **out,
|
||||
+ unsigned char *outlen, const unsigned char *in,
|
||||
+ unsigned int inlen, void *arg)
|
||||
+{
|
||||
+ int *idx = (int *)arg;
|
||||
+
|
||||
+ switch (*idx) {
|
||||
+ case 0:
|
||||
+ *out = (unsigned char *)(fooprot + 1);
|
||||
+ *outlen = *fooprot;
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ case 2:
|
||||
+ *out = (unsigned char *)(barprot + 1);
|
||||
+ *outlen = *barprot;
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ case 3:
|
||||
+ *outlen = 0;
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+
|
||||
+ default:
|
||||
+ case 1:
|
||||
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Test the ALPN callbacks
|
||||
+ * Test 0: client = foo, select = foo
|
||||
+ * Test 1: client = <empty>, select = none
|
||||
+ * Test 2: client = foo, select = bar (should fail)
|
||||
+ * Test 3: client = foo, select = <empty> (should fail)
|
||||
+ */
|
||||
+static int test_alpn(int idx)
|
||||
+{
|
||||
+ SSL_CTX *sctx = NULL, *cctx = NULL;
|
||||
+ SSL *serverssl = NULL, *clientssl = NULL;
|
||||
+ int testresult = 0;
|
||||
+ const unsigned char *prots = fooprot;
|
||||
+ unsigned int protslen = sizeof(fooprot);
|
||||
+
|
||||
+ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(),
|
||||
+ TLS_client_method(), 0, 0,
|
||||
+ &sctx, &cctx, cert, privkey)))
|
||||
+ goto end;
|
||||
+
|
||||
+ SSL_CTX_set_alpn_select_cb(sctx, alpn_select_cb2, &idx);
|
||||
+
|
||||
+ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL,
|
||||
+ NULL)))
|
||||
+ goto end;
|
||||
+
|
||||
+ if (idx == 1) {
|
||||
+ prots = NULL;
|
||||
+ protslen = 0;
|
||||
+ }
|
||||
+
|
||||
+ /* SSL_set_alpn_protos returns 0 for success! */
|
||||
+ if (!TEST_false(SSL_set_alpn_protos(clientssl, prots, protslen)))
|
||||
+ goto end;
|
||||
+
|
||||
+ if (idx == 2 || idx == 3) {
|
||||
+ /* We don't allow empty selection of NPN, so this should fail */
|
||||
+ if (!TEST_false(create_ssl_connection(serverssl, clientssl,
|
||||
+ SSL_ERROR_NONE)))
|
||||
+ goto end;
|
||||
+ } else {
|
||||
+ const unsigned char *prot;
|
||||
+ unsigned int protlen;
|
||||
+
|
||||
+ if (!TEST_true(create_ssl_connection(serverssl, clientssl,
|
||||
+ SSL_ERROR_NONE)))
|
||||
+ goto end;
|
||||
+
|
||||
+ SSL_get0_alpn_selected(clientssl, &prot, &protlen);
|
||||
+ switch (idx) {
|
||||
+ case 0:
|
||||
+ if (!TEST_mem_eq(prot, protlen, fooprot + 1, *fooprot))
|
||||
+ goto end;
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ if (!TEST_uint_eq(protlen, 0))
|
||||
+ goto end;
|
||||
+ break;
|
||||
+ default:
|
||||
+ TEST_error("Should not get here");
|
||||
+ goto end;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ testresult = 1;
|
||||
+ end:
|
||||
+ SSL_free(serverssl);
|
||||
+ SSL_free(clientssl);
|
||||
+ SSL_CTX_free(sctx);
|
||||
+ SSL_CTX_free(cctx);
|
||||
+
|
||||
+ return testresult;
|
||||
+}
|
||||
+
|
||||
OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config dhfile\n")
|
||||
|
||||
int setup_tests(void)
|
||||
@@ -11178,6 +11403,10 @@ int setup_tests(void)
|
||||
ADD_ALL_TESTS(test_handshake_retry, 16);
|
||||
ADD_ALL_TESTS(test_multi_resume, 5);
|
||||
ADD_ALL_TESTS(test_select_next_proto, OSSL_NELEM(next_proto_tests));
|
||||
+#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG)
|
||||
+ ADD_ALL_TESTS(test_npn, 5);
|
||||
+#endif
|
||||
+ ADD_ALL_TESTS(test_alpn, 4);
|
||||
return 1;
|
||||
|
||||
err:
|
||||
--
|
||||
2.25.1
|
||||
|
||||
205
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_9.patch
Normal file
205
meta/recipes-connectivity/openssl/openssl/CVE-2024-5535_9.patch
Normal file
@@ -0,0 +1,205 @@
|
||||
From 475480db0f9592f15f00a7cf692d3e04ad8e742f Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 21 Jun 2024 14:29:26 +0100
|
||||
Subject: [PATCH 9/9] Add a test for an empty NextProto message
|
||||
|
||||
It is valid according to the spec for a NextProto message to have no
|
||||
protocols listed in it. The OpenSSL implementation however does not allow
|
||||
us to create such a message. In order to check that we work as expected
|
||||
when communicating with a client that does generate such messages we have
|
||||
to use a TLSProxy test.
|
||||
|
||||
Follow on from CVE-2024-5535
|
||||
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/24718)
|
||||
|
||||
(cherry picked from commit a201030901de9f9a48b34c38f6922fb0b272f26f)
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/openssl/openssl/commit/99c2b6b971c302595db1801e26a202247238659d]
|
||||
CVE: CVE-2024-5535
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
test/recipes/70-test_npn.t | 73 +++++++++++++++++++++++++++++++++
|
||||
util/perl/TLSProxy/Message.pm | 9 ++++
|
||||
util/perl/TLSProxy/NextProto.pm | 54 ++++++++++++++++++++++++
|
||||
util/perl/TLSProxy/Proxy.pm | 1 +
|
||||
4 files changed, 137 insertions(+)
|
||||
create mode 100644 test/recipes/70-test_npn.t
|
||||
create mode 100644 util/perl/TLSProxy/NextProto.pm
|
||||
|
||||
diff --git a/test/recipes/70-test_npn.t b/test/recipes/70-test_npn.t
|
||||
new file mode 100644
|
||||
index 0000000..f82e71a
|
||||
--- /dev/null
|
||||
+++ b/test/recipes/70-test_npn.t
|
||||
@@ -0,0 +1,73 @@
|
||||
+#! /usr/bin/env perl
|
||||
+# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
+#
|
||||
+# Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
+# this file except in compliance with the License. You can obtain a copy
|
||||
+# in the file LICENSE in the source distribution or at
|
||||
+# https://www.openssl.org/source/license.html
|
||||
+
|
||||
+use strict;
|
||||
+use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file/;
|
||||
+use OpenSSL::Test::Utils;
|
||||
+
|
||||
+use TLSProxy::Proxy;
|
||||
+
|
||||
+my $test_name = "test_npn";
|
||||
+setup($test_name);
|
||||
+
|
||||
+plan skip_all => "TLSProxy isn't usable on $^O"
|
||||
+ if $^O =~ /^(VMS)$/;
|
||||
+
|
||||
+plan skip_all => "$test_name needs the dynamic engine feature enabled"
|
||||
+ if disabled("engine") || disabled("dynamic-engine");
|
||||
+
|
||||
+plan skip_all => "$test_name needs the sock feature enabled"
|
||||
+ if disabled("sock");
|
||||
+
|
||||
+plan skip_all => "$test_name needs NPN enabled"
|
||||
+ if disabled("nextprotoneg");
|
||||
+
|
||||
+plan skip_all => "$test_name needs TLSv1.2 enabled"
|
||||
+ if disabled("tls1_2");
|
||||
+
|
||||
+my $proxy = TLSProxy::Proxy->new(
|
||||
+ undef,
|
||||
+ cmdstr(app(["openssl"]), display => 1),
|
||||
+ srctop_file("apps", "server.pem"),
|
||||
+ (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE})
|
||||
+);
|
||||
+
|
||||
+$proxy->start() or plan skip_all => "Unable to start up Proxy for tests";
|
||||
+plan tests => 1;
|
||||
+
|
||||
+my $npnseen = 0;
|
||||
+
|
||||
+# Test 1: Check sending an empty NextProto message from the client works. This is
|
||||
+# valid as per the spec, but OpenSSL does not allow you to send it.
|
||||
+# Therefore we must be prepared to receive such a message but we cannot
|
||||
+# generate it except via TLSProxy
|
||||
+$proxy->clear();
|
||||
+$proxy->filter(\&npn_filter);
|
||||
+$proxy->clientflags("-nextprotoneg foo -no_tls1_3");
|
||||
+$proxy->serverflags("-nextprotoneg foo");
|
||||
+$proxy->start();
|
||||
+ok($npnseen && TLSProxy::Message->success(), "Empty NPN message");
|
||||
+
|
||||
+sub npn_filter
|
||||
+{
|
||||
+ my $proxy = shift;
|
||||
+ my $message;
|
||||
+
|
||||
+ # The NextProto message always appears in flight 2
|
||||
+ return if $proxy->flight != 2;
|
||||
+
|
||||
+ foreach my $message (@{$proxy->message_list}) {
|
||||
+ if ($message->mt == TLSProxy::Message::MT_NEXT_PROTO) {
|
||||
+ # Our TLSproxy NextProto message support doesn't support parsing of
|
||||
+ # the message. If we repack it just creates an empty NextProto
|
||||
+ # message - which is exactly the scenario we want to test here.
|
||||
+ $message->repack();
|
||||
+ $npnseen = 1;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/util/perl/TLSProxy/Message.pm b/util/perl/TLSProxy/Message.pm
|
||||
index 2c1bdb3..eb350de 100644
|
||||
--- a/util/perl/TLSProxy/Message.pm
|
||||
+++ b/util/perl/TLSProxy/Message.pm
|
||||
@@ -379,6 +379,15 @@ sub create_message
|
||||
[@message_frag_lens]
|
||||
);
|
||||
$message->parse();
|
||||
+ } elsif ($mt == MT_NEXT_PROTO) {
|
||||
+ $message = TLSProxy::NextProto->new(
|
||||
+ $server,
|
||||
+ $data,
|
||||
+ [@message_rec_list],
|
||||
+ $startoffset,
|
||||
+ [@message_frag_lens]
|
||||
+ );
|
||||
+ $message->parse();
|
||||
} else {
|
||||
#Unknown message type
|
||||
$message = TLSProxy::Message->new(
|
||||
diff --git a/util/perl/TLSProxy/NextProto.pm b/util/perl/TLSProxy/NextProto.pm
|
||||
new file mode 100644
|
||||
index 0000000..0e18347
|
||||
--- /dev/null
|
||||
+++ b/util/perl/TLSProxy/NextProto.pm
|
||||
@@ -0,0 +1,54 @@
|
||||
+# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
|
||||
+#
|
||||
+# Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
+# this file except in compliance with the License. You can obtain a copy
|
||||
+# in the file LICENSE in the source distribution or at
|
||||
+# https://www.openssl.org/source/license.html
|
||||
+
|
||||
+use strict;
|
||||
+
|
||||
+package TLSProxy::NextProto;
|
||||
+
|
||||
+use vars '@ISA';
|
||||
+push @ISA, 'TLSProxy::Message';
|
||||
+
|
||||
+sub new
|
||||
+{
|
||||
+ my $class = shift;
|
||||
+ my ($server,
|
||||
+ $data,
|
||||
+ $records,
|
||||
+ $startoffset,
|
||||
+ $message_frag_lens) = @_;
|
||||
+
|
||||
+ my $self = $class->SUPER::new(
|
||||
+ $server,
|
||||
+ TLSProxy::Message::MT_NEXT_PROTO,
|
||||
+ $data,
|
||||
+ $records,
|
||||
+ $startoffset,
|
||||
+ $message_frag_lens);
|
||||
+
|
||||
+ return $self;
|
||||
+}
|
||||
+
|
||||
+sub parse
|
||||
+{
|
||||
+ # We don't support parsing at the moment
|
||||
+}
|
||||
+
|
||||
+# This is supposed to reconstruct the on-the-wire message data following changes.
|
||||
+# For now though since we don't support parsing we just create an empty NextProto
|
||||
+# message - this capability is used in test_npn
|
||||
+sub set_message_contents
|
||||
+{
|
||||
+ my $self = shift;
|
||||
+ my $data;
|
||||
+
|
||||
+ $data = pack("C32", 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
+ 0x00, 0x00, 0x00);
|
||||
+ $self->data($data);
|
||||
+}
|
||||
+1;
|
||||
diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm
|
||||
index 3de10ec..b707722 100644
|
||||
--- a/util/perl/TLSProxy/Proxy.pm
|
||||
+++ b/util/perl/TLSProxy/Proxy.pm
|
||||
@@ -23,6 +23,7 @@ use TLSProxy::CertificateRequest;
|
||||
use TLSProxy::CertificateVerify;
|
||||
use TLSProxy::ServerKeyExchange;
|
||||
use TLSProxy::NewSessionTicket;
|
||||
+use TLSProxy::NextProto;
|
||||
|
||||
my $have_IPv6;
|
||||
my $IP_factory;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -12,15 +12,22 @@ SRC_URI = "http://www.openssl.org/source/openssl-${PV}.tar.gz \
|
||||
file://0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch \
|
||||
file://afalg.patch \
|
||||
file://0001-Configure-do-not-tweak-mips-cflags.patch \
|
||||
file://CVE-2024-2511.patch \
|
||||
file://CVE-2024-4603.patch \
|
||||
file://CVE-2024-5535_1.patch \
|
||||
file://CVE-2024-5535_2.patch \
|
||||
file://CVE-2024-5535_3.patch \
|
||||
file://CVE-2024-5535_4.patch \
|
||||
file://CVE-2024-5535_5.patch \
|
||||
file://CVE-2024-5535_6.patch \
|
||||
file://CVE-2024-5535_7.patch \
|
||||
file://CVE-2024-5535_8.patch \
|
||||
file://CVE-2024-5535_9.patch \
|
||||
"
|
||||
|
||||
SRC_URI:append:class-nativesdk = " \
|
||||
file://environment.d-openssl.sh \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "88525753f79d3bec27d2fa7c66aa0b92b3aa9498dafd93d7cfa4b3780cdae313"
|
||||
SRC_URI[sha256sum] = "eeca035d4dd4e84fc25846d952da6297484afa0650a6f84c682e39df3a4123ca"
|
||||
|
||||
inherit lib_package multilib_header multilib_script ptest perlnative
|
||||
MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash"
|
||||
@@ -0,0 +1,213 @@
|
||||
From f6f7cead3661ceeef54b21f7e799c0afc98537ec Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Sat, 8 Jul 2023 19:55:32 +0300
|
||||
Subject: [PATCH] PEAP client: Update Phase 2 authentication requirements
|
||||
|
||||
The previous PEAP client behavior allowed the server to skip Phase 2
|
||||
authentication with the expectation that the server was authenticated
|
||||
during Phase 1 through TLS server certificate validation. Various PEAP
|
||||
specifications are not exactly clear on what the behavior on this front
|
||||
is supposed to be and as such, this ended up being more flexible than
|
||||
the TTLS/FAST/TEAP cases. However, this is not really ideal when
|
||||
unfortunately common misconfiguration of PEAP is used in deployed
|
||||
devices where the server trust root (ca_cert) is not configured or the
|
||||
user has an easy option for allowing this validation step to be skipped.
|
||||
|
||||
Change the default PEAP client behavior to be to require Phase 2
|
||||
authentication to be successfully completed for cases where TLS session
|
||||
resumption is not used and the client certificate has not been
|
||||
configured. Those two exceptions are the main cases where a deployed
|
||||
authentication server might skip Phase 2 and as such, where a more
|
||||
strict default behavior could result in undesired interoperability
|
||||
issues. Requiring Phase 2 authentication will end up disabling TLS
|
||||
session resumption automatically to avoid interoperability issues.
|
||||
|
||||
Allow Phase 2 authentication behavior to be configured with a new phase1
|
||||
configuration parameter option:
|
||||
'phase2_auth' option can be used to control Phase 2 (i.e., within TLS
|
||||
tunnel) behavior for PEAP:
|
||||
* 0 = do not require Phase 2 authentication
|
||||
* 1 = require Phase 2 authentication when client certificate
|
||||
(private_key/client_cert) is no used and TLS session resumption was
|
||||
not used (default)
|
||||
* 2 = require Phase 2 authentication in all cases
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
|
||||
CVE: CVE-2023-52160
|
||||
Upstream-Status: Backport [https://w1.fi/cgit/hostap/commit/?id=8e6485a1bcb0baffdea9e55255a81270b768439c]
|
||||
|
||||
Signed-off-by: Claus Stovgaard <claus.stovgaard@gmail.com>
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
src/eap_peer/eap_config.h | 8 ++++++
|
||||
src/eap_peer/eap_peap.c | 40 +++++++++++++++++++++++++++---
|
||||
src/eap_peer/eap_tls_common.c | 6 +++++
|
||||
src/eap_peer/eap_tls_common.h | 5 ++++
|
||||
wpa_supplicant/wpa_supplicant.conf | 7 ++++++
|
||||
5 files changed, 63 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
|
||||
index 3238f74..047eec2 100644
|
||||
--- a/src/eap_peer/eap_config.h
|
||||
+++ b/src/eap_peer/eap_config.h
|
||||
@@ -469,6 +469,14 @@ struct eap_peer_config {
|
||||
* 1 = use cryptobinding if server supports it
|
||||
* 2 = require cryptobinding
|
||||
*
|
||||
+ * phase2_auth option can be used to control Phase 2 (i.e., within TLS
|
||||
+ * tunnel) behavior for PEAP:
|
||||
+ * 0 = do not require Phase 2 authentication
|
||||
+ * 1 = require Phase 2 authentication when client certificate
|
||||
+ * (private_key/client_cert) is no used and TLS session resumption was
|
||||
+ * not used (default)
|
||||
+ * 2 = require Phase 2 authentication in all cases
|
||||
+ *
|
||||
* EAP-WSC (WPS) uses following options: pin=Device_Password and
|
||||
* uuid=Device_UUID
|
||||
*
|
||||
diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c
|
||||
index 12e30df..6080697 100644
|
||||
--- a/src/eap_peer/eap_peap.c
|
||||
+++ b/src/eap_peer/eap_peap.c
|
||||
@@ -67,6 +67,7 @@ struct eap_peap_data {
|
||||
u8 cmk[20];
|
||||
int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP)
|
||||
* is enabled. */
|
||||
+ enum { NO_AUTH, FOR_INITIAL, ALWAYS } phase2_auth;
|
||||
};
|
||||
|
||||
|
||||
@@ -114,6 +115,19 @@ static void eap_peap_parse_phase1(struct eap_peap_data *data,
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding");
|
||||
}
|
||||
|
||||
+ if (os_strstr(phase1, "phase2_auth=0")) {
|
||||
+ data->phase2_auth = NO_AUTH;
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "EAP-PEAP: Do not require Phase 2 authentication");
|
||||
+ } else if (os_strstr(phase1, "phase2_auth=1")) {
|
||||
+ data->phase2_auth = FOR_INITIAL;
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "EAP-PEAP: Require Phase 2 authentication for initial connection");
|
||||
+ } else if (os_strstr(phase1, "phase2_auth=2")) {
|
||||
+ data->phase2_auth = ALWAYS;
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "EAP-PEAP: Require Phase 2 authentication for all cases");
|
||||
+ }
|
||||
#ifdef EAP_TNC
|
||||
if (os_strstr(phase1, "tnc=soh2")) {
|
||||
data->soh = 2;
|
||||
@@ -142,6 +156,7 @@ static void * eap_peap_init(struct eap_sm *sm)
|
||||
data->force_peap_version = -1;
|
||||
data->peap_outer_success = 2;
|
||||
data->crypto_binding = OPTIONAL_BINDING;
|
||||
+ data->phase2_auth = FOR_INITIAL;
|
||||
|
||||
if (config && config->phase1)
|
||||
eap_peap_parse_phase1(data, config->phase1);
|
||||
@@ -454,6 +469,20 @@ static int eap_tlv_validate_cryptobinding(struct eap_sm *sm,
|
||||
}
|
||||
|
||||
|
||||
+static bool peap_phase2_sufficient(struct eap_sm *sm,
|
||||
+ struct eap_peap_data *data)
|
||||
+{
|
||||
+ if ((data->phase2_auth == ALWAYS ||
|
||||
+ (data->phase2_auth == FOR_INITIAL &&
|
||||
+ !tls_connection_resumed(sm->ssl_ctx, data->ssl.conn) &&
|
||||
+ !data->ssl.client_cert_conf) ||
|
||||
+ data->phase2_eap_started) &&
|
||||
+ !data->phase2_eap_success)
|
||||
+ return false;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/**
|
||||
* eap_tlv_process - Process a received EAP-TLV message and generate a response
|
||||
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||
@@ -568,6 +597,11 @@ static int eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data,
|
||||
" - force failed Phase 2");
|
||||
resp_status = EAP_TLV_RESULT_FAILURE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
+ } else if (!peap_phase2_sufficient(sm, data)) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ "EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed");
|
||||
+ resp_status = EAP_TLV_RESULT_FAILURE;
|
||||
+ ret->decision = DECISION_FAIL;
|
||||
} else {
|
||||
resp_status = EAP_TLV_RESULT_SUCCESS;
|
||||
ret->decision = DECISION_UNCOND_SUCC;
|
||||
@@ -887,8 +921,7 @@ continue_req:
|
||||
/* EAP-Success within TLS tunnel is used to indicate
|
||||
* shutdown of the TLS channel. The authentication has
|
||||
* been completed. */
|
||||
- if (data->phase2_eap_started &&
|
||||
- !data->phase2_eap_success) {
|
||||
+ if (!peap_phase2_sufficient(sm, data)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 "
|
||||
"Success used to indicate success, "
|
||||
"but Phase 2 EAP was not yet "
|
||||
@@ -1199,8 +1232,9 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv,
|
||||
static bool eap_peap_has_reauth_data(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_peap_data *data = priv;
|
||||
+
|
||||
return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
|
||||
- data->phase2_success;
|
||||
+ data->phase2_success && data->phase2_auth != ALWAYS;
|
||||
}
|
||||
|
||||
|
||||
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
|
||||
index c1837db..a53eeb1 100644
|
||||
--- a/src/eap_peer/eap_tls_common.c
|
||||
+++ b/src/eap_peer/eap_tls_common.c
|
||||
@@ -239,6 +239,12 @@ static int eap_tls_params_from_conf(struct eap_sm *sm,
|
||||
|
||||
sm->ext_cert_check = !!(params->flags & TLS_CONN_EXT_CERT_CHECK);
|
||||
|
||||
+ if (!phase2)
|
||||
+ data->client_cert_conf = params->client_cert ||
|
||||
+ params->client_cert_blob ||
|
||||
+ params->private_key ||
|
||||
+ params->private_key_blob;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/src/eap_peer/eap_tls_common.h b/src/eap_peer/eap_tls_common.h
|
||||
index 9ac0012..3348634 100644
|
||||
--- a/src/eap_peer/eap_tls_common.h
|
||||
+++ b/src/eap_peer/eap_tls_common.h
|
||||
@@ -79,6 +79,11 @@ struct eap_ssl_data {
|
||||
* tls_v13 - Whether TLS v1.3 or newer is used
|
||||
*/
|
||||
int tls_v13;
|
||||
+
|
||||
+ /**
|
||||
+ * client_cert_conf: Whether client certificate has been configured
|
||||
+ */
|
||||
+ bool client_cert_conf;
|
||||
};
|
||||
|
||||
|
||||
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
|
||||
index 6619d6b..d63f73c 100644
|
||||
--- a/wpa_supplicant/wpa_supplicant.conf
|
||||
+++ b/wpa_supplicant/wpa_supplicant.conf
|
||||
@@ -1321,6 +1321,13 @@ fast_reauth=1
|
||||
# * 0 = do not use cryptobinding (default)
|
||||
# * 1 = use cryptobinding if server supports it
|
||||
# * 2 = require cryptobinding
|
||||
+# 'phase2_auth' option can be used to control Phase 2 (i.e., within TLS
|
||||
+# tunnel) behavior for PEAP:
|
||||
+# * 0 = do not require Phase 2 authentication
|
||||
+# * 1 = require Phase 2 authentication when client certificate
|
||||
+# (private_key/client_cert) is no used and TLS session resumption was
|
||||
+# not used (default)
|
||||
+# * 2 = require Phase 2 authentication in all cases
|
||||
# EAP-WSC (WPS) uses following options: pin=<Device Password> or
|
||||
# pbc=1.
|
||||
#
|
||||
@@ -25,6 +25,7 @@ SRC_URI = "http://w1.fi/releases/wpa_supplicant-${PV}.tar.gz \
|
||||
file://wpa_supplicant.conf \
|
||||
file://wpa_supplicant.conf-sane \
|
||||
file://99_wpa_supplicant \
|
||||
file://0001-PEAP-client-Update-Phase-2-authentication-requiremen.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "20df7ae5154b3830355f8ab4269123a87affdea59fe74fe9292a91d0d7e17b2f"
|
||||
|
||||
|
||||
151
meta/recipes-core/busybox/busybox/CVE-2021-42380.patch
Normal file
151
meta/recipes-core/busybox/busybox/CVE-2021-42380.patch
Normal file
@@ -0,0 +1,151 @@
|
||||
From 5dcc443dba039b305a510c01883e9f34e42656ae Mon Sep 17 00:00:00 2001
|
||||
From: Denys Vlasenko <vda.linux@googlemail.com>
|
||||
Date: Fri, 26 May 2023 19:36:58 +0200
|
||||
Subject: [PATCH] awk: fix use-after-realloc (CVE-2021-42380), closes 15601
|
||||
|
||||
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
||||
|
||||
CVE: CVE-2021-42380
|
||||
Upstream-Status: Backport [https://git.busybox.net/busybox/commit/?id=5dcc443dba039b305a510c01883e9f34e42656ae]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
editors/awk.c | 26 ++++++++++++++++-----
|
||||
testsuite/awk.tests | 55 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 75 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/editors/awk.c b/editors/awk.c
|
||||
index 728ee8685..2af823808 100644
|
||||
--- a/editors/awk.c
|
||||
+++ b/editors/awk.c
|
||||
@@ -555,7 +555,7 @@ struct globals {
|
||||
const char *g_progname;
|
||||
int g_lineno;
|
||||
int nfields;
|
||||
- int maxfields; /* used in fsrealloc() only */
|
||||
+ unsigned maxfields;
|
||||
var *Fields;
|
||||
char *g_pos;
|
||||
char g_saved_ch;
|
||||
@@ -1917,9 +1917,9 @@ static void fsrealloc(int size)
|
||||
{
|
||||
int i, newsize;
|
||||
|
||||
- if (size >= maxfields) {
|
||||
- /* Sanity cap, easier than catering for overflows */
|
||||
- if (size > 0xffffff)
|
||||
+ if ((unsigned)size >= maxfields) {
|
||||
+ /* Sanity cap, easier than catering for over/underflows */
|
||||
+ if ((unsigned)size > 0xffffff)
|
||||
bb_die_memory_exhausted();
|
||||
|
||||
i = maxfields;
|
||||
@@ -2877,6 +2877,7 @@ static var *evaluate(node *op, var *res)
|
||||
uint32_t opinfo;
|
||||
int opn;
|
||||
node *op1;
|
||||
+ var *old_Fields_ptr;
|
||||
|
||||
opinfo = op->info;
|
||||
opn = (opinfo & OPNMASK);
|
||||
@@ -2885,10 +2886,16 @@ static var *evaluate(node *op, var *res)
|
||||
debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn);
|
||||
|
||||
/* execute inevitable things */
|
||||
+ old_Fields_ptr = NULL;
|
||||
if (opinfo & OF_RES1) {
|
||||
if ((opinfo & OF_REQUIRED) && !op1)
|
||||
syntax_error(EMSG_TOO_FEW_ARGS);
|
||||
L.v = evaluate(op1, TMPVAR0);
|
||||
+ /* Does L.v point to $n variable? */
|
||||
+ if ((size_t)(L.v - Fields) < maxfields) {
|
||||
+ /* yes, remember where Fields[] is */
|
||||
+ old_Fields_ptr = Fields;
|
||||
+ }
|
||||
if (opinfo & OF_STR1) {
|
||||
L.s = getvar_s(L.v);
|
||||
debug_printf_eval("L.s:'%s'\n", L.s);
|
||||
@@ -2907,8 +2914,15 @@ static var *evaluate(node *op, var *res)
|
||||
*/
|
||||
if (opinfo & OF_RES2) {
|
||||
R.v = evaluate(op->r.n, TMPVAR1);
|
||||
- //TODO: L.v may be invalid now, set L.v to NULL to catch bugs?
|
||||
- //L.v = NULL;
|
||||
+ /* Seen in $5=$$5=$0:
|
||||
+ * Evaluation of R.v ($$5=$0 expression)
|
||||
+ * made L.v ($5) invalid. It's detected here.
|
||||
+ */
|
||||
+ if (old_Fields_ptr) {
|
||||
+ //if (old_Fields_ptr != Fields)
|
||||
+ // debug_printf_eval("L.v moved\n");
|
||||
+ L.v += Fields - old_Fields_ptr;
|
||||
+ }
|
||||
if (opinfo & OF_STR2) {
|
||||
R.s = getvar_s(R.v);
|
||||
debug_printf_eval("R.s:'%s'\n", R.s);
|
||||
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
|
||||
index bcaafe8..08afdb2 100755
|
||||
--- a/testsuite/awk.tests
|
||||
+++ b/testsuite/awk.tests
|
||||
@@ -469,4 +469,59 @@ testing 'awk printf %% prints one %' \
|
||||
"%\n" \
|
||||
'' ''
|
||||
|
||||
+# User-supplied bug (SEGV) example, was causing use-after-realloc
|
||||
+testing 'awk assign while assign' \
|
||||
+ "awk '\$5=\$\$5=\$0'; echo \$?" \
|
||||
+ "\
|
||||
+─ process timing ────────────────────────────────────┬─ ─ process timing ────────────────────────────────────┬─ overall results ────┐ results ────┐
|
||||
+│ run time : │ run time : 0 days, 0 hrs, 0 min, 56 sec │ cycles done : 0 │ days, 0 hrs, 0 min, 56 sec │ cycles done : 0 │
|
||||
+│ last new find │ last new find : 0 days, 0 hrs, 0 min, 1 sec │ corpus count : 208 │ 0 days, 0 hrs, 0 min, 1 sec │ corpus count : 208 │
|
||||
+│last saved crash : │last saved crash : none seen yet │saved crashes : 0 │ seen yet │saved crashes : 0 │
|
||||
+│ last saved hang │ last saved hang : none seen yet │ saved hangs : 0 │ none seen yet │ saved hangs : 0 │
|
||||
+├─ cycle progress ─────────────────────┬─ ├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤ coverage┴──────────────────────┤
|
||||
+│ now processing : │ now processing : 184.1 (88.5%) │ map density : 0.30% / 0.52% │ (88.5%) │ map density : 0.30% / 0.52% │ │ now processing : 184.1 (88.5%) │ map density : 0.30% / 0.52% │
|
||||
+│ runs timed out │ runs timed out : 0 (0.00%) │ count coverage : 2.18 bits/tuple │ 0 (0.00%) │ count coverage : 2.18 bits/tuple │
|
||||
+├─ stage progress ─────────────────────┼─ ├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤ in depth ─────────────────┤
|
||||
+│ now trying : │ now trying : havoc │ favored items : 43 (20.67%) │ │ favored items : 43 (20.67%) │
|
||||
+│ stage execs : │ stage execs : 11.2k/131k (8.51%) │ new edges on : 52 (25.00%) │ (8.51%) │ new edges on │ stage execs : 11.2k/131k (8.51%) │ new edges on : 52 (25.00%) │ 52 (25.00%) │
|
||||
+│ total execs : │ total execs : 179k │ total crashes : 0 (0 saved) │ │ total crashes : 0 (0 saved) │ │ total execs : 179k │ total crashes : 0 (0 saved) │
|
||||
+│ exec speed : │ exec speed : 3143/sec │ total tmouts : 0 (0 saved) │ │ total tmouts : 0 (0 saved) │ │ exec speed : 3143/sec │ total tmouts : 0 (0 saved) │
|
||||
+├─ fuzzing strategy yields ├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤ item geometry ───────┤
|
||||
+│ bit flips : │ bit flips : 11/648, 4/638, 5/618 │ levels : 4 │ 4/638, 5/618 │ levels : │ bit flips : 11/648, 4/638, 5/618 │ levels : 4 │ │
|
||||
+│ byte flips : │ byte flips : 0/81, 0/71, 0/52 │ pending : 199 │ 0/71, 0/52 │ pending : 199 │
|
||||
+│ arithmetics : 11/4494, │ arithmetics : 11/4494, 0/1153, 0/0 │ pend fav : 35 │ 0/0 │ pend fav : 35 │
|
||||
+│ known ints : 1/448, 0/1986, 0/2288 │ own finds : 207 │ known ints : │ known ints : 1/448, 0/1986, 0/2288 │ own finds : 207 │ 0/1986, 0/2288 │ own finds : 207 │
|
||||
+│ dictionary : 0/0, │ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 0 │ 0/0, 0/0 │ imported : 0 │
|
||||
+│havoc/splice : 142/146k, 23/7616 │havoc/splice : 142/146k, 23/7616 │ stability : 100.00% │ stability : 100.00% │
|
||||
+│py/custom/rq : unused, unused, │py/custom/rq : unused, unused, unused, unused ├───────────────────────┘ unused ├───────────────────────┘
|
||||
+│ trim/eff : 57.02%/26, │ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%] │ [cpu000:100%]
|
||||
+└────────────────────────────────────────────────────┘^C └────────────────────────────────────────────────────┘^C
|
||||
+0
|
||||
+" \
|
||||
+ "" \
|
||||
+ "\
|
||||
+─ process timing ────────────────────────────────────┬─ overall results ────┐
|
||||
+│ run time : 0 days, 0 hrs, 0 min, 56 sec │ cycles done : 0 │
|
||||
+│ last new find : 0 days, 0 hrs, 0 min, 1 sec │ corpus count : 208 │
|
||||
+│last saved crash : none seen yet │saved crashes : 0 │
|
||||
+│ last saved hang : none seen yet │ saved hangs : 0 │
|
||||
+├─ cycle progress ─────────────────────┬─ map coverage┴──────────────────────┤
|
||||
+│ now processing : 184.1 (88.5%) │ map density : 0.30% / 0.52% │
|
||||
+│ runs timed out : 0 (0.00%) │ count coverage : 2.18 bits/tuple │
|
||||
+├─ stage progress ─────────────────────┼─ findings in depth ─────────────────┤
|
||||
+│ now trying : havoc │ favored items : 43 (20.67%) │
|
||||
+│ stage execs : 11.2k/131k (8.51%) │ new edges on : 52 (25.00%) │
|
||||
+│ total execs : 179k │ total crashes : 0 (0 saved) │
|
||||
+│ exec speed : 3143/sec │ total tmouts : 0 (0 saved) │
|
||||
+├─ fuzzing strategy yields ────────────┴─────────────┬─ item geometry ───────┤
|
||||
+│ bit flips : 11/648, 4/638, 5/618 │ levels : 4 │
|
||||
+│ byte flips : 0/81, 0/71, 0/52 │ pending : 199 │
|
||||
+│ arithmetics : 11/4494, 0/1153, 0/0 │ pend fav : 35 │
|
||||
+│ known ints : 1/448, 0/1986, 0/2288 │ own finds : 207 │
|
||||
+│ dictionary : 0/0, 0/0, 0/0, 0/0 │ imported : 0 │
|
||||
+│havoc/splice : 142/146k, 23/7616 │ stability : 100.00% │
|
||||
+│py/custom/rq : unused, unused, unused, unused ├───────────────────────┘
|
||||
+│ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%]
|
||||
+└────────────────────────────────────────────────────┘^C"
|
||||
+
|
||||
exit $FAILCOUNT
|
||||
--
|
||||
2.30.2
|
||||
|
||||
68
meta/recipes-core/busybox/busybox/CVE-2023-42363.patch
Normal file
68
meta/recipes-core/busybox/busybox/CVE-2023-42363.patch
Normal file
@@ -0,0 +1,68 @@
|
||||
From fb08d43d44d1fea1f741fafb9aa7e1958a5f69aa Mon Sep 17 00:00:00 2001
|
||||
From: Natanael Copa <ncopa@alpinelinux.org>
|
||||
Date: Mon, 20 May 2024 17:55:28 +0200
|
||||
Subject: awk: fix use after free (CVE-2023-42363)
|
||||
|
||||
function old new delta
|
||||
evaluate 3377 3385 +8
|
||||
|
||||
Fixes https://bugs.busybox.net/show_bug.cgi?id=15865
|
||||
|
||||
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
|
||||
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.busybox.net/busybox/commit/?id=fb08d43d44d1fea1f741fafb9aa7e1958a5f69aa]
|
||||
CVE: CVE-2023-42363
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
editors/awk.c | 21 +++++++++++++--------
|
||||
1 file changed, 13 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/editors/awk.c b/editors/awk.c
|
||||
index 654cbac..4fbc11d 100644
|
||||
--- a/editors/awk.c
|
||||
+++ b/editors/awk.c
|
||||
@@ -2896,19 +2896,14 @@ static var *evaluate(node *op, var *res)
|
||||
/* yes, remember where Fields[] is */
|
||||
old_Fields_ptr = Fields;
|
||||
}
|
||||
- if (opinfo & OF_STR1) {
|
||||
- L.s = getvar_s(L.v);
|
||||
- debug_printf_eval("L.s:'%s'\n", L.s);
|
||||
- }
|
||||
if (opinfo & OF_NUM1) {
|
||||
L_d = getvar_i(L.v);
|
||||
debug_printf_eval("L_d:%f\n", L_d);
|
||||
}
|
||||
}
|
||||
- /* NB: Must get string/numeric values of L (done above)
|
||||
- * _before_ evaluate()'ing R.v: if both L and R are $NNNs,
|
||||
- * and right one is large, then L.v points to Fields[NNN1],
|
||||
- * second evaluate() reallocates and moves (!) Fields[],
|
||||
+ /* NB: if both L and R are $NNNs, and right one is large,
|
||||
+ * then at this pint L.v points to Fields[NNN1], second
|
||||
+ * evaluate() below reallocates and moves (!) Fields[],
|
||||
* R.v points to Fields[NNN2] but L.v now points to freed mem!
|
||||
* (Seen trying to evaluate "$444 $44444")
|
||||
*/
|
||||
@@ -2928,6 +2923,16 @@ static var *evaluate(node *op, var *res)
|
||||
debug_printf_eval("R.s:'%s'\n", R.s);
|
||||
}
|
||||
}
|
||||
+ /* Get L.s _after_ R.v is evaluated: it may have realloc'd L.v
|
||||
+ * so we must get the string after "old_Fields_ptr" correction
|
||||
+ * above. Testcase: x = (v = "abc", gsub("b", "X", v));
|
||||
+ */
|
||||
+ if (opinfo & OF_RES1) {
|
||||
+ if (opinfo & OF_STR1) {
|
||||
+ L.s = getvar_s(L.v);
|
||||
+ debug_printf_eval("L.s:'%s'\n", L.s);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
debug_printf_eval("switch(0x%x)\n", XC(opinfo & OPCLSMASK));
|
||||
switch (XC(opinfo & OPCLSMASK)) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
197
meta/recipes-core/busybox/busybox/CVE-2023-42364_42365-1.patch
Normal file
197
meta/recipes-core/busybox/busybox/CVE-2023-42364_42365-1.patch
Normal file
@@ -0,0 +1,197 @@
|
||||
From dedc9380c76834ba64c8b526aef6f461ea4e7f2e Mon Sep 17 00:00:00 2001
|
||||
From: Denys Vlasenko <vda.linux@googlemail.com>
|
||||
Date: Tue, 30 May 2023 16:42:18 +0200
|
||||
Subject: [PATCH 1/2] awk: fix precedence of = relative to ==
|
||||
|
||||
Discovered while adding code to disallow assignments to non-lvalues
|
||||
|
||||
function old new delta
|
||||
parse_expr 936 991 +55
|
||||
.rodata 105243 105247 +4
|
||||
------------------------------------------------------------------------------
|
||||
(add/remove: 0/0 grow/shrink: 2/0 up/down: 59/0) Total: 59 bytes
|
||||
|
||||
Upstream-Status: Backport [https://git.busybox.net/busybox/commit/?id=0256e00a9d077588bd3a39f5a1ef7e2eaa2911e4]
|
||||
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
|
||||
(cherry picked from commit 0256e00a9d077588bd3a39f5a1ef7e2eaa2911e4)
|
||||
|
||||
CVE: CVE-2023-42364 CVE-2023-42365
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
editors/awk.c | 66 ++++++++++++++++++++++++++++++---------------
|
||||
testsuite/awk.tests | 5 ++++
|
||||
2 files changed, 50 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/editors/awk.c b/editors/awk.c
|
||||
index ec9301e..aff86fe 100644
|
||||
--- a/editors/awk.c
|
||||
+++ b/editors/awk.c
|
||||
@@ -337,7 +337,9 @@ static void debug_parse_print_tc(uint32_t n)
|
||||
#undef P
|
||||
#undef PRIMASK
|
||||
#undef PRIMASK2
|
||||
-#define P(x) (x << 24)
|
||||
+/* Smaller 'x' means _higher_ operator precedence */
|
||||
+#define PRECEDENCE(x) (x << 24)
|
||||
+#define P(x) PRECEDENCE(x)
|
||||
#define PRIMASK 0x7F000000
|
||||
#define PRIMASK2 0x7E000000
|
||||
|
||||
@@ -360,7 +362,7 @@ enum {
|
||||
OC_MOVE = 0x1f00, OC_PGETLINE = 0x2000, OC_REGEXP = 0x2100,
|
||||
OC_REPLACE = 0x2200, OC_RETURN = 0x2300, OC_SPRINTF = 0x2400,
|
||||
OC_TERNARY = 0x2500, OC_UNARY = 0x2600, OC_VAR = 0x2700,
|
||||
- OC_DONE = 0x2800,
|
||||
+ OC_CONST = 0x2800, OC_DONE = 0x2900,
|
||||
|
||||
ST_IF = 0x3000, ST_DO = 0x3100, ST_FOR = 0x3200,
|
||||
ST_WHILE = 0x3300
|
||||
@@ -440,9 +442,9 @@ static const uint32_t tokeninfo[] ALIGN4 = {
|
||||
#define TI_PREINC (OC_UNARY|xV|P(9)|'P')
|
||||
#define TI_PREDEC (OC_UNARY|xV|P(9)|'M')
|
||||
TI_PREINC, TI_PREDEC, OC_FIELD|xV|P(5),
|
||||
- OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(74), OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-',
|
||||
- OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&',
|
||||
- OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&',
|
||||
+ OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(38), OC_REPLACE|NV|P(38)|'+', OC_REPLACE|NV|P(38)|'-',
|
||||
+ OC_REPLACE|NV|P(38)|'*', OC_REPLACE|NV|P(38)|'/', OC_REPLACE|NV|P(38)|'%', OC_REPLACE|NV|P(38)|'&',
|
||||
+ OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(38)|'&', OC_BINARY|NV|P(15)|'&',
|
||||
OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*',
|
||||
OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1,
|
||||
#define TI_LESS (OC_COMPARE|VV|P(39)|2)
|
||||
@@ -1290,7 +1292,7 @@ static uint32_t next_token(uint32_t expected)
|
||||
save_tclass = tc;
|
||||
save_info = t_info;
|
||||
tc = TC_BINOPX;
|
||||
- t_info = OC_CONCAT | SS | P(35);
|
||||
+ t_info = OC_CONCAT | SS | PRECEDENCE(35);
|
||||
}
|
||||
|
||||
t_tclass = tc;
|
||||
@@ -1350,9 +1352,8 @@ static node *parse_expr(uint32_t term_tc)
|
||||
{
|
||||
node sn;
|
||||
node *cn = &sn;
|
||||
- node *vn, *glptr;
|
||||
+ node *glptr;
|
||||
uint32_t tc, expected_tc;
|
||||
- var *v;
|
||||
|
||||
debug_printf_parse("%s() term_tc(%x):", __func__, term_tc);
|
||||
debug_parse_print_tc(term_tc);
|
||||
@@ -1363,11 +1364,12 @@ static node *parse_expr(uint32_t term_tc)
|
||||
expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP | term_tc;
|
||||
|
||||
while (!((tc = next_token(expected_tc)) & term_tc)) {
|
||||
+ node *vn;
|
||||
|
||||
if (glptr && (t_info == TI_LESS)) {
|
||||
/* input redirection (<) attached to glptr node */
|
||||
debug_printf_parse("%s: input redir\n", __func__);
|
||||
- cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37));
|
||||
+ cn = glptr->l.n = new_node(OC_CONCAT | SS | PRECEDENCE(37));
|
||||
cn->a.n = glptr;
|
||||
expected_tc = TS_OPERAND | TS_UOPPRE;
|
||||
glptr = NULL;
|
||||
@@ -1379,24 +1381,42 @@ static node *parse_expr(uint32_t term_tc)
|
||||
* previous operators with higher priority */
|
||||
vn = cn;
|
||||
while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2))
|
||||
- || ((t_info == vn->info) && t_info == TI_COLON)
|
||||
+ || (t_info == vn->info && t_info == TI_COLON)
|
||||
) {
|
||||
vn = vn->a.n;
|
||||
if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN);
|
||||
}
|
||||
if (t_info == TI_TERNARY)
|
||||
//TODO: why?
|
||||
- t_info += P(6);
|
||||
+ t_info += PRECEDENCE(6);
|
||||
cn = vn->a.n->r.n = new_node(t_info);
|
||||
cn->a.n = vn->a.n;
|
||||
if (tc & TS_BINOP) {
|
||||
cn->l.n = vn;
|
||||
-//FIXME: this is the place to detect and reject assignments to non-lvalues.
|
||||
-//Currently we allow "assignments" to consts and temporaries, nonsense like this:
|
||||
-// awk 'BEGIN { "qwe" = 1 }'
|
||||
-// awk 'BEGIN { 7 *= 7 }'
|
||||
-// awk 'BEGIN { length("qwe") = 1 }'
|
||||
-// awk 'BEGIN { (1+1) += 3 }'
|
||||
+
|
||||
+ /* Prevent:
|
||||
+ * awk 'BEGIN { "qwe" = 1 }'
|
||||
+ * awk 'BEGIN { 7 *= 7 }'
|
||||
+ * awk 'BEGIN { length("qwe") = 1 }'
|
||||
+ * awk 'BEGIN { (1+1) += 3 }'
|
||||
+ */
|
||||
+ /* Assignment? (including *= and friends) */
|
||||
+ if (((t_info & OPCLSMASK) == OC_MOVE)
|
||||
+ || ((t_info & OPCLSMASK) == OC_REPLACE)
|
||||
+ ) {
|
||||
+ debug_printf_parse("%s: MOVE/REPLACE vn->info:%08x\n", __func__, vn->info);
|
||||
+ /* Left side is a (variable or array element)
|
||||
+ * or function argument
|
||||
+ * or $FIELD ?
|
||||
+ */
|
||||
+ if ((vn->info & OPCLSMASK) != OC_VAR
|
||||
+ && (vn->info & OPCLSMASK) != OC_FNARG
|
||||
+ && (vn->info & OPCLSMASK) != OC_FIELD
|
||||
+ ) {
|
||||
+ syntax_error(EMSG_UNEXP_TOKEN); /* no. bad */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP;
|
||||
if (t_info == TI_PGETLINE) {
|
||||
/* it's a pipe */
|
||||
@@ -1432,6 +1452,8 @@ static node *parse_expr(uint32_t term_tc)
|
||||
/* one should be very careful with switch on tclass -
|
||||
* only simple tclasses should be used (TC_xyz, not TS_xyz) */
|
||||
switch (tc) {
|
||||
+ var *v;
|
||||
+
|
||||
case TC_VARIABLE:
|
||||
case TC_ARRAY:
|
||||
debug_printf_parse("%s: TC_VARIABLE | TC_ARRAY\n", __func__);
|
||||
@@ -1452,14 +1474,14 @@ static node *parse_expr(uint32_t term_tc)
|
||||
case TC_NUMBER:
|
||||
case TC_STRING:
|
||||
debug_printf_parse("%s: TC_NUMBER | TC_STRING\n", __func__);
|
||||
- cn->info = OC_VAR;
|
||||
+ cn->info = OC_CONST;
|
||||
v = cn->l.v = xzalloc(sizeof(var));
|
||||
- if (tc & TC_NUMBER)
|
||||
+ if (tc & TC_NUMBER) {
|
||||
setvar_i(v, t_double);
|
||||
- else {
|
||||
+ } else {
|
||||
setvar_s(v, t_string);
|
||||
- expected_tc &= ~TC_UOPPOST; /* "str"++ is not allowed */
|
||||
}
|
||||
+ expected_tc &= ~TC_UOPPOST; /* NUM++, "str"++ not allowed */
|
||||
break;
|
||||
|
||||
case TC_REGEXP:
|
||||
@@ -3107,6 +3129,8 @@ static var *evaluate(node *op, var *res)
|
||||
|
||||
/* -- recursive node type -- */
|
||||
|
||||
+ case XC( OC_CONST ):
|
||||
+ debug_printf_eval("CONST ");
|
||||
case XC( OC_VAR ):
|
||||
debug_printf_eval("VAR\n");
|
||||
L.v = op->l.v;
|
||||
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
|
||||
index ddc5104..a78fdcd 100755
|
||||
--- a/testsuite/awk.tests
|
||||
+++ b/testsuite/awk.tests
|
||||
@@ -540,4 +540,9 @@ testing 'awk assign while assign' \
|
||||
│ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%]
|
||||
└────────────────────────────────────────────────────┘^C"
|
||||
|
||||
+testing "awk = has higher precedence than == (despite what gawk manpage claims)" \
|
||||
+ "awk 'BEGIN { v=1; print 2==v; print 2==v=2; print v; print v=3==3; print v}'" \
|
||||
+ '0\n1\n2\n1\n3\n' \
|
||||
+ '' ''
|
||||
+
|
||||
exit $FAILCOUNT
|
||||
@@ -0,0 +1,96 @@
|
||||
From c3bfdac8e0e9a21d524ad72036953f68d2193e52 Mon Sep 17 00:00:00 2001
|
||||
From: Natanael Copa <ncopa@alpinelinux.org>
|
||||
Date: Tue, 21 May 2024 14:46:08 +0200
|
||||
Subject: [PATCH 2/2] awk: fix ternary operator and precedence of =
|
||||
|
||||
Adjust the = precedence test to match behavior of gawk, mawk and
|
||||
FreeBSD. awk 'BEGIN {print v=3==3; print v}' should print two '1'.
|
||||
|
||||
To fix this, and to unbreak the ternary conditional operator, we restore
|
||||
the precedence of = in the token list, but override this with a lower
|
||||
priority when the assignment is on the right side of a compare.
|
||||
|
||||
This fixes commit 0256e00a9d07 (awk: fix precedence of = relative to ==) [1]
|
||||
|
||||
Upstream-Status: Submitted [http://lists.busybox.net/pipermail/busybox/2024-May/090766.html]
|
||||
|
||||
[1] https://bugs.busybox.net/show_bug.cgi?id=15871#c6
|
||||
|
||||
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
|
||||
(cherry picked from commit 1714301c405ef03b39605c85c23f22a190cddd95)
|
||||
|
||||
CVE: CVE-2023-42364 CVE-2023-42365
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
editors/awk.c | 18 ++++++++++++++----
|
||||
testsuite/awk.tests | 9 +++++++--
|
||||
2 files changed, 21 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/editors/awk.c b/editors/awk.c
|
||||
index aff86fe..f320d8c 100644
|
||||
--- a/editors/awk.c
|
||||
+++ b/editors/awk.c
|
||||
@@ -442,9 +442,10 @@ static const uint32_t tokeninfo[] ALIGN4 = {
|
||||
#define TI_PREINC (OC_UNARY|xV|P(9)|'P')
|
||||
#define TI_PREDEC (OC_UNARY|xV|P(9)|'M')
|
||||
TI_PREINC, TI_PREDEC, OC_FIELD|xV|P(5),
|
||||
- OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(38), OC_REPLACE|NV|P(38)|'+', OC_REPLACE|NV|P(38)|'-',
|
||||
- OC_REPLACE|NV|P(38)|'*', OC_REPLACE|NV|P(38)|'/', OC_REPLACE|NV|P(38)|'%', OC_REPLACE|NV|P(38)|'&',
|
||||
- OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(38)|'&', OC_BINARY|NV|P(15)|'&',
|
||||
+#define TI_ASSIGN (OC_MOVE|VV|P(74))
|
||||
+ OC_COMPARE|VV|P(39)|5, TI_ASSIGN, OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-',
|
||||
+ OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&',
|
||||
+ OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&',
|
||||
OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*',
|
||||
OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1,
|
||||
#define TI_LESS (OC_COMPARE|VV|P(39)|2)
|
||||
@@ -1376,11 +1377,19 @@ static node *parse_expr(uint32_t term_tc)
|
||||
continue;
|
||||
}
|
||||
if (tc & (TS_BINOP | TC_UOPPOST)) {
|
||||
+ int prio;
|
||||
debug_printf_parse("%s: TS_BINOP | TC_UOPPOST tc:%x\n", __func__, tc);
|
||||
/* for binary and postfix-unary operators, jump back over
|
||||
* previous operators with higher priority */
|
||||
vn = cn;
|
||||
- while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2))
|
||||
+ /* Let assignment get higher priority when used on right
|
||||
+ * side in compare. i.e: 2==v=3 */
|
||||
+ if (t_info == TI_ASSIGN && (vn->a.n->info & OPCLSMASK) == OC_COMPARE) {
|
||||
+ prio = PRECEDENCE(38);
|
||||
+ } else {
|
||||
+ prio = (t_info & PRIMASK);
|
||||
+ }
|
||||
+ while ((prio > (vn->a.n->info & PRIMASK2))
|
||||
|| (t_info == vn->info && t_info == TI_COLON)
|
||||
) {
|
||||
vn = vn->a.n;
|
||||
@@ -1412,6 +1421,7 @@ static node *parse_expr(uint32_t term_tc)
|
||||
if ((vn->info & OPCLSMASK) != OC_VAR
|
||||
&& (vn->info & OPCLSMASK) != OC_FNARG
|
||||
&& (vn->info & OPCLSMASK) != OC_FIELD
|
||||
+ && (vn->info & OPCLSMASK) != OC_COMPARE
|
||||
) {
|
||||
syntax_error(EMSG_UNEXP_TOKEN); /* no. bad */
|
||||
}
|
||||
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
|
||||
index a78fdcd..d2706de 100755
|
||||
--- a/testsuite/awk.tests
|
||||
+++ b/testsuite/awk.tests
|
||||
@@ -540,9 +540,14 @@ testing 'awk assign while assign' \
|
||||
│ trim/eff : 57.02%/26, 0.00% │ [cpu000:100%]
|
||||
└────────────────────────────────────────────────────┘^C"
|
||||
|
||||
-testing "awk = has higher precedence than == (despite what gawk manpage claims)" \
|
||||
+testing "awk = has higher precedence than == on right side" \
|
||||
"awk 'BEGIN { v=1; print 2==v; print 2==v=2; print v; print v=3==3; print v}'" \
|
||||
- '0\n1\n2\n1\n3\n' \
|
||||
+ '0\n1\n2\n1\n1\n' \
|
||||
+ '' ''
|
||||
+
|
||||
+testing 'awk ternary precedence' \
|
||||
+ "awk 'BEGIN { a = 0 ? \"yes\": \"no\"; print a }'" \
|
||||
+ 'no\n' \
|
||||
'' ''
|
||||
|
||||
exit $FAILCOUNT
|
||||
36
meta/recipes-core/busybox/busybox/CVE-2023-42366.patch
Normal file
36
meta/recipes-core/busybox/busybox/CVE-2023-42366.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 8542236894a8d5f7393327117bc7f64787444efc Mon Sep 17 00:00:00 2001
|
||||
From: Valery Ushakov <uwe@stderr.spb.ru>
|
||||
Date: Wed, 24 Jan 2024 22:24:41 +0300
|
||||
Subject: [PATCH] awk.c: fix CVE-2023-42366 (bug #15874)
|
||||
|
||||
Make sure we don't read past the end of the string in next_token()
|
||||
when backslash is the last character in an (invalid) regexp.
|
||||
a fix and issue reported in bugzilla
|
||||
|
||||
https://bugs.busybox.net/show_bug.cgi?id=15874
|
||||
|
||||
Upstream-Status: Submitted [http://lists.busybox.net/pipermail/busybox/2024-May/090766.html]
|
||||
CVE: CVE-2023-42366
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
editors/awk.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/editors/awk.c b/editors/awk.c
|
||||
index f320d8c..a53b193 100644
|
||||
--- a/editors/awk.c
|
||||
+++ b/editors/awk.c
|
||||
@@ -1168,9 +1168,11 @@ static uint32_t next_token(uint32_t expected)
|
||||
s[-1] = bb_process_escape_sequence((const char **)&pp);
|
||||
if (*p == '\\')
|
||||
*s++ = '\\';
|
||||
- if (pp == p)
|
||||
+ if (pp == p) {
|
||||
+ if (*p == '\0')
|
||||
+ syntax_error(EMSG_UNEXP_EOS);
|
||||
*s++ = *p++;
|
||||
- else
|
||||
+ } else
|
||||
p = pp;
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,11 @@ SRC_URI = "https://busybox.net/downloads/busybox-${PV}.tar.bz2;name=tarball \
|
||||
file://CVE-2022-30065.patch \
|
||||
file://0001-devmem-add-128-bit-width.patch \
|
||||
file://CVE-2022-48174.patch \
|
||||
file://CVE-2021-42380.patch \
|
||||
file://CVE-2023-42363.patch \
|
||||
file://CVE-2023-42364_42365-1.patch \
|
||||
file://CVE-2023-42364_42365-2.patch \
|
||||
file://CVE-2023-42366.patch \
|
||||
"
|
||||
SRC_URI:append:libc-musl = " file://musl.cfg "
|
||||
|
||||
|
||||
129
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_01.patch
Normal file
129
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_01.patch
Normal file
@@ -0,0 +1,129 @@
|
||||
From c4e3022918565253ffad52449dd0e648b6d772c7 Mon Sep 17 00:00:00 2001
|
||||
From: Philip Withnall <pwithnall@gnome.org>
|
||||
Date: Tue, 28 Nov 2023 12:58:20 +0000
|
||||
Subject: [PATCH 01/18] gdbusmessage: Cache the arg0 value
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Technically we can’t rely on it being kept alive by the `message->body`
|
||||
pointer, unless we can guarantee that the `GVariant` is always
|
||||
serialised. That’s not necessarily the case, so keep a separate ref on
|
||||
the arg0 value at all times.
|
||||
|
||||
This avoids a potential use-after-free.
|
||||
|
||||
Spotted by Thomas Haller in
|
||||
https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3720#note_1924707.
|
||||
|
||||
[This is a prerequisite for having tests pass after fixing the
|
||||
vulnerability described in glib#3268, because after fixing that
|
||||
vulnerability, the use-after-free genuinely does happen during
|
||||
regression testing. -smcv]
|
||||
|
||||
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
|
||||
|
||||
Helps: #3183, #3268
|
||||
(cherry picked from commit 10e9a917be7fb92b6b27837ef7a7f1d0be6095d5)
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/c4e3022918565253ffad52449dd0e648b6d772c7]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusmessage.c | 35 ++++++++++++++++++++++-------------
|
||||
1 file changed, 22 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/gio/gdbusmessage.c b/gio/gdbusmessage.c
|
||||
index ecef6cd3c..3fd1151ca 100644
|
||||
--- a/gio/gdbusmessage.c
|
||||
+++ b/gio/gdbusmessage.c
|
||||
@@ -506,6 +506,7 @@ struct _GDBusMessage
|
||||
guint32 serial;
|
||||
GHashTable *headers;
|
||||
GVariant *body;
|
||||
+ GVariant *arg0_cache; /* (nullable) (owned) */
|
||||
#ifdef G_OS_UNIX
|
||||
GUnixFDList *fd_list;
|
||||
#endif
|
||||
@@ -528,6 +529,7 @@ g_dbus_message_finalize (GObject *object)
|
||||
g_hash_table_unref (message->headers);
|
||||
if (message->body != NULL)
|
||||
g_variant_unref (message->body);
|
||||
+ g_clear_pointer (&message->arg0_cache, g_variant_unref);
|
||||
#ifdef G_OS_UNIX
|
||||
if (message->fd_list != NULL)
|
||||
g_object_unref (message->fd_list);
|
||||
@@ -1163,6 +1165,7 @@ g_dbus_message_set_body (GDBusMessage *message,
|
||||
if (body == NULL)
|
||||
{
|
||||
message->body = NULL;
|
||||
+ message->arg0_cache = NULL;
|
||||
g_dbus_message_set_signature (message, NULL);
|
||||
}
|
||||
else
|
||||
@@ -1173,6 +1176,12 @@ g_dbus_message_set_body (GDBusMessage *message,
|
||||
|
||||
message->body = g_variant_ref_sink (body);
|
||||
|
||||
+ if (g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE) &&
|
||||
+ g_variant_n_children (message->body) > 0)
|
||||
+ message->arg0_cache = g_variant_get_child_value (message->body, 0);
|
||||
+ else
|
||||
+ message->arg0_cache = NULL;
|
||||
+
|
||||
type_string = g_variant_get_type_string (body);
|
||||
type_string_len = strlen (type_string);
|
||||
g_assert (type_string_len >= 2);
|
||||
@@ -2325,6 +2334,14 @@ g_dbus_message_new_from_blob (guchar *blob,
|
||||
2,
|
||||
&local_error);
|
||||
g_variant_type_free (variant_type);
|
||||
+
|
||||
+ if (message->body != NULL &&
|
||||
+ g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE) &&
|
||||
+ g_variant_n_children (message->body) > 0)
|
||||
+ message->arg0_cache = g_variant_get_child_value (message->body, 0);
|
||||
+ else
|
||||
+ message->arg0_cache = NULL;
|
||||
+
|
||||
if (message->body == NULL)
|
||||
goto fail;
|
||||
}
|
||||
@@ -3364,22 +3381,13 @@ g_dbus_message_set_signature (GDBusMessage *message,
|
||||
const gchar *
|
||||
g_dbus_message_get_arg0 (GDBusMessage *message)
|
||||
{
|
||||
- const gchar *ret;
|
||||
-
|
||||
g_return_val_if_fail (G_IS_DBUS_MESSAGE (message), NULL);
|
||||
|
||||
- ret = NULL;
|
||||
+ if (message->arg0_cache != NULL &&
|
||||
+ g_variant_is_of_type (message->arg0_cache, G_VARIANT_TYPE_STRING))
|
||||
+ return g_variant_get_string (message->arg0_cache, NULL);
|
||||
|
||||
- if (message->body != NULL && g_variant_is_of_type (message->body, G_VARIANT_TYPE_TUPLE))
|
||||
- {
|
||||
- GVariant *item;
|
||||
- item = g_variant_get_child_value (message->body, 0);
|
||||
- if (g_variant_is_of_type (item, G_VARIANT_TYPE_STRING))
|
||||
- ret = g_variant_get_string (item, NULL);
|
||||
- g_variant_unref (item);
|
||||
- }
|
||||
-
|
||||
- return ret;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
@@ -3822,6 +3830,7 @@ g_dbus_message_copy (GDBusMessage *message,
|
||||
* to just ref (as opposed to deep-copying) the GVariant instances
|
||||
*/
|
||||
ret->body = message->body != NULL ? g_variant_ref (message->body) : NULL;
|
||||
+ ret->arg0_cache = message->arg0_cache != NULL ? g_variant_ref (message->arg0_cache) : NULL;
|
||||
g_hash_table_iter_init (&iter, message->headers);
|
||||
while (g_hash_table_iter_next (&iter, &header_key, (gpointer) &header_value))
|
||||
g_hash_table_insert (ret->headers, header_key, g_variant_ref (header_value));
|
||||
--
|
||||
2.30.2
|
||||
|
||||
62
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_02.patch
Normal file
62
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_02.patch
Normal file
@@ -0,0 +1,62 @@
|
||||
From c805fd3862baaa114d1cceee27cc931264894c98 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Wed, 1 May 2024 15:51:42 +0100
|
||||
Subject: [PATCH 02/18] gdbusconnection: Make a backport of g_set_str()
|
||||
available
|
||||
|
||||
A subsequent commit will need this. Copying all of g_set_str() into a
|
||||
private header seems cleaner than replacing the call to it.
|
||||
|
||||
Helps: GNOME/glib#3268
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/c805fd3862baaa114d1cceee27cc931264894c98]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 1 +
|
||||
glib/glib-private.h | 18 ++++++++++++++++++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index 1159c2db4..82a68437b 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -95,6 +95,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
+#include "glib-private.h"
|
||||
#include "gdbusauth.h"
|
||||
#include "gdbusutils.h"
|
||||
#include "gdbusaddress.h"
|
||||
diff --git a/glib/glib-private.h b/glib/glib-private.h
|
||||
index 943252f1b..f02828ff5 100644
|
||||
--- a/glib/glib-private.h
|
||||
+++ b/glib/glib-private.h
|
||||
@@ -201,4 +201,22 @@ GLibPrivateVTable *glib__private__ (void);
|
||||
# define GLIB_DEFAULT_LOCALE ""
|
||||
#endif
|
||||
|
||||
+/* Backported from GLib 2.78.x, where it is public API in gstrfuncs.h */
|
||||
+static inline gboolean
|
||||
+g_set_str (char **str_pointer,
|
||||
+ const char *new_str)
|
||||
+{
|
||||
+ char *copy;
|
||||
+
|
||||
+ if (*str_pointer == new_str ||
|
||||
+ (*str_pointer && new_str && strcmp (*str_pointer, new_str) == 0))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ copy = g_strdup (new_str);
|
||||
+ g_free (*str_pointer);
|
||||
+ *str_pointer = copy;
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
#endif /* __GLIB_PRIVATE_H__ */
|
||||
--
|
||||
2.30.2
|
||||
|
||||
985
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_03.patch
Normal file
985
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_03.patch
Normal file
@@ -0,0 +1,985 @@
|
||||
From 8b1d90457e2e72f1d7db7cb77b74754af3a5c4ef Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Fri, 8 Mar 2024 14:19:46 +0000
|
||||
Subject: [PATCH 03/18] tests: Add a data-driven test for signal subscriptions
|
||||
|
||||
This somewhat duplicates test_connection_signals(), but is easier to
|
||||
extend to cover different scenarios.
|
||||
|
||||
Each scenario is tested three times: once with lower-level
|
||||
GDBusConnection APIs, once with the higher-level GDBusProxy (which
|
||||
cannot implement all of the subscription scenarios, so some message
|
||||
counts are lower), and once with both (to check that delivery of the
|
||||
same message to multiple destinations is handled appropriately).
|
||||
|
||||
[Backported to glib-2-74, resolving conflicts in gio/tests/meson.build]
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/8b1d90457e2e72f1d7db7cb77b74754af3a5c4ef]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-subscribe.c | 938 ++++++++++++++++++++++++++++++++++++
|
||||
gio/tests/meson.build | 1 +
|
||||
2 files changed, 939 insertions(+)
|
||||
create mode 100644 gio/tests/gdbus-subscribe.c
|
||||
|
||||
diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c
|
||||
new file mode 100644
|
||||
index 000000000..3f53e1d7f
|
||||
--- /dev/null
|
||||
+++ b/gio/tests/gdbus-subscribe.c
|
||||
@@ -0,0 +1,938 @@
|
||||
+/*
|
||||
+ * Copyright 2024 Collabora Ltd.
|
||||
+ * SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+ */
|
||||
+
|
||||
+#include <gio/gio.h>
|
||||
+
|
||||
+#include "gdbus-tests.h"
|
||||
+
|
||||
+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
+#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
+#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS
|
||||
+
|
||||
+/* A signal that each connection emits to indicate that it has finished
|
||||
+ * emitting other signals */
|
||||
+#define FINISHED_PATH "/org/gtk/Test/Finished"
|
||||
+#define FINISHED_INTERFACE "org.gtk.Test.Finished"
|
||||
+#define FINISHED_SIGNAL "Finished"
|
||||
+
|
||||
+/* A signal emitted during testing */
|
||||
+#define EXAMPLE_PATH "/org/gtk/GDBus/ExampleInterface"
|
||||
+#define EXAMPLE_INTERFACE "org.gtk.GDBus.ExampleInterface"
|
||||
+#define FOO_SIGNAL "Foo"
|
||||
+
|
||||
+/* Log @s in a debug message. */
|
||||
+static inline const char *
|
||||
+nonnull (const char *s,
|
||||
+ const char *if_null)
|
||||
+{
|
||||
+ return (s == NULL) ? if_null : s;
|
||||
+}
|
||||
+
|
||||
+typedef enum
|
||||
+{
|
||||
+ TEST_CONN_NONE,
|
||||
+ TEST_CONN_FIRST,
|
||||
+ /* A connection that subscribes to signals */
|
||||
+ TEST_CONN_SUBSCRIBER = TEST_CONN_FIRST,
|
||||
+ /* A mockup of a legitimate service */
|
||||
+ TEST_CONN_SERVICE,
|
||||
+ /* A mockup of a second legitimate service */
|
||||
+ TEST_CONN_SERVICE2,
|
||||
+ /* A connection that tries to trick @subscriber into processing its signals
|
||||
+ * as if they came from @service */
|
||||
+ TEST_CONN_ATTACKER,
|
||||
+ NUM_TEST_CONNS
|
||||
+} TestConn;
|
||||
+
|
||||
+static const char * const test_conn_descriptions[NUM_TEST_CONNS] =
|
||||
+{
|
||||
+ "(unused)",
|
||||
+ "subscriber",
|
||||
+ "service",
|
||||
+ "service 2",
|
||||
+ "attacker"
|
||||
+};
|
||||
+
|
||||
+typedef enum
|
||||
+{
|
||||
+ SUBSCRIPTION_MODE_CONN,
|
||||
+ SUBSCRIPTION_MODE_PROXY,
|
||||
+ SUBSCRIPTION_MODE_PARALLEL
|
||||
+} SubscriptionMode;
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ GDBusProxy *received_by_proxy;
|
||||
+ TestConn sender;
|
||||
+ char *path;
|
||||
+ char *iface;
|
||||
+ char *member;
|
||||
+ GVariant *parameters;
|
||||
+ char *arg0;
|
||||
+ guint32 step;
|
||||
+} ReceivedMessage;
|
||||
+
|
||||
+static void
|
||||
+received_message_free (ReceivedMessage *self)
|
||||
+{
|
||||
+
|
||||
+ g_clear_object (&self->received_by_proxy);
|
||||
+ g_free (self->path);
|
||||
+ g_free (self->iface);
|
||||
+ g_free (self->member);
|
||||
+ g_clear_pointer (&self->parameters, g_variant_unref);
|
||||
+ g_free (self->arg0);
|
||||
+ g_free (self);
|
||||
+}
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ TestConn sender;
|
||||
+ TestConn unicast_to;
|
||||
+ const char *path;
|
||||
+ const char *iface;
|
||||
+ const char *member;
|
||||
+ const char *arg0;
|
||||
+ guint received_by_conn;
|
||||
+ guint received_by_proxy;
|
||||
+} TestEmitSignal;
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ TestConn sender;
|
||||
+ const char *path;
|
||||
+ const char *iface;
|
||||
+ const char *member;
|
||||
+ const char *arg0;
|
||||
+ GDBusSignalFlags flags;
|
||||
+} TestSubscribe;
|
||||
+
|
||||
+typedef enum
|
||||
+{
|
||||
+ TEST_ACTION_NONE = 0,
|
||||
+ TEST_ACTION_SUBSCRIBE,
|
||||
+ TEST_ACTION_EMIT_SIGNAL,
|
||||
+} TestAction;
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ TestAction action;
|
||||
+ union {
|
||||
+ TestEmitSignal signal;
|
||||
+ TestSubscribe subscribe;
|
||||
+ } u;
|
||||
+} TestStep;
|
||||
+
|
||||
+/* Arbitrary, extend as necessary to accommodate the longest test */
|
||||
+#define MAX_TEST_STEPS 10
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ const char *description;
|
||||
+ TestStep steps[MAX_TEST_STEPS];
|
||||
+} TestPlan;
|
||||
+
|
||||
+static const TestPlan plan_simple =
|
||||
+{
|
||||
+ .description = "A broadcast is only received after subscribing to it",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ /* We don't receive a signal if we haven't subscribed yet */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Now it works */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 1,
|
||||
+ /* The proxy can't be used in this case, because it needs
|
||||
+ * a bus name to subscribe to */
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const TestPlan plan_broadcast_from_anyone =
|
||||
+{
|
||||
+ .description = "A subscription with NULL sender accepts broadcast and unicast",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ /* Subscriber wants to receive signals from anyone */
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* First service sends a broadcast */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 1,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Second service also sends a broadcast */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE2,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 1,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* First service sends a unicast signal */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .unicast_to = TEST_CONN_SUBSCRIBER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 1,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Second service also sends a unicast signal */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE2,
|
||||
+ .unicast_to = TEST_CONN_SUBSCRIBER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 1,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const TestPlan plan_match_twice =
|
||||
+{
|
||||
+ .description = "A message matching more than one subscription is received "
|
||||
+ "once per subscription",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 4,
|
||||
+ /* Only the first and last work with GDBusProxy */
|
||||
+ .received_by_proxy = 2
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static const TestPlan plan_limit_by_unique_name =
|
||||
+{
|
||||
+ .description = "A subscription via a unique name only accepts messages "
|
||||
+ "sent by that same unique name",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ /* Subscriber wants to receive signals from service */
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Attacker wants to trick subscriber into thinking that service
|
||||
+ * sent a signal */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Attacker tries harder, by sending a signal unicast directly to
|
||||
+ * the subscriber */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .unicast_to = TEST_CONN_SUBSCRIBER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* When the real service sends a signal, it should still get through */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 1,
|
||||
+ .received_by_proxy = 1
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ const TestPlan *plan;
|
||||
+ SubscriptionMode mode;
|
||||
+ GError *error;
|
||||
+ /* (element-type ReceivedMessage) */
|
||||
+ GPtrArray *received;
|
||||
+ /* conns[TEST_CONN_NONE] is unused and remains NULL */
|
||||
+ GDBusConnection *conns[NUM_TEST_CONNS];
|
||||
+ /* Proxies on conns[TEST_CONN_SUBSCRIBER] */
|
||||
+ GPtrArray *proxies;
|
||||
+ /* unique_names[TEST_CONN_NONE] is unused and remains NULL */
|
||||
+ const char *unique_names[NUM_TEST_CONNS];
|
||||
+ /* finished[TEST_CONN_NONE] is unused and remains FALSE */
|
||||
+ gboolean finished[NUM_TEST_CONNS];
|
||||
+ /* Remains 0 for any step that is not a subscription */
|
||||
+ guint subscriptions[MAX_TEST_STEPS];
|
||||
+ /* Number of times the signal from step n was received */
|
||||
+ guint received_by_conn[MAX_TEST_STEPS];
|
||||
+ /* Number of times the signal from step n was received */
|
||||
+ guint received_by_proxy[MAX_TEST_STEPS];
|
||||
+ guint finished_subscription;
|
||||
+} Fixture;
|
||||
+
|
||||
+/* Wait for asynchronous messages from @conn to have been processed
|
||||
+ * by the message bus, as a sequence point so that we can make
|
||||
+ * "happens before" and "happens after" assertions relative to this.
|
||||
+ * The easiest way to achieve this is to call a message bus method that has
|
||||
+ * no arguments and wait for it to return: because the message bus processes
|
||||
+ * messages in-order, anything we sent before this must have been processed
|
||||
+ * by the time this call arrives. */
|
||||
+static void
|
||||
+connection_wait_for_bus (GDBusConnection *conn)
|
||||
+{
|
||||
+ GError *error = NULL;
|
||||
+ GVariant *call_result;
|
||||
+
|
||||
+ call_result = g_dbus_connection_call_sync (conn,
|
||||
+ DBUS_SERVICE_DBUS,
|
||||
+ DBUS_PATH_DBUS,
|
||||
+ DBUS_INTERFACE_DBUS,
|
||||
+ "GetId",
|
||||
+ NULL, /* arguments */
|
||||
+ NULL, /* result type */
|
||||
+ G_DBUS_CALL_FLAGS_NONE,
|
||||
+ -1,
|
||||
+ NULL,
|
||||
+ &error);
|
||||
+ g_assert_no_error (error);
|
||||
+ g_assert_nonnull (call_result);
|
||||
+ g_variant_unref (call_result);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Called when the subscriber receives a message from any connection
|
||||
+ * announcing that it has emitted all the signals that it plans to emit.
|
||||
+ */
|
||||
+static void
|
||||
+subscriber_finished_cb (GDBusConnection *conn,
|
||||
+ const char *sender_name,
|
||||
+ const char *path,
|
||||
+ const char *iface,
|
||||
+ const char *member,
|
||||
+ GVariant *parameters,
|
||||
+ void *user_data)
|
||||
+{
|
||||
+ Fixture *f = user_data;
|
||||
+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||
+ guint i;
|
||||
+
|
||||
+ g_assert_true (conn == subscriber);
|
||||
+
|
||||
+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++)
|
||||
+ {
|
||||
+ if (g_str_equal (sender_name, f->unique_names[i]))
|
||||
+ {
|
||||
+ g_assert_false (f->finished[i]);
|
||||
+ f->finished[i] = TRUE;
|
||||
+
|
||||
+ g_test_message ("Received Finished signal from %s %s",
|
||||
+ test_conn_descriptions[i], sender_name);
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ g_error ("Received Finished signal from unknown sender %s", sender_name);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Called when we receive a signal, either via the GDBusProxy (proxy != NULL)
|
||||
+ * or via the GDBusConnection (proxy == NULL).
|
||||
+ */
|
||||
+static void
|
||||
+fixture_received_signal (Fixture *f,
|
||||
+ GDBusProxy *proxy,
|
||||
+ const char *sender_name,
|
||||
+ const char *path,
|
||||
+ const char *iface,
|
||||
+ const char *member,
|
||||
+ GVariant *parameters)
|
||||
+{
|
||||
+ guint i;
|
||||
+ ReceivedMessage *received;
|
||||
+
|
||||
+ /* Ignore the Finished signal if it matches a wildcard subscription */
|
||||
+ if (g_str_equal (member, FINISHED_SIGNAL))
|
||||
+ return;
|
||||
+
|
||||
+ received = g_new0 (ReceivedMessage, 1);
|
||||
+
|
||||
+ if (proxy != NULL)
|
||||
+ received->received_by_proxy = g_object_ref (proxy);
|
||||
+ else
|
||||
+ received->received_by_proxy = NULL;
|
||||
+
|
||||
+ received->path = g_strdup (path);
|
||||
+ received->iface = g_strdup (iface);
|
||||
+ received->member = g_strdup (member);
|
||||
+ received->parameters = g_variant_ref (parameters);
|
||||
+
|
||||
+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++)
|
||||
+ {
|
||||
+ if (g_str_equal (sender_name, f->unique_names[i]))
|
||||
+ {
|
||||
+ received->sender = i;
|
||||
+ g_assert_false (f->finished[i]);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ g_assert_cmpint (received->sender, !=, TEST_CONN_NONE);
|
||||
+
|
||||
+ g_test_message ("Signal received from %s %s via %s",
|
||||
+ test_conn_descriptions[received->sender],
|
||||
+ sender_name,
|
||||
+ proxy != NULL ? "proxy" : "connection");
|
||||
+ g_test_message ("\tPath: %s", path);
|
||||
+ g_test_message ("\tInterface: %s", iface);
|
||||
+ g_test_message ("\tMember: %s", member);
|
||||
+
|
||||
+ if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(su)")))
|
||||
+ {
|
||||
+ g_variant_get (parameters, "(su)", &received->arg0, &received->step);
|
||||
+ g_test_message ("\tString argument 0: %s", received->arg0);
|
||||
+ g_test_message ("\tSent in step: %u", received->step);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_assert_cmpstr (g_variant_get_type_string (parameters), ==, "(uu)");
|
||||
+ g_variant_get (parameters, "(uu)", NULL, &received->step);
|
||||
+ g_test_message ("\tArgument 0: (not a string)");
|
||||
+ g_test_message ("\tSent in step: %u", received->step);
|
||||
+ }
|
||||
+
|
||||
+ g_ptr_array_add (f->received, g_steal_pointer (&received));
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+proxy_signal_cb (GDBusProxy *proxy,
|
||||
+ const char *sender_name,
|
||||
+ const char *member,
|
||||
+ GVariant *parameters,
|
||||
+ void *user_data)
|
||||
+{
|
||||
+ Fixture *f = user_data;
|
||||
+
|
||||
+ fixture_received_signal (f, proxy, sender_name,
|
||||
+ g_dbus_proxy_get_object_path (proxy),
|
||||
+ g_dbus_proxy_get_interface_name (proxy),
|
||||
+ member, parameters);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+subscribed_signal_cb (GDBusConnection *conn,
|
||||
+ const char *sender_name,
|
||||
+ const char *path,
|
||||
+ const char *iface,
|
||||
+ const char *member,
|
||||
+ GVariant *parameters,
|
||||
+ void *user_data)
|
||||
+{
|
||||
+ Fixture *f = user_data;
|
||||
+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||
+
|
||||
+ g_assert_true (conn == subscriber);
|
||||
+
|
||||
+ fixture_received_signal (f, NULL, sender_name, path, iface, member, parameters);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+fixture_subscribe (Fixture *f,
|
||||
+ const TestSubscribe *subscribe,
|
||||
+ guint step_number)
|
||||
+{
|
||||
+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||
+ const char *sender;
|
||||
+
|
||||
+ if (subscribe->sender != TEST_CONN_NONE)
|
||||
+ {
|
||||
+ sender = f->unique_names[subscribe->sender];
|
||||
+ g_test_message ("\tSender: %s %s",
|
||||
+ test_conn_descriptions[subscribe->sender],
|
||||
+ sender);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ sender = NULL;
|
||||
+ g_test_message ("\tSender: (any)");
|
||||
+ }
|
||||
+
|
||||
+ g_test_message ("\tPath: %s", nonnull (subscribe->path, "(any)"));
|
||||
+ g_test_message ("\tInterface: %s",
|
||||
+ nonnull (subscribe->iface, "(any)"));
|
||||
+ g_test_message ("\tMember: %s",
|
||||
+ nonnull (subscribe->member, "(any)"));
|
||||
+ g_test_message ("\tString argument 0: %s",
|
||||
+ nonnull (subscribe->arg0, "(any)"));
|
||||
+ g_test_message ("\tFlags: %x", subscribe->flags);
|
||||
+
|
||||
+ if (f->mode != SUBSCRIPTION_MODE_PROXY)
|
||||
+ {
|
||||
+ /* CONN or PARALLEL */
|
||||
+ guint id;
|
||||
+
|
||||
+ g_test_message ("\tSubscribing via connection");
|
||||
+ id = g_dbus_connection_signal_subscribe (subscriber,
|
||||
+ sender,
|
||||
+ subscribe->iface,
|
||||
+ subscribe->member,
|
||||
+ subscribe->path,
|
||||
+ subscribe->arg0,
|
||||
+ subscribe->flags,
|
||||
+ subscribed_signal_cb,
|
||||
+ f, NULL);
|
||||
+ g_assert_cmpuint (id, !=, 0);
|
||||
+ f->subscriptions[step_number] = id;
|
||||
+ }
|
||||
+
|
||||
+ if (f->mode != SUBSCRIPTION_MODE_CONN)
|
||||
+ {
|
||||
+ /* PROXY or PARALLEL */
|
||||
+
|
||||
+ if (sender == NULL)
|
||||
+ {
|
||||
+ g_test_message ("\tCannot subscribe via proxy: no bus name");
|
||||
+ }
|
||||
+ else if (subscribe->path == NULL)
|
||||
+ {
|
||||
+ g_test_message ("\tCannot subscribe via proxy: no path");
|
||||
+ }
|
||||
+ else if (subscribe->iface == NULL)
|
||||
+ {
|
||||
+ g_test_message ("\tCannot subscribe via proxy: no interface");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ GDBusProxy *proxy;
|
||||
+
|
||||
+ g_test_message ("\tSubscribing via proxy");
|
||||
+ proxy = g_dbus_proxy_new_sync (subscriber,
|
||||
+ (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
|
||||
+ | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START),
|
||||
+ NULL, /* GDBusInterfaceInfo */
|
||||
+ sender,
|
||||
+ subscribe->path,
|
||||
+ subscribe->iface,
|
||||
+ NULL, /* GCancellable */
|
||||
+ &f->error);
|
||||
+ g_assert_no_error (f->error);
|
||||
+ g_assert_nonnull (proxy);
|
||||
+ g_signal_connect (proxy, "g-signal", G_CALLBACK (proxy_signal_cb), f);
|
||||
+ g_ptr_array_add (f->proxies, g_steal_pointer (&proxy));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* As in setup(), we need to wait for AddMatch to happen. */
|
||||
+ g_test_message ("Waiting for AddMatch to be processed");
|
||||
+ connection_wait_for_bus (subscriber);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+fixture_emit_signal (Fixture *f,
|
||||
+ const TestEmitSignal *signal,
|
||||
+ guint step_number)
|
||||
+{
|
||||
+ GVariant *body;
|
||||
+ const char *destination;
|
||||
+ gboolean ok;
|
||||
+
|
||||
+ g_test_message ("\tSender: %s",
|
||||
+ test_conn_descriptions[signal->sender]);
|
||||
+
|
||||
+ if (signal->unicast_to != TEST_CONN_NONE)
|
||||
+ {
|
||||
+ destination = f->unique_names[signal->unicast_to];
|
||||
+ g_test_message ("\tDestination: %s %s",
|
||||
+ test_conn_descriptions[signal->unicast_to],
|
||||
+ destination);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ destination = NULL;
|
||||
+ g_test_message ("\tDestination: (broadcast)");
|
||||
+ }
|
||||
+
|
||||
+ g_assert_nonnull (signal->path);
|
||||
+ g_test_message ("\tPath: %s", signal->path);
|
||||
+ g_assert_nonnull (signal->iface);
|
||||
+ g_test_message ("\tInterface: %s", signal->iface);
|
||||
+ g_assert_nonnull (signal->member);
|
||||
+ g_test_message ("\tMember: %s", signal->member);
|
||||
+
|
||||
+ /* If arg0 is non-NULL, put it in the message's argument 0.
|
||||
+ * Otherwise put something that will not match any arg0.
|
||||
+ * Either way, put the sequence number in argument 1 so we can
|
||||
+ * correlate sent messages with received messages later. */
|
||||
+ if (signal->arg0 != NULL)
|
||||
+ {
|
||||
+ g_test_message ("\tString argument 0: %s", signal->arg0);
|
||||
+ /* floating */
|
||||
+ body = g_variant_new ("(su)", signal->arg0, (guint32) step_number);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_test_message ("\tArgument 0: (not a string)");
|
||||
+ body = g_variant_new ("(uu)", (guint32) 0, (guint32) step_number);
|
||||
+ }
|
||||
+
|
||||
+ ok = g_dbus_connection_emit_signal (f->conns[signal->sender],
|
||||
+ destination,
|
||||
+ signal->path,
|
||||
+ signal->iface,
|
||||
+ signal->member,
|
||||
+ /* steals floating reference */
|
||||
+ g_steal_pointer (&body),
|
||||
+ &f->error);
|
||||
+ g_assert_no_error (f->error);
|
||||
+ g_assert_true (ok);
|
||||
+
|
||||
+ /* Emitting the signal is asynchronous, so if we want subsequent steps
|
||||
+ * to be guaranteed to happen after the signal from the message bus's
|
||||
+ * perspective, we have to do a round-trip to the message bus to sync up. */
|
||||
+ g_test_message ("Waiting for signal to reach message bus");
|
||||
+ connection_wait_for_bus (f->conns[signal->sender]);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+fixture_run_plan (Fixture *f,
|
||||
+ const TestPlan *plan,
|
||||
+ SubscriptionMode mode)
|
||||
+{
|
||||
+ guint i;
|
||||
+
|
||||
+ G_STATIC_ASSERT (G_N_ELEMENTS (plan->steps) == G_N_ELEMENTS (f->subscriptions));
|
||||
+ G_STATIC_ASSERT (G_N_ELEMENTS (plan->steps) == G_N_ELEMENTS (f->received_by_conn));
|
||||
+ G_STATIC_ASSERT (G_N_ELEMENTS (plan->steps) == G_N_ELEMENTS (f->received_by_proxy));
|
||||
+
|
||||
+ f->mode = mode;
|
||||
+ f->plan = plan;
|
||||
+
|
||||
+ g_test_summary (plan->description);
|
||||
+
|
||||
+ for (i = 0; i < G_N_ELEMENTS (plan->steps); i++)
|
||||
+ {
|
||||
+ const TestStep *step = &plan->steps[i];
|
||||
+
|
||||
+ switch (step->action)
|
||||
+ {
|
||||
+ case TEST_ACTION_SUBSCRIBE:
|
||||
+ g_test_message ("Step %u: adding subscription", i);
|
||||
+ fixture_subscribe (f, &step->u.subscribe, i);
|
||||
+ break;
|
||||
+
|
||||
+ case TEST_ACTION_EMIT_SIGNAL:
|
||||
+ g_test_message ("Step %u: emitting signal", i);
|
||||
+ fixture_emit_signal (f, &step->u.signal, i);
|
||||
+ break;
|
||||
+
|
||||
+ case TEST_ACTION_NONE:
|
||||
+ /* Padding to fill the rest of the array, do nothing */
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ g_return_if_reached ();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Now that we have done everything we wanted to do, emit Finished
|
||||
+ * from each connection. */
|
||||
+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++)
|
||||
+ {
|
||||
+ gboolean ok;
|
||||
+
|
||||
+ ok = g_dbus_connection_emit_signal (f->conns[i],
|
||||
+ NULL,
|
||||
+ FINISHED_PATH,
|
||||
+ FINISHED_INTERFACE,
|
||||
+ FINISHED_SIGNAL,
|
||||
+ NULL,
|
||||
+ &f->error);
|
||||
+ g_assert_no_error (f->error);
|
||||
+ g_assert_true (ok);
|
||||
+ }
|
||||
+
|
||||
+ /* Wait until we have seen the Finished signal from each sender */
|
||||
+ while (TRUE)
|
||||
+ {
|
||||
+ gboolean all_finished = TRUE;
|
||||
+
|
||||
+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++)
|
||||
+ all_finished = all_finished && f->finished[i];
|
||||
+
|
||||
+ if (all_finished)
|
||||
+ break;
|
||||
+
|
||||
+ g_main_context_iteration (NULL, TRUE);
|
||||
+ }
|
||||
+
|
||||
+ /* Assert that the correct things happened before each Finished signal */
|
||||
+ for (i = 0; i < f->received->len; i++)
|
||||
+ {
|
||||
+ const ReceivedMessage *received = g_ptr_array_index (f->received, i);
|
||||
+
|
||||
+ g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_conn));
|
||||
+ g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_proxy));
|
||||
+ g_assert_cmpint (plan->steps[received->step].action,
|
||||
+ ==, TEST_ACTION_EMIT_SIGNAL);
|
||||
+
|
||||
+ if (received->received_by_proxy != NULL)
|
||||
+ f->received_by_proxy[received->step] += 1;
|
||||
+ else
|
||||
+ f->received_by_conn[received->step] += 1;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < G_N_ELEMENTS (plan->steps); i++)
|
||||
+ {
|
||||
+ const TestStep *step = &plan->steps[i];
|
||||
+
|
||||
+ if (step->action == TEST_ACTION_EMIT_SIGNAL)
|
||||
+ {
|
||||
+ const TestEmitSignal *signal = &plan->steps[i].u.signal;
|
||||
+
|
||||
+ if (mode != SUBSCRIPTION_MODE_PROXY)
|
||||
+ {
|
||||
+ g_test_message ("Signal from step %u was received %u times by "
|
||||
+ "GDBusConnection, expected %u",
|
||||
+ i, f->received_by_conn[i], signal->received_by_conn);
|
||||
+ g_assert_cmpuint (f->received_by_conn[i], ==, signal->received_by_conn);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_assert_cmpuint (f->received_by_conn[i], ==, 0);
|
||||
+ }
|
||||
+
|
||||
+ if (mode != SUBSCRIPTION_MODE_CONN)
|
||||
+ {
|
||||
+ g_test_message ("Signal from step %u was received %u times by "
|
||||
+ "GDBusProxy, expected %u",
|
||||
+ i, f->received_by_proxy[i], signal->received_by_proxy);
|
||||
+ g_assert_cmpuint (f->received_by_proxy[i], ==, signal->received_by_proxy);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_assert_cmpuint (f->received_by_proxy[i], ==, 0);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+setup (Fixture *f,
|
||||
+ G_GNUC_UNUSED const void *context)
|
||||
+{
|
||||
+ GDBusConnection *subscriber;
|
||||
+ guint i;
|
||||
+
|
||||
+ session_bus_up ();
|
||||
+
|
||||
+ f->proxies = g_ptr_array_new_full (MAX_TEST_STEPS, g_object_unref);
|
||||
+ f->received = g_ptr_array_new_full (MAX_TEST_STEPS,
|
||||
+ (GDestroyNotify) received_message_free);
|
||||
+
|
||||
+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++)
|
||||
+ {
|
||||
+ f->conns[i] = _g_bus_get_priv (G_BUS_TYPE_SESSION, NULL, &f->error);
|
||||
+ g_assert_no_error (f->error);
|
||||
+ g_assert_nonnull (f->conns[i]);
|
||||
+
|
||||
+ f->unique_names[i] = g_dbus_connection_get_unique_name (f->conns[i]);
|
||||
+ g_assert_nonnull (f->unique_names[i]);
|
||||
+ g_test_message ("%s is %s",
|
||||
+ test_conn_descriptions[i],
|
||||
+ f->unique_names[i]);
|
||||
+ }
|
||||
+
|
||||
+ subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||
+
|
||||
+ /* Used to wait for all connections to finish sending whatever they
|
||||
+ * wanted to send */
|
||||
+ f->finished_subscription = g_dbus_connection_signal_subscribe (subscriber,
|
||||
+ NULL,
|
||||
+ FINISHED_INTERFACE,
|
||||
+ FINISHED_SIGNAL,
|
||||
+ FINISHED_PATH,
|
||||
+ NULL,
|
||||
+ G_DBUS_SIGNAL_FLAGS_NONE,
|
||||
+ subscriber_finished_cb,
|
||||
+ f, NULL);
|
||||
+ /* AddMatch is sent asynchronously, so we don't know how
|
||||
+ * soon it will be processed. Before emitting signals, we
|
||||
+ * need to wait for the message bus to get as far as processing
|
||||
+ * AddMatch. */
|
||||
+ g_test_message ("Waiting for AddMatch to be processed");
|
||||
+ connection_wait_for_bus (subscriber);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_conn_subscribe (Fixture *f,
|
||||
+ const void *context)
|
||||
+{
|
||||
+ fixture_run_plan (f, context, SUBSCRIPTION_MODE_CONN);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_proxy_subscribe (Fixture *f,
|
||||
+ const void *context)
|
||||
+{
|
||||
+ fixture_run_plan (f, context, SUBSCRIPTION_MODE_PROXY);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+test_parallel_subscribe (Fixture *f,
|
||||
+ const void *context)
|
||||
+{
|
||||
+ fixture_run_plan (f, context, SUBSCRIPTION_MODE_PARALLEL);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+teardown (Fixture *f,
|
||||
+ G_GNUC_UNUSED const void *context)
|
||||
+{
|
||||
+ GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||
+ guint i;
|
||||
+
|
||||
+ g_ptr_array_unref (f->proxies);
|
||||
+
|
||||
+ if (f->finished_subscription != 0)
|
||||
+ g_dbus_connection_signal_unsubscribe (subscriber, f->finished_subscription);
|
||||
+
|
||||
+ for (i = 0; i < G_N_ELEMENTS (f->subscriptions); i++)
|
||||
+ {
|
||||
+ if (f->subscriptions[i] != 0)
|
||||
+ g_dbus_connection_signal_unsubscribe (subscriber, f->subscriptions[i]);
|
||||
+ }
|
||||
+
|
||||
+ g_ptr_array_unref (f->received);
|
||||
+
|
||||
+ for (i = TEST_CONN_FIRST; i < G_N_ELEMENTS (f->conns); i++)
|
||||
+ g_clear_object (&f->conns[i]);
|
||||
+
|
||||
+ g_clear_error (&f->error);
|
||||
+
|
||||
+ session_bus_down ();
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main (int argc,
|
||||
+ char *argv[])
|
||||
+{
|
||||
+ g_test_init (&argc, &argv, G_TEST_OPTION_ISOLATE_DIRS, NULL);
|
||||
+
|
||||
+ g_test_dbus_unset ();
|
||||
+
|
||||
+#define ADD_SUBSCRIBE_TEST(name) \
|
||||
+ do { \
|
||||
+ g_test_add ("/gdbus/subscribe/conn/" #name, \
|
||||
+ Fixture, &plan_ ## name, \
|
||||
+ setup, test_conn_subscribe, teardown); \
|
||||
+ g_test_add ("/gdbus/subscribe/proxy/" #name, \
|
||||
+ Fixture, &plan_ ## name, \
|
||||
+ setup, test_proxy_subscribe, teardown); \
|
||||
+ g_test_add ("/gdbus/subscribe/parallel/" #name, \
|
||||
+ Fixture, &plan_ ## name, \
|
||||
+ setup, test_parallel_subscribe, teardown); \
|
||||
+ } while (0)
|
||||
+
|
||||
+ ADD_SUBSCRIBE_TEST (simple);
|
||||
+ ADD_SUBSCRIBE_TEST (broadcast_from_anyone);
|
||||
+ ADD_SUBSCRIBE_TEST (match_twice);
|
||||
+ ADD_SUBSCRIBE_TEST (limit_by_unique_name);
|
||||
+
|
||||
+ return g_test_run();
|
||||
+}
|
||||
diff --git a/gio/tests/meson.build b/gio/tests/meson.build
|
||||
index 383d84319..a1551aa53 100644
|
||||
--- a/gio/tests/meson.build
|
||||
+++ b/gio/tests/meson.build
|
||||
@@ -354,6 +354,7 @@ if host_machine.system() != 'windows'
|
||||
},
|
||||
'gdbus-proxy-unique-name' : {'extra_sources' : extra_sources},
|
||||
'gdbus-proxy-well-known-name' : {'extra_sources' : extra_sources},
|
||||
+ 'gdbus-subscribe' : {'extra_sources' : extra_sources},
|
||||
'gdbus-test-codegen' : {
|
||||
'extra_sources' : [extra_sources, gdbus_test_codegen_generated, gdbus_test_codegen_generated_interface_info],
|
||||
'c_args' : ['-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'],
|
||||
--
|
||||
2.30.2
|
||||
|
||||
253
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_04.patch
Normal file
253
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_04.patch
Normal file
@@ -0,0 +1,253 @@
|
||||
From a87931c257a6bb1b7c104623beadd9b14d766ca6 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Fri, 8 Mar 2024 19:28:15 +0000
|
||||
Subject: [PATCH 04/18] tests: Add support for subscribing to signals from a
|
||||
well-known name
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/a87931c257a6bb1b7c104623beadd9b14d766ca6]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-subscribe.c | 133 ++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 126 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c
|
||||
index 3f53e1d7f..3d2a14e03 100644
|
||||
--- a/gio/tests/gdbus-subscribe.c
|
||||
+++ b/gio/tests/gdbus-subscribe.c
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
#include "gdbus-tests.h"
|
||||
|
||||
+/* From the D-Bus Specification */
|
||||
+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
|
||||
+
|
||||
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS
|
||||
@@ -22,6 +25,9 @@
|
||||
#define EXAMPLE_INTERFACE "org.gtk.GDBus.ExampleInterface"
|
||||
#define FOO_SIGNAL "Foo"
|
||||
|
||||
+#define ALREADY_OWNED_NAME "org.gtk.Test.AlreadyOwned"
|
||||
+#define OWNED_LATER_NAME "org.gtk.Test.OwnedLater"
|
||||
+
|
||||
/* Log @s in a debug message. */
|
||||
static inline const char *
|
||||
nonnull (const char *s,
|
||||
@@ -101,7 +107,8 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
- TestConn sender;
|
||||
+ const char *string_sender;
|
||||
+ TestConn unique_sender;
|
||||
const char *path;
|
||||
const char *iface;
|
||||
const char *member;
|
||||
@@ -109,11 +116,18 @@ typedef struct
|
||||
GDBusSignalFlags flags;
|
||||
} TestSubscribe;
|
||||
|
||||
+typedef struct
|
||||
+{
|
||||
+ const char *name;
|
||||
+ TestConn owner;
|
||||
+} TestOwnName;
|
||||
+
|
||||
typedef enum
|
||||
{
|
||||
TEST_ACTION_NONE = 0,
|
||||
TEST_ACTION_SUBSCRIBE,
|
||||
TEST_ACTION_EMIT_SIGNAL,
|
||||
+ TEST_ACTION_OWN_NAME,
|
||||
} TestAction;
|
||||
|
||||
typedef struct
|
||||
@@ -122,6 +136,7 @@ typedef struct
|
||||
union {
|
||||
TestEmitSignal signal;
|
||||
TestSubscribe subscribe;
|
||||
+ TestOwnName own_name;
|
||||
} u;
|
||||
} TestStep;
|
||||
|
||||
@@ -247,7 +262,7 @@ static const TestPlan plan_match_twice =
|
||||
{
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
- .sender = TEST_CONN_SERVICE,
|
||||
+ .unique_sender = TEST_CONN_SERVICE,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
@@ -267,7 +282,7 @@ static const TestPlan plan_match_twice =
|
||||
{
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
- .sender = TEST_CONN_SERVICE,
|
||||
+ .unique_sender = TEST_CONN_SERVICE,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
@@ -296,7 +311,7 @@ static const TestPlan plan_limit_by_unique_name =
|
||||
/* Subscriber wants to receive signals from service */
|
||||
.action = TEST_ACTION_SUBSCRIBE,
|
||||
.u.subscribe = {
|
||||
- .sender = TEST_CONN_SERVICE,
|
||||
+ .unique_sender = TEST_CONN_SERVICE,
|
||||
.path = EXAMPLE_PATH,
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
@@ -343,6 +358,62 @@ static const TestPlan plan_limit_by_unique_name =
|
||||
},
|
||||
};
|
||||
|
||||
+static const TestPlan plan_limit_by_well_known_name =
|
||||
+{
|
||||
+ .description = "A subscription via a well-known name only accepts messages "
|
||||
+ "sent by the owner of that well-known name",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ /* Service already owns one name */
|
||||
+ .action = TEST_ACTION_OWN_NAME,
|
||||
+ .u.own_name = {
|
||||
+ .name = ALREADY_OWNED_NAME,
|
||||
+ .owner = TEST_CONN_SERVICE
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Subscriber wants to receive signals from service */
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .string_sender = ALREADY_OWNED_NAME,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Subscriber wants to receive signals from service by another name */
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .string_sender = OWNED_LATER_NAME,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Service claims another name */
|
||||
+ .action = TEST_ACTION_OWN_NAME,
|
||||
+ .u.own_name = {
|
||||
+ .name = OWNED_LATER_NAME,
|
||||
+ .owner = TEST_CONN_SERVICE
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Now the subscriber gets this signal twice, once for each
|
||||
+ * subscription; and similarly each of the two proxies gets this
|
||||
+ * signal twice */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 2,
|
||||
+ .received_by_proxy = 2
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
typedef struct
|
||||
{
|
||||
const TestPlan *plan;
|
||||
@@ -540,11 +611,16 @@ fixture_subscribe (Fixture *f,
|
||||
GDBusConnection *subscriber = f->conns[TEST_CONN_SUBSCRIBER];
|
||||
const char *sender;
|
||||
|
||||
- if (subscribe->sender != TEST_CONN_NONE)
|
||||
+ if (subscribe->string_sender != NULL)
|
||||
{
|
||||
- sender = f->unique_names[subscribe->sender];
|
||||
+ sender = subscribe->string_sender;
|
||||
+ g_test_message ("\tSender: %s", sender);
|
||||
+ }
|
||||
+ else if (subscribe->unique_sender != TEST_CONN_NONE)
|
||||
+ {
|
||||
+ sender = f->unique_names[subscribe->unique_sender];
|
||||
g_test_message ("\tSender: %s %s",
|
||||
- test_conn_descriptions[subscribe->sender],
|
||||
+ test_conn_descriptions[subscribe->unique_sender],
|
||||
sender);
|
||||
}
|
||||
else
|
||||
@@ -689,6 +765,43 @@ fixture_emit_signal (Fixture *f,
|
||||
connection_wait_for_bus (f->conns[signal->sender]);
|
||||
}
|
||||
|
||||
+static void
|
||||
+fixture_own_name (Fixture *f,
|
||||
+ const TestOwnName *own_name)
|
||||
+{
|
||||
+ GVariant *call_result;
|
||||
+ guint32 flags;
|
||||
+ guint32 result_code;
|
||||
+
|
||||
+ g_test_message ("\tName: %s", own_name->name);
|
||||
+ g_test_message ("\tOwner: %s",
|
||||
+ test_conn_descriptions[own_name->owner]);
|
||||
+
|
||||
+ /* For simplicity, we do this via a direct bus call rather than
|
||||
+ * using g_bus_own_name_on_connection(). The flags in
|
||||
+ * GBusNameOwnerFlags are numerically equal to those in the
|
||||
+ * D-Bus wire protocol. */
|
||||
+ flags = G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE;
|
||||
+ call_result = g_dbus_connection_call_sync (f->conns[own_name->owner],
|
||||
+ DBUS_SERVICE_DBUS,
|
||||
+ DBUS_PATH_DBUS,
|
||||
+ DBUS_INTERFACE_DBUS,
|
||||
+ "RequestName",
|
||||
+ g_variant_new ("(su)",
|
||||
+ own_name->name,
|
||||
+ flags),
|
||||
+ G_VARIANT_TYPE ("(u)"),
|
||||
+ G_DBUS_CALL_FLAGS_NONE,
|
||||
+ -1,
|
||||
+ NULL,
|
||||
+ &f->error);
|
||||
+ g_assert_no_error (f->error);
|
||||
+ g_assert_nonnull (call_result);
|
||||
+ g_variant_get (call_result, "(u)", &result_code);
|
||||
+ g_assert_cmpuint (result_code, ==, DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
|
||||
+ g_variant_unref (call_result);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
fixture_run_plan (Fixture *f,
|
||||
const TestPlan *plan,
|
||||
@@ -721,6 +834,11 @@ fixture_run_plan (Fixture *f,
|
||||
fixture_emit_signal (f, &step->u.signal, i);
|
||||
break;
|
||||
|
||||
+ case TEST_ACTION_OWN_NAME:
|
||||
+ g_test_message ("Step %u: claiming bus name", i);
|
||||
+ fixture_own_name (f, &step->u.own_name);
|
||||
+ break;
|
||||
+
|
||||
case TEST_ACTION_NONE:
|
||||
/* Padding to fill the rest of the array, do nothing */
|
||||
break;
|
||||
@@ -933,6 +1051,7 @@ main (int argc,
|
||||
ADD_SUBSCRIBE_TEST (broadcast_from_anyone);
|
||||
ADD_SUBSCRIBE_TEST (match_twice);
|
||||
ADD_SUBSCRIBE_TEST (limit_by_unique_name);
|
||||
+ ADD_SUBSCRIBE_TEST (limit_by_well_known_name);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
||||
88
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_05.patch
Normal file
88
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_05.patch
Normal file
@@ -0,0 +1,88 @@
|
||||
From 4d4c40e858cb71a229b19f89196e6e02e235eb5b Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Fri, 8 Mar 2024 19:44:03 +0000
|
||||
Subject: [PATCH 05/18] tests: Add a test-case for what happens if a unique
|
||||
name doesn't exist
|
||||
|
||||
On GNOME/glib#3268 there was some concern about whether this would
|
||||
allow an attacker to send signals and have them be matched to a
|
||||
GDBusProxy in this situation, but it seems that was a false alarm.
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/4d4c40e858cb71a229b19f89196e6e02e235eb5b]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-subscribe.c | 48 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
|
||||
diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c
|
||||
index 3d2a14e03..350ec9f52 100644
|
||||
--- a/gio/tests/gdbus-subscribe.c
|
||||
+++ b/gio/tests/gdbus-subscribe.c
|
||||
@@ -358,6 +358,53 @@ static const TestPlan plan_limit_by_unique_name =
|
||||
},
|
||||
};
|
||||
|
||||
+static const TestPlan plan_nonexistent_unique_name =
|
||||
+{
|
||||
+ .description = "A subscription via a unique name that doesn't exist "
|
||||
+ "accepts no messages",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ /* Subscriber wants to receive signals from service */
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ /* This relies on the implementation detail that the dbus-daemon
|
||||
+ * (and presumably other bus implementations) never actually generates
|
||||
+ * a unique name in this format */
|
||||
+ .string_sender = ":0.this.had.better.not.exist",
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Attacker wants to trick subscriber into thinking that service
|
||||
+ * sent a signal */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Attacker tries harder, by sending a signal unicast directly to
|
||||
+ * the subscriber */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .unicast_to = TEST_CONN_SUBSCRIBER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const TestPlan plan_limit_by_well_known_name =
|
||||
{
|
||||
.description = "A subscription via a well-known name only accepts messages "
|
||||
@@ -1051,6 +1098,7 @@ main (int argc,
|
||||
ADD_SUBSCRIBE_TEST (broadcast_from_anyone);
|
||||
ADD_SUBSCRIBE_TEST (match_twice);
|
||||
ADD_SUBSCRIBE_TEST (limit_by_unique_name);
|
||||
+ ADD_SUBSCRIBE_TEST (nonexistent_unique_name);
|
||||
ADD_SUBSCRIBE_TEST (limit_by_well_known_name);
|
||||
|
||||
return g_test_run();
|
||||
--
|
||||
2.30.2
|
||||
|
||||
263
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_06.patch
Normal file
263
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_06.patch
Normal file
@@ -0,0 +1,263 @@
|
||||
From 4d8106ba534c7f3c2037cca4c654fd13ce0b93d9 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Fri, 8 Mar 2024 20:10:29 +0000
|
||||
Subject: [PATCH 06/18] tests: Add test coverage for signals that match the
|
||||
message bus's name
|
||||
|
||||
This is a special case of unique names, even though it's syntactically
|
||||
a well-known name.
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/4d8106ba534c7f3c2037cca4c654fd13ce0b93d9]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-subscribe.c | 161 ++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 154 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c
|
||||
index 350ec9f52..af100de7d 100644
|
||||
--- a/gio/tests/gdbus-subscribe.c
|
||||
+++ b/gio/tests/gdbus-subscribe.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS
|
||||
+#define NAME_OWNER_CHANGED "NameOwnerChanged"
|
||||
|
||||
/* A signal that each connection emits to indicate that it has finished
|
||||
* emitting other signals */
|
||||
@@ -101,6 +102,7 @@ typedef struct
|
||||
const char *iface;
|
||||
const char *member;
|
||||
const char *arg0;
|
||||
+ const char *args;
|
||||
guint received_by_conn;
|
||||
guint received_by_proxy;
|
||||
} TestEmitSignal;
|
||||
@@ -120,6 +122,8 @@ typedef struct
|
||||
{
|
||||
const char *name;
|
||||
TestConn owner;
|
||||
+ guint received_by_conn;
|
||||
+ guint received_by_proxy;
|
||||
} TestOwnName;
|
||||
|
||||
typedef enum
|
||||
@@ -461,6 +465,63 @@ static const TestPlan plan_limit_by_well_known_name =
|
||||
},
|
||||
};
|
||||
|
||||
+static const TestPlan plan_limit_to_message_bus =
|
||||
+{
|
||||
+ .description = "A subscription to the message bus only accepts messages "
|
||||
+ "from the message bus",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ /* Subscriber wants to receive signals from the message bus itself */
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .string_sender = DBUS_SERVICE_DBUS,
|
||||
+ .path = DBUS_PATH_DBUS,
|
||||
+ .iface = DBUS_INTERFACE_DBUS,
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Attacker wants to trick subscriber into thinking that the message
|
||||
+ * bus sent a signal */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .path = DBUS_PATH_DBUS,
|
||||
+ .iface = DBUS_INTERFACE_DBUS,
|
||||
+ .member = NAME_OWNER_CHANGED,
|
||||
+ .arg0 = "would I lie to you?",
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Attacker tries harder, by sending a signal unicast directly to
|
||||
+ * the subscriber, and using more realistic arguments */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .unicast_to = TEST_CONN_SUBSCRIBER,
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .path = DBUS_PATH_DBUS,
|
||||
+ .iface = DBUS_INTERFACE_DBUS,
|
||||
+ .member = NAME_OWNER_CHANGED,
|
||||
+ .args = "('com.example.Name', '', ':1.12')",
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* When the message bus sends a signal (in this case triggered by
|
||||
+ * owning a name), it should still get through */
|
||||
+ .action = TEST_ACTION_OWN_NAME,
|
||||
+ .u.own_name = {
|
||||
+ .name = OWNED_LATER_NAME,
|
||||
+ .owner = TEST_CONN_SERVICE,
|
||||
+ .received_by_conn = 1,
|
||||
+ .received_by_proxy = 1
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
typedef struct
|
||||
{
|
||||
const TestPlan *plan;
|
||||
@@ -591,7 +652,18 @@ fixture_received_signal (Fixture *f,
|
||||
}
|
||||
}
|
||||
|
||||
- g_assert_cmpint (received->sender, !=, TEST_CONN_NONE);
|
||||
+ if (g_str_equal (sender_name, DBUS_SERVICE_DBUS))
|
||||
+ {
|
||||
+ g_test_message ("Signal received from message bus %s",
|
||||
+ sender_name);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_test_message ("Signal received from %s %s",
|
||||
+ test_conn_descriptions[received->sender],
|
||||
+ sender_name);
|
||||
+ g_assert_cmpint (received->sender, !=, TEST_CONN_NONE);
|
||||
+ }
|
||||
|
||||
g_test_message ("Signal received from %s %s via %s",
|
||||
test_conn_descriptions[received->sender],
|
||||
@@ -607,13 +679,56 @@ fixture_received_signal (Fixture *f,
|
||||
g_test_message ("\tString argument 0: %s", received->arg0);
|
||||
g_test_message ("\tSent in step: %u", received->step);
|
||||
}
|
||||
- else
|
||||
+ else if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(uu)")))
|
||||
{
|
||||
- g_assert_cmpstr (g_variant_get_type_string (parameters), ==, "(uu)");
|
||||
g_variant_get (parameters, "(uu)", NULL, &received->step);
|
||||
g_test_message ("\tArgument 0: (not a string)");
|
||||
g_test_message ("\tSent in step: %u", received->step);
|
||||
}
|
||||
+ else if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(sss)")))
|
||||
+ {
|
||||
+ const char *name;
|
||||
+ const char *old_owner;
|
||||
+ const char *new_owner;
|
||||
+
|
||||
+ /* The only signal of this signature that we legitimately receive
|
||||
+ * during this test is NameOwnerChanged, so just assert that it
|
||||
+ * is from the message bus and can be matched to a plausible step.
|
||||
+ * (This is less thorough than the above, and will not work if we
|
||||
+ * add a test scenario where a name's ownership is repeatedly
|
||||
+ * changed while watching NameOwnerChanged - so don't do that.) */
|
||||
+ g_assert_cmpstr (sender_name, ==, DBUS_SERVICE_DBUS);
|
||||
+ g_assert_cmpstr (path, ==, DBUS_PATH_DBUS);
|
||||
+ g_assert_cmpstr (iface, ==, DBUS_INTERFACE_DBUS);
|
||||
+ g_assert_cmpstr (member, ==, NAME_OWNER_CHANGED);
|
||||
+
|
||||
+ g_variant_get (parameters, "(&s&s&s)", &name, &old_owner, &new_owner);
|
||||
+
|
||||
+ for (i = 0; i < G_N_ELEMENTS (f->plan->steps); i++)
|
||||
+ {
|
||||
+ const TestStep *step = &f->plan->steps[i];
|
||||
+
|
||||
+ if (step->action == TEST_ACTION_OWN_NAME)
|
||||
+ {
|
||||
+ const TestOwnName *own_name = &step->u.own_name;
|
||||
+
|
||||
+ if (g_str_equal (name, own_name->name)
|
||||
+ && g_str_equal (new_owner, f->unique_names[own_name->owner])
|
||||
+ && own_name->received_by_conn > 0)
|
||||
+ {
|
||||
+ received->step = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (i >= G_N_ELEMENTS (f->plan->steps))
|
||||
+ g_error ("Could not match message to a test step");
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_error ("Unexpected message received");
|
||||
+ }
|
||||
|
||||
g_ptr_array_add (f->received, g_steal_pointer (&received));
|
||||
}
|
||||
@@ -782,10 +897,15 @@ fixture_emit_signal (Fixture *f,
|
||||
* Otherwise put something that will not match any arg0.
|
||||
* Either way, put the sequence number in argument 1 so we can
|
||||
* correlate sent messages with received messages later. */
|
||||
- if (signal->arg0 != NULL)
|
||||
+ if (signal->args != NULL)
|
||||
{
|
||||
- g_test_message ("\tString argument 0: %s", signal->arg0);
|
||||
/* floating */
|
||||
+ body = g_variant_new_parsed (signal->args);
|
||||
+ g_assert_nonnull (body);
|
||||
+ }
|
||||
+ else if (signal->arg0 != NULL)
|
||||
+ {
|
||||
+ g_test_message ("\tString argument 0: %s", signal->arg0);
|
||||
body = g_variant_new ("(su)", signal->arg0, (guint32) step_number);
|
||||
}
|
||||
else
|
||||
@@ -933,8 +1053,6 @@ fixture_run_plan (Fixture *f,
|
||||
|
||||
g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_conn));
|
||||
g_assert_cmpuint (received->step, <, G_N_ELEMENTS (f->received_by_proxy));
|
||||
- g_assert_cmpint (plan->steps[received->step].action,
|
||||
- ==, TEST_ACTION_EMIT_SIGNAL);
|
||||
|
||||
if (received->received_by_proxy != NULL)
|
||||
f->received_by_proxy[received->step] += 1;
|
||||
@@ -974,6 +1092,34 @@ fixture_run_plan (Fixture *f,
|
||||
g_assert_cmpuint (f->received_by_proxy[i], ==, 0);
|
||||
}
|
||||
}
|
||||
+ else if (step->action == TEST_ACTION_OWN_NAME)
|
||||
+ {
|
||||
+ const TestOwnName *own_name = &plan->steps[i].u.own_name;
|
||||
+
|
||||
+ if (mode != SUBSCRIPTION_MODE_PROXY)
|
||||
+ {
|
||||
+ g_test_message ("NameOwnerChanged from step %u was received %u "
|
||||
+ "times by GDBusConnection, expected %u",
|
||||
+ i, f->received_by_conn[i], own_name->received_by_conn);
|
||||
+ g_assert_cmpuint (f->received_by_conn[i], ==, own_name->received_by_conn);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_assert_cmpuint (f->received_by_conn[i], ==, 0);
|
||||
+ }
|
||||
+
|
||||
+ if (mode != SUBSCRIPTION_MODE_CONN)
|
||||
+ {
|
||||
+ g_test_message ("NameOwnerChanged from step %u was received %u "
|
||||
+ "times by GDBusProxy, expected %u",
|
||||
+ i, f->received_by_proxy[i], own_name->received_by_proxy);
|
||||
+ g_assert_cmpuint (f->received_by_proxy[i], ==, own_name->received_by_proxy);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_assert_cmpuint (f->received_by_proxy[i], ==, 0);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1100,6 +1246,7 @@ main (int argc,
|
||||
ADD_SUBSCRIBE_TEST (limit_by_unique_name);
|
||||
ADD_SUBSCRIBE_TEST (nonexistent_unique_name);
|
||||
ADD_SUBSCRIBE_TEST (limit_by_well_known_name);
|
||||
+ ADD_SUBSCRIBE_TEST (limit_to_message_bus);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
||||
45
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_07.patch
Normal file
45
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_07.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
From 5057b6a0e488af6495146cfe96e93eb5e7beb66b Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Thu, 14 Mar 2024 19:18:15 +0000
|
||||
Subject: [PATCH 07/18] gdbusprivate: Add symbolic constants for the message
|
||||
bus itself
|
||||
|
||||
Using these is a bit more clearly correct than repeating them everywhere.
|
||||
To avoid excessive diffstat in a branch for a bug fix, I'm not
|
||||
immediately replacing all existing occurrences of the same literals with
|
||||
these names.
|
||||
|
||||
The names of these constants are chosen to be consistent with libdbus,
|
||||
despite using somewhat outdated terminology (D-Bus now uses the term
|
||||
"well-known bus name" for what used to be called a service name,
|
||||
reserving the word "service" to mean specifically the programs that
|
||||
have .service files and participate in service activation).
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/5057b6a0e488af6495146cfe96e93eb5e7beb66b]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusprivate.h | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/gio/gdbusprivate.h b/gio/gdbusprivate.h
|
||||
index 72d2c32a9..ac737bd7a 100644
|
||||
--- a/gio/gdbusprivate.h
|
||||
+++ b/gio/gdbusprivate.h
|
||||
@@ -29,6 +29,11 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
+/* Bus name, interface and object path of the message bus itself */
|
||||
+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
+#define DBUS_INTERFACE_DBUS DBUS_SERVICE_DBUS
|
||||
+#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
+
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
typedef struct GDBusWorker GDBusWorker;
|
||||
--
|
||||
2.30.2
|
||||
|
||||
168
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_08.patch
Normal file
168
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_08.patch
Normal file
@@ -0,0 +1,168 @@
|
||||
From 467ff27a5a08c21705e20da70a988a55b9f15513 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Thu, 14 Mar 2024 19:24:24 +0000
|
||||
Subject: [PATCH 08/18] gdbusconnection: Move SignalData, SignalSubscriber
|
||||
higher up
|
||||
|
||||
Subsequent changes will need to access these data structures from
|
||||
on_worker_message_received(). No functional change here, only moving
|
||||
code around.
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/467ff27a5a08c21705e20da70a988a55b9f15513]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 128 +++++++++++++++++++++---------------------
|
||||
1 file changed, 65 insertions(+), 63 deletions(-)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index 82a68437b..4f31e8502 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -283,6 +283,71 @@ call_destroy_notify (GMainContext *context,
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
+typedef struct
|
||||
+{
|
||||
+ /* All fields are immutable after construction. */
|
||||
+ gatomicrefcount ref_count;
|
||||
+ GDBusSignalCallback callback;
|
||||
+ gpointer user_data;
|
||||
+ GDestroyNotify user_data_free_func;
|
||||
+ guint id;
|
||||
+ GMainContext *context;
|
||||
+} SignalSubscriber;
|
||||
+
|
||||
+static SignalSubscriber *
|
||||
+signal_subscriber_ref (SignalSubscriber *subscriber)
|
||||
+{
|
||||
+ g_atomic_ref_count_inc (&subscriber->ref_count);
|
||||
+ return subscriber;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+signal_subscriber_unref (SignalSubscriber *subscriber)
|
||||
+{
|
||||
+ if (g_atomic_ref_count_dec (&subscriber->ref_count))
|
||||
+ {
|
||||
+ /* Destroy the user data. It doesn’t matter which thread
|
||||
+ * signal_subscriber_unref() is called in (or whether it’s called with a
|
||||
+ * lock held), as call_destroy_notify() always defers to the next
|
||||
+ * #GMainContext iteration. */
|
||||
+ call_destroy_notify (subscriber->context,
|
||||
+ subscriber->user_data_free_func,
|
||||
+ subscriber->user_data);
|
||||
+
|
||||
+ g_main_context_unref (subscriber->context);
|
||||
+ g_free (subscriber);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+typedef struct
|
||||
+{
|
||||
+ gchar *rule;
|
||||
+ gchar *sender;
|
||||
+ gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */
|
||||
+ gchar *interface_name;
|
||||
+ gchar *member;
|
||||
+ gchar *object_path;
|
||||
+ gchar *arg0;
|
||||
+ GDBusSignalFlags flags;
|
||||
+ GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */
|
||||
+} SignalData;
|
||||
+
|
||||
+static void
|
||||
+signal_data_free (SignalData *signal_data)
|
||||
+{
|
||||
+ g_free (signal_data->rule);
|
||||
+ g_free (signal_data->sender);
|
||||
+ g_free (signal_data->sender_unique_name);
|
||||
+ g_free (signal_data->interface_name);
|
||||
+ g_free (signal_data->member);
|
||||
+ g_free (signal_data->object_path);
|
||||
+ g_free (signal_data->arg0);
|
||||
+ g_ptr_array_unref (signal_data->subscribers);
|
||||
+ g_free (signal_data);
|
||||
+}
|
||||
+
|
||||
+/* ---------------------------------------------------------------------------------------------------- */
|
||||
+
|
||||
#ifdef G_OS_WIN32
|
||||
#define CONNECTION_ENSURE_LOCK(obj) do { ; } while (FALSE)
|
||||
#else
|
||||
@@ -3238,69 +3303,6 @@ g_dbus_connection_remove_filter (GDBusConnection *connection,
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
-typedef struct
|
||||
-{
|
||||
- gchar *rule;
|
||||
- gchar *sender;
|
||||
- gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */
|
||||
- gchar *interface_name;
|
||||
- gchar *member;
|
||||
- gchar *object_path;
|
||||
- gchar *arg0;
|
||||
- GDBusSignalFlags flags;
|
||||
- GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */
|
||||
-} SignalData;
|
||||
-
|
||||
-static void
|
||||
-signal_data_free (SignalData *signal_data)
|
||||
-{
|
||||
- g_free (signal_data->rule);
|
||||
- g_free (signal_data->sender);
|
||||
- g_free (signal_data->sender_unique_name);
|
||||
- g_free (signal_data->interface_name);
|
||||
- g_free (signal_data->member);
|
||||
- g_free (signal_data->object_path);
|
||||
- g_free (signal_data->arg0);
|
||||
- g_ptr_array_unref (signal_data->subscribers);
|
||||
- g_free (signal_data);
|
||||
-}
|
||||
-
|
||||
-typedef struct
|
||||
-{
|
||||
- /* All fields are immutable after construction. */
|
||||
- gatomicrefcount ref_count;
|
||||
- GDBusSignalCallback callback;
|
||||
- gpointer user_data;
|
||||
- GDestroyNotify user_data_free_func;
|
||||
- guint id;
|
||||
- GMainContext *context;
|
||||
-} SignalSubscriber;
|
||||
-
|
||||
-static SignalSubscriber *
|
||||
-signal_subscriber_ref (SignalSubscriber *subscriber)
|
||||
-{
|
||||
- g_atomic_ref_count_inc (&subscriber->ref_count);
|
||||
- return subscriber;
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-signal_subscriber_unref (SignalSubscriber *subscriber)
|
||||
-{
|
||||
- if (g_atomic_ref_count_dec (&subscriber->ref_count))
|
||||
- {
|
||||
- /* Destroy the user data. It doesn’t matter which thread
|
||||
- * signal_subscriber_unref() is called in (or whether it’s called with a
|
||||
- * lock held), as call_destroy_notify() always defers to the next
|
||||
- * #GMainContext iteration. */
|
||||
- call_destroy_notify (subscriber->context,
|
||||
- subscriber->user_data_free_func,
|
||||
- subscriber->user_data);
|
||||
-
|
||||
- g_main_context_unref (subscriber->context);
|
||||
- g_free (subscriber);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static gchar *
|
||||
args_to_rule (const gchar *sender,
|
||||
const gchar *interface_name,
|
||||
--
|
||||
2.30.2
|
||||
|
||||
81
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_09.patch
Normal file
81
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_09.patch
Normal file
@@ -0,0 +1,81 @@
|
||||
From f75e2d73645598e5f3aa064adfece95da435525f Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Thu, 14 Mar 2024 19:30:12 +0000
|
||||
Subject: [PATCH 09/18] gdbusconnection: Factor out signal_data_new_take()
|
||||
|
||||
No functional changes, except that the implicit ownership-transfer
|
||||
for the rule field becomes explicit (the local variable is set to NULL
|
||||
afterwards).
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/f75e2d73645598e5f3aa064adfece95da435525f]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 42 ++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 32 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index 4f31e8502..b8fd920d9 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -332,6 +332,30 @@ typedef struct
|
||||
GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */
|
||||
} SignalData;
|
||||
|
||||
+static SignalData *
|
||||
+signal_data_new_take (gchar *rule,
|
||||
+ gchar *sender,
|
||||
+ gchar *sender_unique_name,
|
||||
+ gchar *interface_name,
|
||||
+ gchar *member,
|
||||
+ gchar *object_path,
|
||||
+ gchar *arg0,
|
||||
+ GDBusSignalFlags flags)
|
||||
+{
|
||||
+ SignalData *signal_data = g_new0 (SignalData, 1);
|
||||
+
|
||||
+ signal_data->rule = rule;
|
||||
+ signal_data->sender = sender;
|
||||
+ signal_data->sender_unique_name = sender_unique_name;
|
||||
+ signal_data->interface_name = interface_name;
|
||||
+ signal_data->member = member;
|
||||
+ signal_data->object_path = object_path;
|
||||
+ signal_data->arg0 = arg0;
|
||||
+ signal_data->flags = flags;
|
||||
+ signal_data->subscribers = g_ptr_array_new_with_free_func ((GDestroyNotify) signal_subscriber_unref);
|
||||
+ return g_steal_pointer (&signal_data);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
signal_data_free (SignalData *signal_data)
|
||||
{
|
||||
@@ -3569,16 +3593,14 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- signal_data = g_new0 (SignalData, 1);
|
||||
- signal_data->rule = rule;
|
||||
- signal_data->sender = g_strdup (sender);
|
||||
- signal_data->sender_unique_name = g_strdup (sender_unique_name);
|
||||
- signal_data->interface_name = g_strdup (interface_name);
|
||||
- signal_data->member = g_strdup (member);
|
||||
- signal_data->object_path = g_strdup (object_path);
|
||||
- signal_data->arg0 = g_strdup (arg0);
|
||||
- signal_data->flags = flags;
|
||||
- signal_data->subscribers = g_ptr_array_new_with_free_func ((GDestroyNotify) signal_subscriber_unref);
|
||||
+ signal_data = signal_data_new_take (g_steal_pointer (&rule),
|
||||
+ g_strdup (sender),
|
||||
+ g_strdup (sender_unique_name),
|
||||
+ g_strdup (interface_name),
|
||||
+ g_strdup (member),
|
||||
+ g_strdup (object_path),
|
||||
+ g_strdup (arg0),
|
||||
+ flags);
|
||||
g_ptr_array_add (signal_data->subscribers, subscriber);
|
||||
|
||||
g_hash_table_insert (connection->map_rule_to_signal_data,
|
||||
--
|
||||
2.30.2
|
||||
|
||||
108
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_10.patch
Normal file
108
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_10.patch
Normal file
@@ -0,0 +1,108 @@
|
||||
From 7f8b44ecdf5bc02e132de4c3242e961f8f27e9f2 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Tue, 23 Apr 2024 20:31:57 +0100
|
||||
Subject: [PATCH 10/18] gdbusconnection: Factor out add_signal_data()
|
||||
|
||||
No functional changes.
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/7f8b44ecdf5bc02e132de4c3242e961f8f27e9f2]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 64 +++++++++++++++++++++++++------------------
|
||||
1 file changed, 37 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index b8fd920d9..3b170845c 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -3447,6 +3447,42 @@ is_signal_data_for_name_lost_or_acquired (SignalData *signal_data)
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
+/* called in any thread, connection lock is held */
|
||||
+static void
|
||||
+add_signal_data (GDBusConnection *connection,
|
||||
+ SignalData *signal_data)
|
||||
+{
|
||||
+ GPtrArray *signal_data_array;
|
||||
+
|
||||
+ g_hash_table_insert (connection->map_rule_to_signal_data,
|
||||
+ signal_data->rule,
|
||||
+ signal_data);
|
||||
+
|
||||
+ /* Add the match rule to the bus...
|
||||
+ *
|
||||
+ * Avoid adding match rules for NameLost and NameAcquired messages - the bus will
|
||||
+ * always send such messages to us.
|
||||
+ */
|
||||
+ if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION)
|
||||
+ {
|
||||
+ if (!is_signal_data_for_name_lost_or_acquired (signal_data))
|
||||
+ add_match_rule (connection, signal_data->rule);
|
||||
+ }
|
||||
+
|
||||
+ signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
|
||||
+ signal_data->sender_unique_name);
|
||||
+ if (signal_data_array == NULL)
|
||||
+ {
|
||||
+ signal_data_array = g_ptr_array_new ();
|
||||
+ g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array,
|
||||
+ g_strdup (signal_data->sender_unique_name),
|
||||
+ signal_data_array);
|
||||
+ }
|
||||
+ g_ptr_array_add (signal_data_array, signal_data);
|
||||
+}
|
||||
+
|
||||
+/* ---------------------------------------------------------------------------------------------------- */
|
||||
+
|
||||
/**
|
||||
* g_dbus_connection_signal_subscribe:
|
||||
* @connection: a #GDBusConnection
|
||||
@@ -3536,7 +3572,6 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
gchar *rule;
|
||||
SignalData *signal_data;
|
||||
SignalSubscriber *subscriber;
|
||||
- GPtrArray *signal_data_array;
|
||||
const gchar *sender_unique_name;
|
||||
|
||||
/* Right now we abort if AddMatch() fails since it can only fail with the bus being in
|
||||
@@ -3602,32 +3637,7 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
g_strdup (arg0),
|
||||
flags);
|
||||
g_ptr_array_add (signal_data->subscribers, subscriber);
|
||||
-
|
||||
- g_hash_table_insert (connection->map_rule_to_signal_data,
|
||||
- signal_data->rule,
|
||||
- signal_data);
|
||||
-
|
||||
- /* Add the match rule to the bus...
|
||||
- *
|
||||
- * Avoid adding match rules for NameLost and NameAcquired messages - the bus will
|
||||
- * always send such messages to us.
|
||||
- */
|
||||
- if (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION)
|
||||
- {
|
||||
- if (!is_signal_data_for_name_lost_or_acquired (signal_data))
|
||||
- add_match_rule (connection, signal_data->rule);
|
||||
- }
|
||||
-
|
||||
- signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- signal_data->sender_unique_name);
|
||||
- if (signal_data_array == NULL)
|
||||
- {
|
||||
- signal_data_array = g_ptr_array_new ();
|
||||
- g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- g_strdup (signal_data->sender_unique_name),
|
||||
- signal_data_array);
|
||||
- }
|
||||
- g_ptr_array_add (signal_data_array, signal_data);
|
||||
+ add_signal_data (connection, signal_data);
|
||||
|
||||
out:
|
||||
g_hash_table_insert (connection->map_id_to_signal_data,
|
||||
--
|
||||
2.30.2
|
||||
|
||||
133
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_11.patch
Normal file
133
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_11.patch
Normal file
@@ -0,0 +1,133 @@
|
||||
From 1704bc6a70c0dcdc5555f23ebab8e3e7ed697998 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Thu, 14 Mar 2024 19:51:59 +0000
|
||||
Subject: [PATCH 11/18] gdbusconnection: Factor out
|
||||
remove_signal_data_if_unused
|
||||
|
||||
No functional change, just removing some nesting. The check for whether
|
||||
signal_data->subscribers is empty changes from a conditional that tests
|
||||
whether it is into an early-return if it isn't.
|
||||
|
||||
A subsequent commit will add additional conditions that make us consider
|
||||
a SignalData to be still in use and therefore not eligible to be removed.
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/1704bc6a70c0dcdc5555f23ebab8e3e7ed697998]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 83 +++++++++++++++++++++++++------------------
|
||||
1 file changed, 48 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index 3b170845c..114cdde29 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -3651,6 +3651,52 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
+/*
|
||||
+ * Called in any thread.
|
||||
+ * Must hold the connection lock when calling this, unless
|
||||
+ * connection->finalizing is TRUE.
|
||||
+ * May free signal_data, so do not dereference it after this.
|
||||
+ */
|
||||
+static void
|
||||
+remove_signal_data_if_unused (GDBusConnection *connection,
|
||||
+ SignalData *signal_data)
|
||||
+{
|
||||
+ GPtrArray *signal_data_array;
|
||||
+
|
||||
+ if (signal_data->subscribers->len != 0)
|
||||
+ return;
|
||||
+
|
||||
+ g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule));
|
||||
+
|
||||
+ signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
|
||||
+ signal_data->sender_unique_name);
|
||||
+ g_warn_if_fail (signal_data_array != NULL);
|
||||
+ g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data));
|
||||
+
|
||||
+ if (signal_data_array->len == 0)
|
||||
+ {
|
||||
+ g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array,
|
||||
+ signal_data->sender_unique_name));
|
||||
+ }
|
||||
+
|
||||
+ /* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */
|
||||
+ if ((connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) &&
|
||||
+ !is_signal_data_for_name_lost_or_acquired (signal_data) &&
|
||||
+ !g_dbus_connection_is_closed (connection) &&
|
||||
+ !connection->finalizing)
|
||||
+ {
|
||||
+ /* The check for g_dbus_connection_is_closed() means that
|
||||
+ * sending the RemoveMatch message can't fail with
|
||||
+ * G_IO_ERROR_CLOSED, because we're holding the lock,
|
||||
+ * so on_worker_closed() can't happen between the check we just
|
||||
+ * did, and releasing the lock later.
|
||||
+ */
|
||||
+ remove_match_rule (connection, signal_data->rule);
|
||||
+ }
|
||||
+
|
||||
+ signal_data_free (signal_data);
|
||||
+}
|
||||
+
|
||||
/* called in any thread */
|
||||
/* must hold lock when calling this (except if connection->finalizing is TRUE)
|
||||
* returns the number of removed subscribers */
|
||||
@@ -3659,7 +3705,6 @@ unsubscribe_id_internal (GDBusConnection *connection,
|
||||
guint subscription_id)
|
||||
{
|
||||
SignalData *signal_data;
|
||||
- GPtrArray *signal_data_array;
|
||||
guint n;
|
||||
guint n_removed = 0;
|
||||
|
||||
@@ -3686,40 +3731,8 @@ unsubscribe_id_internal (GDBusConnection *connection,
|
||||
GUINT_TO_POINTER (subscription_id)));
|
||||
n_removed++;
|
||||
g_ptr_array_remove_index_fast (signal_data->subscribers, n);
|
||||
-
|
||||
- if (signal_data->subscribers->len == 0)
|
||||
- {
|
||||
- g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule));
|
||||
-
|
||||
- signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- signal_data->sender_unique_name);
|
||||
- g_warn_if_fail (signal_data_array != NULL);
|
||||
- g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data));
|
||||
-
|
||||
- if (signal_data_array->len == 0)
|
||||
- {
|
||||
- g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- signal_data->sender_unique_name));
|
||||
- }
|
||||
-
|
||||
- /* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */
|
||||
- if ((connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION) &&
|
||||
- !is_signal_data_for_name_lost_or_acquired (signal_data) &&
|
||||
- !g_dbus_connection_is_closed (connection) &&
|
||||
- !connection->finalizing)
|
||||
- {
|
||||
- /* The check for g_dbus_connection_is_closed() means that
|
||||
- * sending the RemoveMatch message can't fail with
|
||||
- * G_IO_ERROR_CLOSED, because we're holding the lock,
|
||||
- * so on_worker_closed() can't happen between the check we just
|
||||
- * did, and releasing the lock later.
|
||||
- */
|
||||
- remove_match_rule (connection, signal_data->rule);
|
||||
- }
|
||||
-
|
||||
- signal_data_free (signal_data);
|
||||
- }
|
||||
-
|
||||
+ /* May free signal_data */
|
||||
+ remove_signal_data_if_unused (connection, signal_data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
||||
173
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_12.patch
Normal file
173
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_12.patch
Normal file
@@ -0,0 +1,173 @@
|
||||
From 5377b4d9061b73bb47af85cc99253a18dc58e83e Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Tue, 23 Apr 2024 20:39:05 +0100
|
||||
Subject: [PATCH 12/18] gdbusconnection: Stop storing sender_unique_name in
|
||||
SignalData
|
||||
|
||||
This will become confusing when we start tracking the owner of a
|
||||
well-known-name sender, and it's redundant anyway. Instead, track the
|
||||
1 bit of data that we actually need: whether it's a well-known name.
|
||||
|
||||
Strictly speaking this too is redundant, because it's syntactically
|
||||
derivable from the sender, but only via extra string operations.
|
||||
A subsequent commit will add a data structure to keep track of the
|
||||
owner of a well-known-name sender, at which point this boolean will
|
||||
be replaced by the presence or absence of that data structure.
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/5377b4d9061b73bb47af85cc99253a18dc58e83e]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 36 ++++++++++++++++++++++++------------
|
||||
1 file changed, 24 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index 114cdde29..8c1d77b62 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -323,19 +323,19 @@ typedef struct
|
||||
{
|
||||
gchar *rule;
|
||||
gchar *sender;
|
||||
- gchar *sender_unique_name; /* if sender is unique or org.freedesktop.DBus, then that name... otherwise blank */
|
||||
gchar *interface_name;
|
||||
gchar *member;
|
||||
gchar *object_path;
|
||||
gchar *arg0;
|
||||
GDBusSignalFlags flags;
|
||||
GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */
|
||||
+ gboolean sender_is_its_own_owner;
|
||||
} SignalData;
|
||||
|
||||
static SignalData *
|
||||
signal_data_new_take (gchar *rule,
|
||||
gchar *sender,
|
||||
- gchar *sender_unique_name,
|
||||
+ gboolean sender_is_its_own_owner,
|
||||
gchar *interface_name,
|
||||
gchar *member,
|
||||
gchar *object_path,
|
||||
@@ -346,7 +346,7 @@ signal_data_new_take (gchar *rule,
|
||||
|
||||
signal_data->rule = rule;
|
||||
signal_data->sender = sender;
|
||||
- signal_data->sender_unique_name = sender_unique_name;
|
||||
+ signal_data->sender_is_its_own_owner = sender_is_its_own_owner;
|
||||
signal_data->interface_name = interface_name;
|
||||
signal_data->member = member;
|
||||
signal_data->object_path = object_path;
|
||||
@@ -361,7 +361,6 @@ signal_data_free (SignalData *signal_data)
|
||||
{
|
||||
g_free (signal_data->rule);
|
||||
g_free (signal_data->sender);
|
||||
- g_free (signal_data->sender_unique_name);
|
||||
g_free (signal_data->interface_name);
|
||||
g_free (signal_data->member);
|
||||
g_free (signal_data->object_path);
|
||||
@@ -3438,7 +3437,7 @@ remove_match_rule (GDBusConnection *connection,
|
||||
static gboolean
|
||||
is_signal_data_for_name_lost_or_acquired (SignalData *signal_data)
|
||||
{
|
||||
- return g_strcmp0 (signal_data->sender_unique_name, "org.freedesktop.DBus") == 0 &&
|
||||
+ return g_strcmp0 (signal_data->sender, "org.freedesktop.DBus") == 0 &&
|
||||
g_strcmp0 (signal_data->interface_name, "org.freedesktop.DBus") == 0 &&
|
||||
g_strcmp0 (signal_data->object_path, "/org/freedesktop/DBus") == 0 &&
|
||||
(g_strcmp0 (signal_data->member, "NameLost") == 0 ||
|
||||
@@ -3450,7 +3449,8 @@ is_signal_data_for_name_lost_or_acquired (SignalData *signal_data)
|
||||
/* called in any thread, connection lock is held */
|
||||
static void
|
||||
add_signal_data (GDBusConnection *connection,
|
||||
- SignalData *signal_data)
|
||||
+ SignalData *signal_data,
|
||||
+ const char *sender_unique_name)
|
||||
{
|
||||
GPtrArray *signal_data_array;
|
||||
|
||||
@@ -3470,12 +3470,12 @@ add_signal_data (GDBusConnection *connection,
|
||||
}
|
||||
|
||||
signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- signal_data->sender_unique_name);
|
||||
+ sender_unique_name);
|
||||
if (signal_data_array == NULL)
|
||||
{
|
||||
signal_data_array = g_ptr_array_new ();
|
||||
g_hash_table_insert (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- g_strdup (signal_data->sender_unique_name),
|
||||
+ g_strdup (sender_unique_name),
|
||||
signal_data_array);
|
||||
}
|
||||
g_ptr_array_add (signal_data_array, signal_data);
|
||||
@@ -3572,6 +3572,7 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
gchar *rule;
|
||||
SignalData *signal_data;
|
||||
SignalSubscriber *subscriber;
|
||||
+ gboolean sender_is_its_own_owner;
|
||||
const gchar *sender_unique_name;
|
||||
|
||||
/* Right now we abort if AddMatch() fails since it can only fail with the bus being in
|
||||
@@ -3607,6 +3608,11 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
rule = args_to_rule (sender, interface_name, member, object_path, arg0, flags);
|
||||
|
||||
if (sender != NULL && (g_dbus_is_unique_name (sender) || g_strcmp0 (sender, "org.freedesktop.DBus") == 0))
|
||||
+ sender_is_its_own_owner = TRUE;
|
||||
+ else
|
||||
+ sender_is_its_own_owner = FALSE;
|
||||
+
|
||||
+ if (sender_is_its_own_owner)
|
||||
sender_unique_name = sender;
|
||||
else
|
||||
sender_unique_name = "";
|
||||
@@ -3630,14 +3636,14 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
|
||||
signal_data = signal_data_new_take (g_steal_pointer (&rule),
|
||||
g_strdup (sender),
|
||||
- g_strdup (sender_unique_name),
|
||||
+ sender_is_its_own_owner,
|
||||
g_strdup (interface_name),
|
||||
g_strdup (member),
|
||||
g_strdup (object_path),
|
||||
g_strdup (arg0),
|
||||
flags);
|
||||
g_ptr_array_add (signal_data->subscribers, subscriber);
|
||||
- add_signal_data (connection, signal_data);
|
||||
+ add_signal_data (connection, signal_data, sender_unique_name);
|
||||
|
||||
out:
|
||||
g_hash_table_insert (connection->map_id_to_signal_data,
|
||||
@@ -3661,22 +3667,28 @@ static void
|
||||
remove_signal_data_if_unused (GDBusConnection *connection,
|
||||
SignalData *signal_data)
|
||||
{
|
||||
+ const gchar *sender_unique_name;
|
||||
GPtrArray *signal_data_array;
|
||||
|
||||
if (signal_data->subscribers->len != 0)
|
||||
return;
|
||||
|
||||
+ if (signal_data->sender_is_its_own_owner)
|
||||
+ sender_unique_name = signal_data->sender;
|
||||
+ else
|
||||
+ sender_unique_name = "";
|
||||
+
|
||||
g_warn_if_fail (g_hash_table_remove (connection->map_rule_to_signal_data, signal_data->rule));
|
||||
|
||||
signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- signal_data->sender_unique_name);
|
||||
+ sender_unique_name);
|
||||
g_warn_if_fail (signal_data_array != NULL);
|
||||
g_warn_if_fail (g_ptr_array_remove (signal_data_array, signal_data));
|
||||
|
||||
if (signal_data_array->len == 0)
|
||||
{
|
||||
g_warn_if_fail (g_hash_table_remove (connection->map_sender_unique_name_to_signal_data_array,
|
||||
- signal_data->sender_unique_name));
|
||||
+ sender_unique_name));
|
||||
}
|
||||
|
||||
/* remove the match rule from the bus unless NameLost or NameAcquired (see subscribe()) */
|
||||
--
|
||||
2.30.2
|
||||
|
||||
513
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_13.patch
Normal file
513
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_13.patch
Normal file
@@ -0,0 +1,513 @@
|
||||
From 9114439d886137cfb903e109b612869535aa05b6 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Wed, 1 May 2024 15:43:09 +0100
|
||||
Subject: [PATCH 13/18] gdbus: Track name owners for signal subscriptions
|
||||
|
||||
We will use this in a subsequent commit to prevent signals from an
|
||||
impostor from being delivered to a subscriber.
|
||||
|
||||
To avoid message reordering leading to misleading situations, this does
|
||||
not use the existing mechanism for watching bus name ownership, which
|
||||
delivers the ownership changes to other main-contexts. Instead, it all
|
||||
happens on the single thread used by the GDBusWorker, so the order in
|
||||
which messages are received is the order in which they are processed.
|
||||
|
||||
[Backported to glib-2-74, resolving minor conflicts]
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/9114439d886137cfb903e109b612869535aa05b6]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 350 +++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 343 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index 8c1d77b62..1ac120bc5 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -320,6 +320,31 @@ signal_subscriber_unref (SignalSubscriber *subscriber)
|
||||
}
|
||||
|
||||
typedef struct
|
||||
+{
|
||||
+ /*
|
||||
+ * 1 reference while waiting for GetNameOwner() to finish
|
||||
+ * 1 reference for each SignalData that points to this one as its
|
||||
+ * shared_name_watcher
|
||||
+ */
|
||||
+ grefcount ref_count;
|
||||
+
|
||||
+ gchar *owner;
|
||||
+ guint32 get_name_owner_serial;
|
||||
+} WatchedName;
|
||||
+
|
||||
+static WatchedName *
|
||||
+watched_name_new (void)
|
||||
+{
|
||||
+ WatchedName *watched_name = g_new0 (WatchedName, 1);
|
||||
+
|
||||
+ g_ref_count_init (&watched_name->ref_count);
|
||||
+ watched_name->owner = NULL;
|
||||
+ return g_steal_pointer (&watched_name);
|
||||
+}
|
||||
+
|
||||
+typedef struct SignalData SignalData;
|
||||
+
|
||||
+struct SignalData
|
||||
{
|
||||
gchar *rule;
|
||||
gchar *sender;
|
||||
@@ -329,13 +354,36 @@ typedef struct
|
||||
gchar *arg0;
|
||||
GDBusSignalFlags flags;
|
||||
GPtrArray *subscribers; /* (owned) (element-type SignalSubscriber) */
|
||||
- gboolean sender_is_its_own_owner;
|
||||
-} SignalData;
|
||||
+
|
||||
+ /*
|
||||
+ * If the sender is a well-known name, this is an unowned SignalData
|
||||
+ * representing the NameOwnerChanged signal that tracks its owner.
|
||||
+ * NULL if sender is NULL.
|
||||
+ * NULL if sender is its own owner (a unique name or DBUS_SERVICE_DBUS).
|
||||
+ *
|
||||
+ * Invariants: if not NULL, then
|
||||
+ * shared_name_watcher->sender == DBUS_SERVICE_DBUS
|
||||
+ * shared_name_watcher->interface_name == DBUS_INTERFACE_DBUS
|
||||
+ * shared_name_watcher->member == "NameOwnerChanged"
|
||||
+ * shared_name_watcher->object_path == DBUS_PATH_DBUS
|
||||
+ * shared_name_watcher->arg0 == sender
|
||||
+ * shared_name_watcher->flags == NONE
|
||||
+ * shared_name_watcher->watched_name == NULL
|
||||
+ */
|
||||
+ SignalData *shared_name_watcher;
|
||||
+
|
||||
+ /*
|
||||
+ * Non-NULL if this SignalData is another SignalData's shared_name_watcher.
|
||||
+ * One reference for each SignalData that has this one as its
|
||||
+ * shared_name_watcher.
|
||||
+ * Otherwise NULL.
|
||||
+ */
|
||||
+ WatchedName *watched_name;
|
||||
+};
|
||||
|
||||
static SignalData *
|
||||
signal_data_new_take (gchar *rule,
|
||||
gchar *sender,
|
||||
- gboolean sender_is_its_own_owner,
|
||||
gchar *interface_name,
|
||||
gchar *member,
|
||||
gchar *object_path,
|
||||
@@ -346,7 +394,6 @@ signal_data_new_take (gchar *rule,
|
||||
|
||||
signal_data->rule = rule;
|
||||
signal_data->sender = sender;
|
||||
- signal_data->sender_is_its_own_owner = sender_is_its_own_owner;
|
||||
signal_data->interface_name = interface_name;
|
||||
signal_data->member = member;
|
||||
signal_data->object_path = object_path;
|
||||
@@ -359,6 +406,17 @@ signal_data_new_take (gchar *rule,
|
||||
static void
|
||||
signal_data_free (SignalData *signal_data)
|
||||
{
|
||||
+ /* The SignalData should not be freed while it still has subscribers */
|
||||
+ g_assert (signal_data->subscribers->len == 0);
|
||||
+
|
||||
+ /* The SignalData should not be freed while it is watching for
|
||||
+ * NameOwnerChanged on behalf of another SignalData */
|
||||
+ g_assert (signal_data->watched_name == NULL);
|
||||
+
|
||||
+ /* The SignalData should be detached from its name watcher, if any,
|
||||
+ * before it is freed */
|
||||
+ g_assert (signal_data->shared_name_watcher == NULL);
|
||||
+
|
||||
g_free (signal_data->rule);
|
||||
g_free (signal_data->sender);
|
||||
g_free (signal_data->interface_name);
|
||||
@@ -366,6 +424,7 @@ signal_data_free (SignalData *signal_data)
|
||||
g_free (signal_data->object_path);
|
||||
g_free (signal_data->arg0);
|
||||
g_ptr_array_unref (signal_data->subscribers);
|
||||
+
|
||||
g_free (signal_data);
|
||||
}
|
||||
|
||||
@@ -497,6 +556,7 @@ struct _GDBusConnection
|
||||
|
||||
/* Map used for managing method replies, protected by @lock */
|
||||
GHashTable *map_method_serial_to_task; /* guint32 -> GTask* */
|
||||
+ GHashTable *map_method_serial_to_name_watcher; /* guint32 -> unowned SignalData* */
|
||||
|
||||
/* Maps used for managing signal subscription, protected by @lock */
|
||||
GHashTable *map_rule_to_signal_data; /* match rule (gchar*) -> SignalData */
|
||||
@@ -745,6 +805,7 @@ g_dbus_connection_finalize (GObject *object)
|
||||
g_error_free (connection->initialization_error);
|
||||
|
||||
g_hash_table_unref (connection->map_method_serial_to_task);
|
||||
+ g_hash_table_unref (connection->map_method_serial_to_name_watcher);
|
||||
|
||||
g_hash_table_unref (connection->map_rule_to_signal_data);
|
||||
g_hash_table_unref (connection->map_id_to_signal_data);
|
||||
@@ -1149,6 +1210,7 @@ g_dbus_connection_init (GDBusConnection *connection)
|
||||
g_mutex_init (&connection->init_lock);
|
||||
|
||||
connection->map_method_serial_to_task = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
+ connection->map_method_serial_to_name_watcher = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL);
|
||||
|
||||
connection->map_rule_to_signal_data = g_hash_table_new (g_str_hash,
|
||||
g_str_equal);
|
||||
@@ -2266,6 +2328,191 @@ g_dbus_connection_send_message_with_reply_sync (GDBusConnection *connecti
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
+/*
|
||||
+ * Called in any thread.
|
||||
+ * Must hold the connection lock when calling this, unless
|
||||
+ * connection->finalizing is TRUE.
|
||||
+ */
|
||||
+static void
|
||||
+name_watcher_unref_watched_name (GDBusConnection *connection,
|
||||
+ SignalData *name_watcher)
|
||||
+{
|
||||
+ WatchedName *watched_name = name_watcher->watched_name;
|
||||
+
|
||||
+ g_assert (watched_name != NULL);
|
||||
+
|
||||
+ if (!g_ref_count_dec (&watched_name->ref_count))
|
||||
+ return;
|
||||
+
|
||||
+ /* Removing watched_name from the name_watcher may result in
|
||||
+ * name_watcher being freed, so we must make sure name_watcher is no
|
||||
+ * longer in map_method_serial_to_name_watcher.
|
||||
+ *
|
||||
+ * If we stop watching the name while our GetNameOwner call was still
|
||||
+ * in-flight, then when the reply eventually arrives, we will not find
|
||||
+ * its serial number in the map and harmlessly ignore it as a result. */
|
||||
+ if (watched_name->get_name_owner_serial != 0)
|
||||
+ g_hash_table_remove (connection->map_method_serial_to_name_watcher,
|
||||
+ GUINT_TO_POINTER (watched_name->get_name_owner_serial));
|
||||
+
|
||||
+ name_watcher->watched_name = NULL;
|
||||
+ g_free (watched_name->owner);
|
||||
+ g_free (watched_name);
|
||||
+}
|
||||
+
|
||||
+/* called in GDBusWorker thread with lock held */
|
||||
+static void
|
||||
+name_watcher_set_name_owner_unlocked (SignalData *name_watcher,
|
||||
+ const char *new_owner)
|
||||
+{
|
||||
+ if (new_owner != NULL && new_owner[0] == '\0')
|
||||
+ new_owner = NULL;
|
||||
+
|
||||
+ g_assert (name_watcher->watched_name != NULL);
|
||||
+ g_set_str (&name_watcher->watched_name->owner, new_owner);
|
||||
+}
|
||||
+
|
||||
+/* called in GDBusWorker thread with lock held */
|
||||
+static void
|
||||
+name_watcher_deliver_name_owner_changed_unlocked (SignalData *name_watcher,
|
||||
+ GDBusMessage *message)
|
||||
+{
|
||||
+ GVariant *body;
|
||||
+
|
||||
+ body = g_dbus_message_get_body (message);
|
||||
+
|
||||
+ if (G_LIKELY (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(sss)"))))
|
||||
+ {
|
||||
+ const char *name;
|
||||
+ const char *new_owner;
|
||||
+
|
||||
+ g_variant_get (body, "(&s&s&s)", &name, NULL, &new_owner);
|
||||
+
|
||||
+ /* Our caller already checked this */
|
||||
+ g_assert (g_strcmp0 (name_watcher->arg0, name) == 0);
|
||||
+
|
||||
+ if (G_LIKELY (new_owner[0] == '\0' || g_dbus_is_unique_name (new_owner)))
|
||||
+ name_watcher_set_name_owner_unlocked (name_watcher, new_owner);
|
||||
+ else
|
||||
+ g_warning ("Received NameOwnerChanged signal with invalid owner \"%s\" for \"%s\"",
|
||||
+ new_owner, name);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_warning ("Received NameOwnerChanged signal with unexpected "
|
||||
+ "signature %s",
|
||||
+ body == NULL ? "()" : g_variant_get_type_string (body));
|
||||
+
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* called in GDBusWorker thread with lock held */
|
||||
+static void
|
||||
+name_watcher_deliver_get_name_owner_reply_unlocked (SignalData *name_watcher,
|
||||
+ GDBusConnection *connection,
|
||||
+ GDBusMessage *message)
|
||||
+{
|
||||
+ GDBusMessageType type;
|
||||
+ GVariant *body;
|
||||
+ WatchedName *watched_name;
|
||||
+
|
||||
+ watched_name = name_watcher->watched_name;
|
||||
+ g_assert (watched_name != NULL);
|
||||
+ g_assert (watched_name->get_name_owner_serial != 0);
|
||||
+
|
||||
+ type = g_dbus_message_get_message_type (message);
|
||||
+ body = g_dbus_message_get_body (message);
|
||||
+
|
||||
+ if (type == G_DBUS_MESSAGE_TYPE_ERROR)
|
||||
+ {
|
||||
+ if (g_strcmp0 (g_dbus_message_get_error_name (message),
|
||||
+ "org.freedesktop.DBus.Error.NameHasNoOwner"))
|
||||
+ name_watcher_set_name_owner_unlocked (name_watcher, NULL);
|
||||
+ /* else it's something like NoReply or AccessDenied, which tells
|
||||
+ * us nothing - leave the owner set to whatever we most recently
|
||||
+ * learned from NameOwnerChanged, or NULL */
|
||||
+ }
|
||||
+ else if (type != G_DBUS_MESSAGE_TYPE_METHOD_RETURN)
|
||||
+ {
|
||||
+ g_warning ("Received GetNameOwner reply with unexpected type %d",
|
||||
+ type);
|
||||
+ }
|
||||
+ else if (G_LIKELY (body != NULL && g_variant_is_of_type (body, G_VARIANT_TYPE ("(s)"))))
|
||||
+ {
|
||||
+ const char *new_owner;
|
||||
+
|
||||
+ g_variant_get (body, "(&s)", &new_owner);
|
||||
+
|
||||
+ if (G_LIKELY (g_dbus_is_unique_name (new_owner)))
|
||||
+ name_watcher_set_name_owner_unlocked (name_watcher, new_owner);
|
||||
+ else
|
||||
+ g_warning ("Received GetNameOwner reply with invalid owner \"%s\" for \"%s\"",
|
||||
+ new_owner, name_watcher->arg0);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_warning ("Received GetNameOwner reply with unexpected signature %s",
|
||||
+ body == NULL ? "()" : g_variant_get_type_string (body));
|
||||
+ }
|
||||
+
|
||||
+ g_hash_table_remove (connection->map_method_serial_to_name_watcher,
|
||||
+ GUINT_TO_POINTER (watched_name->get_name_owner_serial));
|
||||
+ watched_name->get_name_owner_serial = 0;
|
||||
+}
|
||||
+
|
||||
+/* Called in a user thread, lock is held */
|
||||
+static void
|
||||
+name_watcher_call_get_name_owner_unlocked (GDBusConnection *connection,
|
||||
+ SignalData *name_watcher)
|
||||
+{
|
||||
+ GDBusMessage *message;
|
||||
+ GError *local_error = NULL;
|
||||
+ WatchedName *watched_name;
|
||||
+
|
||||
+ g_assert (g_strcmp0 (name_watcher->sender, DBUS_SERVICE_DBUS) == 0);
|
||||
+ g_assert (g_strcmp0 (name_watcher->interface_name, DBUS_INTERFACE_DBUS) == 0);
|
||||
+ g_assert (g_strcmp0 (name_watcher->member, "NameOwnerChanged") == 0);
|
||||
+ g_assert (g_strcmp0 (name_watcher->object_path, DBUS_PATH_DBUS) == 0);
|
||||
+ /* arg0 of the NameOwnerChanged message is the well-known name whose owner
|
||||
+ * we are interested in */
|
||||
+ g_assert (g_dbus_is_name (name_watcher->arg0));
|
||||
+ g_assert (name_watcher->flags == G_DBUS_SIGNAL_FLAGS_NONE);
|
||||
+
|
||||
+ watched_name = name_watcher->watched_name;
|
||||
+ g_assert (watched_name != NULL);
|
||||
+ g_assert (watched_name->owner == NULL);
|
||||
+ g_assert (watched_name->get_name_owner_serial == 0);
|
||||
+ g_assert (name_watcher->shared_name_watcher == NULL);
|
||||
+
|
||||
+ message = g_dbus_message_new_method_call (DBUS_SERVICE_DBUS,
|
||||
+ DBUS_PATH_DBUS,
|
||||
+ DBUS_INTERFACE_DBUS,
|
||||
+ "GetNameOwner");
|
||||
+ g_dbus_message_set_body (message, g_variant_new ("(s)", name_watcher->arg0));
|
||||
+
|
||||
+ if (g_dbus_connection_send_message_unlocked (connection, message,
|
||||
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE,
|
||||
+ &watched_name->get_name_owner_serial,
|
||||
+ &local_error))
|
||||
+ {
|
||||
+ g_assert (watched_name->get_name_owner_serial != 0);
|
||||
+ g_hash_table_insert (connection->map_method_serial_to_name_watcher,
|
||||
+ GUINT_TO_POINTER (watched_name->get_name_owner_serial),
|
||||
+ name_watcher);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_critical ("Error while sending GetNameOwner() message: %s",
|
||||
+ local_error->message);
|
||||
+ g_clear_error (&local_error);
|
||||
+ g_assert (watched_name->get_name_owner_serial == 0);
|
||||
+ }
|
||||
+
|
||||
+ g_object_unref (message);
|
||||
+}
|
||||
+
|
||||
+/* ---------------------------------------------------------------------------------------------------- */
|
||||
+
|
||||
typedef struct
|
||||
{
|
||||
guint id;
|
||||
@@ -2389,6 +2636,7 @@ on_worker_message_received (GDBusWorker *worker,
|
||||
{
|
||||
guint32 reply_serial;
|
||||
GTask *task;
|
||||
+ SignalData *name_watcher;
|
||||
|
||||
reply_serial = g_dbus_message_get_reply_serial (message);
|
||||
CONNECTION_LOCK (connection);
|
||||
@@ -2404,6 +2652,19 @@ on_worker_message_received (GDBusWorker *worker,
|
||||
{
|
||||
//g_debug ("message reply/error for serial %d but no SendMessageData found for %p", reply_serial, connection);
|
||||
}
|
||||
+
|
||||
+ name_watcher = g_hash_table_lookup (connection->map_method_serial_to_name_watcher,
|
||||
+ GUINT_TO_POINTER (reply_serial));
|
||||
+
|
||||
+ if (name_watcher != NULL)
|
||||
+ {
|
||||
+ g_assert (name_watcher->watched_name != NULL);
|
||||
+ g_assert (name_watcher->watched_name->get_name_owner_serial == reply_serial);
|
||||
+ name_watcher_deliver_get_name_owner_reply_unlocked (name_watcher,
|
||||
+ connection,
|
||||
+ message);
|
||||
+ }
|
||||
+
|
||||
CONNECTION_UNLOCK (connection);
|
||||
}
|
||||
else if (message_type == G_DBUS_MESSAGE_TYPE_SIGNAL)
|
||||
@@ -3571,6 +3832,7 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
{
|
||||
gchar *rule;
|
||||
SignalData *signal_data;
|
||||
+ SignalData *name_watcher = NULL;
|
||||
SignalSubscriber *subscriber;
|
||||
gboolean sender_is_its_own_owner;
|
||||
const gchar *sender_unique_name;
|
||||
@@ -3636,13 +3898,59 @@ g_dbus_connection_signal_subscribe (GDBusConnection *connection,
|
||||
|
||||
signal_data = signal_data_new_take (g_steal_pointer (&rule),
|
||||
g_strdup (sender),
|
||||
- sender_is_its_own_owner,
|
||||
g_strdup (interface_name),
|
||||
g_strdup (member),
|
||||
g_strdup (object_path),
|
||||
g_strdup (arg0),
|
||||
flags);
|
||||
g_ptr_array_add (signal_data->subscribers, subscriber);
|
||||
+
|
||||
+ /* If subscribing to a signal from a specific sender with a well-known
|
||||
+ * name, we must first subscribe to NameOwnerChanged signals for that
|
||||
+ * well-known name, so that we can match the current owner of the name
|
||||
+ * against the sender of each signal. */
|
||||
+ if (sender != NULL && !sender_is_its_own_owner)
|
||||
+ {
|
||||
+ gchar *name_owner_rule = NULL;
|
||||
+
|
||||
+ /* We already checked that sender != NULL implies MESSAGE_BUS_CONNECTION */
|
||||
+ g_assert (connection->flags & G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION);
|
||||
+
|
||||
+ name_owner_rule = args_to_rule (DBUS_SERVICE_DBUS,
|
||||
+ DBUS_INTERFACE_DBUS,
|
||||
+ "NameOwnerChanged",
|
||||
+ DBUS_PATH_DBUS,
|
||||
+ sender,
|
||||
+ G_DBUS_SIGNAL_FLAGS_NONE);
|
||||
+ name_watcher = g_hash_table_lookup (connection->map_rule_to_signal_data, name_owner_rule);
|
||||
+
|
||||
+ if (name_watcher == NULL)
|
||||
+ {
|
||||
+ name_watcher = signal_data_new_take (g_steal_pointer (&name_owner_rule),
|
||||
+ g_strdup (DBUS_SERVICE_DBUS),
|
||||
+ g_strdup (DBUS_INTERFACE_DBUS),
|
||||
+ g_strdup ("NameOwnerChanged"),
|
||||
+ g_strdup (DBUS_PATH_DBUS),
|
||||
+ g_strdup (sender),
|
||||
+ G_DBUS_SIGNAL_FLAGS_NONE);
|
||||
+ add_signal_data (connection, name_watcher, DBUS_SERVICE_DBUS);
|
||||
+ }
|
||||
+
|
||||
+ if (name_watcher->watched_name == NULL)
|
||||
+ {
|
||||
+ name_watcher->watched_name = watched_name_new ();
|
||||
+ name_watcher_call_get_name_owner_unlocked (connection, name_watcher);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_ref_count_inc (&name_watcher->watched_name->ref_count);
|
||||
+ }
|
||||
+
|
||||
+ signal_data->shared_name_watcher = name_watcher;
|
||||
+
|
||||
+ g_clear_pointer (&name_owner_rule, g_free);
|
||||
+ }
|
||||
+
|
||||
add_signal_data (connection, signal_data, sender_unique_name);
|
||||
|
||||
out:
|
||||
@@ -3670,10 +3978,18 @@ remove_signal_data_if_unused (GDBusConnection *connection,
|
||||
const gchar *sender_unique_name;
|
||||
GPtrArray *signal_data_array;
|
||||
|
||||
+ /* Cannot remove while there are still subscribers */
|
||||
if (signal_data->subscribers->len != 0)
|
||||
return;
|
||||
|
||||
- if (signal_data->sender_is_its_own_owner)
|
||||
+ /* Cannot remove while another SignalData is still using this one
|
||||
+ * as its shared_name_watcher, which holds watched_name->ref_count > 0 */
|
||||
+ if (signal_data->watched_name != NULL)
|
||||
+ return;
|
||||
+
|
||||
+ /* Point of no return: we have committed to removing it */
|
||||
+
|
||||
+ if (signal_data->sender != NULL && signal_data->shared_name_watcher == NULL)
|
||||
sender_unique_name = signal_data->sender;
|
||||
else
|
||||
sender_unique_name = "";
|
||||
@@ -3706,6 +4022,15 @@ remove_signal_data_if_unused (GDBusConnection *connection,
|
||||
remove_match_rule (connection, signal_data->rule);
|
||||
}
|
||||
|
||||
+ if (signal_data->shared_name_watcher != NULL)
|
||||
+ {
|
||||
+ SignalData *name_watcher = g_steal_pointer (&signal_data->shared_name_watcher);
|
||||
+
|
||||
+ name_watcher_unref_watched_name (connection, name_watcher);
|
||||
+ /* May free signal_data */
|
||||
+ remove_signal_data_if_unused (connection, name_watcher);
|
||||
+ }
|
||||
+
|
||||
signal_data_free (signal_data);
|
||||
}
|
||||
|
||||
@@ -3978,6 +4303,17 @@ schedule_callbacks (GDBusConnection *connection,
|
||||
continue;
|
||||
}
|
||||
|
||||
+ if (signal_data->watched_name != NULL)
|
||||
+ {
|
||||
+ /* Invariant: SignalData should only have a watched_name if it
|
||||
+ * represents the NameOwnerChanged signal */
|
||||
+ g_assert (g_strcmp0 (sender, DBUS_SERVICE_DBUS) == 0);
|
||||
+ g_assert (g_strcmp0 (interface, DBUS_INTERFACE_DBUS) == 0);
|
||||
+ g_assert (g_strcmp0 (path, DBUS_PATH_DBUS) == 0);
|
||||
+ g_assert (g_strcmp0 (member, "NameOwnerChanged") == 0);
|
||||
+ name_watcher_deliver_name_owner_changed_unlocked (signal_data, message);
|
||||
+ }
|
||||
+
|
||||
for (m = 0; m < signal_data->subscribers->len; m++)
|
||||
{
|
||||
SignalSubscriber *subscriber = signal_data->subscribers->pdata[m];
|
||||
@@ -4039,7 +4375,7 @@ distribute_signals (GDBusConnection *connection,
|
||||
schedule_callbacks (connection, signal_data_array, message, sender);
|
||||
}
|
||||
|
||||
- /* collect subscribers not matching on sender */
|
||||
+ /* collect subscribers not matching on sender, or matching a well-known name */
|
||||
signal_data_array = g_hash_table_lookup (connection->map_sender_unique_name_to_signal_data_array, "");
|
||||
if (signal_data_array != NULL)
|
||||
schedule_callbacks (connection, signal_data_array, message, sender);
|
||||
--
|
||||
2.30.2
|
||||
|
||||
75
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_14.patch
Normal file
75
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_14.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
From 69799764cb40a2842d4891d4e1d72c3ce73964ed Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Thu, 14 Mar 2024 20:42:41 +0000
|
||||
Subject: [PATCH 14/18] gdbusconnection: Don't deliver signals if the sender
|
||||
doesn't match
|
||||
|
||||
Otherwise a malicious connection on a shared bus, especially the system
|
||||
bus, could trick GDBus clients into processing signals sent by the
|
||||
malicious connection as though they had come from the real owner of a
|
||||
well-known service name.
|
||||
|
||||
Resolves: https://gitlab.gnome.org/GNOME/glib/-/issues/3268
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/69799764cb40a2842d4891d4e1d72c3ce73964ed]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/gdbusconnection.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 40 insertions(+)
|
||||
|
||||
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
|
||||
index 1ac120bc5..7cde0e3bf 100644
|
||||
--- a/gio/gdbusconnection.c
|
||||
+++ b/gio/gdbusconnection.c
|
||||
@@ -4284,6 +4284,46 @@ schedule_callbacks (GDBusConnection *connection,
|
||||
if (signal_data->object_path != NULL && g_strcmp0 (signal_data->object_path, path) != 0)
|
||||
continue;
|
||||
|
||||
+ if (signal_data->shared_name_watcher != NULL)
|
||||
+ {
|
||||
+ /* We want signals from a specified well-known name, which means
|
||||
+ * the signal's sender needs to be the unique name that currently
|
||||
+ * owns that well-known name, and we will have found this
|
||||
+ * SignalData in
|
||||
+ * connection->map_sender_unique_name_to_signal_data_array[""]. */
|
||||
+ const WatchedName *watched_name;
|
||||
+ const char *current_owner;
|
||||
+
|
||||
+ g_assert (signal_data->sender != NULL);
|
||||
+ /* Invariant: We never need to watch for the owner of a unique
|
||||
+ * name, or for the owner of DBUS_SERVICE_DBUS, either of which
|
||||
+ * is always its own owner */
|
||||
+ g_assert (!g_dbus_is_unique_name (signal_data->sender));
|
||||
+ g_assert (g_strcmp0 (signal_data->sender, DBUS_SERVICE_DBUS) != 0);
|
||||
+
|
||||
+ watched_name = signal_data->shared_name_watcher->watched_name;
|
||||
+ g_assert (watched_name != NULL);
|
||||
+ current_owner = watched_name->owner;
|
||||
+
|
||||
+ /* Skip the signal if the actual sender is not known to own
|
||||
+ * the required name */
|
||||
+ if (current_owner == NULL || g_strcmp0 (current_owner, sender) != 0)
|
||||
+ continue;
|
||||
+ }
|
||||
+ else if (signal_data->sender != NULL)
|
||||
+ {
|
||||
+ /* We want signals from a unique name or o.fd.DBus... */
|
||||
+ g_assert (g_dbus_is_unique_name (signal_data->sender)
|
||||
+ || g_str_equal (signal_data->sender, DBUS_SERVICE_DBUS));
|
||||
+
|
||||
+ /* ... which means we must have found this SignalData in
|
||||
+ * connection->map_sender_unique_name_to_signal_data_array[signal_data->sender],
|
||||
+ * therefore we would only have found it if the signal's
|
||||
+ * actual sender matches the required signal_data->sender */
|
||||
+ g_assert (g_strcmp0 (signal_data->sender, sender) == 0);
|
||||
+ }
|
||||
+ /* else the sender is unspecified and we will accept anything */
|
||||
+
|
||||
if (signal_data->arg0 != NULL)
|
||||
{
|
||||
if (arg0 == NULL)
|
||||
--
|
||||
2.30.2
|
||||
|
||||
47
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_15.patch
Normal file
47
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_15.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 505e2c644d02a5cf581fb85d145e820d51dc3f1b Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Fri, 8 Mar 2024 19:51:50 +0000
|
||||
Subject: [PATCH 15/18] tests: Add a test for matching by two well-known names
|
||||
|
||||
The expected result is that because TEST_CONN_SERVICE owns
|
||||
ALREADY_OWNED_NAME but not (yet) OWNED_LATER_NAME, the signal will be
|
||||
delivered to the subscriber for the former but not the latter.
|
||||
Before #3268 was fixed, it was incorrectly delivered to both.
|
||||
|
||||
Reproduces: https://gitlab.gnome.org/GNOME/glib/-/issues/3268 (partially)
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/505e2c644d02a5cf581fb85d145e820d51dc3f1b]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-subscribe.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c
|
||||
index af100de7d..171d6107d 100644
|
||||
--- a/gio/tests/gdbus-subscribe.c
|
||||
+++ b/gio/tests/gdbus-subscribe.c
|
||||
@@ -440,6 +440,19 @@ static const TestPlan plan_limit_by_well_known_name =
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ /* When the service sends a signal with the name it already owns,
|
||||
+ * it should get through */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 1,
|
||||
+ .received_by_proxy = 1
|
||||
+ },
|
||||
+ },
|
||||
{
|
||||
/* Service claims another name */
|
||||
.action = TEST_ACTION_OWN_NAME,
|
||||
--
|
||||
2.30.2
|
||||
|
||||
62
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_16.patch
Normal file
62
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_16.patch
Normal file
@@ -0,0 +1,62 @@
|
||||
From 8338f7ac107f642283437d05d7b4d49ca8968cdf Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Fri, 8 Mar 2024 19:53:22 +0000
|
||||
Subject: [PATCH 16/18] tests: Add a test for signal filtering by well-known
|
||||
name
|
||||
|
||||
The vulnerability reported as GNOME/glib#3268 can be characterized
|
||||
as: these signals from an attacker should not be delivered to either
|
||||
the GDBusConnection or the GDBusProxy, but in fact they are (in at
|
||||
least some scenarios).
|
||||
|
||||
Reproduces: https://gitlab.gnome.org/GNOME/glib/-/issues/3268
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/8338f7ac107f642283437d05d7b4d49ca8968cdf]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-subscribe.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c
|
||||
index 171d6107d..5406ba7e2 100644
|
||||
--- a/gio/tests/gdbus-subscribe.c
|
||||
+++ b/gio/tests/gdbus-subscribe.c
|
||||
@@ -440,6 +440,33 @@ static const TestPlan plan_limit_by_well_known_name =
|
||||
.iface = EXAMPLE_INTERFACE,
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ /* Attacker wants to trick subscriber into thinking that service
|
||||
+ * sent a signal */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ /* Attacker tries harder, by sending a signal unicast directly to
|
||||
+ * the subscriber */
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_ATTACKER,
|
||||
+ .unicast_to = TEST_CONN_SUBSCRIBER,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ .received_by_proxy = 0
|
||||
+ },
|
||||
+ },
|
||||
{
|
||||
/* When the service sends a signal with the name it already owns,
|
||||
* it should get through */
|
||||
--
|
||||
2.30.2
|
||||
|
||||
121
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_17.patch
Normal file
121
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_17.patch
Normal file
@@ -0,0 +1,121 @@
|
||||
From ff467241a37a0119d3c6df53548bb61fe4d4fbf9 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Tue, 23 Apr 2024 21:39:43 +0100
|
||||
Subject: [PATCH 17/18] tests: Ensure that unsubscribing with GetNameOwner
|
||||
in-flight doesn't crash
|
||||
|
||||
This was a bug that existed during development of this branch; make sure
|
||||
it doesn't come back.
|
||||
|
||||
This test fails with a use-after-free and crash if we comment out the
|
||||
part of name_watcher_unref_watched_name() that removes the name watcher
|
||||
from `map_method_serial_to_name_watcher`.
|
||||
|
||||
It would also fail with an assertion failure if we asserted in
|
||||
name_watcher_unref_watched_name() that get_name_owner_serial == 0
|
||||
(i.e. that GetNameOwner is not in-flight at destruction).
|
||||
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/ff467241a37a0119d3c6df53548bb61fe4d4fbf9]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-subscribe.c | 52 ++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 51 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gio/tests/gdbus-subscribe.c b/gio/tests/gdbus-subscribe.c
|
||||
index 5406ba7e2..4cba4f565 100644
|
||||
--- a/gio/tests/gdbus-subscribe.c
|
||||
+++ b/gio/tests/gdbus-subscribe.c
|
||||
@@ -116,6 +116,7 @@ typedef struct
|
||||
const char *member;
|
||||
const char *arg0;
|
||||
GDBusSignalFlags flags;
|
||||
+ gboolean unsubscribe_immediately;
|
||||
} TestSubscribe;
|
||||
|
||||
typedef struct
|
||||
@@ -141,6 +142,7 @@ typedef struct
|
||||
TestEmitSignal signal;
|
||||
TestSubscribe subscribe;
|
||||
TestOwnName own_name;
|
||||
+ guint unsubscribe_undo_step;
|
||||
} u;
|
||||
} TestStep;
|
||||
|
||||
@@ -505,6 +507,43 @@ static const TestPlan plan_limit_by_well_known_name =
|
||||
},
|
||||
};
|
||||
|
||||
+static const TestPlan plan_unsubscribe_immediately =
|
||||
+{
|
||||
+ .description = "Unsubscribing before GetNameOwner can return doesn't result in a crash",
|
||||
+ .steps = {
|
||||
+ {
|
||||
+ /* Service already owns one name */
|
||||
+ .action = TEST_ACTION_OWN_NAME,
|
||||
+ .u.own_name = {
|
||||
+ .name = ALREADY_OWNED_NAME,
|
||||
+ .owner = TEST_CONN_SERVICE
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .action = TEST_ACTION_SUBSCRIBE,
|
||||
+ .u.subscribe = {
|
||||
+ .string_sender = ALREADY_OWNED_NAME,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .unsubscribe_immediately = TRUE
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ .action = TEST_ACTION_EMIT_SIGNAL,
|
||||
+ .u.signal = {
|
||||
+ .sender = TEST_CONN_SERVICE,
|
||||
+ .path = EXAMPLE_PATH,
|
||||
+ .iface = EXAMPLE_INTERFACE,
|
||||
+ .member = FOO_SIGNAL,
|
||||
+ .received_by_conn = 0,
|
||||
+ /* The proxy can't unsubscribe, except by destroying the proxy
|
||||
+ * completely, which we don't currently implement in this test */
|
||||
+ .received_by_proxy = 1
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static const TestPlan plan_limit_to_message_bus =
|
||||
{
|
||||
.description = "A subscription to the message bus only accepts messages "
|
||||
@@ -855,8 +894,18 @@ fixture_subscribe (Fixture *f,
|
||||
subscribe->flags,
|
||||
subscribed_signal_cb,
|
||||
f, NULL);
|
||||
+
|
||||
g_assert_cmpuint (id, !=, 0);
|
||||
- f->subscriptions[step_number] = id;
|
||||
+
|
||||
+ if (subscribe->unsubscribe_immediately)
|
||||
+ {
|
||||
+ g_test_message ("\tImmediately unsubscribing");
|
||||
+ g_dbus_connection_signal_unsubscribe (subscriber, id);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ f->subscriptions[step_number] = id;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (f->mode != SUBSCRIPTION_MODE_CONN)
|
||||
@@ -1287,6 +1336,7 @@ main (int argc,
|
||||
ADD_SUBSCRIBE_TEST (nonexistent_unique_name);
|
||||
ADD_SUBSCRIBE_TEST (limit_by_well_known_name);
|
||||
ADD_SUBSCRIBE_TEST (limit_to_message_bus);
|
||||
+ ADD_SUBSCRIBE_TEST (unsubscribe_immediately);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
||||
50
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_18.patch
Normal file
50
meta/recipes-core/glib-2.0/glib-2.0/CVE-2024-34397_18.patch
Normal file
@@ -0,0 +1,50 @@
|
||||
From fe11c6a513a1b16462442e361bab753246c8de2e Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@debian.org>
|
||||
Date: Mon, 6 May 2024 21:24:53 +0100
|
||||
Subject: [PATCH 18/18] gdbus-proxy test: Wait before asserting name owner has
|
||||
gone away
|
||||
|
||||
GDBusConnection sends each signal to recipients in a separate idle
|
||||
callback, and there's no particular guarantee about the order in which
|
||||
they're scheduled or dispatched. For the NameOwnerChanged signal that
|
||||
reports the name becoming unowned, it's possible that g_bus_watch_name()
|
||||
gets its idle callback called before the GDBusProxy:g-name-owner
|
||||
machinery has updated the name owner, in which case the assertion
|
||||
will fail.
|
||||
|
||||
Fixing GNOME/glib#3268 introduced a new subscription to NameOwnerChanged
|
||||
which can alter the order of delivery, particularly in the case where
|
||||
G_DBUS_PROXY_FLAGS_NO_MATCH_RULE was used (as tested in
|
||||
/gdbus/proxy/no-match-rule). The resulting test failure is intermittent,
|
||||
but reliably appears within 100 repetitions of that test.
|
||||
|
||||
Fixes: 511c5f5b "tests: Wait for gdbus-testserver to die when killing it"
|
||||
Signed-off-by: Simon McVittie <smcv@debian.org>
|
||||
|
||||
CVE: CVE-2024-34397
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/glib/-/commit/fe11c6a513a1b16462442e361bab753246c8de2e]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
gio/tests/gdbus-proxy.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/gio/tests/gdbus-proxy.c b/gio/tests/gdbus-proxy.c
|
||||
index eed75acf4..9303d0088 100644
|
||||
--- a/gio/tests/gdbus-proxy.c
|
||||
+++ b/gio/tests/gdbus-proxy.c
|
||||
@@ -778,6 +778,12 @@ kill_test_service (GDBusConnection *connection)
|
||||
while (!name_disappeared)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
+ /* GDBusConnection doesn't guarantee that different subscriptions to the
|
||||
+ * same signal will get their callbacks scheduled in any particular order,
|
||||
+ * so make sure they have all happened */
|
||||
+ while (g_main_context_iteration (NULL, FALSE))
|
||||
+ continue;
|
||||
+
|
||||
g_bus_unwatch_name (watch_id);
|
||||
#else
|
||||
g_warning ("Can't kill com.example.TestService");
|
||||
--
|
||||
2.30.2
|
||||
|
||||
@@ -31,6 +31,24 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \
|
||||
file://CVE-2023-32611-0002.patch \
|
||||
file://CVE-2023-32643.patch \
|
||||
file://CVE-2023-32636.patch \
|
||||
file://CVE-2024-34397_01.patch \
|
||||
file://CVE-2024-34397_02.patch \
|
||||
file://CVE-2024-34397_03.patch \
|
||||
file://CVE-2024-34397_04.patch \
|
||||
file://CVE-2024-34397_05.patch \
|
||||
file://CVE-2024-34397_06.patch \
|
||||
file://CVE-2024-34397_07.patch \
|
||||
file://CVE-2024-34397_08.patch \
|
||||
file://CVE-2024-34397_09.patch \
|
||||
file://CVE-2024-34397_10.patch \
|
||||
file://CVE-2024-34397_11.patch \
|
||||
file://CVE-2024-34397_12.patch \
|
||||
file://CVE-2024-34397_13.patch \
|
||||
file://CVE-2024-34397_14.patch \
|
||||
file://CVE-2024-34397_15.patch \
|
||||
file://CVE-2024-34397_16.patch \
|
||||
file://CVE-2024-34397_17.patch \
|
||||
file://CVE-2024-34397_18.patch \
|
||||
"
|
||||
SRC_URI:append:class-native = " file://relocate-modules.patch"
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ python __anonymous() {
|
||||
d.setVar("PACKAGES", "${PN} ${PN}-ptest")
|
||||
|
||||
d.setVar("PROVIDES", "${PN} ${PN}-ptest")
|
||||
d.setVar("RPROVIDES", "${PN} ${PN}-ptest")
|
||||
|
||||
bbclassextend = d.getVar("BBCLASSEXTEND").replace("nativesdk", "").strip()
|
||||
d.setVar("BBCLASSEXTEND", bbclassextend)
|
||||
@@ -29,7 +28,8 @@ python __anonymous() {
|
||||
# Remove any leftovers from original glibc recipe
|
||||
RPROVIDES:${PN} = "${PN}"
|
||||
RRECOMMENDS:${PN} = ""
|
||||
RDEPENDS:${PN} = " glibc sed"
|
||||
RDEPENDS:${PN} = " glibc sed bash"
|
||||
RDEPENDS:${PN}-ptest = "${PN}"
|
||||
DEPENDS += "sed"
|
||||
|
||||
export oe_srcdir="${exec_prefix}/src/debug/glibc/${PV}/"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SRCBRANCH ?= "release/2.35/master"
|
||||
PV = "2.35"
|
||||
SRCREV_glibc ?= "54a666dc5c94897dab63856ba264ab2c53503303"
|
||||
SRCREV_glibc ?= "72abffe225485d10ea76adde963c13157bf3b310"
|
||||
SRCREV_localedef ?= "794da69788cbf9bf57b59a852f9f11307663fa87"
|
||||
|
||||
GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# ptest script for glibc - to run time related tests to
|
||||
# facilitate Y2038 validation
|
||||
# Run with 'ptest-runner glibc-tests'
|
||||
|
||||
@@ -24,7 +24,7 @@ IMAGE_FSTYPES = "wic.vmdk wic.vhd wic.vhdx"
|
||||
|
||||
inherit core-image setuptools3
|
||||
|
||||
SRCREV ?= "4cf40d460852e5e8b4a48dc044fd1c9e650061b3"
|
||||
SRCREV ?= "940c885c239be4139908c1c322cd335e02d27a92"
|
||||
SRC_URI = "git://git.yoctoproject.org/poky;branch=kirkstone \
|
||||
file://Yocto_Build_Appliance.vmx \
|
||||
file://Yocto_Build_Appliance.vmxf \
|
||||
|
||||
30
meta/recipes-core/libxml/libxml2/CVE-2024-34459.patch
Normal file
30
meta/recipes-core/libxml/libxml2/CVE-2024-34459.patch
Normal file
@@ -0,0 +1,30 @@
|
||||
From 78fce372041d53cfeaaf2c11c71d07eef55ecfd1 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 8 May 2024 11:49:31 +0200
|
||||
Subject: [PATCH] Fix buffer overread with `xmllint --htmlout`
|
||||
|
||||
Add a missing bounds check.
|
||||
|
||||
Upstream-Status: Backport from [https://gitlab.gnome.org/GNOME/libxml2/-/commit/2876ac5392a4e891b81e40e592c3ac6cb46016ce]
|
||||
CVE: CVE-2024-34459
|
||||
Signed-off-by: Siddharth Doshi <sdoshi@mvista.com>
|
||||
---
|
||||
xmllint.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xmllint.c b/xmllint.c
|
||||
index ee6bfdc..2f792f1 100644
|
||||
--- a/xmllint.c
|
||||
+++ b/xmllint.c
|
||||
@@ -602,7 +602,7 @@ xmlHTMLPrintFileContext(xmlParserInputPtr input) {
|
||||
len = strlen(buffer);
|
||||
snprintf(&buffer[len], sizeof(buffer) - len, "\n");
|
||||
cur = input->cur;
|
||||
- while ((*cur == '\n') || (*cur == '\r'))
|
||||
+ while ((cur > base) && ((*cur == '\n') || (*cur == '\r')))
|
||||
cur--;
|
||||
n = 0;
|
||||
while ((cur != base) && (n++ < 80)) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -32,6 +32,7 @@ SRC_URI += "http://www.w3.org/XML/Test/xmlts20080827.tar;subdir=${BP};name=testt
|
||||
file://CVE-2023-45322-1.patch \
|
||||
file://CVE-2023-45322-2.patch \
|
||||
file://CVE-2024-25062.patch \
|
||||
file://CVE-2024-34459.patch \
|
||||
"
|
||||
|
||||
SRC_URI[archive.sha256sum] = "60d74a257d1ccec0475e749cba2f21559e48139efba6ff28224357c7c798dfee"
|
||||
|
||||
@@ -145,7 +145,7 @@ do_install:append:class-target () {
|
||||
ln -s ../${TARGET_SYS}/ext ${D}${includedir}/c++/${BINV}/${TARGET_ARCH}${TARGET_VENDOR_MULTILIB_ORIGINAL}-${TARGET_OS}/ext
|
||||
fi
|
||||
|
||||
if [ "${TARGET_ARCH}" == "x86_64" -a "${MULTILIB_VARIANTS}" != "" ];then
|
||||
if [ "${TARGET_ARCH}" = "x86_64" -a "${MULTILIB_VARIANTS}" != "" ];then
|
||||
ln -sf ../${X86ARCH32}${TARGET_VENDOR}-${TARGET_OS} ${D}${includedir}/c++/${BINV}/${TARGET_ARCH}${TARGET_VENDOR}-${TARGET_OS}/32
|
||||
fi
|
||||
|
||||
|
||||
@@ -56,6 +56,8 @@ SRC_URI += "\
|
||||
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 \
|
||||
"
|
||||
SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd"
|
||||
|
||||
|
||||
78
meta/recipes-devtools/go/go-1.21/CVE-2024-24789.patch
Normal file
78
meta/recipes-devtools/go/go-1.21/CVE-2024-24789.patch
Normal file
@@ -0,0 +1,78 @@
|
||||
From c8e40338cf00f3c1d86c8fb23863ad67a4c72bcc Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Tue, 14 May 2024 14:39:10 -0700
|
||||
Subject: [PATCH] [release-branch.go1.21] archive/zip: treat truncated EOCDR
|
||||
comment as an error
|
||||
|
||||
When scanning for an end of central directory record,
|
||||
treat an EOCDR signature with a record containing a truncated
|
||||
comment as an error. Previously, we would skip over the invalid
|
||||
record and look for another one. Other implementations do not
|
||||
do this (they either consider this a hard error, or just ignore
|
||||
the truncated comment). This parser misalignment allowed
|
||||
presenting entirely different archive contents to Go programs
|
||||
and other zip decoders.
|
||||
|
||||
For #66869
|
||||
Fixes #67553
|
||||
|
||||
Change-Id: I94e5cb028534bb5704588b8af27f1e22ea49c7c6
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/585397
|
||||
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
(cherry picked from commit 33d725e5758bf1fea62e6c77fc70b57a828a49f5)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/588795
|
||||
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
|
||||
|
||||
CVE: CVE-2024-24789
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/c8e40338cf00f3c1d86c8fb23863ad67a4c72bcc]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
src/archive/zip/reader.go | 8 ++++++--
|
||||
src/archive/zip/reader_test.go | 8 ++++++++
|
||||
2 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
|
||||
index e40a2c6..987f543 100644
|
||||
--- a/src/archive/zip/reader.go
|
||||
+++ b/src/archive/zip/reader.go
|
||||
@@ -644,9 +644,13 @@ func findSignatureInBlock(b []byte) int {
|
||||
if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 {
|
||||
// n is length of comment
|
||||
n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8
|
||||
- if n+directoryEndLen+i <= len(b) {
|
||||
- return i
|
||||
+ if n+directoryEndLen+i > len(b) {
|
||||
+ // Truncated comment.
|
||||
+ // Some parsers (such as Info-ZIP) ignore the truncated comment
|
||||
+ // rather than treating it as a hard error.
|
||||
+ return -1
|
||||
}
|
||||
+ return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
|
||||
index a549153..7ac394d 100644
|
||||
--- a/src/archive/zip/reader_test.go
|
||||
+++ b/src/archive/zip/reader_test.go
|
||||
@@ -487,6 +487,14 @@ var tests = []ZipTest{
|
||||
},
|
||||
},
|
||||
},
|
||||
+ // Issue 66869: Don't skip over an EOCDR with a truncated comment.
|
||||
+ // The test file sneakily hides a second EOCDR before the first one;
|
||||
+ // previously we would extract one file ("file") from this archive,
|
||||
+ // while most other tools would reject the file or extract a different one ("FILE").
|
||||
+ {
|
||||
+ Name: "comment-truncated.zip",
|
||||
+ Error: ErrFormat,
|
||||
+ },
|
||||
}
|
||||
|
||||
func TestReader(t *testing.T) {
|
||||
--
|
||||
2.40.0
|
||||
359
meta/recipes-devtools/go/go-1.21/CVE-2024-24791.patch
Normal file
359
meta/recipes-devtools/go/go-1.21/CVE-2024-24791.patch
Normal file
@@ -0,0 +1,359 @@
|
||||
From c9be6ae748b7679b644a38182d456cb5a6ac06ee Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Thu, 6 Jun 2024 12:50:46 -0700
|
||||
Subject: [PATCH] [release-branch.go1.21] net/http: send body or close
|
||||
connection on expect-100-continue requests
|
||||
|
||||
When sending a request with an "Expect: 100-continue" header,
|
||||
we must send the request body before sending any further requests
|
||||
on the connection.
|
||||
|
||||
When receiving a non-1xx response to an "Expect: 100-continue" request,
|
||||
send the request body if the connection isn't being closed after
|
||||
processing the response. In other words, if either the request
|
||||
or response contains a "Connection: close" header, then skip sending
|
||||
the request body (because the connection will not be used for
|
||||
further requests), but otherwise send it.
|
||||
|
||||
Correct a comment on the server-side Expect: 100-continue handling
|
||||
that implied sending the request body is optional. It isn't.
|
||||
|
||||
For #67555
|
||||
Fixes #68199
|
||||
|
||||
Change-Id: Ia2f12091bee697771087f32ac347509ec5922d54
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/591255
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
Reviewed-by: Jonathan Amsterdam <jba@google.com>
|
||||
(cherry picked from commit cf501e05e138e6911f759a5db786e90b295499b9)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/595096
|
||||
Reviewed-by: Joedian Reid <joedian@google.com>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
|
||||
CVE: CVE-2024-24791
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/c9be6ae748b7679b644a38182d456cb5a6ac06ee ]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
src/net/http/server.go | 25 ++--
|
||||
src/net/http/transport.go | 34 ++++--
|
||||
src/net/http/transport_test.go | 203 ++++++++++++++++++++-------------
|
||||
3 files changed, 164 insertions(+), 98 deletions(-)
|
||||
|
||||
diff --git a/src/net/http/server.go b/src/net/http/server.go
|
||||
index 4fc8fed..1648f1c 100644
|
||||
--- a/src/net/http/server.go
|
||||
+++ b/src/net/http/server.go
|
||||
@@ -1297,16 +1297,21 @@ func (cw *chunkWriter) writeHeader(p []byte) {
|
||||
|
||||
// If the client wanted a 100-continue but we never sent it to
|
||||
// them (or, more strictly: we never finished reading their
|
||||
- // request body), don't reuse this connection because it's now
|
||||
- // in an unknown state: we might be sending this response at
|
||||
- // the same time the client is now sending its request body
|
||||
- // after a timeout. (Some HTTP clients send Expect:
|
||||
- // 100-continue but knowing that some servers don't support
|
||||
- // it, the clients set a timer and send the body later anyway)
|
||||
- // If we haven't seen EOF, we can't skip over the unread body
|
||||
- // because we don't know if the next bytes on the wire will be
|
||||
- // the body-following-the-timer or the subsequent request.
|
||||
- // See Issue 11549.
|
||||
+ // request body), don't reuse this connection.
|
||||
+ //
|
||||
+ // This behavior was first added on the theory that we don't know
|
||||
+ // if the next bytes on the wire are going to be the remainder of
|
||||
+ // the request body or the subsequent request (see issue 11549),
|
||||
+ // but that's not correct: If we keep using the connection,
|
||||
+ // the client is required to send the request body whether we
|
||||
+ // asked for it or not.
|
||||
+ //
|
||||
+ // We probably do want to skip reusing the connection in most cases,
|
||||
+ // however. If the client is offering a large request body that we
|
||||
+ // don't intend to use, then it's better to close the connection
|
||||
+ // than to read the body. For now, assume that if we're sending
|
||||
+ // headers, the handler is done reading the body and we should
|
||||
+ // drop the connection if we haven't seen EOF.
|
||||
if ecr, ok := w.req.Body.(*expectContinueReader); ok && !ecr.sawEOF.isSet() {
|
||||
w.closeAfterReply = true
|
||||
}
|
||||
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
|
||||
index 309194e..e46ddef 100644
|
||||
--- a/src/net/http/transport.go
|
||||
+++ b/src/net/http/transport.go
|
||||
@@ -2282,17 +2282,12 @@ func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTr
|
||||
return
|
||||
}
|
||||
resCode := resp.StatusCode
|
||||
- if continueCh != nil {
|
||||
- if resCode == 100 {
|
||||
- if trace != nil && trace.Got100Continue != nil {
|
||||
- trace.Got100Continue()
|
||||
- }
|
||||
- continueCh <- struct{}{}
|
||||
- continueCh = nil
|
||||
- } else if resCode >= 200 {
|
||||
- close(continueCh)
|
||||
- continueCh = nil
|
||||
+ if continueCh != nil && resCode == StatusContinue {
|
||||
+ if trace != nil && trace.Got100Continue != nil {
|
||||
+ trace.Got100Continue()
|
||||
}
|
||||
+ continueCh <- struct{}{}
|
||||
+ continueCh = nil
|
||||
}
|
||||
is1xx := 100 <= resCode && resCode <= 199
|
||||
// treat 101 as a terminal status, see issue 26161
|
||||
@@ -2315,6 +2310,25 @@ func (pc *persistConn) readResponse(rc requestAndChan, trace *httptrace.ClientTr
|
||||
if resp.isProtocolSwitch() {
|
||||
resp.Body = newReadWriteCloserBody(pc.br, pc.conn)
|
||||
}
|
||||
+ if continueCh != nil {
|
||||
+ // We send an "Expect: 100-continue" header, but the server
|
||||
+ // responded with a terminal status and no 100 Continue.
|
||||
+ //
|
||||
+ // If we're going to keep using the connection, we need to send the request body.
|
||||
+ // Tell writeLoop to skip sending the body if we're going to close the connection,
|
||||
+ // or to send it otherwise.
|
||||
+ //
|
||||
+ // The case where we receive a 101 Switching Protocols response is a bit
|
||||
+ // ambiguous, since we don't know what protocol we're switching to.
|
||||
+ // Conceivably, it's one that doesn't need us to send the body.
|
||||
+ // Given that we'll send the body if ExpectContinueTimeout expires,
|
||||
+ // be consistent and always send it if we aren't closing the connection.
|
||||
+ if resp.Close || rc.req.Close {
|
||||
+ close(continueCh) // don't send the body; the connection will close
|
||||
+ } else {
|
||||
+ continueCh <- struct{}{} // send the body
|
||||
+ }
|
||||
+ }
|
||||
|
||||
resp.TLS = pc.tlsState
|
||||
return
|
||||
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
|
||||
index 58f12af..8000ecc 100644
|
||||
--- a/src/net/http/transport_test.go
|
||||
+++ b/src/net/http/transport_test.go
|
||||
@@ -1130,95 +1130,142 @@ func TestTransportGzip(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
-// If a request has Expect:100-continue header, the request blocks sending body until the first response.
|
||||
-// Premature consumption of the request body should not be occurred.
|
||||
-func TestTransportExpect100Continue(t *testing.T) {
|
||||
- setParallel(t)
|
||||
- defer afterTest(t)
|
||||
+// A transport100Continue test exercises Transport behaviors when sending a
|
||||
+// request with an Expect: 100-continue header.
|
||||
+type transport100ContinueTest struct {
|
||||
+ t *testing.T
|
||||
|
||||
- ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
|
||||
- switch req.URL.Path {
|
||||
- case "/100":
|
||||
- // This endpoint implicitly responds 100 Continue and reads body.
|
||||
- if _, err := io.Copy(io.Discard, req.Body); err != nil {
|
||||
- t.Error("Failed to read Body", err)
|
||||
- }
|
||||
- rw.WriteHeader(StatusOK)
|
||||
- case "/200":
|
||||
- // Go 1.5 adds Connection: close header if the client expect
|
||||
- // continue but not entire request body is consumed.
|
||||
- rw.WriteHeader(StatusOK)
|
||||
- case "/500":
|
||||
- rw.WriteHeader(StatusInternalServerError)
|
||||
- case "/keepalive":
|
||||
- // This hijacked endpoint responds error without Connection:close.
|
||||
- _, bufrw, err := rw.(Hijacker).Hijack()
|
||||
- if err != nil {
|
||||
- log.Fatal(err)
|
||||
- }
|
||||
- bufrw.WriteString("HTTP/1.1 500 Internal Server Error\r\n")
|
||||
- bufrw.WriteString("Content-Length: 0\r\n\r\n")
|
||||
- bufrw.Flush()
|
||||
- case "/timeout":
|
||||
- // This endpoint tries to read body without 100 (Continue) response.
|
||||
- // After ExpectContinueTimeout, the reading will be started.
|
||||
- conn, bufrw, err := rw.(Hijacker).Hijack()
|
||||
- if err != nil {
|
||||
- log.Fatal(err)
|
||||
- }
|
||||
- if _, err := io.CopyN(io.Discard, bufrw, req.ContentLength); err != nil {
|
||||
- t.Error("Failed to read Body", err)
|
||||
- }
|
||||
- bufrw.WriteString("HTTP/1.1 200 OK\r\n\r\n")
|
||||
- bufrw.Flush()
|
||||
- conn.Close()
|
||||
- }
|
||||
+ reqdone chan struct{}
|
||||
+ resp *Response
|
||||
+ respErr error
|
||||
|
||||
- }))
|
||||
- defer ts.Close()
|
||||
+ conn net.Conn
|
||||
+ reader *bufio.Reader
|
||||
+}
|
||||
|
||||
- tests := []struct {
|
||||
- path string
|
||||
- body []byte
|
||||
- sent int
|
||||
- status int
|
||||
- }{
|
||||
- {path: "/100", body: []byte("hello"), sent: 5, status: 200}, // Got 100 followed by 200, entire body is sent.
|
||||
- {path: "/200", body: []byte("hello"), sent: 0, status: 200}, // Got 200 without 100. body isn't sent.
|
||||
- {path: "/500", body: []byte("hello"), sent: 0, status: 500}, // Got 500 without 100. body isn't sent.
|
||||
- {path: "/keepalive", body: []byte("hello"), sent: 0, status: 500}, // Although without Connection:close, body isn't sent.
|
||||
- {path: "/timeout", body: []byte("hello"), sent: 5, status: 200}, // Timeout exceeded and entire body is sent.
|
||||
+const transport100ContinueTestBody = "request body"
|
||||
+
|
||||
+// newTransport100ContinueTest creates a Transport and sends an Expect: 100-continue
|
||||
+// request on it.
|
||||
+func newTransport100ContinueTest(t *testing.T, timeout time.Duration) *transport100ContinueTest {
|
||||
+ ln := newLocalListener(t)
|
||||
+ defer ln.Close()
|
||||
+
|
||||
+ test := &transport100ContinueTest{
|
||||
+ t: t,
|
||||
+ reqdone: make(chan struct{}),
|
||||
}
|
||||
|
||||
- c := ts.Client()
|
||||
- for i, v := range tests {
|
||||
- tr := &Transport{
|
||||
- ExpectContinueTimeout: 2 * time.Second,
|
||||
- }
|
||||
- defer tr.CloseIdleConnections()
|
||||
- c.Transport = tr
|
||||
- body := bytes.NewReader(v.body)
|
||||
- req, err := NewRequest("PUT", ts.URL+v.path, body)
|
||||
- if err != nil {
|
||||
- t.Fatal(err)
|
||||
- }
|
||||
+ tr := &Transport{
|
||||
+ ExpectContinueTimeout: timeout,
|
||||
+ }
|
||||
+ go func() {
|
||||
+ defer close(test.reqdone)
|
||||
+ body := strings.NewReader(transport100ContinueTestBody)
|
||||
+ req, _ := NewRequest("PUT", "http://"+ln.Addr().String(), body)
|
||||
req.Header.Set("Expect", "100-continue")
|
||||
- req.ContentLength = int64(len(v.body))
|
||||
+ req.ContentLength = int64(len(transport100ContinueTestBody))
|
||||
+ test.resp, test.respErr = tr.RoundTrip(req)
|
||||
+ test.resp.Body.Close()
|
||||
+ }()
|
||||
|
||||
- resp, err := c.Do(req)
|
||||
- if err != nil {
|
||||
- t.Fatal(err)
|
||||
+ c, err := ln.Accept()
|
||||
+ if err != nil {
|
||||
+ t.Fatalf("Accept: %v", err)
|
||||
+ }
|
||||
+ t.Cleanup(func() {
|
||||
+ c.Close()
|
||||
+ })
|
||||
+ br := bufio.NewReader(c)
|
||||
+ _, err = ReadRequest(br)
|
||||
+ if err != nil {
|
||||
+ t.Fatalf("ReadRequest: %v", err)
|
||||
+ }
|
||||
+ test.conn = c
|
||||
+ test.reader = br
|
||||
+ t.Cleanup(func() {
|
||||
+ <-test.reqdone
|
||||
+ tr.CloseIdleConnections()
|
||||
+ got, _ := io.ReadAll(test.reader)
|
||||
+ if len(got) > 0 {
|
||||
+ t.Fatalf("Transport sent unexpected bytes: %q", got)
|
||||
}
|
||||
- resp.Body.Close()
|
||||
+ })
|
||||
|
||||
- sent := len(v.body) - body.Len()
|
||||
- if v.status != resp.StatusCode {
|
||||
- t.Errorf("test %d: status code should be %d but got %d. (%s)", i, v.status, resp.StatusCode, v.path)
|
||||
- }
|
||||
- if v.sent != sent {
|
||||
- t.Errorf("test %d: sent body should be %d but sent %d. (%s)", i, v.sent, sent, v.path)
|
||||
+ return test
|
||||
+}
|
||||
+
|
||||
+// respond sends response lines from the server to the transport.
|
||||
+func (test *transport100ContinueTest) respond(lines ...string) {
|
||||
+ for _, line := range lines {
|
||||
+ if _, err := test.conn.Write([]byte(line + "\r\n")); err != nil {
|
||||
+ test.t.Fatalf("Write: %v", err)
|
||||
}
|
||||
}
|
||||
+ if _, err := test.conn.Write([]byte("\r\n")); err != nil {
|
||||
+ test.t.Fatalf("Write: %v", err)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// wantBodySent ensures the transport has sent the request body to the server.
|
||||
+func (test *transport100ContinueTest) wantBodySent() {
|
||||
+ got, err := io.ReadAll(io.LimitReader(test.reader, int64(len(transport100ContinueTestBody))))
|
||||
+ if err != nil {
|
||||
+ test.t.Fatalf("unexpected error reading body: %v", err)
|
||||
+ }
|
||||
+ if got, want := string(got), transport100ContinueTestBody; got != want {
|
||||
+ test.t.Fatalf("unexpected body: got %q, want %q", got, want)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// wantRequestDone ensures the Transport.RoundTrip has completed with the expected status.
|
||||
+func (test *transport100ContinueTest) wantRequestDone(want int) {
|
||||
+ <-test.reqdone
|
||||
+ if test.respErr != nil {
|
||||
+ test.t.Fatalf("unexpected RoundTrip error: %v", test.respErr)
|
||||
+ }
|
||||
+ if got := test.resp.StatusCode; got != want {
|
||||
+ test.t.Fatalf("unexpected response code: got %v, want %v", got, want)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func TestTransportExpect100ContinueSent(t *testing.T) {
|
||||
+ test := newTransport100ContinueTest(t, 1*time.Hour)
|
||||
+ // Server sends a 100 Continue response, and the client sends the request body.
|
||||
+ test.respond("HTTP/1.1 100 Continue")
|
||||
+ test.wantBodySent()
|
||||
+ test.respond("HTTP/1.1 200", "Content-Length: 0")
|
||||
+ test.wantRequestDone(200)
|
||||
+}
|
||||
+
|
||||
+func TestTransportExpect100Continue200ResponseNoConnClose(t *testing.T) {
|
||||
+ test := newTransport100ContinueTest(t, 1*time.Hour)
|
||||
+ // No 100 Continue response, no Connection: close header.
|
||||
+ test.respond("HTTP/1.1 200", "Content-Length: 0")
|
||||
+ test.wantBodySent()
|
||||
+ test.wantRequestDone(200)
|
||||
+}
|
||||
+
|
||||
+func TestTransportExpect100Continue200ResponseWithConnClose(t *testing.T) {
|
||||
+ test := newTransport100ContinueTest(t, 1*time.Hour)
|
||||
+ // No 100 Continue response, Connection: close header set.
|
||||
+ test.respond("HTTP/1.1 200", "Connection: close", "Content-Length: 0")
|
||||
+ test.wantRequestDone(200)
|
||||
+}
|
||||
+
|
||||
+func TestTransportExpect100Continue500ResponseNoConnClose(t *testing.T) {
|
||||
+ test := newTransport100ContinueTest(t, 1*time.Hour)
|
||||
+ // No 100 Continue response, no Connection: close header.
|
||||
+ test.respond("HTTP/1.1 500", "Content-Length: 0")
|
||||
+ test.wantBodySent()
|
||||
+ test.wantRequestDone(500)
|
||||
+}
|
||||
+
|
||||
+func TestTransportExpect100Continue500ResponseTimeout(t *testing.T) {
|
||||
+ test := newTransport100ContinueTest(t, 5*time.Millisecond) // short timeout
|
||||
+ test.wantBodySent() // after timeout
|
||||
+ test.respond("HTTP/1.1 200", "Content-Length: 0")
|
||||
+ test.wantRequestDone(200)
|
||||
}
|
||||
|
||||
func TestSOCKS5Proxy(t *testing.T) {
|
||||
--
|
||||
2.40.0
|
||||
34
meta/recipes-devtools/llvm/llvm/CVE-2023-46049.patch
Normal file
34
meta/recipes-devtools/llvm/llvm/CVE-2023-46049.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
commit c2515a8f2be5dd23354c9891f41ad104000f88c4
|
||||
Author: Nikita Popov <npopov@redhat.com>
|
||||
Date: Tue Sep 26 16:51:40 2023 +0200
|
||||
|
||||
[Bitcode] Add some missing GetTypeByID failure checks
|
||||
|
||||
Print an error instead of crashing.
|
||||
|
||||
Fixes https://github.com/llvm/llvm-project/issues/67388.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/c2515a8f2be5dd23354c9891f41ad104000f88c4]
|
||||
CVE: CVE-2023-46049
|
||||
Signed-off-by: Deepthi Hemraj <Deepthi.Hemraj@windriver.com>
|
||||
|
||||
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp 2022-01-20 13:31:59.000000000 -0800
|
||||
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp 2024-07-28 21:35:31.062992219 -0700
|
||||
@@ -1235,7 +1235,7 @@
|
||||
}
|
||||
|
||||
Type *Ty = getTypeByID(Record[0]);
|
||||
- if (Ty->isMetadataTy() || Ty->isVoidTy()) {
|
||||
+ if (!Ty || Ty->isMetadataTy() || Ty->isVoidTy()) {
|
||||
dropRecord();
|
||||
break;
|
||||
}
|
||||
@@ -1277,7 +1277,7 @@
|
||||
return error("Invalid record");
|
||||
|
||||
Type *Ty = getTypeByID(Record[0]);
|
||||
- if (Ty->isMetadataTy() || Ty->isVoidTy())
|
||||
+ if (!Ty || Ty->isMetadataTy() || Ty->isVoidTy())
|
||||
return error("Invalid record");
|
||||
|
||||
MetadataList.assignValue(
|
||||
85
meta/recipes-devtools/llvm/llvm/CVE-2024-31852-1.patch
Normal file
85
meta/recipes-devtools/llvm/llvm/CVE-2024-31852-1.patch
Normal file
@@ -0,0 +1,85 @@
|
||||
commit b1a5ee1febd8a903cec3dfdad61d57900dc3823e
|
||||
Author: Florian Hahn <flo@fhahn.com>
|
||||
Date: Wed Dec 20 16:56:15 2023 +0100
|
||||
|
||||
[ARM] Check all terms in emitPopInst when clearing Restored for LR. (#75527)
|
||||
|
||||
emitPopInst checks a single function exit MBB. If other paths also exit
|
||||
the function and any of there terminators uses LR implicitly, it is not
|
||||
save to clear the Restored bit.
|
||||
|
||||
Check all terminators for the function before clearing Restored.
|
||||
|
||||
This fixes a mis-compile in outlined-fn-may-clobber-lr-in-caller.ll
|
||||
where the machine-outliner previously introduced BLs that clobbered LR
|
||||
which in turn is used by the tail call return.
|
||||
|
||||
Alternative to #73553
|
||||
|
||||
Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/b1a5ee1febd8a903cec3dfdad61d57900dc3823e]
|
||||
CVE: CVE-2024-31852
|
||||
Signed-off-by: Deepthi Hemraj <Deepthi.Hemraj@windriver.com>
|
||||
---
|
||||
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||
index 025e43444f9c..a9acf338ebf5 100644
|
||||
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||
@@ -1236,9 +1236,6 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB,
|
||||
// Fold the return instruction into the LDM.
|
||||
DeleteRet = true;
|
||||
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
|
||||
- // We 'restore' LR into PC so it is not live out of the return block:
|
||||
- // Clear Restored bit.
|
||||
- Info.setRestored(false);
|
||||
}
|
||||
|
||||
// If NoGap is true, pop consecutive registers and then leave the rest
|
||||
@@ -2292,6 +2289,33 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
|
||||
}
|
||||
|
||||
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||
+ MachineFunction &MF, RegScavenger *RS) const {
|
||||
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
||||
+
|
||||
+ MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
+ if (!MFI.isCalleeSavedInfoValid())
|
||||
+ return;
|
||||
+
|
||||
+ // Check if all terminators do not implicitly use LR. Then we can 'restore' LR
|
||||
+ // into PC so it is not live out of the return block: Clear the Restored bit
|
||||
+ // in that case.
|
||||
+ for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
|
||||
+ if (Info.getReg() != ARM::LR)
|
||||
+ continue;
|
||||
+ if (all_of(MF, [](const MachineBasicBlock &MBB) {
|
||||
+ return all_of(MBB.terminators(), [](const MachineInstr &Term) {
|
||||
+ return !Term.isReturn() || Term.getOpcode() == ARM::LDMIA_RET ||
|
||||
+ Term.getOpcode() == ARM::t2LDMIA_RET ||
|
||||
+ Term.getOpcode() == ARM::tPOP_RET;
|
||||
+ });
|
||||
+ })) {
|
||||
+ Info.setRestored(false);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
|
||||
BitVector &SavedRegs) const {
|
||||
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
|
||||
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||
index 9822e2321bb4..266d642bb97b 100644
|
||||
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
||||
RegScavenger *RS) const override;
|
||||
|
||||
+ void processFunctionBeforeFrameFinalized(
|
||||
+ MachineFunction &MF, RegScavenger *RS = nullptr) const override;
|
||||
+
|
||||
void adjustForSegmentedStacks(MachineFunction &MF,
|
||||
MachineBasicBlock &MBB) const override;
|
||||
|
||||
|
||||
117
meta/recipes-devtools/llvm/llvm/CVE-2024-31852-2.patch
Normal file
117
meta/recipes-devtools/llvm/llvm/CVE-2024-31852-2.patch
Normal file
@@ -0,0 +1,117 @@
|
||||
commit 0e16af8e4cf3a66ad5d078d52744ae2776f9c4b2
|
||||
Author: ostannard <oliver.stannard@arm.com>
|
||||
Date: Mon Feb 26 12:23:25 2024 +0000
|
||||
|
||||
[ARM] Update IsRestored for LR based on all returns (#82745)
|
||||
|
||||
PR #75527 fixed ARMFrameLowering to set the IsRestored flag for LR based
|
||||
on all of the return instructions in the function, not just one.
|
||||
However, there is also code in ARMLoadStoreOptimizer which changes
|
||||
return instructions, but it set IsRestored based on the one instruction
|
||||
it changed, not the whole function.
|
||||
|
||||
The fix is to factor out the code added in #75527, and also call it from
|
||||
ARMLoadStoreOptimizer if it made a change to return instructions.
|
||||
|
||||
Fixes #80287.
|
||||
|
||||
(cherry picked from commit 749384c08e042739342c88b521c8ba5dac1b9276)
|
||||
|
||||
Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/0e16af8e4cf3a66ad5d078d52744ae2776f9c4b2]
|
||||
CVE: CVE-2024-31852
|
||||
Signed-off-by: Deepthi Hemraj <Deepthi.Hemraj@windriver.com>
|
||||
---
|
||||
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||
index a9acf338ebf5..13d3cbf650ed 100644
|
||||
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
|
||||
@@ -2289,10 +2289,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
||||
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
|
||||
}
|
||||
|
||||
-void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||
- MachineFunction &MF, RegScavenger *RS) const {
|
||||
- TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
||||
-
|
||||
+void ARMFrameLowering::updateLRRestored(MachineFunction &MF) {
|
||||
MachineFrameInfo &MFI = MF.getFrameInfo();
|
||||
if (!MFI.isCalleeSavedInfoValid())
|
||||
return;
|
||||
@@ -2316,6 +2313,12 @@ void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||
}
|
||||
}
|
||||
|
||||
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
|
||||
+ MachineFunction &MF, RegScavenger *RS) const {
|
||||
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
|
||||
+ updateLRRestored(MF);
|
||||
+}
|
||||
+
|
||||
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
|
||||
BitVector &SavedRegs) const {
|
||||
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
|
||||
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||
index 67505b61a5e1..b13b76d7086c 100644
|
||||
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h
|
||||
@@ -58,6 +58,10 @@ public:
|
||||
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
|
||||
RegScavenger *RS) const override;
|
||||
|
||||
+ /// Update the IsRestored flag on LR if it is spilled, based on the return
|
||||
+ /// instructions.
|
||||
+ static void updateLRRestored(MachineFunction &MF);
|
||||
+
|
||||
void processFunctionBeforeFrameFinalized(
|
||||
MachineFunction &MF, RegScavenger *RS = nullptr) const override;
|
||||
|
||||
diff --git a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
||||
index fd06bfdf352c..561c1396190d 100644
|
||||
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
||||
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
|
||||
@@ -2060,17 +2060,6 @@ bool ARMLoadStoreOpt::MergeReturnIntoLDM(MachineBasicBlock &MBB) {
|
||||
MO.setReg(ARM::PC);
|
||||
PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
|
||||
MBB.erase(MBBI);
|
||||
- // We now restore LR into PC so it is not live-out of the return block
|
||||
- // anymore: Clear the CSI Restored bit.
|
||||
- MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
|
||||
- // CSI should be fixed after PrologEpilog Insertion
|
||||
- assert(MFI.isCalleeSavedInfoValid() && "CSI should be valid");
|
||||
- for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
|
||||
- if (Info.getReg() == ARM::LR) {
|
||||
- Info.setRestored(false);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2118,16 +2107,24 @@ bool ARMLoadStoreOpt::runOnMachineFunction(MachineFunction &Fn) {
|
||||
isThumb2 = AFI->isThumb2Function();
|
||||
isThumb1 = AFI->isThumbFunction() && !isThumb2;
|
||||
|
||||
- bool Modified = false;
|
||||
+ bool Modified = false, ModifiedLDMReturn = false;
|
||||
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
|
||||
++MFI) {
|
||||
MachineBasicBlock &MBB = *MFI;
|
||||
Modified |= LoadStoreMultipleOpti(MBB);
|
||||
if (STI->hasV5TOps())
|
||||
- Modified |= MergeReturnIntoLDM(MBB);
|
||||
+ ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
|
||||
if (isThumb1)
|
||||
Modified |= CombineMovBx(MBB);
|
||||
}
|
||||
+ Modified |= ModifiedLDMReturn;
|
||||
+
|
||||
+ // If we merged a BX instruction into an LDM, we need to re-calculate whether
|
||||
+ // LR is restored. This check needs to consider the whole function, not just
|
||||
+ // the instruction(s) we changed, because there may be other BX returns which
|
||||
+ // still need LR to be restored.
|
||||
+ if (ModifiedLDMReturn)
|
||||
+ ARMFrameLowering::updateLRRestored(Fn);
|
||||
|
||||
Allocator.DestroyAll();
|
||||
return Modified;
|
||||
|
||||
@@ -33,6 +33,9 @@ SRC_URI = "git://github.com/llvm/llvm-project.git;branch=${BRANCH};protocol=http
|
||||
file://0007-llvm-allow-env-override-of-exe-path.patch;striplevel=2 \
|
||||
file://0001-AsmMatcherEmitter-sort-ClassInfo-lists-by-name-as-we.patch;striplevel=2 \
|
||||
file://0001-Support-Add-missing-cstdint-header-to-Signals.h.patch;striplevel=2 \
|
||||
file://CVE-2023-46049.patch;striplevel=2 \
|
||||
file://CVE-2024-31852-1.patch;striplevel=2 \
|
||||
file://CVE-2024-31852-2.patch;striplevel=2 \
|
||||
"
|
||||
|
||||
UPSTREAM_CHECK_GITTAGREGEX = "llvmorg-(?P<pver>\d+(\.\d+)+)"
|
||||
|
||||
@@ -5,7 +5,7 @@ LICENSE = "BSD-2-Clause & BSD-3-Clause"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=1400bd9d09e8af56b9ec982b3d85797e"
|
||||
|
||||
SRC_URI = "http://gstreamer.freedesktop.org/src/orc/orc-${PV}.tar.xz"
|
||||
SRC_URI[sha256sum] = "a66e3d8f2b7e65178d786a01ef61f2a0a0b4d0b8370de7ce134ba73da4af18f0"
|
||||
SRC_URI[sha256sum] = "33ed2387f49b825fa1b9c3b0072e05f259141b895474ad085ae51143d3040cc0"
|
||||
|
||||
inherit meson pkgconfig gtk-doc
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
From bd8153872e9c6fc98f4023df9c2deaffea2fa463 Mon Sep 17 00:00:00 2001
|
||||
From: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
|
||||
Date: Wed, 3 Jul 2024 21:34:29 -0400
|
||||
Subject: [PATCH] 2024.07.04 (#295)
|
||||
|
||||
Co-authored-by: alex <772+alex@users.noreply.github.com>
|
||||
|
||||
CVE: CVE-2024-39689
|
||||
|
||||
Upstream-Status: Backport [https://github.com/certifi/python-certifi/commit/bd8153872e9c6fc98f4023df9c2deaffea2fa463]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
certifi/cacert.pem | 40 ----------------------------------------
|
||||
1 file changed, 40 deletions(-)
|
||||
|
||||
diff --git a/certifi/cacert.pem b/certifi/cacert.pem
|
||||
index 1bec256..6bb8cf8 100644
|
||||
--- a/certifi/cacert.pem
|
||||
+++ b/certifi/cacert.pem
|
||||
@@ -3857,46 +3857,6 @@ DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ
|
||||
+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
-# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH
|
||||
-# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH
|
||||
-# Label: "GLOBALTRUST 2020"
|
||||
-# Serial: 109160994242082918454945253
|
||||
-# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8
|
||||
-# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2
|
||||
-# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a
|
||||
------BEGIN CERTIFICATE-----
|
||||
-MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG
|
||||
-A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw
|
||||
-FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx
|
||||
-MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u
|
||||
-aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq
|
||||
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b
|
||||
-RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z
|
||||
-YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3
|
||||
-QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw
|
||||
-yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+
|
||||
-BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ
|
||||
-SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH
|
||||
-r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0
|
||||
-4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me
|
||||
-dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw
|
||||
-q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2
|
||||
-nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
|
||||
-AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu
|
||||
-H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA
|
||||
-VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC
|
||||
-XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd
|
||||
-6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf
|
||||
-+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi
|
||||
-kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7
|
||||
-wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB
|
||||
-TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C
|
||||
-MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn
|
||||
-4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I
|
||||
-aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy
|
||||
-qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==
|
||||
------END CERTIFICATE-----
|
||||
-
|
||||
# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz
|
||||
# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz
|
||||
# Label: "ANF Secure Server Root CA"
|
||||
--
|
||||
2.40.0
|
||||
@@ -9,6 +9,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=67da0714c3f9471067b729eca6c9fbe8"
|
||||
|
||||
SRC_URI += "file://CVE-2022-23491.patch \
|
||||
file://CVE-2023-37920.patch \
|
||||
file://CVE-2024-39689.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"
|
||||
|
||||
@@ -2,17 +2,17 @@ DESCRIPTION = "Python Jinja2: A small but fast and easy to use stand-alone templ
|
||||
HOMEPAGE = "https://pypi.org/project/Jinja2/"
|
||||
|
||||
LICENSE = "BSD-3-Clause"
|
||||
LIC_FILES_CHKSUM = "file://LICENSE.rst;md5=5dc88300786f1c214c1e9827a5229462"
|
||||
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=5dc88300786f1c214c1e9827a5229462"
|
||||
|
||||
SRC_URI[sha256sum] = "ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"
|
||||
SRC_URI[sha256sum] = "4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"
|
||||
|
||||
PYPI_PACKAGE = "Jinja2"
|
||||
PYPI_PACKAGE = "jinja2"
|
||||
|
||||
CVE_PRODUCT = "jinja2 jinja"
|
||||
|
||||
CLEANBROKEN = "1"
|
||||
|
||||
inherit pypi setuptools3
|
||||
inherit pypi python_flit_core
|
||||
inherit ${@bb.utils.filter('DISTRO_FEATURES', 'ptest', d)}
|
||||
|
||||
SRC_URI += " \
|
||||
@@ -1,5 +1,5 @@
|
||||
require python-pycryptodome.inc
|
||||
inherit setuptools3
|
||||
inherit python_setuptools_build_meta
|
||||
|
||||
SRC_URI[sha256sum] = "e04e40a7f8c1669195536a37979dd87da2c32dbdc73d6fe35f0077b0c17c803b"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
require python-pycryptodome.inc
|
||||
inherit setuptools3
|
||||
inherit python_setuptools_build_meta
|
||||
|
||||
SRC_URI[sha256sum] = "2ce76ed0081fd6ac8c74edc75b9d14eca2064173af79843c24fa62573263c1f2"
|
||||
|
||||
|
||||
124
meta/recipes-devtools/python/python3/CVE-2024-8088.patch
Normal file
124
meta/recipes-devtools/python/python3/CVE-2024-8088.patch
Normal file
@@ -0,0 +1,124 @@
|
||||
From e0264a61119d551658d9445af38323ba94fc16db Mon Sep 17 00:00:00 2001
|
||||
From: "Jason R. Coombs" <jaraco@jaraco.com>
|
||||
Date: Thu, 22 Aug 2024 19:24:33 -0400
|
||||
Subject: [PATCH] CVE-2024-8088: Sanitize names in zipfile.Path. (GH-122906)
|
||||
|
||||
Upstream-Status: Backport from https://github.com/python/cpython/commit/e0264a61119d551658d9445af38323ba94fc16db
|
||||
CVE: CVE-2024-8088
|
||||
|
||||
Signed-off-by: Rohini Sangam <rsangam@mvista.com>
|
||||
---
|
||||
Lib/test/test_zipfile.py | 17 ++++++
|
||||
Lib/zipfile.py | 61 ++++++++++++++++++-
|
||||
2 files changed, 77 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
|
||||
index 32c0170..a60dc11 100644
|
||||
--- a/Lib/test/test_zipfile.py
|
||||
+++ b/Lib/test/test_zipfile.py
|
||||
@@ -3280,6 +3280,23 @@ with zipfile.ZipFile(io.BytesIO(), "w") as zf:
|
||||
zipfile.Path(zf)
|
||||
zf.extractall(source_path.parent)
|
||||
|
||||
+ def test_malformed_paths(self):
|
||||
+ """
|
||||
+ Path should handle malformed paths.
|
||||
+ """
|
||||
+ data = io.BytesIO()
|
||||
+ zf = zipfile.ZipFile(data, "w")
|
||||
+ zf.writestr("/one-slash.txt", b"content")
|
||||
+ zf.writestr("//two-slash.txt", b"content")
|
||||
+ zf.writestr("../parent.txt", b"content")
|
||||
+ zf.filename = ''
|
||||
+ root = zipfile.Path(zf)
|
||||
+ assert list(map(str, root.iterdir())) == [
|
||||
+ 'one-slash.txt',
|
||||
+ 'two-slash.txt',
|
||||
+ 'parent.txt',
|
||||
+ ]
|
||||
+
|
||||
|
||||
class StripExtraTests(unittest.TestCase):
|
||||
# Note: all of the "z" characters are technically invalid, but up
|
||||
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
|
||||
index 7d18bc2..cbac8d9 100644
|
||||
--- a/Lib/zipfile.py
|
||||
+++ b/Lib/zipfile.py
|
||||
@@ -9,6 +9,7 @@ import io
|
||||
import itertools
|
||||
import os
|
||||
import posixpath
|
||||
+import re
|
||||
import shutil
|
||||
import stat
|
||||
import struct
|
||||
@@ -2182,7 +2183,65 @@ def _difference(minuend, subtrahend):
|
||||
return itertools.filterfalse(set(subtrahend).__contains__, minuend)
|
||||
|
||||
|
||||
-class CompleteDirs(ZipFile):
|
||||
+class SanitizedNames:
|
||||
+ """
|
||||
+ ZipFile mix-in to ensure names are sanitized.
|
||||
+ """
|
||||
+
|
||||
+ def namelist(self):
|
||||
+ return list(map(self._sanitize, super().namelist()))
|
||||
+
|
||||
+ @staticmethod
|
||||
+ def _sanitize(name):
|
||||
+ r"""
|
||||
+ Ensure a relative path with posix separators and no dot names.
|
||||
+ Modeled after
|
||||
+ https://github.com/python/cpython/blob/bcc1be39cb1d04ad9fc0bd1b9193d3972835a57c/Lib/zipfile/__init__.py#L1799-L1813
|
||||
+ but provides consistent cross-platform behavior.
|
||||
+ >>> san = SanitizedNames._sanitize
|
||||
+ >>> san('/foo/bar')
|
||||
+ 'foo/bar'
|
||||
+ >>> san('//foo.txt')
|
||||
+ 'foo.txt'
|
||||
+ >>> san('foo/.././bar.txt')
|
||||
+ 'foo/bar.txt'
|
||||
+ >>> san('foo../.bar.txt')
|
||||
+ 'foo../.bar.txt'
|
||||
+ >>> san('\\foo\\bar.txt')
|
||||
+ 'foo/bar.txt'
|
||||
+ >>> san('D:\\foo.txt')
|
||||
+ 'D/foo.txt'
|
||||
+ >>> san('\\\\server\\share\\file.txt')
|
||||
+ 'server/share/file.txt'
|
||||
+ >>> san('\\\\?\\GLOBALROOT\\Volume3')
|
||||
+ '?/GLOBALROOT/Volume3'
|
||||
+ >>> san('\\\\.\\PhysicalDrive1\\root')
|
||||
+ 'PhysicalDrive1/root'
|
||||
+ Retain any trailing slash.
|
||||
+ >>> san('abc/')
|
||||
+ 'abc/'
|
||||
+ Raises a ValueError if the result is empty.
|
||||
+ >>> san('../..')
|
||||
+ Traceback (most recent call last):
|
||||
+ ...
|
||||
+ ValueError: Empty filename
|
||||
+ """
|
||||
+
|
||||
+ def allowed(part):
|
||||
+ return part and part not in {'..', '.'}
|
||||
+
|
||||
+ # Remove the drive letter.
|
||||
+ # Don't use ntpath.splitdrive, because that also strips UNC paths
|
||||
+ bare = re.sub('^([A-Z]):', r'\1', name, flags=re.IGNORECASE)
|
||||
+ clean = bare.replace('\\', '/')
|
||||
+ parts = clean.split('/')
|
||||
+ joined = '/'.join(filter(allowed, parts))
|
||||
+ if not joined:
|
||||
+ raise ValueError("Empty filename")
|
||||
+ return joined + '/' * name.endswith('/')
|
||||
+
|
||||
+
|
||||
+class CompleteDirs(SanitizedNames, ZipFile):
|
||||
"""
|
||||
A ZipFile subclass that ensures that implied directories
|
||||
are always included in the namelist.
|
||||
--
|
||||
2.35.7
|
||||
|
||||
@@ -36,6 +36,7 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
|
||||
file://deterministic_imports.patch \
|
||||
file://0001-Avoid-shebang-overflow-on-python-config.py.patch \
|
||||
file://0001-test_storlines-skip-due-to-load-variability.patch \
|
||||
file://CVE-2024-8088.patch \
|
||||
"
|
||||
|
||||
SRC_URI:append:class-native = " \
|
||||
@@ -106,7 +107,8 @@ CACHED_CONFIGUREVARS = " \
|
||||
PACKAGECONFIG:class-target ??= "readline gdbm ${@bb.utils.filter('DISTRO_FEATURES', 'lto', d)}"
|
||||
PACKAGECONFIG:class-native ??= "readline gdbm"
|
||||
PACKAGECONFIG:class-nativesdk ??= "readline gdbm"
|
||||
PACKAGECONFIG[readline] = ",,readline"
|
||||
PACKAGECONFIG[readline] = "--with-readline=readline,,readline,,,editline"
|
||||
PACKAGECONFIG[editline] = "--with-readline=editline,,libedit,,,readline"
|
||||
# Use profile guided optimisation by running PyBench inside qemu-user
|
||||
PACKAGECONFIG[pgo] = "--enable-optimizations,,qemu-native"
|
||||
PACKAGECONFIG[tk] = ",,tk"
|
||||
@@ -118,7 +120,7 @@ do_configure:prepend () {
|
||||
cat > ${B}/Modules/Setup.local << EOF
|
||||
*disabled*
|
||||
${@bb.utils.contains('PACKAGECONFIG', 'gdbm', '', '_gdbm _dbm', d)}
|
||||
${@bb.utils.contains('PACKAGECONFIG', 'readline', '', 'readline', d)}
|
||||
${@bb.utils.contains_any('PACKAGECONFIG', 'readline editline', '', 'readline', d)}
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +109,10 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
|
||||
file://scsi-disk-ensure-block-size-is-non-zero-and-changes-limited-to-bits-8-15.patch \
|
||||
file://CVE-2023-42467.patch \
|
||||
file://CVE-2023-6683.patch \
|
||||
file://CVE-2024-7409-0001.patch \
|
||||
file://CVE-2024-7409-0002.patch \
|
||||
file://CVE-2024-7409-0003.patch \
|
||||
file://CVE-2024-7409-0004.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
|
||||
|
||||
|
||||
162
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0001.patch
Normal file
162
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0001.patch
Normal file
@@ -0,0 +1,162 @@
|
||||
From fb1c2aaa981e0a2fa6362c9985f1296b74f055ac Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 7 Aug 2024 08:50:01 -0500
|
||||
Subject: [PATCH] nbd/server: Plumb in new args to nbd_client_add()
|
||||
|
||||
Upcoming patches to fix a CVE need to track an opaque pointer passed
|
||||
in by the owner of a client object, as well as request for a time
|
||||
limit on how fast negotiation must complete. Prepare for that by
|
||||
changing the signature of nbd_client_new() and adding an accessor to
|
||||
get at the opaque pointer, although for now the two servers
|
||||
(qemu-nbd.c and blockdev-nbd.c) do not change behavior even though
|
||||
they pass in a new default timeout value.
|
||||
|
||||
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20240807174943.771624-11-eblake@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
[eblake: s/LIMIT/MAX_SECS/ as suggested by Dan]
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
|
||||
CVE: CVE-2024-7409
|
||||
Upstream-Status: Backport [https://github.com/qemu/qemu/commit/fb1c2aaa981e0a2fa6362c9985f1296b74f055ac]
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
blockdev-nbd.c | 6 ++++--
|
||||
include/block/nbd.h | 11 ++++++++++-
|
||||
nbd/server.c | 20 +++++++++++++++++---
|
||||
qemu-nbd.c | 4 +++-
|
||||
4 files changed, 34 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
|
||||
index bdfa7ed3a..b9e8dc78f 100644
|
||||
--- a/blockdev-nbd.c
|
||||
+++ b/blockdev-nbd.c
|
||||
@@ -59,8 +59,10 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
|
||||
nbd_update_server_watch(nbd_server);
|
||||
|
||||
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
|
||||
- nbd_client_new(cioc, nbd_server->tlscreds, nbd_server->tlsauthz,
|
||||
- nbd_blockdev_client_closed);
|
||||
+ /* TODO - expose handshake timeout as QMP option */
|
||||
+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
|
||||
+ nbd_server->tlscreds, nbd_server->tlsauthz,
|
||||
+ nbd_blockdev_client_closed, NULL);
|
||||
}
|
||||
|
||||
static void nbd_update_server_watch(NBDServerData *s)
|
||||
diff --git a/include/block/nbd.h b/include/block/nbd.h
|
||||
index 78d101b77..b71a29724 100644
|
||||
--- a/include/block/nbd.h
|
||||
+++ b/include/block/nbd.h
|
||||
@@ -27,6 +27,12 @@
|
||||
|
||||
extern const BlockExportDriver blk_exp_nbd;
|
||||
|
||||
+/*
|
||||
+ * NBD_DEFAULT_HANDSHAKE_MAX_SECS: Number of seconds in which client must
|
||||
+ * succeed at NBD_OPT_GO before being forcefully dropped as too slow.
|
||||
+ */
|
||||
+#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10
|
||||
+
|
||||
/* Handshake phase structs - this struct is passed on the wire */
|
||||
|
||||
struct NBDOption {
|
||||
@@ -338,9 +344,12 @@ AioContext *nbd_export_aio_context(NBDExport *exp);
|
||||
NBDExport *nbd_export_find(const char *name);
|
||||
|
||||
void nbd_client_new(QIOChannelSocket *sioc,
|
||||
+ uint32_t handshake_max_secs,
|
||||
QCryptoTLSCreds *tlscreds,
|
||||
const char *tlsauthz,
|
||||
- void (*close_fn)(NBDClient *, bool));
|
||||
+ void (*close_fn)(NBDClient *, bool),
|
||||
+ void *owner);
|
||||
+void *nbd_client_owner(NBDClient *client);
|
||||
void nbd_client_get(NBDClient *client);
|
||||
void nbd_client_put(NBDClient *client);
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index 4630dd732..12680c8dc 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -121,9 +121,11 @@ struct NBDClient {
|
||||
int refcount;
|
||||
void (*close_fn)(NBDClient *client, bool negotiated);
|
||||
|
||||
+ void *owner;
|
||||
NBDExport *exp;
|
||||
QCryptoTLSCreds *tlscreds;
|
||||
char *tlsauthz;
|
||||
+ uint32_t handshake_max_secs;
|
||||
QIOChannelSocket *sioc; /* The underlying data channel */
|
||||
QIOChannel *ioc; /* The current I/O channel which may differ (eg TLS) */
|
||||
|
||||
@@ -2703,6 +2705,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
|
||||
|
||||
qemu_co_mutex_init(&client->send_lock);
|
||||
|
||||
+ /* TODO - utilize client->handshake_max_secs */
|
||||
if (nbd_negotiate(client, &local_err)) {
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
@@ -2715,14 +2718,17 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
|
||||
}
|
||||
|
||||
/*
|
||||
- * Create a new client listener using the given channel @sioc.
|
||||
+ * Create a new client listener using the given channel @sioc and @owner.
|
||||
* Begin servicing it in a coroutine. When the connection closes, call
|
||||
- * @close_fn with an indication of whether the client completed negotiation.
|
||||
+ * @close_fn with an indication of whether the client completed negotiation
|
||||
+ * within @handshake_max_secs seconds (0 for unbounded).
|
||||
*/
|
||||
void nbd_client_new(QIOChannelSocket *sioc,
|
||||
+ uint32_t handshake_max_secs,
|
||||
QCryptoTLSCreds *tlscreds,
|
||||
const char *tlsauthz,
|
||||
- void (*close_fn)(NBDClient *, bool))
|
||||
+ void (*close_fn)(NBDClient *, bool),
|
||||
+ void *owner)
|
||||
{
|
||||
NBDClient *client;
|
||||
Coroutine *co;
|
||||
@@ -2734,12 +2740,20 @@ void nbd_client_new(QIOChannelSocket *sioc,
|
||||
object_ref(OBJECT(client->tlscreds));
|
||||
}
|
||||
client->tlsauthz = g_strdup(tlsauthz);
|
||||
+ client->handshake_max_secs = handshake_max_secs;
|
||||
client->sioc = sioc;
|
||||
object_ref(OBJECT(client->sioc));
|
||||
client->ioc = QIO_CHANNEL(sioc);
|
||||
object_ref(OBJECT(client->ioc));
|
||||
client->close_fn = close_fn;
|
||||
+ client->owner = owner;
|
||||
|
||||
co = qemu_coroutine_create(nbd_co_client_start, client);
|
||||
qemu_coroutine_enter(co);
|
||||
}
|
||||
+
|
||||
+void *
|
||||
+nbd_client_owner(NBDClient *client)
|
||||
+{
|
||||
+ return client->owner;
|
||||
+}
|
||||
diff --git a/qemu-nbd.c b/qemu-nbd.c
|
||||
index c6c20df68..f48abf379 100644
|
||||
--- a/qemu-nbd.c
|
||||
+++ b/qemu-nbd.c
|
||||
@@ -363,7 +363,9 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
|
||||
|
||||
nb_fds++;
|
||||
nbd_update_server_watch();
|
||||
- nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed);
|
||||
+ /* TODO - expose handshake timeout as command line option */
|
||||
+ nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
|
||||
+ tlscreds, tlsauthz, nbd_client_closed, NULL);
|
||||
}
|
||||
|
||||
static void nbd_update_server_watch(void)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
174
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0002.patch
Normal file
174
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0002.patch
Normal file
@@ -0,0 +1,174 @@
|
||||
From c8a76dbd90c2f48df89b75bef74917f90a59b623 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Tue, 6 Aug 2024 13:53:00 -0500
|
||||
Subject: [PATCH] nbd/server: CVE-2024-7409: Cap default max-connections to 100
|
||||
|
||||
Allowing an unlimited number of clients to any web service is a recipe
|
||||
for a rudimentary denial of service attack: the client merely needs to
|
||||
open lots of sockets without closing them, until qemu no longer has
|
||||
any more fds available to allocate.
|
||||
|
||||
For qemu-nbd, we default to allowing only 1 connection unless more are
|
||||
explicitly asked for (-e or --shared); this was historically picked as
|
||||
a nice default (without an explicit -t, a non-persistent qemu-nbd goes
|
||||
away after a client disconnects, without needing any additional
|
||||
follow-up commands), and we are not going to change that interface now
|
||||
(besides, someday we want to point people towards qemu-storage-daemon
|
||||
instead of qemu-nbd).
|
||||
|
||||
But for qemu proper, and the newer qemu-storage-daemon, the QMP
|
||||
nbd-server-start command has historically had a default of unlimited
|
||||
number of connections, in part because unlike qemu-nbd it is
|
||||
inherently persistent until nbd-server-stop. Allowing multiple client
|
||||
sockets is particularly useful for clients that can take advantage of
|
||||
MULTI_CONN (creating parallel sockets to increase throughput),
|
||||
although known clients that do so (such as libnbd's nbdcopy) typically
|
||||
use only 8 or 16 connections (the benefits of scaling diminish once
|
||||
more sockets are competing for kernel attention). Picking a number
|
||||
large enough for typical use cases, but not unlimited, makes it
|
||||
slightly harder for a malicious client to perform a denial of service
|
||||
merely by opening lots of connections withot progressing through the
|
||||
handshake.
|
||||
|
||||
This change does not eliminate CVE-2024-7409 on its own, but reduces
|
||||
the chance for fd exhaustion or unlimited memory usage as an attack
|
||||
surface. On the other hand, by itself, it makes it more obvious that
|
||||
with a finite limit, we have the problem of an unauthenticated client
|
||||
holding 100 fds opened as a way to block out a legitimate client from
|
||||
being able to connect; thus, later patches will further add timeouts
|
||||
to reject clients that are not making progress.
|
||||
|
||||
This is an INTENTIONAL change in behavior, and will break any client
|
||||
of nbd-server-start that was not passing an explicit max-connections
|
||||
parameter, yet expects more than 100 simultaneous connections. We are
|
||||
not aware of any such client (as stated above, most clients aware of
|
||||
MULTI_CONN get by just fine on 8 or 16 connections, and probably cope
|
||||
with later connections failing by relying on the earlier connections;
|
||||
libvirt has not yet been passing max-connections, but generally
|
||||
creates NBD servers with the intent for a single client for the sake
|
||||
of live storage migration; meanwhile, the KubeSAN project anticipates
|
||||
a large cluster sharing multiple clients [up to 8 per node, and up to
|
||||
100 nodes in a cluster], but it currently uses qemu-nbd with an
|
||||
explicit --shared=0 rather than qemu-storage-daemon with
|
||||
nbd-server-start).
|
||||
|
||||
We considered using a deprecation period (declare that omitting
|
||||
max-parameters is deprecated, and make it mandatory in 3 releases -
|
||||
then we don't need to pick an arbitrary default); that has zero risk
|
||||
of breaking any apps that accidentally depended on more than 100
|
||||
connections, and where such breakage might not be noticed under unit
|
||||
testing but only under the larger loads of production usage. But it
|
||||
does not close the denial-of-service hole until far into the future,
|
||||
and requires all apps to change to add the parameter even if 100 was
|
||||
good enough. It also has a drawback that any app (like libvirt) that
|
||||
is accidentally relying on an unlimited default should seriously
|
||||
consider their own CVE now, at which point they are going to change to
|
||||
pass explicit max-connections sooner than waiting for 3 qemu releases.
|
||||
Finally, if our changed default breaks an app, that app can always
|
||||
pass in an explicit max-parameters with a larger value.
|
||||
|
||||
It is also intentional that the HMP interface to nbd-server-start is
|
||||
not changed to expose max-connections (any client needing to fine-tune
|
||||
things should be using QMP).
|
||||
|
||||
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20240807174943.771624-12-eblake@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
[ericb: Expand commit message to summarize Dan's argument for why we
|
||||
break corner-case back-compat behavior without a deprecation period]
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
|
||||
CVE: CVE-2024-7409
|
||||
Upstream-Status: Backport [https://github.com/qemu/qemu/commit/c8a76dbd90c2f48df89b75bef74917f90a59b623]
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
block/monitor/block-hmp-cmds.c | 3 ++-
|
||||
blockdev-nbd.c | 8 ++++++++
|
||||
include/block/nbd.h | 7 +++++++
|
||||
qapi/block-export.json | 4 ++--
|
||||
4 files changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
|
||||
index 2ac4aedff..32a666b5d 100644
|
||||
--- a/block/monitor/block-hmp-cmds.c
|
||||
+++ b/block/monitor/block-hmp-cmds.c
|
||||
@@ -411,7 +411,8 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- nbd_server_start(addr, NULL, NULL, 0, &local_err);
|
||||
+ nbd_server_start(addr, NULL, NULL, NBD_DEFAULT_MAX_CONNECTIONS,
|
||||
+ &local_err);
|
||||
qapi_free_SocketAddress(addr);
|
||||
if (local_err != NULL) {
|
||||
goto exit;
|
||||
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
|
||||
index b9e8dc78f..4bd90bac1 100644
|
||||
--- a/blockdev-nbd.c
|
||||
+++ b/blockdev-nbd.c
|
||||
@@ -171,6 +171,10 @@ void nbd_server_start(SocketAddress *addr, const char *tls_creds,
|
||||
|
||||
void nbd_server_start_options(NbdServerOptions *arg, Error **errp)
|
||||
{
|
||||
+ if (!arg->has_max_connections) {
|
||||
+ arg->max_connections = NBD_DEFAULT_MAX_CONNECTIONS;
|
||||
+ }
|
||||
+
|
||||
nbd_server_start(arg->addr, arg->tls_creds, arg->tls_authz,
|
||||
arg->max_connections, errp);
|
||||
}
|
||||
@@ -183,6 +187,10 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr,
|
||||
{
|
||||
SocketAddress *addr_flat = socket_address_flatten(addr);
|
||||
|
||||
+ if (!has_max_connections) {
|
||||
+ max_connections = NBD_DEFAULT_MAX_CONNECTIONS;
|
||||
+ }
|
||||
+
|
||||
nbd_server_start(addr_flat, tls_creds, tls_authz, max_connections, errp);
|
||||
qapi_free_SocketAddress(addr_flat);
|
||||
}
|
||||
diff --git a/include/block/nbd.h b/include/block/nbd.h
|
||||
index b71a29724..a31c34a8a 100644
|
||||
--- a/include/block/nbd.h
|
||||
+++ b/include/block/nbd.h
|
||||
@@ -33,6 +33,13 @@ extern const BlockExportDriver blk_exp_nbd;
|
||||
*/
|
||||
#define NBD_DEFAULT_HANDSHAKE_MAX_SECS 10
|
||||
|
||||
+/*
|
||||
+ * NBD_DEFAULT_MAX_CONNECTIONS: Number of client sockets to allow at
|
||||
+ * once; must be large enough to allow a MULTI_CONN-aware client like
|
||||
+ * nbdcopy to create its typical number of 8-16 sockets.
|
||||
+ */
|
||||
+#define NBD_DEFAULT_MAX_CONNECTIONS 100
|
||||
+
|
||||
/* Handshake phase structs - this struct is passed on the wire */
|
||||
|
||||
struct NBDOption {
|
||||
diff --git a/qapi/block-export.json b/qapi/block-export.json
|
||||
index c1b92ce1c..181d7238f 100644
|
||||
--- a/qapi/block-export.json
|
||||
+++ b/qapi/block-export.json
|
||||
@@ -21,7 +21,7 @@
|
||||
# recreated on the fly while the NBD server is active.
|
||||
# If missing, it will default to denying access (since 4.0).
|
||||
# @max-connections: The maximum number of connections to allow at the same
|
||||
-# time, 0 for unlimited. (since 5.2; default: 0)
|
||||
+# time, 0 for unlimited. (since 5.2; default: 100)
|
||||
#
|
||||
# Since: 4.2
|
||||
##
|
||||
@@ -50,7 +50,7 @@
|
||||
# recreated on the fly while the NBD server is active.
|
||||
# If missing, it will default to denying access (since 4.0).
|
||||
# @max-connections: The maximum number of connections to allow at the same
|
||||
-# time, 0 for unlimited. (since 5.2; default: 0)
|
||||
+# time, 0 for unlimited. (since 5.2; default: 100)
|
||||
#
|
||||
# Returns: error if the server is already running.
|
||||
#
|
||||
--
|
||||
2.25.1
|
||||
|
||||
122
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0003.patch
Normal file
122
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0003.patch
Normal file
@@ -0,0 +1,122 @@
|
||||
From b9b72cb3ce15b693148bd09cef7e50110566d8a0 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Thu, 8 Aug 2024 16:05:08 -0500
|
||||
Subject: [PATCH] nbd/server: CVE-2024-7409: Drop non-negotiating clients
|
||||
|
||||
A client that opens a socket but does not negotiate is merely hogging
|
||||
qemu's resources (an open fd and a small amount of memory); and a
|
||||
malicious client that can access the port where NBD is listening can
|
||||
attempt a denial of service attack by intentionally opening and
|
||||
abandoning lots of unfinished connections. The previous patch put a
|
||||
default bound on the number of such ongoing connections, but once that
|
||||
limit is hit, no more clients can connect (including legitimate ones).
|
||||
The solution is to insist that clients complete handshake within a
|
||||
reasonable time limit, defaulting to 10 seconds. A client that has
|
||||
not successfully completed NBD_OPT_GO by then (including the case of
|
||||
where the client didn't know TLS credentials to even reach the point
|
||||
of NBD_OPT_GO) is wasting our time and does not deserve to stay
|
||||
connected. Later patches will allow fine-tuning the limit away from
|
||||
the default value (including disabling it for doing integration
|
||||
testing of the handshake process itself).
|
||||
|
||||
Note that this patch in isolation actually makes it more likely to see
|
||||
qemu SEGV after nbd-server-stop, as any client socket still connected
|
||||
when the server shuts down will now be closed after 10 seconds rather
|
||||
than at the client's whims. That will be addressed in the next patch.
|
||||
|
||||
For a demo of this patch in action:
|
||||
$ qemu-nbd -f raw -r -t -e 10 file &
|
||||
$ nbdsh --opt-mode -c '
|
||||
H = list()
|
||||
for i in range(20):
|
||||
print(i)
|
||||
H.insert(i, nbd.NBD())
|
||||
H[i].set_opt_mode(True)
|
||||
H[i].connect_uri("nbd://localhost")
|
||||
'
|
||||
$ kill $!
|
||||
|
||||
where later connections get to start progressing once earlier ones are
|
||||
forcefully dropped for taking too long, rather than hanging.
|
||||
|
||||
Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20240807174943.771624-13-eblake@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
[eblake: rebase to changes earlier in series, reduce scope of timer]
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
|
||||
CVE: CVE-2024-7409
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/b9b72cb3ce15b693148bd09cef7e50110566d8a0]
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
nbd/server.c | 28 +++++++++++++++++++++++++++-
|
||||
nbd/trace-events | 1 +
|
||||
2 files changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/nbd/server.c b/nbd/server.c
|
||||
index 12680c8dc..1bb253726 100644
|
||||
--- a/nbd/server.c
|
||||
+++ b/nbd/server.c
|
||||
@@ -2698,22 +2698,48 @@ static void nbd_client_receive_next_request(NBDClient *client)
|
||||
}
|
||||
}
|
||||
|
||||
+static void nbd_handshake_timer_cb(void *opaque)
|
||||
+{
|
||||
+ QIOChannel *ioc = opaque;
|
||||
+
|
||||
+ trace_nbd_handshake_timer_cb();
|
||||
+ qio_channel_shutdown(ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
|
||||
+}
|
||||
+
|
||||
static coroutine_fn void nbd_co_client_start(void *opaque)
|
||||
{
|
||||
NBDClient *client = opaque;
|
||||
Error *local_err = NULL;
|
||||
+ QEMUTimer *handshake_timer = NULL;
|
||||
|
||||
qemu_co_mutex_init(&client->send_lock);
|
||||
|
||||
- /* TODO - utilize client->handshake_max_secs */
|
||||
+ /*
|
||||
+ * Create a timer to bound the time spent in negotiation. If the
|
||||
+ * timer expires, it is likely nbd_negotiate will fail because the
|
||||
+ * socket was shutdown.
|
||||
+ */
|
||||
+ if (client->handshake_max_secs > 0) {
|
||||
+ handshake_timer = aio_timer_new(qemu_get_aio_context(),
|
||||
+ QEMU_CLOCK_REALTIME,
|
||||
+ SCALE_NS,
|
||||
+ nbd_handshake_timer_cb,
|
||||
+ client->sioc);
|
||||
+ timer_mod(handshake_timer,
|
||||
+ qemu_clock_get_ns(QEMU_CLOCK_REALTIME) +
|
||||
+ client->handshake_max_secs * NANOSECONDS_PER_SECOND);
|
||||
+ }
|
||||
+
|
||||
if (nbd_negotiate(client, &local_err)) {
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
+ timer_free(handshake_timer);
|
||||
client_close(client, false);
|
||||
return;
|
||||
}
|
||||
|
||||
+ timer_free(handshake_timer);
|
||||
nbd_client_receive_next_request(client);
|
||||
}
|
||||
|
||||
diff --git a/nbd/trace-events b/nbd/trace-events
|
||||
index c4919a2dd..553546f1f 100644
|
||||
--- a/nbd/trace-events
|
||||
+++ b/nbd/trace-events
|
||||
@@ -73,3 +73,4 @@ nbd_co_receive_request_decode_type(uint64_t handle, uint16_t type, const char *n
|
||||
nbd_co_receive_request_payload_received(uint64_t handle, uint32_t len) "Payload received: handle = %" PRIu64 ", len = %" PRIu32
|
||||
nbd_co_receive_align_compliance(const char *op, uint64_t from, uint32_t len, uint32_t align) "client sent non-compliant unaligned %s request: from=0x%" PRIx64 ", len=0x%" PRIx32 ", align=0x%" PRIx32
|
||||
nbd_trip(void) "Reading request"
|
||||
+nbd_handshake_timer_cb(void) "client took too long to negotiate"
|
||||
--
|
||||
2.25.1
|
||||
|
||||
163
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0004.patch
Normal file
163
meta/recipes-devtools/qemu/qemu/CVE-2024-7409-0004.patch
Normal file
@@ -0,0 +1,163 @@
|
||||
From 3e7ef738c8462c45043a1d39f702a0990406a3b3 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 7 Aug 2024 12:23:13 -0500
|
||||
Subject: [PATCH] nbd/server: CVE-2024-7409: Close stray clients at server-stop
|
||||
|
||||
A malicious client can attempt to connect to an NBD server, and then
|
||||
intentionally delay progress in the handshake, including if it does
|
||||
not know the TLS secrets. Although the previous two patches reduce
|
||||
this behavior by capping the default max-connections parameter and
|
||||
killing slow clients, they did not eliminate the possibility of a
|
||||
client waiting to close the socket until after the QMP nbd-server-stop
|
||||
command is executed, at which point qemu would SEGV when trying to
|
||||
dereference the NULL nbd_server global which is no longer present.
|
||||
This amounts to a denial of service attack. Worse, if another NBD
|
||||
server is started before the malicious client disconnects, I cannot
|
||||
rule out additional adverse effects when the old client interferes
|
||||
with the connection count of the new server (although the most likely
|
||||
is a crash due to an assertion failure when checking
|
||||
nbd_server->connections > 0).
|
||||
|
||||
For environments without this patch, the CVE can be mitigated by
|
||||
ensuring (such as via a firewall) that only trusted clients can
|
||||
connect to an NBD server. Note that using frameworks like libvirt
|
||||
that ensure that TLS is used and that nbd-server-stop is not executed
|
||||
while any trusted clients are still connected will only help if there
|
||||
is also no possibility for an untrusted client to open a connection
|
||||
but then stall on the NBD handshake.
|
||||
|
||||
Given the previous patches, it would be possible to guarantee that no
|
||||
clients remain connected by having nbd-server-stop sleep for longer
|
||||
than the default handshake deadline before finally freeing the global
|
||||
nbd_server object, but that could make QMP non-responsive for a long
|
||||
time. So intead, this patch fixes the problem by tracking all client
|
||||
sockets opened while the server is running, and forcefully closing any
|
||||
such sockets remaining without a completed handshake at the time of
|
||||
nbd-server-stop, then waiting until the coroutines servicing those
|
||||
sockets notice the state change. nbd-server-stop now has a second
|
||||
AIO_WAIT_WHILE_UNLOCKED (the first is indirectly through the
|
||||
blk_exp_close_all_type() that disconnects all clients that completed
|
||||
handshakes), but forced socket shutdown is enough to progress the
|
||||
coroutines and quickly tear down all clients before the server is
|
||||
freed, thus finally fixing the CVE.
|
||||
|
||||
This patch relies heavily on the fact that nbd/server.c guarantees
|
||||
that it only calls nbd_blockdev_client_closed() from the main loop
|
||||
(see the assertion in nbd_client_put() and the hoops used in
|
||||
nbd_client_put_nonzero() to achieve that); if we did not have that
|
||||
guarantee, we would also need a mutex protecting our accesses of the
|
||||
list of connections to survive re-entrancy from independent iothreads.
|
||||
|
||||
Although I did not actually try to test old builds, it looks like this
|
||||
problem has existed since at least commit 862172f45c (v2.12.0, 2017) -
|
||||
even back when that patch started using a QIONetListener to handle
|
||||
listening on multiple sockets, nbd_server_free() was already unaware
|
||||
that the nbd_blockdev_client_closed callback can be reached later by a
|
||||
client thread that has not completed handshakes (and therefore the
|
||||
client's socket never got added to the list closed in
|
||||
nbd_export_close_all), despite that patch intentionally tearing down
|
||||
the QIONetListener to prevent new clients.
|
||||
|
||||
Reported-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
|
||||
Fixes: CVE-2024-7409
|
||||
CC: qemu-stable@nongnu.org
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
Message-ID: <20240807174943.771624-14-eblake@redhat.com>
|
||||
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
CVE: CVE-2024-7409
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/3e7ef738c8462c45043a1d39f702a0990406a3b3]
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
blockdev-nbd.c | 35 ++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 34 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
|
||||
index 4bd90bac1..c71ca38d2 100644
|
||||
--- a/blockdev-nbd.c
|
||||
+++ b/blockdev-nbd.c
|
||||
@@ -21,12 +21,18 @@
|
||||
#include "io/channel-socket.h"
|
||||
#include "io/net-listener.h"
|
||||
|
||||
+typedef struct NBDConn {
|
||||
+ QIOChannelSocket *cioc;
|
||||
+ QLIST_ENTRY(NBDConn) next;
|
||||
+} NBDConn;
|
||||
+
|
||||
typedef struct NBDServerData {
|
||||
QIONetListener *listener;
|
||||
QCryptoTLSCreds *tlscreds;
|
||||
char *tlsauthz;
|
||||
uint32_t max_connections;
|
||||
uint32_t connections;
|
||||
+ QLIST_HEAD(, NBDConn) conns;
|
||||
} NBDServerData;
|
||||
|
||||
static NBDServerData *nbd_server;
|
||||
@@ -46,6 +52,14 @@ bool nbd_server_is_running(void)
|
||||
|
||||
static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
|
||||
{
|
||||
+ NBDConn *conn = nbd_client_owner(client);
|
||||
+
|
||||
+ assert(qemu_mutex_iothread_locked() && nbd_server);
|
||||
+
|
||||
+ object_unref(OBJECT(conn->cioc));
|
||||
+ QLIST_REMOVE(conn, next);
|
||||
+ g_free(conn);
|
||||
+
|
||||
nbd_client_put(client);
|
||||
assert(nbd_server->connections > 0);
|
||||
nbd_server->connections--;
|
||||
@@ -55,14 +69,20 @@ static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
|
||||
static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
|
||||
gpointer opaque)
|
||||
{
|
||||
+ NBDConn *conn = g_new0(NBDConn, 1);
|
||||
+
|
||||
+ assert(qemu_mutex_iothread_locked() && nbd_server);
|
||||
nbd_server->connections++;
|
||||
+ object_ref(OBJECT(cioc));
|
||||
+ conn->cioc = cioc;
|
||||
+ QLIST_INSERT_HEAD(&nbd_server->conns, conn, next);
|
||||
nbd_update_server_watch(nbd_server);
|
||||
|
||||
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
|
||||
/* TODO - expose handshake timeout as QMP option */
|
||||
nbd_client_new(cioc, NBD_DEFAULT_HANDSHAKE_MAX_SECS,
|
||||
nbd_server->tlscreds, nbd_server->tlsauthz,
|
||||
- nbd_blockdev_client_closed, NULL);
|
||||
+ nbd_blockdev_client_closed, conn);
|
||||
}
|
||||
|
||||
static void nbd_update_server_watch(NBDServerData *s)
|
||||
@@ -76,12 +96,25 @@ static void nbd_update_server_watch(NBDServerData *s)
|
||||
|
||||
static void nbd_server_free(NBDServerData *server)
|
||||
{
|
||||
+ NBDConn *conn, *tmp;
|
||||
+
|
||||
if (!server) {
|
||||
return;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Forcefully close the listener socket, and any clients that have
|
||||
+ * not yet disconnected on their own.
|
||||
+ */
|
||||
qio_net_listener_disconnect(server->listener);
|
||||
object_unref(OBJECT(server->listener));
|
||||
+ QLIST_FOREACH_SAFE(conn, &server->conns, next, tmp) {
|
||||
+ qio_channel_shutdown(QIO_CHANNEL(conn->cioc), QIO_CHANNEL_SHUTDOWN_BOTH,
|
||||
+ NULL);
|
||||
+ }
|
||||
+
|
||||
+ AIO_WAIT_WHILE(NULL, server->connections > 0);
|
||||
+
|
||||
if (server->tlscreds) {
|
||||
object_unref(OBJECT(server->tlscreds));
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
87
meta/recipes-devtools/ruby/ruby/CVE-2024-27280.patch
Normal file
87
meta/recipes-devtools/ruby/ruby/CVE-2024-27280.patch
Normal file
@@ -0,0 +1,87 @@
|
||||
From a35268a3ac1b5f0058e5b7c1a041a7e86d9da067 Mon Sep 17 00:00:00 2001
|
||||
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
Date: Mon, 10 Jun 2024 11:46:53 +0000
|
||||
Subject: [PATCH] Fix expanding size at ungetc/ungetbyte
|
||||
|
||||
CVE: CVE-2024-27280
|
||||
Upstream-Status: Backport [https://github.com/ruby/stringio/commit/a35268a3ac1b5f0058e5b7c1a041a7e86d9da067]
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
ext/stringio/stringio.c | 2 +-
|
||||
test/stringio/test_stringio.rb | 25 +++++++++++++++++++++----
|
||||
2 files changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
|
||||
index 8df07e8..b2e8632 100644
|
||||
--- a/ext/stringio/stringio.c
|
||||
+++ b/ext/stringio/stringio.c
|
||||
@@ -984,7 +984,7 @@ strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
|
||||
len = RSTRING_LEN(str);
|
||||
rest = pos - len;
|
||||
if (cl > pos) {
|
||||
- long ex = (rest < 0 ? cl-pos : cl+rest);
|
||||
+ long ex = cl - (rest < 0 ? pos : len);
|
||||
rb_str_modify_expand(str, ex);
|
||||
rb_str_set_len(str, len + ex);
|
||||
s = RSTRING_PTR(str);
|
||||
diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb
|
||||
index e0b4504..4853513 100644
|
||||
--- a/test/stringio/test_stringio.rb
|
||||
+++ b/test/stringio/test_stringio.rb
|
||||
@@ -757,6 +757,15 @@ class TestStringIO < Test::Unit::TestCase
|
||||
assert_equal("b""\0""a", s.string)
|
||||
end
|
||||
|
||||
+ def test_ungetc_fill
|
||||
+ count = 100
|
||||
+ s = StringIO.new
|
||||
+ s.print 'a' * count
|
||||
+ s.ungetc('b' * (count * 5))
|
||||
+ assert_equal((count * 5), s.string.size)
|
||||
+ assert_match(/\Ab+\z/, s.string)
|
||||
+ end
|
||||
+
|
||||
def test_ungetbyte_pos
|
||||
b = '\\b00010001 \\B00010001 \\b1 \\B1 \\b000100011'
|
||||
s = StringIO.new( b )
|
||||
@@ -782,6 +791,15 @@ class TestStringIO < Test::Unit::TestCase
|
||||
assert_equal("b""\0""a", s.string)
|
||||
end
|
||||
|
||||
+ def test_ungetbyte_fill
|
||||
+ count = 100
|
||||
+ s = StringIO.new
|
||||
+ s.print 'a' * count
|
||||
+ s.ungetbyte('b' * (count * 5))
|
||||
+ assert_equal((count * 5), s.string.size)
|
||||
+ assert_match(/\Ab+\z/, s.string)
|
||||
+ end
|
||||
+
|
||||
def test_frozen
|
||||
s = StringIO.new
|
||||
s.freeze
|
||||
@@ -825,18 +843,17 @@ class TestStringIO < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_overflow
|
||||
- omit if RbConfig::SIZEOF["void*"] > RbConfig::SIZEOF["long"]
|
||||
+ return if RbConfig::SIZEOF["void*"] > RbConfig::SIZEOF["long"]
|
||||
limit = RbConfig::LIMITS["INTPTR_MAX"] - 0x10
|
||||
assert_separately(%w[-rstringio], "#{<<-"begin;"}\n#{<<-"end;"}")
|
||||
begin;
|
||||
limit = #{limit}
|
||||
ary = []
|
||||
- while true
|
||||
+ begin
|
||||
x = "a"*0x100000
|
||||
break if [x].pack("p").unpack("i!")[0] < 0
|
||||
ary << x
|
||||
- omit if ary.size > 100
|
||||
- end
|
||||
+ end while ary.size <= 100
|
||||
s = StringIO.new(x)
|
||||
s.gets("xxx", limit)
|
||||
assert_equal(0x100000, s.pos)
|
||||
--
|
||||
2.40.0
|
||||
29
meta/recipes-devtools/ruby/ruby/CVE-2024-27282.patch
Normal file
29
meta/recipes-devtools/ruby/ruby/CVE-2024-27282.patch
Normal file
@@ -0,0 +1,29 @@
|
||||
From 989a2355808a63fc45367785c82ffd46d18c900a Mon Sep 17 00:00:00 2001
|
||||
From: Hiroshi SHIBATA <hsbt@ruby-lang.org>
|
||||
Date: Fri, 12 Apr 2024 15:01:47 +1000
|
||||
Subject: [PATCH] Fix Use-After-Free issue for Regexp
|
||||
|
||||
Co-authored-by: Isaac Peka <7493006+isaac-peka@users.noreply.github.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/ruby/ruby/commit/989a2355808a63fc45367785c82ffd46d18c900a]
|
||||
CVE: CVE-2024-27282
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
|
||||
|
||||
regexec.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/regexec.c b/regexec.c
|
||||
index 73694ab14a0b0a..140691ad42489f 100644
|
||||
--- a/regexec.c
|
||||
+++ b/regexec.c
|
||||
@@ -3449,8 +3449,8 @@ match_at(regex_t* reg, const UChar* str, const UChar* end,
|
||||
CASE(OP_MEMORY_END_PUSH_REC) MOP_IN(OP_MEMORY_END_PUSH_REC);
|
||||
GET_MEMNUM_INC(mem, p);
|
||||
STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
|
||||
- STACK_PUSH_MEM_END(mem, s);
|
||||
mem_start_stk[mem] = GET_STACK_INDEX(stkp);
|
||||
+ STACK_PUSH_MEM_END(mem, s);
|
||||
MOP_OUT;
|
||||
JUMP;
|
||||
|
||||
@@ -34,6 +34,8 @@ SRC_URI = "http://cache.ruby-lang.org/pub/ruby/${SHRT_VER}/ruby-${PV}.tar.gz \
|
||||
file://CVE-2023-36617_1.patch \
|
||||
file://CVE-2023-36617_2.patch \
|
||||
file://CVE-2024-27281.patch \
|
||||
file://CVE-2024-27280.patch \
|
||||
file://CVE-2024-27282.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_URI = "https://www.ruby-lang.org/en/downloads/"
|
||||
|
||||
|
||||
33
meta/recipes-extended/acpica/acpica/CVE-2024-24856.patch
Normal file
33
meta/recipes-extended/acpica/acpica/CVE-2024-24856.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
From 4d4547cf13cca820ff7e0f859ba83e1a610b9fd0 Mon Sep 17 00:00:00 2001
|
||||
From: Huai-Yuan Liu <qq810974084@gmail.com>
|
||||
Date: Tue, 4 Jun 2024 11:52:15 +0000
|
||||
Subject: [PATCH] check null return of ACPI_ALLOCATE_ZEROED in
|
||||
|
||||
AcpiDbConvertToPackage ACPI_ALLOCATE_ZEROED may fails, Elements
|
||||
might be null and will cause null pointer dereference later.
|
||||
|
||||
Signed-off-by: Huai-Yuan Liu <qq810974084@gmail.com>
|
||||
|
||||
CVE: CVE-2024-24856
|
||||
Upstream-Status: Backport [https://github.com/acpica/acpica/commit/4d4547cf13cca820ff7e0f859ba83e1a610b9fd0]
|
||||
|
||||
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
||||
---
|
||||
source/components/debugger/dbconvert.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/source/components/debugger/dbconvert.c b/source/components/debugger/dbconvert.c
|
||||
index 55307d0..c17a5ab 100644
|
||||
--- a/source/components/debugger/dbconvert.c
|
||||
+++ b/source/components/debugger/dbconvert.c
|
||||
@@ -354,6 +354,8 @@ AcpiDbConvertToPackage (
|
||||
|
||||
Elements = ACPI_ALLOCATE_ZEROED (
|
||||
DB_DEFAULT_PKG_ELEMENTS * sizeof (ACPI_OBJECT));
|
||||
+ if (!Elements)
|
||||
+ return (AE_NO_MEMORY);
|
||||
|
||||
This = String;
|
||||
for (i = 0; i < (DB_DEFAULT_PKG_ELEMENTS - 1); i++)
|
||||
--
|
||||
2.40.0
|
||||
@@ -16,7 +16,9 @@ COMPATIBLE_HOST = "(i.86|x86_64|arm|aarch64).*-linux"
|
||||
|
||||
DEPENDS = "m4-native flex-native bison-native"
|
||||
|
||||
SRC_URI = "https://acpica.org/sites/acpica/files/acpica-unix-${PV}.tar.gz"
|
||||
SRC_URI = "https://acpica.org/sites/acpica/files/acpica-unix-${PV}.tar.gz \
|
||||
file://CVE-2024-24856.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "2511f85828820d747fa3e2c3433d3a38c22db3d9c2fd900e1a84eb4173cb5992"
|
||||
|
||||
UPSTREAM_CHECK_URI = "https://acpica.org/downloads"
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 77dc7f699beba606937b7ea23b50cf5974fa64b1 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Thu, 25 Jan 2024 11:55:49 +0000
|
||||
Subject: [PATCH] Bug 707510 - don't allow PDF files with bad Filters to
|
||||
overflow the debug buffer
|
||||
|
||||
Item #2 of the report.
|
||||
|
||||
Allocate a buffer to hold the filter name, instead of assuming it will
|
||||
fit in a fixed buffer.
|
||||
|
||||
Reviewed all the other PDFDEBUG cases, no others use a fixed buffer like
|
||||
this.
|
||||
|
||||
CVE: CVE-2024-29506
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=77dc7f699beba606937b7ea23b50cf5974fa64b1]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
pdf/pdf_file.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pdf/pdf_file.c b/pdf/pdf_file.c
|
||||
index 214d448..93c2402 100644
|
||||
--- a/pdf/pdf_file.c
|
||||
+++ b/pdf/pdf_file.c
|
||||
@@ -767,10 +767,14 @@ static int pdfi_apply_filter(pdf_context *ctx, pdf_dict *dict, pdf_name *n, pdf_
|
||||
|
||||
if (ctx->args.pdfdebug)
|
||||
{
|
||||
- char str[100];
|
||||
+ char *str;
|
||||
+ str = gs_alloc_bytes(ctx->memory, n->length + 1, "temp string for debug");
|
||||
+ if (str == NULL)
|
||||
+ return_error(gs_error_VMerror);
|
||||
memcpy(str, (const char *)n->data, n->length);
|
||||
str[n->length] = '\0';
|
||||
dmprintf1(ctx->memory, "FILTER NAME:%s\n", str);
|
||||
+ gs_free_object(ctx->memory, str, "temp string for debug");
|
||||
}
|
||||
|
||||
if (pdfi_name_is(n, "RunLengthDecode")) {
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,45 @@
|
||||
From 917b3a71fb20748965254631199ad98210d6c2fb Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Thu, 25 Jan 2024 11:58:22 +0000
|
||||
Subject: [PATCH] Bug 707510 - don't use strlen on passwords
|
||||
|
||||
Item #1 of the report. This looks like an oversight when first coding
|
||||
the routine. We should use the PostScript string length, because
|
||||
PostScript strings may not be NULL terminated (and as here may contain
|
||||
internal NULL characters).
|
||||
|
||||
Fix the R6 handler which has the same problem too.
|
||||
|
||||
CVE: CVE-2024-29509
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=917b3a71fb20748965254631199ad98210d6c2fb]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
pdf/pdf_sec.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/pdf/pdf_sec.c b/pdf/pdf_sec.c
|
||||
index ff60805..2bb59e1 100644
|
||||
--- a/pdf/pdf_sec.c
|
||||
+++ b/pdf/pdf_sec.c
|
||||
@@ -1250,7 +1250,7 @@ static int check_password_R5(pdf_context *ctx, char *Password, int PasswordLen,
|
||||
if (code < 0) {
|
||||
pdf_string *P = NULL, *P_UTF8 = NULL;
|
||||
|
||||
- code = pdfi_object_alloc(ctx, PDF_STRING, strlen(ctx->encryption.Password), (pdf_obj **)&P);
|
||||
+ code = pdfi_object_alloc(ctx, PDF_STRING, PasswordLen, (pdf_obj **)&P);
|
||||
if (code < 0) {
|
||||
return code;
|
||||
}
|
||||
@@ -1300,7 +1300,7 @@ static int check_password_R6(pdf_context *ctx, char *Password, int PasswordLen,
|
||||
if (code < 0) {
|
||||
pdf_string *P = NULL, *P_UTF8 = NULL;
|
||||
|
||||
- code = pdfi_object_alloc(ctx, PDF_STRING, strlen(ctx->encryption.Password), (pdf_obj **)&P);
|
||||
+ code = pdfi_object_alloc(ctx, PDF_STRING, PasswordLen, (pdf_obj **)&P);
|
||||
if (code < 0)
|
||||
return code;
|
||||
memcpy(P->data, Password, PasswordLen);
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,100 @@
|
||||
From 638159c43dbb48425a187d244ec288d252d0ecf4 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Liddell <chris.liddell@artifex.com>
|
||||
Date: Wed, 31 Jan 2024 14:08:18 +0000
|
||||
Subject: [PATCH 1/2] Bug 707510(5): Reject OCRLanguage changes after SAFER
|
||||
enabled
|
||||
|
||||
In the devices that support OCR, OCRLanguage really ought never to be set from
|
||||
PostScript, so reject attempts to change it if path_control_active is true.
|
||||
|
||||
CVE: CVE-2024-29511
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=3d4cfdc1a44b1969a0f14c86673a372654d443c4]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
devices/gdevocr.c | 15 ++++++++++-----
|
||||
devices/gdevpdfocr.c | 15 ++++++++++-----
|
||||
devices/vector/gdevpdfp.c | 15 ++++++++++-----
|
||||
3 files changed, 30 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/devices/gdevocr.c b/devices/gdevocr.c
|
||||
index 88c759c..287b74b 100644
|
||||
--- a/devices/gdevocr.c
|
||||
+++ b/devices/gdevocr.c
|
||||
@@ -187,11 +187,16 @@ ocr_put_params(gx_device *dev, gs_param_list *plist)
|
||||
|
||||
switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
|
||||
case 0:
|
||||
- len = langstr.size;
|
||||
- if (len >= sizeof(pdev->language))
|
||||
- len = sizeof(pdev->language)-1;
|
||||
- memcpy(pdev->language, langstr.data, len);
|
||||
- pdev->language[len] = 0;
|
||||
+ if (pdev->memory->gs_lib_ctx->core->path_control_active) {
|
||||
+ return_error(gs_error_invalidaccess);
|
||||
+ }
|
||||
+ else {
|
||||
+ len = langstr.size;
|
||||
+ if (len >= sizeof(pdev->language))
|
||||
+ len = sizeof(pdev->language)-1;
|
||||
+ memcpy(pdev->language, langstr.data, len);
|
||||
+ pdev->language[len] = 0;
|
||||
+ }
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
diff --git a/devices/gdevpdfocr.c b/devices/gdevpdfocr.c
|
||||
index 8dd5a59..4c694e3 100644
|
||||
--- a/devices/gdevpdfocr.c
|
||||
+++ b/devices/gdevpdfocr.c
|
||||
@@ -50,11 +50,16 @@ pdfocr_put_some_params(gx_device * dev, gs_param_list * plist)
|
||||
|
||||
switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
|
||||
case 0:
|
||||
- len = langstr.size;
|
||||
- if (len >= sizeof(pdf_dev->ocr.language))
|
||||
- len = sizeof(pdf_dev->ocr.language)-1;
|
||||
- memcpy(pdf_dev->ocr.language, langstr.data, len);
|
||||
- pdf_dev->ocr.language[len] = 0;
|
||||
+ if (pdf_dev->memory->gs_lib_ctx->core->path_control_active) {
|
||||
+ return_error(gs_error_invalidaccess);
|
||||
+ }
|
||||
+ else {
|
||||
+ len = langstr.size;
|
||||
+ if (len >= sizeof(pdf_dev->ocr.language))
|
||||
+ len = sizeof(pdf_dev->ocr.language)-1;
|
||||
+ memcpy(pdf_dev->ocr.language, langstr.data, len);
|
||||
+ pdf_dev->ocr.language[len] = 0;
|
||||
+ }
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
diff --git a/devices/vector/gdevpdfp.c b/devices/vector/gdevpdfp.c
|
||||
index 42fa1c5..23e9bc8 100644
|
||||
--- a/devices/vector/gdevpdfp.c
|
||||
+++ b/devices/vector/gdevpdfp.c
|
||||
@@ -458,11 +458,16 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
|
||||
gs_param_string langstr;
|
||||
switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
|
||||
case 0:
|
||||
- len = langstr.size;
|
||||
- if (len >= sizeof(pdev->ocr_language))
|
||||
- len = sizeof(pdev->ocr_language)-1;
|
||||
- memcpy(pdev->ocr_language, langstr.data, len);
|
||||
- pdev->ocr_language[len] = 0;
|
||||
+ if (pdev->memory->gs_lib_ctx->core->path_control_active) {
|
||||
+ return_error(gs_error_invalidaccess);
|
||||
+ }
|
||||
+ else {
|
||||
+ len = langstr.size;
|
||||
+ if (len >= sizeof(pdev->ocr_language))
|
||||
+ len = sizeof(pdev->ocr_language)-1;
|
||||
+ memcpy(pdev->ocr_language, langstr.data, len);
|
||||
+ pdev->ocr_language[len] = 0;
|
||||
+ }
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,219 @@
|
||||
From 360153f3aa63c8fef0d507eccde75f46342c5264 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Liddell <chris.liddell@artifex.com>
|
||||
Date: Wed, 31 Jan 2024 14:08:18 +0000
|
||||
Subject: [PATCH 2/2] Bug 707510(5)2: The original fix was overly aggressive
|
||||
|
||||
The way the default OCRLanguage value was set was for the relevant get_params
|
||||
methods to check if the value had been set, and if not return a default value.
|
||||
This could result in the first time the put_params seeing that value being after
|
||||
path control has been enabled, meaning it would throw an invalidaccess error.
|
||||
|
||||
This changes how we set the default: they now uses an init_device method, so
|
||||
the string is populated from the device's creation. This works correctly for
|
||||
both the default value, and for values set on the command line.
|
||||
|
||||
CVE: CVE-2024-29511
|
||||
|
||||
Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;a=patch;h=638159c43dbb48425a187d244ec288d252d0ecf4]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
devices/gdevocr.c | 17 ++++++++++++++++-
|
||||
devices/gdevpdfocr.c | 28 ++++++++++++++++++++++------
|
||||
devices/vector/gdevpdf.c | 15 +++++++++++++++
|
||||
devices/vector/gdevpdfp.c | 3 ++-
|
||||
4 files changed, 55 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/devices/gdevocr.c b/devices/gdevocr.c
|
||||
index 287b74b..a616ef4 100644
|
||||
--- a/devices/gdevocr.c
|
||||
+++ b/devices/gdevocr.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#define X_DPI 72
|
||||
#define Y_DPI 72
|
||||
|
||||
+static dev_proc_initialize_device(ocr_initialize_device);
|
||||
static dev_proc_print_page(ocr_print_page);
|
||||
static dev_proc_print_page(hocr_print_page);
|
||||
static dev_proc_get_params(ocr_get_params);
|
||||
@@ -55,6 +56,7 @@ ocr_initialize_device_procs(gx_device *dev)
|
||||
{
|
||||
gdev_prn_initialize_device_procs_gray_bg(dev);
|
||||
|
||||
+ set_dev_proc(dev, initialize_device, ocr_initialize_device);
|
||||
set_dev_proc(dev, open_device, ocr_open);
|
||||
set_dev_proc(dev, close_device, ocr_close);
|
||||
set_dev_proc(dev, get_params, ocr_get_params);
|
||||
@@ -79,6 +81,7 @@ hocr_initialize_device_procs(gx_device *dev)
|
||||
{
|
||||
gdev_prn_initialize_device_procs_gray_bg(dev);
|
||||
|
||||
+ set_dev_proc(dev, initialize_device, ocr_initialize_device);
|
||||
set_dev_proc(dev, open_device, ocr_open);
|
||||
set_dev_proc(dev, close_device, hocr_close);
|
||||
set_dev_proc(dev, get_params, ocr_get_params);
|
||||
@@ -102,6 +105,17 @@ const gx_device_ocr gs_hocr_device =
|
||||
#define HOCR_HEADER "<html>\n <body>\n"
|
||||
#define HOCR_TRAILER " </body>\n</html>\n"
|
||||
|
||||
+static int
|
||||
+ocr_initialize_device(gx_device *dev)
|
||||
+{
|
||||
+ gx_device_ocr *odev = (gx_device_ocr *)dev;
|
||||
+ const char *default_ocr_lang = "eng";
|
||||
+
|
||||
+ odev->language[0] = '\0';
|
||||
+ strcpy(odev->language, default_ocr_lang);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
ocr_open(gx_device *pdev)
|
||||
{
|
||||
@@ -187,7 +201,8 @@ ocr_put_params(gx_device *dev, gs_param_list *plist)
|
||||
|
||||
switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
|
||||
case 0:
|
||||
- if (pdev->memory->gs_lib_ctx->core->path_control_active) {
|
||||
+ if (pdev->memory->gs_lib_ctx->core->path_control_active
|
||||
+ && (strlen(pdev->language) != langstr.size || memcmp(pdev->language, langstr.data, langstr.size) != 0)) {
|
||||
return_error(gs_error_invalidaccess);
|
||||
}
|
||||
else {
|
||||
diff --git a/devices/gdevpdfocr.c b/devices/gdevpdfocr.c
|
||||
index 4c694e3..e4f9862 100644
|
||||
--- a/devices/gdevpdfocr.c
|
||||
+++ b/devices/gdevpdfocr.c
|
||||
@@ -33,9 +33,9 @@
|
||||
#include "gdevpdfimg.h"
|
||||
#include "tessocr.h"
|
||||
|
||||
-int pdf_ocr_open(gx_device *pdev);
|
||||
-int pdf_ocr_close(gx_device *pdev);
|
||||
-
|
||||
+static dev_proc_initialize_device(pdf_ocr_initialize_device);
|
||||
+static dev_proc_open_device(pdf_ocr_open);
|
||||
+static dev_proc_close_device(pdf_ocr_close);
|
||||
|
||||
static int
|
||||
pdfocr_put_some_params(gx_device * dev, gs_param_list * plist)
|
||||
@@ -50,7 +50,8 @@ pdfocr_put_some_params(gx_device * dev, gs_param_list * plist)
|
||||
|
||||
switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
|
||||
case 0:
|
||||
- if (pdf_dev->memory->gs_lib_ctx->core->path_control_active) {
|
||||
+ if (pdf_dev->memory->gs_lib_ctx->core->path_control_active
|
||||
+ && (strlen(pdf_dev->ocr.language) != langstr.size || memcmp(pdf_dev->ocr.language, langstr.data, langstr.size) != 0)) {
|
||||
return_error(gs_error_invalidaccess);
|
||||
}
|
||||
else {
|
||||
@@ -152,6 +153,8 @@ pdfocr8_initialize_device_procs(gx_device *dev)
|
||||
{
|
||||
gdev_prn_initialize_device_procs_gray(dev);
|
||||
|
||||
+ set_dev_proc(dev, initialize_device, pdf_ocr_initialize_device);
|
||||
+ set_dev_proc(dev, initialize_device, pdf_ocr_initialize_device);
|
||||
set_dev_proc(dev, open_device, pdf_ocr_open);
|
||||
set_dev_proc(dev, output_page, gdev_prn_output_page_seekable);
|
||||
set_dev_proc(dev, close_device, pdf_ocr_close);
|
||||
@@ -185,6 +188,7 @@ pdfocr24_initialize_device_procs(gx_device *dev)
|
||||
{
|
||||
gdev_prn_initialize_device_procs_rgb(dev);
|
||||
|
||||
+ set_dev_proc(dev, initialize_device, pdf_ocr_initialize_device);
|
||||
set_dev_proc(dev, open_device, pdf_ocr_open);
|
||||
set_dev_proc(dev, output_page, gdev_prn_output_page_seekable);
|
||||
set_dev_proc(dev, close_device, pdf_ocr_close);
|
||||
@@ -216,6 +220,7 @@ pdfocr32_initialize_device_procs(gx_device *dev)
|
||||
{
|
||||
gdev_prn_initialize_device_procs_cmyk8(dev);
|
||||
|
||||
+ set_dev_proc(dev, initialize_device, pdf_ocr_initialize_device);
|
||||
set_dev_proc(dev, open_device, pdf_ocr_open);
|
||||
set_dev_proc(dev, output_page, gdev_prn_output_page_seekable);
|
||||
set_dev_proc(dev, close_device, pdf_ocr_close);
|
||||
@@ -703,7 +708,18 @@ ocr_end_page(gx_device_pdf_image *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int
|
||||
+static int
|
||||
+pdf_ocr_initialize_device(gx_device *dev)
|
||||
+{
|
||||
+ gx_device_pdf_image *ppdev = (gx_device_pdf_image *)dev;
|
||||
+ const char *default_ocr_lang = "eng";
|
||||
+
|
||||
+ ppdev->ocr.language[0] = '\0';
|
||||
+ strcpy(ppdev->ocr.language, default_ocr_lang);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
pdf_ocr_open(gx_device *pdev)
|
||||
{
|
||||
gx_device_pdf_image *ppdev;
|
||||
@@ -726,7 +742,7 @@ pdf_ocr_open(gx_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int
|
||||
+static int
|
||||
pdf_ocr_close(gx_device *pdev)
|
||||
{
|
||||
gx_device_pdf_image *pdf_dev;
|
||||
diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c
|
||||
index 9ab562c..5caabb8 100644
|
||||
--- a/devices/vector/gdevpdf.c
|
||||
+++ b/devices/vector/gdevpdf.c
|
||||
@@ -206,6 +206,7 @@ device_pdfwrite_finalize(const gs_memory_t *cmem, void *vpdev)
|
||||
}
|
||||
|
||||
/* Driver procedures */
|
||||
+static dev_proc_initialize_device(pdfwrite_initialize_device);
|
||||
static dev_proc_open_device(pdf_open);
|
||||
static dev_proc_output_page(pdf_output_page);
|
||||
static dev_proc_close_device(pdf_close);
|
||||
@@ -223,6 +224,7 @@ static dev_proc_close_device(pdf_close);
|
||||
static void
|
||||
pdfwrite_initialize_device_procs(gx_device *dev)
|
||||
{
|
||||
+ set_dev_proc(dev, initialize_device, pdfwrite_initialize_device);
|
||||
set_dev_proc(dev, open_device, pdf_open);
|
||||
set_dev_proc(dev, get_initial_matrix, gx_upright_get_initial_matrix);
|
||||
set_dev_proc(dev, output_page, pdf_output_page);
|
||||
@@ -766,6 +768,19 @@ pdf_reset_text(gx_device_pdf * pdev)
|
||||
pdf_reset_text_state(pdev->text);
|
||||
}
|
||||
|
||||
+static int
|
||||
+pdfwrite_initialize_device(gx_device *dev)
|
||||
+{
|
||||
+#if OCR_VERSION > 0
|
||||
+ gx_device_pdf *pdev = (gx_device_pdf *) dev;
|
||||
+ const char *default_ocr_lang = "eng";
|
||||
+ pdev->ocr_language[0] = '\0';
|
||||
+ strcpy(pdev->ocr_language, default_ocr_lang);
|
||||
+#endif
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* Open the device. */
|
||||
static int
|
||||
pdf_open(gx_device * dev)
|
||||
diff --git a/devices/vector/gdevpdfp.c b/devices/vector/gdevpdfp.c
|
||||
index 23e9bc8..42a1794 100644
|
||||
--- a/devices/vector/gdevpdfp.c
|
||||
+++ b/devices/vector/gdevpdfp.c
|
||||
@@ -458,7 +458,8 @@ gdev_pdf_put_params_impl(gx_device * dev, const gx_device_pdf * save_dev, gs_par
|
||||
gs_param_string langstr;
|
||||
switch (code = param_read_string(plist, (param_name = "OCRLanguage"), &langstr)) {
|
||||
case 0:
|
||||
- if (pdev->memory->gs_lib_ctx->core->path_control_active) {
|
||||
+ if (pdev->memory->gs_lib_ctx->core->path_control_active
|
||||
+ && (strlen(pdev->ocr_language) != langstr.size || memcmp(pdev->ocr_language, langstr.data, langstr.size) != 0)) {
|
||||
return_error(gs_error_invalidaccess);
|
||||
}
|
||||
else {
|
||||
--
|
||||
2.40.0
|
||||
@@ -50,6 +50,10 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d
|
||||
file://CVE-2024-33871-0002.patch \
|
||||
file://CVE-2024-29510.patch \
|
||||
file://CVE-2023-52722.patch \
|
||||
file://CVE-2024-29511-0001.patch \
|
||||
file://CVE-2024-29511-0002.patch \
|
||||
file://CVE-2024-29509.patch \
|
||||
file://CVE-2024-29506.patch \
|
||||
"
|
||||
|
||||
SRC_URI = "${SRC_URI_BASE} \
|
||||
|
||||
@@ -38,6 +38,8 @@ SRC_URI[sha256sum] = "ba6d02f15ba04aba9c23fd5f236bb234eab9d5209e95d1c4df85c44d5f
|
||||
|
||||
# upstream-wontfix: upstream has documented that reported function is not thread-safe
|
||||
CVE_CHECK_IGNORE += "CVE-2023-30571"
|
||||
# cpe-incorrect: this vulnerability was not in any release; introduced in v3.7.3-14-g91f27004; fixed in b6a97948
|
||||
CVE_CHECK_IGNORE += "CVE-2024-37407"
|
||||
|
||||
inherit autotools update-alternatives pkgconfig
|
||||
|
||||
|
||||
@@ -21,16 +21,12 @@ do_compile[noexec] = "1"
|
||||
|
||||
do_install() {
|
||||
oe_runmake install prefix=${prefix} DESTDIR=${D}
|
||||
rm -rf ${D}${mandir}/man3/crypt.3
|
||||
rm -rf ${D}${mandir}/man3/crypt_r.3
|
||||
rm -rf ${D}${mandir}/man3/getspnam.3
|
||||
rm -rf ${D}${mandir}/man5/passwd.5
|
||||
}
|
||||
|
||||
# Only deliveres man-pages so FILES:${PN} gets everything
|
||||
FILES:${PN}-doc = ""
|
||||
FILES:${PN} = "${mandir}/*"
|
||||
|
||||
inherit update-alternatives
|
||||
|
||||
ALTERNATIVE_PRIORITY = "100"
|
||||
ALTERNATIVE:${PN} = "passwd.5 getspnam.3 crypt.3"
|
||||
ALTERNATIVE_LINK_NAME[passwd.5] = "${mandir}/man5/passwd.5"
|
||||
ALTERNATIVE_LINK_NAME[getspnam.3] = "${mandir}/man3/getspnam.3"
|
||||
ALTERNATIVE_LINK_NAME[crypt.3] = "${mandir}/man3/crypt.3"
|
||||
|
||||
79
meta/recipes-extended/wget/wget/CVE-2024-38428.patch
Normal file
79
meta/recipes-extended/wget/wget/CVE-2024-38428.patch
Normal file
@@ -0,0 +1,79 @@
|
||||
From ed0c7c7e0e8f7298352646b2fd6e06a11e242ace Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tim=20R=C3=BChsen?= <tim.ruehsen@gmx.de>
|
||||
Date: Sun, 2 Jun 2024 12:40:16 +0200
|
||||
Subject: Properly re-implement userinfo parsing (rfc2396)
|
||||
|
||||
* src/url.c (url_skip_credentials): Properly re-implement userinfo parsing (rfc2396)
|
||||
|
||||
The reason why the implementation is based on RFC 2396, an outdated standard,
|
||||
is that the whole file is based on that RFC, and mixing standard here might be
|
||||
dangerous.
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/wget.git/commit/?id=ed0c7c7e0e8f7298352646b2fd6e06a11e242ace]
|
||||
CVE: CVE-2024-38428
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/url.c | 40 ++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 34 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/url.c b/src/url.c
|
||||
index 69e948b..07c3bc8 100644
|
||||
--- a/src/url.c
|
||||
+++ b/src/url.c
|
||||
@@ -41,6 +41,7 @@ as that of the covered work. */
|
||||
#include "url.h"
|
||||
#include "host.h" /* for is_valid_ipv6_address */
|
||||
#include "c-strcase.h"
|
||||
+#include "c-ctype.h"
|
||||
|
||||
#ifdef HAVE_ICONV
|
||||
# include <iconv.h>
|
||||
@@ -526,12 +527,39 @@ scheme_leading_string (enum url_scheme scheme)
|
||||
static const char *
|
||||
url_skip_credentials (const char *url)
|
||||
{
|
||||
- /* Look for '@' that comes before terminators, such as '/', '?',
|
||||
- '#', or ';'. */
|
||||
- const char *p = (const char *)strpbrk (url, "@/?#;");
|
||||
- if (!p || *p != '@')
|
||||
- return url;
|
||||
- return p + 1;
|
||||
+ /*
|
||||
+ * This whole file implements https://www.rfc-editor.org/rfc/rfc2396 .
|
||||
+ * RFC 2396 is outdated since 2005 and needs a rewrite or a thorough re-visit.
|
||||
+ *
|
||||
+ * The RFC says
|
||||
+ * server = [ [ userinfo "@" ] hostport ]
|
||||
+ * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" | "+" | "$" | "," )
|
||||
+ * unreserved = alphanum | mark
|
||||
+ * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
|
||||
+ */
|
||||
+ static const char *allowed = "-_.!~*'();:&=+$,";
|
||||
+
|
||||
+ for (const char *p = url; *p; p++)
|
||||
+ {
|
||||
+ if (c_isalnum(*p))
|
||||
+ continue;
|
||||
+
|
||||
+ if (strchr(allowed, *p))
|
||||
+ continue;
|
||||
+
|
||||
+ if (*p == '%' && c_isxdigit(p[1]) && c_isxdigit(p[2]))
|
||||
+ {
|
||||
+ p += 2;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (*p == '@')
|
||||
+ return p + 1;
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return url;
|
||||
}
|
||||
|
||||
/* Parse credentials contained in [BEG, END). The region is expected
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
SRC_URI = "${GNU_MIRROR}/wget/wget-${PV}.tar.gz \
|
||||
file://0002-improve-reproducibility.patch \
|
||||
file://CVE-2024-38428.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "81542f5cefb8faacc39bbbc6c82ded80e3e4a88505ae72ea51df27525bcde04c"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user