mirror of
https://git.yoctoproject.org/poky
synced 2026-02-22 09:29:40 +01:00
Compare commits
78 Commits
kirkstone-
...
kirkstone-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bd3969d32 | ||
|
|
75ff26ce99 | ||
|
|
be9285cbd9 | ||
|
|
945b58b5ba | ||
|
|
b5381de5ba | ||
|
|
979f68bad0 | ||
|
|
9170d3f0f3 | ||
|
|
14065a801b | ||
|
|
6635675a68 | ||
|
|
cbac0f1bfc | ||
|
|
7c5fc9fedc | ||
|
|
af50c9154c | ||
|
|
940a24ab8b | ||
|
|
14fe1f1319 | ||
|
|
52f1435174 | ||
|
|
064e000b18 | ||
|
|
e2366b9d09 | ||
|
|
f27a1997b6 | ||
|
|
35a517b7bd | ||
|
|
4374c6dfab | ||
|
|
e139e9d0ce | ||
|
|
4cf40d4608 | ||
|
|
d08e8d726d | ||
|
|
ec87d3ca28 | ||
|
|
b0b5da10e1 | ||
|
|
2db6158ba5 | ||
|
|
c44a4b4958 | ||
|
|
acf74d7113 | ||
|
|
f60be736e6 | ||
|
|
db3cb6f113 | ||
|
|
95d2f8cf15 | ||
|
|
96242e3146 | ||
|
|
6ae41f83ca | ||
|
|
04b2e68c4f | ||
|
|
8d93dec85f | ||
|
|
22e55c047c | ||
|
|
6d2a4fcdba | ||
|
|
2af7a635be | ||
|
|
e575d02196 | ||
|
|
3b038cab56 | ||
|
|
bb39884146 | ||
|
|
688f3725d2 | ||
|
|
0eea8a2194 | ||
|
|
e0fdd6f40a | ||
|
|
445c60a484 | ||
|
|
9a7f9a95ca | ||
|
|
6169212f74 | ||
|
|
5c841acbab | ||
|
|
8e81c67e12 | ||
|
|
5479d5c70a | ||
|
|
b049cef243 | ||
|
|
894f506635 | ||
|
|
6024b7be01 | ||
|
|
59d099b690 | ||
|
|
e44b0a798e | ||
|
|
de2e7f617e | ||
|
|
c24960e133 | ||
|
|
affef9de9f | ||
|
|
1f9aa7874a | ||
|
|
ea08276b46 | ||
|
|
7bcb5213be | ||
|
|
a871df9e3e | ||
|
|
94ad2c81e0 | ||
|
|
779b489229 | ||
|
|
bd0795ed5a | ||
|
|
f90f4e8d92 | ||
|
|
f1ad013a29 | ||
|
|
197002083a | ||
|
|
049e890f7a | ||
|
|
c0acd30703 | ||
|
|
c4612ee606 | ||
|
|
645aff93b3 | ||
|
|
88287ba521 | ||
|
|
2b21c6009a | ||
|
|
d7906b39ef | ||
|
|
966777e0a4 | ||
|
|
43b8c2ab9f | ||
|
|
65303b3236 |
@@ -49,20 +49,23 @@ class SkipPackage(SkipRecipe):
|
||||
__mtime_cache = {}
|
||||
def cached_mtime(f):
|
||||
if f not in __mtime_cache:
|
||||
__mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
|
||||
res = os.stat(f)
|
||||
__mtime_cache[f] = (res.st_mtime_ns, res.st_size, res.st_ino)
|
||||
return __mtime_cache[f]
|
||||
|
||||
def cached_mtime_noerror(f):
|
||||
if f not in __mtime_cache:
|
||||
try:
|
||||
__mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
|
||||
res = os.stat(f)
|
||||
__mtime_cache[f] = (res.st_mtime_ns, res.st_size, res.st_ino)
|
||||
except OSError:
|
||||
return 0
|
||||
return __mtime_cache[f]
|
||||
|
||||
def update_mtime(f):
|
||||
try:
|
||||
__mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
|
||||
res = os.stat(f)
|
||||
__mtime_cache[f] = (res.st_mtime_ns, res.st_size, res.st_ino)
|
||||
except OSError:
|
||||
if f in __mtime_cache:
|
||||
del __mtime_cache[f]
|
||||
|
||||
@@ -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", "")
|
||||
|
||||
@@ -4,10 +4,16 @@ Creating Your Own Distribution
|
||||
******************************
|
||||
|
||||
When you build an image using the Yocto Project and do not alter any
|
||||
distribution :term:`Metadata`, you are
|
||||
creating a Poky distribution. If you wish to gain more control over
|
||||
package alternative selections, compile-time options, and other
|
||||
low-level configurations, you can create your own distribution.
|
||||
distribution :term:`Metadata`, you are using the Poky distribution.
|
||||
Poky is explicitly a *reference* distribution for testing and
|
||||
development purposes. It enables most hardware and software features
|
||||
so that they can be tested, but this also means that from a security
|
||||
point of view the attack surface is very large. Additionally, at some
|
||||
point it is likely that you will want to gain more control over package
|
||||
alternative selections, compile-time options, and other low-level
|
||||
configurations. For both of these reasons, if you are using the Yocto
|
||||
Project for production use then you are strongly encouraged to create
|
||||
your own distribution.
|
||||
|
||||
To create your own distribution, the basic steps consist of creating
|
||||
your own distribution layer, creating your own distribution
|
||||
@@ -107,3 +113,23 @@ layer. The following steps provide some more detail:
|
||||
For information on append files, see the
|
||||
":ref:`dev-manual/layers:appending other layers metadata with your layer`"
|
||||
section.
|
||||
|
||||
Copying and modifying the Poky distribution
|
||||
===========================================
|
||||
|
||||
Instead of creating a custom distribution from scratch as per above, you may
|
||||
wish to start your custom distribution configuration by copying the Poky
|
||||
distribution provided within the ``meta-poky`` layer and then modifying it.
|
||||
This is fine, however if you do this you should keep the following in mind:
|
||||
|
||||
- Every reference to Poky needs to be updated in your copy so that it
|
||||
will still apply. This includes override usage within files (e.g. ``:poky``)
|
||||
and in directory names. This is a good opportunity to evaluate each one of
|
||||
these customizations to see if they are needed for your use case.
|
||||
|
||||
- Unless you also intend to use them, the ``poky-tiny``, ``poky-altcfg`` and
|
||||
``poky-bleeding`` variants and any references to them can be removed.
|
||||
|
||||
- More generally, the Poky distribution configuration enables a lot more
|
||||
than you likely need for your production use case. You should evaluate *every*
|
||||
configuration choice made in your copy to determine if it is needed.
|
||||
|
||||
@@ -24,3 +24,5 @@ Release 4.0 (kirkstone)
|
||||
release-notes-4.0.15
|
||||
release-notes-4.0.16
|
||||
release-notes-4.0.17
|
||||
release-notes-4.0.18
|
||||
release-notes-4.0.19
|
||||
|
||||
191
documentation/migration-guides/release-notes-4.0.18.rst
Normal file
191
documentation/migration-guides/release-notes-4.0.18.rst
Normal file
@@ -0,0 +1,191 @@
|
||||
.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
|
||||
|
||||
Release notes for Yocto-4.0.18 (Kirkstone)
|
||||
------------------------------------------
|
||||
|
||||
Security Fixes in Yocto-4.0.18
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- curl: Fix :cve:`2024-2398`
|
||||
- expat: fix :cve:`2023-52426` and :cve:`2024-28757`
|
||||
- libssh2: fix :cve:`2023-48795`
|
||||
- ncurses: Fix :cve:`2023-50495`
|
||||
- nghttp2: Fix :cve:`2024-28182` and :cve:`2023-44487`
|
||||
- openssh: Ignore :cve:`2023-51767`
|
||||
- openssl: Fix :cve:`2024-2511`
|
||||
- perl: Ignore :cve:`2023-47100`
|
||||
- python3-cryptography: Fix :cve:`2024-26130`
|
||||
- python3-urllib3: Fix :cve:`2023-45803`
|
||||
- qemu: Fix :cve:`2023-6683`
|
||||
- ruby: fix :cve_mitre:`2024-27281`
|
||||
- rust: Ignore :cve:`2024-24576`
|
||||
- tiff: Fix :cve:`2023-52356` and :cve:`2023-6277`
|
||||
- xserver-xorg: Fix :cve:`2024-31080` and :cve:`2024-31081`
|
||||
- xwayland: Fix :cve:`2023-6816`, :cve:`2024-0408` and :cve:`2024-0409`
|
||||
|
||||
|
||||
Fixes in Yocto-4.0.18
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- build-appliance-image: Update to kirkstone head revision
|
||||
- common-licenses: Backport missing license
|
||||
- contributor-guide: add notes for tests
|
||||
- contributor-guide: be more specific about meta-* trees
|
||||
- cups: fix typo in :cve:`2023-32360` backport patch
|
||||
- cve-update-nvd2-native: Add an age threshold for incremental update
|
||||
- cve-update-nvd2-native: Fix CVE configuration update
|
||||
- cve-update-nvd2-native: Fix typo in comment
|
||||
- cve-update-nvd2-native: Remove duplicated CVE_CHECK_DB_FILE definition
|
||||
- cve-update-nvd2-native: Remove rejected CVE from database
|
||||
- cve-update-nvd2-native: nvd_request_next: Improve comment
|
||||
- dev-manual: improve descriptions of 'bitbake -S printdiff'
|
||||
- dev-manual: packages: fix capitalization
|
||||
- docs: conf.py: properly escape backslashes for latex_elements
|
||||
- gcc: Backport sanitizer fix for 32-bit ALSR
|
||||
- glibc: Fix subscript typos for get_nscd_addresses
|
||||
- kernel-dev: join mkdir commands with -p
|
||||
- linux-firmware: Upgrade to 20240220
|
||||
- manuals: add initial sphinx-lint support
|
||||
- manuals: add initial stylechecks with Vale
|
||||
- manuals: document VIRTUAL-RUNTIME variables
|
||||
- manuals: fix duplicate "stylecheck" target
|
||||
- manuals: fix incorrect double backticks
|
||||
- manuals: fix trailing spaces
|
||||
- manuals: refer to new yocto-patches mailing list wherever appropriate
|
||||
- manuals: remove tab characters
|
||||
- manuals: replace hyphens with em dashes
|
||||
- manuals: use "manual page(s)"
|
||||
- migration-guides: add release notes for 4.0.17
|
||||
- poky.conf: bump version for 4.0.18
|
||||
- profile-manual: usage.rst: fix reference to bug report
|
||||
- profile-manual: usage.rst: formatting fixes
|
||||
- profile-manual: usage.rst: further style improvements
|
||||
- python3-urllib3: Upgrade to v1.26.18
|
||||
- ref-manual: add documentation of the variable :term:`SPDX_NAMESPACE_PREFIX`
|
||||
- ref-manual: tasks: do_cleanall: recommend using '-f' instead
|
||||
- ref-manual: tasks: do_cleansstate: recommend using '-f' instead for a shared sstate
|
||||
- ref-manual: variables: adding multiple groups in :term:`GROUPADD_PARAM`
|
||||
- ref-manual: variables: correct sdk installation default path
|
||||
- stress-ng: avoid calling sync during do_compile
|
||||
- systemd: Fix vlan qos mapping
|
||||
- tcl: Add a way to skip ptests
|
||||
- tcl: skip async and event tests in run-ptest
|
||||
- tcl: skip timing-dependent tests in run-ptest
|
||||
- valgrind: skip intermittently failing ptest
|
||||
- wireless-regdb: Upgrade to 2024.01.23
|
||||
- yocto-uninative: Update to 4.4 for glibc 2.39
|
||||
|
||||
|
||||
Known Issues in Yocto-4.0.18
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- N/A
|
||||
|
||||
|
||||
Contributors to Yocto-4.0.18
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Alex Kiernan
|
||||
- Alex Stewart
|
||||
- Alexander Kanavin
|
||||
- BELOUARGA Mohamed
|
||||
- Claus Stovgaard
|
||||
- Colin McAllister
|
||||
- Geoff Parker
|
||||
- Haitao Liu
|
||||
- Harish Sadineni
|
||||
- Johan Bezem
|
||||
- Jonathan GUILLOT
|
||||
- Jörg Sommer
|
||||
- Khem Raj
|
||||
- Lee Chee Yang
|
||||
- Luca Ceresoli
|
||||
- Martin Jansa
|
||||
- Meenali Gupta
|
||||
- Michael Halstead
|
||||
- Michael Opdenacker
|
||||
- Peter Marko
|
||||
- Quentin Schulz
|
||||
- Ross Burton
|
||||
- Sana Kazi
|
||||
- Simone Weiß
|
||||
- Soumya Sambu
|
||||
- Steve Sakoman
|
||||
- Tan Wen Yan
|
||||
- Vijay Anusuri
|
||||
- Wang Mingyu
|
||||
- Yoann Congal
|
||||
- Yogita Urade
|
||||
- Zahir Hussain
|
||||
|
||||
|
||||
Repositories / Downloads for Yocto-4.0.18
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
poky
|
||||
|
||||
- Repository Location: :yocto_git:`/poky`
|
||||
- Branch: :yocto_git:`kirkstone </poky/log/?h=kirkstone>`
|
||||
- Tag: :yocto_git:`yocto-4.0.18 </poky/log/?h=yocto-4.0.18>`
|
||||
- Git Revision: :yocto_git:`31751bba1c789f15f574773a659b8017d7bcf440 </poky/commit/?id=31751bba1c789f15f574773a659b8017d7bcf440>`
|
||||
- Release Artefact: poky-31751bba1c789f15f574773a659b8017d7bcf440
|
||||
- sha: 72d5aa65c3c37766ebc24b212740272c1d52342468548f9c070241d3522ad2ca
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.18/poky-31751bba1c789f15f574773a659b8017d7bcf440.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.18/poky-31751bba1c789f15f574773a659b8017d7bcf440.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.18 </openembedded-core/log/?h=yocto-4.0.18>`
|
||||
- Git Revision: :oe_git:`b7182571242dc4e23e5250a449d90348e62a6abc </openembedded-core/commit/?id=b7182571242dc4e23e5250a449d90348e62a6abc>`
|
||||
- Release Artefact: oecore-b7182571242dc4e23e5250a449d90348e62a6abc
|
||||
- sha: 6f257e50c10ebae673dcf61a833b3270db6d22781f02f6794a370aac839f1020
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.18/oecore-b7182571242dc4e23e5250a449d90348e62a6abc.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.18/oecore-b7182571242dc4e23e5250a449d90348e62a6abc.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.18 </meta-mingw/log/?h=yocto-4.0.18>`
|
||||
- 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.18/meta-mingw-f6b38ce3c90e1600d41c2ebb41e152936a0357d7.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.18/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.18 </meta-gplv2/log/?h=yocto-4.0.18>`
|
||||
- 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.18/meta-gplv2-d2f8b5cdb285b72a4ed93450f6703ca27aa42e8a.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.18/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.18 </bitbake/log/?h=yocto-4.0.18>`
|
||||
- Git Revision: :oe_git:`40fd5f4eef7460ca67f32cfce8e229e67e1ff607 </bitbake/commit/?id=40fd5f4eef7460ca67f32cfce8e229e67e1ff607>`
|
||||
- Release Artefact: bitbake-40fd5f4eef7460ca67f32cfce8e229e67e1ff607
|
||||
- sha: 5d20a0e4c5d0fce44bd84778168714a261a30a4b83f67c88df3b8a7e7115e444
|
||||
- Download Locations:
|
||||
http://downloads.yoctoproject.org/releases/yocto/yocto-4.0.18/bitbake-40fd5f4eef7460ca67f32cfce8e229e67e1ff607.tar.bz2
|
||||
http://mirrors.kernel.org/yocto/yocto/yocto-4.0.18/bitbake-40fd5f4eef7460ca67f32cfce8e229e67e1ff607.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.18 </yocto-docs/log/?h=yocto-4.0.18>`
|
||||
- Git Revision: :yocto_git:`fd1423141e7458ba557db465c171b0b4e9063987 </yocto-docs/commit/?id=fd1423141e7458ba557db465c171b0b4e9063987>`
|
||||
|
||||
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
@@ -12,19 +12,19 @@ YOCTO_AB_URL : "https://autobuilder.yoctoproject.org"
|
||||
YOCTO_RELEASE_DL_URL : "&YOCTO_DL_URL;/releases/yocto/yocto-&DISTRO;"
|
||||
UBUNTU_HOST_PACKAGES_ESSENTIAL : "gawk wget git diffstat unzip texinfo gcc \
|
||||
build-essential chrpath socat cpio python3 python3-pip python3-pexpect \
|
||||
xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \
|
||||
python3-subunit mesa-common-dev zstd liblz4-tool file locales
|
||||
xz-utils debianutils iputils-ping python3-git python3-jinja2 \
|
||||
python3-subunit zstd liblz4-tool file locales libacl1
|
||||
\n\ $ sudo locale-gen en_US.UTF-8"
|
||||
FEDORA_HOST_PACKAGES_ESSENTIAL : "gawk make wget tar bzip2 gzip python3 unzip perl patch \
|
||||
diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath \
|
||||
ccache perl-Data-Dumper perl-Text-ParseWords perl-Thread-Queue perl-bignum socat \
|
||||
python3-pexpect findutils which file cpio python python3-pip xz python3-GitPython \
|
||||
python3-jinja2 SDL-devel xterm rpcgen mesa-libGL-devel perl-FindBin perl-File-Compare \
|
||||
perl-File-Copy perl-locale zstd lz4"
|
||||
python3-jinja2 rpcgen perl-FindBin perl-File-Compare \
|
||||
perl-File-Copy perl-locale zstd lz4 hostname glibc-langpack-en libacl"
|
||||
OPENSUSE_HOST_PACKAGES_ESSENTIAL : "python gcc gcc-c++ git chrpath make wget python-xml \
|
||||
diffstat makeinfo python-curses patch socat python3 python3-curses tar python3-pip \
|
||||
python3-pexpect xz which python3-Jinja2 Mesa-libEGL1 libSDL-devel rpcgen Mesa-dri-devel \
|
||||
zstd lz4 bzip2 gzip hostname
|
||||
python3-pexpect xz which python3-Jinja2 rpcgen \
|
||||
zstd lz4 bzip2 gzip hostname libacl1
|
||||
\n\ $ sudo pip3 install GitPython"
|
||||
ALMALINUX_HOST_PACKAGES_ESSENTIAL : "-y epel-release
|
||||
\n\ $ sudo yum install dnf-plugins-core
|
||||
@@ -33,8 +33,8 @@ ALMALINUX_HOST_PACKAGES_ESSENTIAL : "-y epel-release
|
||||
\n\ $ sudo dnf install gawk make wget tar bzip2 gzip python3 unzip perl patch \
|
||||
diffutils diffstat git cpp gcc gcc-c++ glibc-devel texinfo chrpath ccache \
|
||||
socat perl-Data-Dumper perl-Text-ParseWords perl-Thread-Queue python3-pip \
|
||||
python3-GitPython python3-jinja2 python3-pexpect xz which SDL-devel xterm \
|
||||
rpcgen mesa-libGL-devel zstd lz4"
|
||||
python3-GitPython python3-jinja2 python3-pexpect xz which \
|
||||
rpcgen zstd lz4 cpio glibc-langpack-en libacl"
|
||||
PIP3_HOST_PACKAGES_DOC : "$ sudo pip3 install sphinx sphinx_rtd_theme pyyaml"
|
||||
MIN_PYTHON_VERSION : "3.6.0"
|
||||
MIN_TAR_VERSION : "1.28"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
width="2040.0006"
|
||||
height="624.30518"
|
||||
viewBox="0 0 2040.0006 624.30515"
|
||||
height="669.30511"
|
||||
viewBox="0 0 2040.0006 669.30509"
|
||||
sodipodi:docname="releases.svg"
|
||||
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
@@ -409,8 +409,8 @@
|
||||
id="namedview4"
|
||||
showgrid="true"
|
||||
inkscape:zoom="1.4472045"
|
||||
inkscape:cx="736.24703"
|
||||
inkscape:cy="312.32629"
|
||||
inkscape:cx="987.76641"
|
||||
inkscape:cy="357.93145"
|
||||
inkscape:window-x="1728"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
@@ -427,13 +427,13 @@
|
||||
type="xygrid"
|
||||
id="grid1257"
|
||||
originx="-289.99936"
|
||||
originy="325" />
|
||||
originy="369.99998" />
|
||||
</sodipodi:namedview>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Image"
|
||||
id="g10"
|
||||
transform="translate(-289.99936,325.00004)">
|
||||
transform="translate(-289.99936,370.00003)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 1080,220.00003 v -515.00007 0 0"
|
||||
@@ -669,11 +669,11 @@
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan10317-2-9-1-4">4.2</tspan></text>
|
||||
<g
|
||||
id="g1379">
|
||||
id="g1258">
|
||||
<rect
|
||||
style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-opacity:1"
|
||||
id="rect917-0-0-4-4-9-4-5-38"
|
||||
width="140.00003"
|
||||
width="120.00002"
|
||||
height="45.000004"
|
||||
x="1220"
|
||||
y="-230.00005"
|
||||
@@ -696,53 +696,76 @@
|
||||
id="tspan10317-2-9-1-4-6">4.3</tspan></text>
|
||||
</g>
|
||||
<rect
|
||||
style="opacity:0.75;fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-opacity:1"
|
||||
id="rect917-0-0-4-4-9-4-5-3-9"
|
||||
width="979.99994"
|
||||
style="opacity:0.75;fill:#241f31;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-opacity:1"
|
||||
id="rect917-0-0-4-4-9-4-5-3-9-2"
|
||||
width="140"
|
||||
height="45.000004"
|
||||
x="1320"
|
||||
y="-285.00003"
|
||||
x="1440"
|
||||
y="-340.00003"
|
||||
ry="2.2558987" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-weight:bold;font-size:13.3333px;line-height:125%;font-family:'Nimbus Roman';-inkscape-font-specification:'Nimbus Roman, Bold';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#fffefe;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="1373.233"
|
||||
y="-265.32928"
|
||||
id="text1185-3-55-4-0-0-0-1-1-6"><tspan
|
||||
x="1487.233"
|
||||
y="-320.32928"
|
||||
id="text1185-3-55-4-0-0-0-1-1-6-4"><tspan
|
||||
sodipodi:role="line"
|
||||
x="1373.233"
|
||||
y="-265.32928"
|
||||
x="1487.233"
|
||||
y="-320.32928"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan957-2-8-6-3-9-7-4-2">Scarthgap</tspan><tspan
|
||||
id="tspan957-2-8-6-3-9-7-4-2-0">Styhead</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="1373.233"
|
||||
y="-247.33261"
|
||||
x="1487.233"
|
||||
y="-302.33261"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan10317-2-9-1-4-6-5">5.0</tspan></text>
|
||||
<rect
|
||||
style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-opacity:1"
|
||||
id="rect917-0-0-4-4-9-9"
|
||||
width="960.00012"
|
||||
height="45.000004"
|
||||
x="859.99994"
|
||||
y="-64.999992"
|
||||
ry="2.2558987" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-weight:bold;font-size:13.3333px;line-height:125%;font-family:'Nimbus Roman';-inkscape-font-specification:'Nimbus Roman, Bold';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#fffefe;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="928.49872"
|
||||
y="-45.648258"
|
||||
id="text1185-3-55-4-0-0-9"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan10317-2-9-1-4-6-5-6">5.1</tspan></text>
|
||||
<g
|
||||
id="g1591">
|
||||
<rect
|
||||
style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-opacity:1"
|
||||
id="rect917-0-0-4-4-9-9"
|
||||
width="960.00012"
|
||||
height="45.000004"
|
||||
x="859.99994"
|
||||
y="-64.999992"
|
||||
ry="2.2558987" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-weight:bold;font-size:13.3333px;line-height:125%;font-family:'Nimbus Roman';-inkscape-font-specification:'Nimbus Roman, Bold';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#fffefe;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="928.49872"
|
||||
y="-45.648258"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan957-2-8-6-3-6">Kirkstone (LTS)</tspan><tspan
|
||||
id="text1185-3-55-4-0-0-9"><tspan
|
||||
sodipodi:role="line"
|
||||
x="928.49872"
|
||||
y="-45.648258"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan957-2-8-6-3-6">Kirkstone (LTS)</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="928.49872"
|
||||
y="-27.651579"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan10317-2-9-0">4.0</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
id="rect917-0-0-4-4-9-9-9"
|
||||
style="fill:#333333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-opacity:1"
|
||||
d="m 1322.3015,-285.00003 c -1.2753,0 -2.302,1.00609 -2.302,2.25586 v 40.48828 c 0,1.24977 1.0267,2.25586 2.302,2.25586 h 975.0412 c 1.2754,0 2.302,-1.00609 2.302,-2.25586 v -40.48828 c 0,-1.24977 -1.0266,-2.25586 -2.302,-2.25586 z" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-weight:bold;font-size:13.3333px;line-height:125%;font-family:'Nimbus Roman';-inkscape-font-specification:'Nimbus Roman, Bold';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#fffefe;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="1390.4988"
|
||||
y="-265.64832"
|
||||
id="text1185-3-55-4-0-0-9-0"><tspan
|
||||
sodipodi:role="line"
|
||||
x="928.49872"
|
||||
y="-27.651579"
|
||||
x="1390.4988"
|
||||
y="-265.64832"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan10317-2-9-0">4.0</tspan></text>
|
||||
id="tspan957-2-8-6-3-6-8">Scarthgap (LTS)</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="1390.4988"
|
||||
y="-247.65164"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.3333px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans Bold';text-align:center;text-anchor:middle;fill:#fffefe;fill-opacity:1;stroke:none"
|
||||
id="tspan10317-2-9-0-1">5.0</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-weight:bold;font-size:13.3333px;line-height:125%;font-family:'Nimbus Roman';-inkscape-font-specification:'Nimbus Roman, Bold';letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;fill:#fffefe;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
|
||||
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 108 KiB |
@@ -3768,7 +3768,7 @@ system and gives an overview of their function and contents.
|
||||
The default value of the variable is set as follows in the
|
||||
``meta/conf/distro/defaultsetup.conf`` file::
|
||||
|
||||
INHERIT_DISTRO ?= "debian devshell sstate license"
|
||||
INHERIT_DISTRO ?= "debian devshell sstate license remove-libtool"
|
||||
|
||||
:term:`INHIBIT_DEFAULT_DEPS`
|
||||
Prevents the default dependencies, namely the C compiler and standard
|
||||
|
||||
@@ -22,7 +22,92 @@ what Wikipedia or the project defining this word uses.
|
||||
|
||||
## Text standards
|
||||
|
||||
This section has not been filled yet
|
||||
### Bulleted lists
|
||||
|
||||
Though Sphinx supports both the ``*`` and ``-`` characters
|
||||
for introducing bulleted lists, we have chosen to use
|
||||
only ``-`` for this purpose.
|
||||
|
||||
Though not strictly required by Sphinx, we have also chosen
|
||||
to use two space characters after ``-`` to introduce each
|
||||
list item:
|
||||
|
||||
- Paragraph 1
|
||||
|
||||
- Paragraph 2
|
||||
|
||||
As shown in the above example, there should also be an empty
|
||||
line between each list item.
|
||||
|
||||
An exception to this rule is when the list items are just made
|
||||
of a few words, instead of entire paragraphs:
|
||||
|
||||
- Item 1
|
||||
- Item 2
|
||||
|
||||
This is again a matter of style, not syntax.
|
||||
|
||||
### Line wrapping
|
||||
|
||||
Source code for the documentation shouldn't have lines
|
||||
wider than 80 characters. This makes patch lines more
|
||||
readable and code easier to quote in e-mail clients.
|
||||
|
||||
If you have to include long commands or lines in configuration
|
||||
files, provided the syntax makes this possible, split them
|
||||
into multiple lines, using the ``\`` character.
|
||||
|
||||
Here is an example:
|
||||
|
||||
$ scripts/install-buildtools \
|
||||
--without-extended-buildtools \
|
||||
--base-url https://downloads.yoctoproject.org/releases/yocto \
|
||||
--release yocto-4.0.1 \
|
||||
--installer-version 4.0.1
|
||||
|
||||
Exceptions are granted for file contents whose lines
|
||||
cannot be split without infringing syntactic rules
|
||||
or reducing readability, as well as for command output
|
||||
which should be kept unmodified.
|
||||
|
||||
### File, tool and command names
|
||||
|
||||
File, tool, command and package names should be double tick-quoted.
|
||||
For example, ``` ``conf/local.conf`` ``` is preferred over
|
||||
`"conf/local.conf"`.
|
||||
|
||||
### Project names
|
||||
|
||||
Project names should be introduced with single quotes, to have them rendered
|
||||
with an italic font and make them easier to distinguish from command names
|
||||
(double tick-quoted) and from regular English words.
|
||||
|
||||
An exception is when project names appear in hyperlinks, as nested markup
|
||||
is not supported by Sphinx yet.
|
||||
|
||||
Project names should also be capitalized (or not) in the same way they are on
|
||||
Wikipedia, or on their own project pages if they are not described on
|
||||
Wikipedia. If a project name isn't capitalized, it should remain so even
|
||||
at the beginning of a sentence.
|
||||
|
||||
For example:
|
||||
|
||||
* ``` `BitBake` ```
|
||||
* ``` `ftrace` ```
|
||||
|
||||
### Variables
|
||||
|
||||
Every variable should be mentioned with:
|
||||
|
||||
:term:`VARIABLE`
|
||||
|
||||
This assumes that `VARIABLE` is described either
|
||||
in the Yocto Project documentation variable index (`ref-manual/variables.rst`)
|
||||
or in the BitBake User Manual
|
||||
(`doc/bitbake-user-manual/bitbake-user-manual-ref-variables.rst`)
|
||||
|
||||
If it is not described yet, the variable should be added to the
|
||||
glossary before or in the same patch it is used, so that `:term:` can be used.
|
||||
|
||||
## ReStructured Text Syntax standards
|
||||
|
||||
@@ -41,8 +126,14 @@ To include a screenshot in PNG format:
|
||||
.. image:: figures/user-configuration.png
|
||||
:align: center
|
||||
|
||||
Depending on the size of the image, you may also shrink it
|
||||
to prevent it from filling the whole page width:
|
||||
A diagram with many details usually needs to use
|
||||
the whole page width to be readable on all media.
|
||||
In this case, the `:align:` directive is unnecessary:
|
||||
|
||||
:scale: 100%
|
||||
|
||||
Conversely, you may also shrink some images to
|
||||
to prevent them from filling the whole page width:
|
||||
|
||||
:scale: 50%
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
DISTRO = "poky"
|
||||
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
|
||||
#DISTRO_VERSION = "3.4+snapshot-${METADATA_REVISION}"
|
||||
DISTRO_VERSION = "4.0.18"
|
||||
DISTRO_VERSION = "4.0.20"
|
||||
DISTRO_CODENAME = "kirkstone"
|
||||
SDK_VENDOR = "-pokysdk"
|
||||
SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${METADATA_REVISION}', 'snapshot')}"
|
||||
|
||||
@@ -18,3 +18,7 @@ inherit go
|
||||
|
||||
GO_WORKDIR ?= "${GO_IMPORT}"
|
||||
do_compile[dirs] += "${B}/src/${GO_WORKDIR}"
|
||||
|
||||
export GOMODCACHE = "${B}/.mod"
|
||||
|
||||
do_compile[cleandirs] += "${B}/.mod"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
inherit goarch
|
||||
inherit linuxloader
|
||||
|
||||
GO_PARALLEL_BUILD ?= "${@oe.utils.parallel_make_argument(d, '-p %d')}"
|
||||
|
||||
@@ -44,7 +45,10 @@ GO_LINKMODE ?= ""
|
||||
GO_LINKMODE:class-nativesdk = "--linkmode=external"
|
||||
GO_LINKMODE:class-native = "--linkmode=external"
|
||||
GO_EXTRA_LDFLAGS ?= ""
|
||||
GO_LDFLAGS ?= '-ldflags="${GO_RPATH} ${GO_LINKMODE} ${GO_EXTRA_LDFLAGS} -extldflags '${GO_EXTLDFLAGS}'"'
|
||||
GO_LINUXLOADER ?= "-I ${@get_linuxloader(d)}"
|
||||
# Use system loader. If uninative is used, the uninative loader will be patched automatically
|
||||
GO_LINUXLOADER:class-native = ""
|
||||
GO_LDFLAGS ?= '-ldflags="${GO_RPATH} ${GO_LINKMODE} ${GO_LINUXLOADER} ${GO_EXTRA_LDFLAGS} -extldflags '${GO_EXTLDFLAGS}'"'
|
||||
export GOBUILDFLAGS ?= "-v ${GO_LDFLAGS} -trimpath"
|
||||
export GOPATH_OMIT_IN_ACTIONID ?= "1"
|
||||
export GOPTESTBUILDFLAGS ?= "${GOBUILDFLAGS} -c"
|
||||
|
||||
@@ -452,7 +452,7 @@ kernel_do_install() {
|
||||
rm -f "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/build"
|
||||
rm -f "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/source"
|
||||
# Remove empty module directories to prevent QA issues
|
||||
find "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel" -type d -empty -delete
|
||||
[ -d "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel" ] && find "${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/kernel" -type d -empty -delete
|
||||
else
|
||||
bbnote "no modules to install"
|
||||
fi
|
||||
|
||||
@@ -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"):
|
||||
|
||||
@@ -119,7 +119,9 @@ read_only_rootfs_hook () {
|
||||
# Also tweak the key location for dropbear in the same way.
|
||||
if [ -d ${IMAGE_ROOTFS}/etc/dropbear ]; then
|
||||
if [ ! -e ${IMAGE_ROOTFS}/etc/dropbear/dropbear_rsa_host_key ]; then
|
||||
echo "DROPBEAR_RSAKEY_DIR=/var/lib/dropbear" >> ${IMAGE_ROOTFS}/etc/default/dropbear
|
||||
if ! grep -q "^DROPBEAR_RSAKEY_DIR=" ${IMAGE_ROOTFS}/etc/default/dropbear ; then
|
||||
echo "DROPBEAR_RSAKEY_DIR=/var/lib/dropbear" >> ${IMAGE_ROOTFS}/etc/default/dropbear
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -55,6 +55,8 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/bluetooth/bluez-${PV}.tar.xz \
|
||||
file://0001-tests-add-a-target-for-building-tests-without-runnin.patch \
|
||||
file://0001-test-gatt-Fix-hung-issue.patch \
|
||||
file://CVE-2023-45866.patch \
|
||||
file://CVE-2023-27349.patch \
|
||||
file://CVE-2023-50229_CVE-2023-50230.patch \
|
||||
"
|
||||
S = "${WORKDIR}/bluez-${PV}"
|
||||
|
||||
|
||||
48
meta/recipes-connectivity/bluez5/bluez5/CVE-2023-27349.patch
Normal file
48
meta/recipes-connectivity/bluez5/bluez5/CVE-2023-27349.patch
Normal file
@@ -0,0 +1,48 @@
|
||||
From f54299a850676d92c3dafd83e9174fcfe420ccc9 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||||
Date: Wed, 22 Mar 2023 11:34:24 -0700
|
||||
Subject: [PATCH] avrcp: Fix crash while handling unsupported events
|
||||
|
||||
The following crash can be observed if the remote peer send and
|
||||
unsupported event:
|
||||
|
||||
ERROR: AddressSanitizer: heap-use-after-free on address 0x60b000148f11
|
||||
at pc 0x559644552088 bp 0x7ffe28b3c7b0 sp 0x7ffe28b3c7a0
|
||||
WRITE of size 1 at 0x60b000148f11 thread T0
|
||||
#0 0x559644552087 in avrcp_handle_event profiles/audio/avrcp.c:3907
|
||||
#1 0x559644536c22 in control_response profiles/audio/avctp.c:939
|
||||
#2 0x5596445379ab in session_cb profiles/audio/avctp.c:1108
|
||||
#3 0x7fbcb3e51c43 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x55c43)
|
||||
#4 0x7fbcb3ea66c7 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xaa6c7)
|
||||
#5 0x7fbcb3e512b2 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x552b2)
|
||||
#6 0x559644754ab6 in mainloop_run src/shared/mainloop-glib.c:66
|
||||
#7 0x559644755606 in mainloop_run_with_signal src/shared/mainloop-notify.c:188
|
||||
#8 0x5596445bb963 in main src/main.c:1289
|
||||
#9 0x7fbcb3bafd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
|
||||
#10 0x7fbcb3bafe3f in __libc_start_main_impl ../csu/libc-start.c:392
|
||||
#11 0x5596444e8224 in _start (/usr/local/libexec/bluetooth/bluetoothd+0xf0224)
|
||||
|
||||
Upstream-Status: Backport [https://github.com/bluez/bluez/commit/f54299a850676d92c3dafd83e9174fcfe420ccc9]
|
||||
CVE: CVE-2023-27349
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
profiles/audio/avrcp.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
|
||||
index 80f34c7a77..dda9a303fb 100644
|
||||
--- a/profiles/audio/avrcp.c
|
||||
+++ b/profiles/audio/avrcp.c
|
||||
@@ -3901,6 +3901,12 @@ static gboolean avrcp_handle_event(struct avctp *conn, uint8_t code,
|
||||
case AVRCP_EVENT_UIDS_CHANGED:
|
||||
avrcp_uids_changed(session, pdu);
|
||||
break;
|
||||
+ default:
|
||||
+ if (event > AVRCP_EVENT_LAST) {
|
||||
+ warn("Unsupported event: %u", event);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
|
||||
session->registered_events |= (1 << event);
|
||||
@@ -0,0 +1,67 @@
|
||||
From 5ab5352531a9cc7058cce569607f3a6831464443 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||||
Date: Tue, 19 Sep 2023 12:14:01 -0700
|
||||
Subject: [PATCH] pbap: Fix not checking Primary/Secundary Counter length
|
||||
|
||||
Primary/Secundary Counters are supposed to be 16 bytes values, if the
|
||||
server has implemented them incorrectly it may lead to the following
|
||||
crash:
|
||||
|
||||
=================================================================
|
||||
==31860==ERROR: AddressSanitizer: heap-buffer-overflow on address
|
||||
0x607000001878 at pc 0x7f95a1575638 bp 0x7fff58c6bb80 sp 0x7fff58c6b328
|
||||
|
||||
READ of size 48 at 0x607000001878 thread T0
|
||||
#0 0x7f95a1575637 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long) ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:860
|
||||
#1 0x7f95a1575ba6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:892
|
||||
#2 0x7f95a1575ba6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:887
|
||||
#3 0x564df69c77a0 in read_version obexd/client/pbap.c:288
|
||||
#4 0x564df69c77a0 in read_return_apparam obexd/client/pbap.c:352
|
||||
#5 0x564df69c77a0 in phonebook_size_callback obexd/client/pbap.c:374
|
||||
#6 0x564df69bea3c in session_terminate_transfer obexd/client/session.c:921
|
||||
#7 0x564df69d56b0 in get_xfer_progress_first obexd/client/transfer.c:729
|
||||
#8 0x564df698b9ee in handle_response gobex/gobex.c:1140
|
||||
#9 0x564df698cdea in incoming_data gobex/gobex.c:1385
|
||||
#10 0x7f95a12fdc43 in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x55c43)
|
||||
#11 0x7f95a13526c7 (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0xaa6c7)
|
||||
#12 0x7f95a12fd2b2 in g_main_loop_run (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x552b2)
|
||||
#13 0x564df6977d41 in main obexd/src/main.c:307
|
||||
#14 0x7f95a10a7d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
|
||||
#15 0x7f95a10a7e3f in __libc_start_main_impl ../csu/libc-start.c:392
|
||||
#16 0x564df6978704 in _start (/usr/local/libexec/bluetooth/obexd+0x8b704)
|
||||
0x607000001878 is located 0 bytes to the right of 72-byte region [0x607000001830,0x607000001878)
|
||||
|
||||
allocated by thread T0 here:
|
||||
#0 0x7f95a1595a37 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
|
||||
#1 0x564df69c8b6a in pbap_probe obexd/client/pbap.c:1259
|
||||
|
||||
Upstream-Status: Backport [https://github.com/bluez/bluez/commit/5ab5352531a9cc7058cce569607f3a6831464443]
|
||||
CVE: CVE-2023-50229 CVE-2023-50230
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
obexd/client/pbap.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/obexd/client/pbap.c b/obexd/client/pbap.c
|
||||
index 1ed8c68ecc..2d2aa95089 100644
|
||||
--- a/obexd/client/pbap.c
|
||||
+++ b/obexd/client/pbap.c
|
||||
@@ -285,7 +285,7 @@ static void read_version(struct pbap_data *pbap, GObexApparam *apparam)
|
||||
data = value;
|
||||
}
|
||||
|
||||
- if (memcmp(pbap->primary, data, len)) {
|
||||
+ if (len == sizeof(pbap->primary) && memcmp(pbap->primary, data, len)) {
|
||||
memcpy(pbap->primary, data, len);
|
||||
g_dbus_emit_property_changed(conn,
|
||||
obc_session_get_path(pbap->session),
|
||||
@@ -299,7 +299,8 @@ static void read_version(struct pbap_data *pbap, GObexApparam *apparam)
|
||||
data = value;
|
||||
}
|
||||
|
||||
- if (memcmp(pbap->secondary, data, len)) {
|
||||
+ if (len == sizeof(pbap->secondary) &&
|
||||
+ memcmp(pbap->secondary, data, len)) {
|
||||
memcpy(pbap->secondary, data, len);
|
||||
g_dbus_emit_property_changed(conn,
|
||||
obc_session_get_path(pbap->session),
|
||||
32
meta/recipes-connectivity/ofono/ofono/CVE-2023-4233.patch
Normal file
32
meta/recipes-connectivity/ofono/ofono/CVE-2023-4233.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From 1a5fbefa59465bec80425add562bdb1d36ec8e23 Mon Sep 17 00:00:00 2001
|
||||
From: Denis Grigorev <d.grigorev@omp.ru>
|
||||
Date: Fri, 29 Dec 2023 13:30:04 +0300
|
||||
Subject: [PATCH] smsutil: Validate the length of the address field
|
||||
|
||||
This addresses CVE-2023-4233.
|
||||
|
||||
CVE: CVE-2023-4233
|
||||
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/network/ofono/ofono.git/commit/?id=1a5fbefa59465bec]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
src/smsutil.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/smsutil.c b/src/smsutil.c
|
||||
index 5a12708..8dd2126 100644
|
||||
--- a/src/smsutil.c
|
||||
+++ b/src/smsutil.c
|
||||
@@ -626,6 +626,9 @@ gboolean sms_decode_address_field(const unsigned char *pdu, int len,
|
||||
|
||||
if (!next_octet(pdu, len, offset, &addr_len))
|
||||
return FALSE;
|
||||
+ /* According to 23.040 9.1.2.5 Address-Length must not exceed 20 */
|
||||
+ if (addr_len > 20)
|
||||
+ return FALSE;
|
||||
|
||||
if (sc && addr_len == 0) {
|
||||
out->address[0] = '\0';
|
||||
--
|
||||
2.40.0
|
||||
39
meta/recipes-connectivity/ofono/ofono/CVE-2023-4234.patch
Normal file
39
meta/recipes-connectivity/ofono/ofono/CVE-2023-4234.patch
Normal file
@@ -0,0 +1,39 @@
|
||||
From 8d74bc66146ea78620d140640a0a57af86fc8936 Mon Sep 17 00:00:00 2001
|
||||
From: Denis Grigorev <d.grigorev@omp.ru>
|
||||
Date: Thu, 21 Dec 2023 17:16:38 +0300
|
||||
Subject: [PATCH] smsutil: Check that submit report fits in memory
|
||||
|
||||
This addresses CVE-2023-4234.
|
||||
|
||||
CVE: CVE-2023-4234.
|
||||
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/network/ofono/ofono.git/commit/?id=8d74bc66146ea786]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
src/smsutil.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/src/smsutil.c b/src/smsutil.c
|
||||
index 8e57a06..5a12708 100644
|
||||
--- a/src/smsutil.c
|
||||
+++ b/src/smsutil.c
|
||||
@@ -938,10 +938,16 @@ static gboolean decode_submit_report(const unsigned char *pdu, int len,
|
||||
return FALSE;
|
||||
|
||||
if (out->type == SMS_TYPE_SUBMIT_REPORT_ERROR) {
|
||||
+ if (expected > (int) sizeof(out->submit_err_report.ud))
|
||||
+ return FALSE;
|
||||
+
|
||||
out->submit_err_report.udl = udl;
|
||||
memcpy(out->submit_err_report.ud,
|
||||
pdu + offset, expected);
|
||||
} else {
|
||||
+ if (expected > (int) sizeof(out->submit_ack_report.ud))
|
||||
+ return FALSE;
|
||||
+
|
||||
out->submit_ack_report.udl = udl;
|
||||
memcpy(out->submit_ack_report.ud,
|
||||
pdu + offset, expected);
|
||||
--
|
||||
2.40.0
|
||||
@@ -12,6 +12,8 @@ SRC_URI = "\
|
||||
file://ofono \
|
||||
file://0001-mbim-add-an-optional-TEMP_FAILURE_RETRY-macro-copy.patch \
|
||||
file://0002-mbim-Fix-build-with-ell-0.39-by-restoring-unlikely-m.patch \
|
||||
file://CVE-2023-4234.patch \
|
||||
file://CVE-2023-4233.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) {
|
||||
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,14 +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-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"
|
||||
@@ -5,7 +5,7 @@ SECTION = "console/network"
|
||||
HOMEPAGE = "http://samba.org/ppp/"
|
||||
BUGTRACKER = "http://ppp.samba.org/cgi-bin/ppp-bugs"
|
||||
DEPENDS = "libpcap openssl virtual/crypt"
|
||||
LICENSE = "BSD-3-Clause & BSD-3-Clause-Attribution & GPL-2.0-or-later & LGPL-2.0-or-later & PD"
|
||||
LICENSE = "BSD-3-Clause & BSD-3-Clause-Attribution & GPL-2.0-or-later & LGPL-2.0-or-later & PD & RSA-MD"
|
||||
LIC_FILES_CHKSUM = "file://pppd/ccp.c;beginline=1;endline=29;md5=e2c43fe6e81ff77d87dc9c290a424dea \
|
||||
file://pppd/plugins/passprompt.c;beginline=1;endline=10;md5=3bcbcdbf0e369c9a3e0b8c8275b065d8 \
|
||||
file://pppd/tdb.c;beginline=1;endline=27;md5=4ca3a9991b011038d085d6675ae7c4e6 \
|
||||
|
||||
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 ?= "c84018a05aec80f5ee6f682db0da1130b0196aef"
|
||||
SRCREV_glibc ?= "72abffe225485d10ea76adde963c13157bf3b310"
|
||||
SRCREV_localedef ?= "794da69788cbf9bf57b59a852f9f11307663fa87"
|
||||
|
||||
GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git"
|
||||
|
||||
@@ -11,16 +11,15 @@ Upstream-Status: Inappropriate [ OE-Specific ]
|
||||
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
---
|
||||
sysdeps/aarch64/bits/wordsize.h | 8 ++++++--
|
||||
sysdeps/{aarch64 => arm}/bits/wordsize.h | 10 +++++++---
|
||||
2 files changed, 13 insertions(+), 5 deletions(-)
|
||||
copy sysdeps/{aarch64 => arm}/bits/wordsize.h (80%)
|
||||
sysdeps/aarch64/bits/wordsize.h | 11 +++++++++--
|
||||
sysdeps/arm/bits/wordsize.h | 16 +++++++++++++++-
|
||||
2 files changed, 24 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/sysdeps/aarch64/bits/wordsize.h b/sysdeps/aarch64/bits/wordsize.h
|
||||
index 4635431f0e..5ef0ed21f3 100644
|
||||
index 4635431f0e..1639bcb063 100644
|
||||
--- a/sysdeps/aarch64/bits/wordsize.h
|
||||
+++ b/sysdeps/aarch64/bits/wordsize.h
|
||||
@@ -17,12 +17,16 @@
|
||||
@@ -17,12 +17,19 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
@@ -33,38 +32,47 @@ index 4635431f0e..5ef0ed21f3 100644
|
||||
# define __WORDSIZE32_SIZE_ULONG 1
|
||||
# define __WORDSIZE32_PTRDIFF_LONG 1
|
||||
+#else
|
||||
+# define __WORDSIZE 32
|
||||
+# define __WORDSIZE32_SIZE_ULONG 0
|
||||
+# define __WORDSIZE32_PTRDIFF_LONG 0
|
||||
+#define __WORDSIZE 32
|
||||
+#define __WORDSIZE_TIME64_COMPAT32 1
|
||||
+#define __WORDSIZE32_SIZE_ULONG 0
|
||||
+#define __WORDSIZE32_PTRDIFF_LONG 0
|
||||
#endif
|
||||
|
||||
+#ifdef __aarch64__
|
||||
#define __WORDSIZE_TIME64_COMPAT32 0
|
||||
diff --git a/sysdeps/aarch64/bits/wordsize.h b/sysdeps/arm/bits/wordsize.h
|
||||
similarity index 80%
|
||||
copy from sysdeps/aarch64/bits/wordsize.h
|
||||
copy to sysdeps/arm/bits/wordsize.h
|
||||
index 4635431f0e..34fcdef1f1 100644
|
||||
--- a/sysdeps/aarch64/bits/wordsize.h
|
||||
+#endif
|
||||
diff --git a/sysdeps/arm/bits/wordsize.h b/sysdeps/arm/bits/wordsize.h
|
||||
index 6ecbfe7c86..1639bcb063 100644
|
||||
--- a/sysdeps/arm/bits/wordsize.h
|
||||
+++ b/sysdeps/arm/bits/wordsize.h
|
||||
@@ -17,12 +17,16 @@
|
||||
@@ -1,4 +1,6 @@
|
||||
-/* Copyright (C) 1999-2024 Free Software Foundation, Inc.
|
||||
+/* Determine the wordsize from the preprocessor defines.
|
||||
+
|
||||
+ Copyright (C) 2016-2022 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@@ -15,7 +17,19 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
-#ifdef __LP64__
|
||||
+#if defined (__aarch64__) && defined (__LP64__)
|
||||
# define __WORDSIZE 64
|
||||
-#else
|
||||
+# define __WORDSIZE 64
|
||||
+#elif defined (__aarch64__)
|
||||
# define __WORDSIZE 32
|
||||
# define __WORDSIZE32_SIZE_ULONG 1
|
||||
# define __WORDSIZE32_PTRDIFF_LONG 1
|
||||
+#else
|
||||
+# define __WORDSIZE 32
|
||||
+# define __WORDSIZE32_SIZE_ULONG 0
|
||||
+# define __WORDSIZE32_PTRDIFF_LONG 0
|
||||
#endif
|
||||
|
||||
#define __WORDSIZE_TIME64_COMPAT32 0
|
||||
+# define __WORDSIZE32_SIZE_ULONG 1
|
||||
+# define __WORDSIZE32_PTRDIFF_LONG 1
|
||||
+#else
|
||||
#define __WORDSIZE 32
|
||||
#define __WORDSIZE_TIME64_COMPAT32 1
|
||||
#define __WORDSIZE32_SIZE_ULONG 0
|
||||
#define __WORDSIZE32_PTRDIFF_LONG 0
|
||||
+#endif
|
||||
+
|
||||
+#ifdef __aarch64__
|
||||
+#define __WORDSIZE_TIME64_COMPAT32 0
|
||||
+#endif
|
||||
--
|
||||
2.34.1
|
||||
|
||||
|
||||
@@ -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,10 @@ CVE_CHECK_IGNORE += "CVE-2019-1010025"
|
||||
CVE_CHECK_IGNORE += "CVE-2023-4527"
|
||||
|
||||
# To avoid these in cve-check reports since the recipe version did not change
|
||||
CVE_CHECK_IGNORE += "CVE-2023-0687 CVE-2023-4813 CVE-2023-4806 CVE-2023-4911 CVE-2023-5156"
|
||||
CVE_CHECK_IGNORE += " \
|
||||
CVE-2023-0687 CVE-2023-4813 CVE-2023-4806 CVE-2023-4911 CVE-2023-5156 \
|
||||
CVE-2024-2961 CVE-2024-33599 CVE-2024-33600 CVE-2024-33601 CVE-2024-33602 \
|
||||
"
|
||||
|
||||
DEPENDS += "gperf-native bison-native"
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ IMAGE_FSTYPES = "wic.vmdk wic.vhd wic.vhdx"
|
||||
|
||||
inherit core-image setuptools3
|
||||
|
||||
SRCREV ?= "700eac59a68baaba3361ed40ab14fe55e66f8211"
|
||||
SRCREV ?= "75ff26ce9921dd4cb579274bb30f97bad502ba34"
|
||||
SRC_URI = "git://git.yoctoproject.org/poky;branch=kirkstone \
|
||||
file://Yocto_Build_Appliance.vmx \
|
||||
file://Yocto_Build_Appliance.vmxf \
|
||||
|
||||
@@ -37,9 +37,9 @@ if [ "$1" = "start" ] ; then
|
||||
mkdir -p /var/volatile/.lib-work
|
||||
# Try to mount using overlay, which is much faster than copying
|
||||
# files. If that fails, fallback to the slower copy
|
||||
if ! mount -t overlay overlay -olowerdir=/var/lib,upperdir=/var/volatile/lib,workdir=/var/volatile/.lib-work /var/lib > /dev/null 2>&1; then
|
||||
if ! mount -t overlay overlay SED_VARLIBMOUNTARGS -olowerdir=/var/lib,upperdir=/var/volatile/lib,workdir=/var/volatile/.lib-work /var/lib > /dev/null 2>&1; then
|
||||
cp -a /var/lib/* /var/volatile/lib
|
||||
mount --bind /var/volatile/lib /var/lib
|
||||
mount SED_VARLIBMOUNTARGS --bind /var/volatile/lib /var/lib
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -59,10 +59,12 @@ FILES:${PN}-functions = "${sysconfdir}/init.d/functions*"
|
||||
FILES:${PN}-sushell = "${base_sbindir}/sushell"
|
||||
|
||||
HALTARGS ?= "-d -f"
|
||||
VARLIBMOUNTARGS ?= ""
|
||||
|
||||
do_configure() {
|
||||
sed -i -e "s:SED_HALTARGS:${HALTARGS}:g" ${WORKDIR}/halt
|
||||
sed -i -e "s:SED_HALTARGS:${HALTARGS}:g" ${WORKDIR}/reboot
|
||||
sed -i -e "s:SED_VARLIBMOUNTARGS:${VARLIBMOUNTARGS}:g" ${WORKDIR}/read-only-rootfs-hook.sh
|
||||
}
|
||||
|
||||
do_install () {
|
||||
|
||||
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"
|
||||
|
||||
180
meta/recipes-core/ncurses/files/CVE-2023-45918.patch
Normal file
180
meta/recipes-core/ncurses/files/CVE-2023-45918.patch
Normal file
@@ -0,0 +1,180 @@
|
||||
From bcf02d3242f1c7d57224a95f7903fcf4b5e7695d Mon Sep 17 00:00:00 2001
|
||||
From: Thomas E. Dickey <dickey@invisible-island.net>
|
||||
Date: Fri, 16 Jun 2023 02:54:29 +0530
|
||||
Subject: [PATCH] Fix CVE-2023-45918
|
||||
|
||||
CVE: CVE-2023-45918
|
||||
|
||||
Upstream-Status: Backport [https://ncurses.scripts.mit.edu/?p=ncurses.git;a=commit;h=bcf02d3242f1c7d57224a95f7903fcf4b5e7695d]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
ncurses/tinfo/comp_error.c | 15 ++++++---
|
||||
ncurses/tinfo/read_entry.c | 65 ++++++++++++++++++++++++++------------
|
||||
2 files changed, 56 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/ncurses/tinfo/comp_error.c b/ncurses/tinfo/comp_error.c
|
||||
index 48f48784..ee518e28 100644
|
||||
--- a/ncurses/tinfo/comp_error.c
|
||||
+++ b/ncurses/tinfo/comp_error.c
|
||||
@@ -60,8 +60,15 @@ _nc_get_source(void)
|
||||
NCURSES_EXPORT(void)
|
||||
_nc_set_source(const char *const name)
|
||||
{
|
||||
- FreeIfNeeded(SourceName);
|
||||
- SourceName = strdup(name);
|
||||
+ if (name == NULL) {
|
||||
+ free(SourceName);
|
||||
+ SourceName = NULL;
|
||||
+ } else if (SourceName == NULL) {
|
||||
+ SourceName = strdup(name);
|
||||
+ } else if (strcmp(name, SourceName)) {
|
||||
+ free(SourceName);
|
||||
+ SourceName = strdup(name);
|
||||
+ }
|
||||
}
|
||||
|
||||
NCURSES_EXPORT(void)
|
||||
@@ -95,9 +102,9 @@ static NCURSES_INLINE void
|
||||
where_is_problem(void)
|
||||
{
|
||||
fprintf(stderr, "\"%s\"", SourceName ? SourceName : "?");
|
||||
- if (_nc_curr_line >= 0)
|
||||
+ if (_nc_curr_line > 0)
|
||||
fprintf(stderr, ", line %d", _nc_curr_line);
|
||||
- if (_nc_curr_col >= 0)
|
||||
+ if (_nc_curr_col > 0)
|
||||
fprintf(stderr, ", col %d", _nc_curr_col);
|
||||
if (TermType != 0 && TermType[0] != '\0')
|
||||
fprintf(stderr, ", terminal '%s'", TermType);
|
||||
diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c
|
||||
index 8ccb1570..101bbe09 100644
|
||||
--- a/ncurses/tinfo/read_entry.c
|
||||
+++ b/ncurses/tinfo/read_entry.c
|
||||
@@ -140,12 +140,13 @@ convert_16bits(char *buf, NCURSES_INT2 *Numbers, int count)
|
||||
}
|
||||
#endif
|
||||
|
||||
-static void
|
||||
-convert_strings(char *buf, char **Strings, int count, int size, char *table)
|
||||
+static bool
|
||||
+convert_strings(char *buf, char **Strings, int count, int size,
|
||||
+ char *table, bool always)
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
- bool corrupt = FALSE;
|
||||
+ bool success = TRUE;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (IS_NEG1(buf + 2 * i)) {
|
||||
@@ -161,13 +162,10 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table)
|
||||
TR(TRACE_DATABASE, ("Strings[%d] = %s", i,
|
||||
_nc_visbuf(Strings[i])));
|
||||
} else {
|
||||
- if (!corrupt) {
|
||||
- corrupt = TRUE;
|
||||
- TR(TRACE_DATABASE,
|
||||
- ("ignore out-of-range index %d to Strings[]", nn));
|
||||
- _nc_warning("corrupt data found in convert_strings");
|
||||
- }
|
||||
- Strings[i] = ABSENT_STRING;
|
||||
+ TR(TRACE_DATABASE,
|
||||
+ ("found out-of-range index %d to Strings[%d]", nn, i));
|
||||
+ success = FALSE;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,10 +175,25 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table)
|
||||
if (*p == '\0')
|
||||
break;
|
||||
/* if there is no NUL, ignore the string */
|
||||
- if (p >= table + size)
|
||||
+ if (p >= table + size) {
|
||||
Strings[i] = ABSENT_STRING;
|
||||
+ } else if (p == Strings[i] && always) {
|
||||
+ TR(TRACE_DATABASE,
|
||||
+ ("found empty but required Strings[%d]", i));
|
||||
+ success = FALSE;
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (always) { /* names are always needed */
|
||||
+ TR(TRACE_DATABASE,
|
||||
+ ("found invalid but required Strings[%d]", i));
|
||||
+ success = FALSE;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
+ if (!success) {
|
||||
+ _nc_warning("corrupt data found in convert_strings");
|
||||
+ }
|
||||
+ return success;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -383,7 +396,10 @@ _nc_read_termtype(TERMTYPE2 *ptr, char *buffer, int limit)
|
||||
if (Read(string_table, (unsigned) str_size) != str_size) {
|
||||
returnDB(TGETENT_NO);
|
||||
}
|
||||
- convert_strings(buf, ptr->Strings, str_count, str_size, string_table);
|
||||
+ if (!convert_strings(buf, ptr->Strings, str_count, str_size,
|
||||
+ string_table, FALSE)) {
|
||||
+ returnDB(TGETENT_NO);
|
||||
+ }
|
||||
}
|
||||
#if NCURSES_XNAMES
|
||||
|
||||
@@ -484,8 +500,10 @@ _nc_read_termtype(TERMTYPE2 *ptr, char *buffer, int limit)
|
||||
("Before computing extended-string capabilities "
|
||||
"str_count=%d, ext_str_count=%d",
|
||||
str_count, ext_str_count));
|
||||
- convert_strings(buf, ptr->Strings + str_count, ext_str_count,
|
||||
- ext_str_limit, ptr->ext_str_table);
|
||||
+ if (!convert_strings(buf, ptr->Strings + str_count, ext_str_count,
|
||||
+ ext_str_limit, ptr->ext_str_table, FALSE)) {
|
||||
+ returnDB(TGETENT_NO);
|
||||
+ }
|
||||
for (i = ext_str_count - 1; i >= 0; i--) {
|
||||
TR(TRACE_DATABASE, ("MOVE from [%d:%d] %s",
|
||||
i, i + str_count,
|
||||
@@ -519,10 +537,13 @@ _nc_read_termtype(TERMTYPE2 *ptr, char *buffer, int limit)
|
||||
TR(TRACE_DATABASE,
|
||||
("ext_NAMES starting @%d in extended_strings, first = %s",
|
||||
base, _nc_visbuf(ptr->ext_str_table + base)));
|
||||
- convert_strings(buf + (2 * ext_str_count),
|
||||
- ptr->ext_Names,
|
||||
- (int) need,
|
||||
- ext_str_limit, ptr->ext_str_table + base);
|
||||
+ if (!convert_strings(buf + (2 * ext_str_count),
|
||||
+ ptr->ext_Names,
|
||||
+ (int) need,
|
||||
+ ext_str_limit, ptr->ext_str_table + base,
|
||||
+ TRUE)) {
|
||||
+ returnDB(TGETENT_NO);
|
||||
+ }
|
||||
}
|
||||
|
||||
TR(TRACE_DATABASE,
|
||||
@@ -575,13 +596,17 @@ _nc_read_file_entry(const char *const filename, TERMTYPE2 *ptr)
|
||||
int limit;
|
||||
char buffer[MAX_ENTRY_SIZE + 1];
|
||||
|
||||
- if ((limit = (int) fread(buffer, sizeof(char), sizeof(buffer), fp))
|
||||
- > 0) {
|
||||
+ limit = (int) fread(buffer, sizeof(char), sizeof(buffer), fp);
|
||||
+ if (limit > 0) {
|
||||
+ const char *old_source = _nc_get_source();
|
||||
|
||||
TR(TRACE_DATABASE, ("read terminfo %s", filename));
|
||||
+ if (old_source == NULL)
|
||||
+ _nc_set_source(filename);
|
||||
if ((code = _nc_read_termtype(ptr, buffer, limit)) == TGETENT_NO) {
|
||||
_nc_free_termtype2(ptr);
|
||||
}
|
||||
+ _nc_set_source(old_source);
|
||||
} else {
|
||||
code = TGETENT_NO;
|
||||
}
|
||||
--
|
||||
2.40.0
|
||||
@@ -5,6 +5,7 @@ SRC_URI += "file://0001-tic-hang.patch \
|
||||
file://0003-gen-pkgconfig.in-Do-not-include-LDFLAGS-in-generated.patch \
|
||||
file://CVE-2023-29491.patch \
|
||||
file://CVE-2023-50495.patch \
|
||||
file://CVE-2023-45918.patch \
|
||||
"
|
||||
# commit id corresponds to the revision in package version
|
||||
SRCREV = "a0bc708bc6954b5d3c0a38d92b683c3ec3135260"
|
||||
|
||||
@@ -26,6 +26,9 @@ locations = list()
|
||||
|
||||
class SystemdFile():
|
||||
"""Class representing a single systemd configuration file"""
|
||||
|
||||
_clearable_keys = ['WantedBy']
|
||||
|
||||
def __init__(self, root, path, instance_unit_name):
|
||||
self.sections = dict()
|
||||
self._parse(root, path)
|
||||
@@ -80,6 +83,14 @@ class SystemdFile():
|
||||
v = m.group('value')
|
||||
if k not in section:
|
||||
section[k] = list()
|
||||
|
||||
# If we come across a "key=" line for a "clearable key", then
|
||||
# forget all preceding assignments. This works because we are
|
||||
# processing files in correct parse order.
|
||||
if k in self._clearable_keys and not v:
|
||||
del section[k]
|
||||
continue
|
||||
|
||||
section[k].extend(v.split())
|
||||
|
||||
def get(self, section, prop):
|
||||
|
||||
@@ -35,6 +35,11 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/utils/util-linux/v${MAJOR_VERSION}/util-lin
|
||||
file://run-ptest \
|
||||
file://display_testname_for_subtest.patch \
|
||||
file://avoid_parallel_tests.patch \
|
||||
file://CVE-2024-28085-0001.patch \
|
||||
file://CVE-2024-28085-0002.patch \
|
||||
file://CVE-2024-28085-0003.patch \
|
||||
file://CVE-2024-28085-0004.patch \
|
||||
file://CVE-2024-28085-0005.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "634e6916ad913366c3536b6468e7844769549b99a7b2bf80314de78ab5655b83"
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
From 8a7b8456d1dc0e7ca557d1ac31f638986704757f Mon Sep 17 00:00:00 2001
|
||||
From: наб <nabijaczleweli@nabijaczleweli.xyz>
|
||||
Date: Wed Mar 15 16:16:31 2023 +0100
|
||||
Subject: [PATCH] write: correctly handle wide characters
|
||||
|
||||
Do this by replacing fputc_careful() (notice that the description said
|
||||
it's locale-aware ‒ it very much is /not/), with a fputs_careful() which
|
||||
does the same thing, but if it were to output a byte in the \123 format,
|
||||
first it checks whether this byte starts a valid multibyte character.
|
||||
|
||||
If it does, and that character is printable, write it verbatim.
|
||||
This means that
|
||||
echo 'foo åäö ąęćźżń bar' | write nabijaczleweli pts/4
|
||||
instead of
|
||||
foo \303\245\303\244\303\266
|
||||
\304\205\304\231\304\207\305\272\305\274\305\204 bar
|
||||
yields
|
||||
foo åäö ąęćźżń bar
|
||||
or, more realistically, from a message I got earlier today,
|
||||
Filip powiedzia\305\202 \305\274e zap\305\202aci jutro
|
||||
becomes
|
||||
Filip powiedział że zapłaci jutro
|
||||
|
||||
Invalid/non-printable sequences get processed as before.
|
||||
|
||||
Line reading in write must become getline() to avoid dealing with
|
||||
partial characters: for example on input consisting solely of
|
||||
ąęćźżń, where every {1} is an instance, the output would be
|
||||
{42}ąęć\305\272żń{84}ąęćź\305\274ń{84}ąęćźż\305\204{39}
|
||||
with just fixed-512 fgets()
|
||||
|
||||
Bug-Debian: https://bugs.debian.org/826596
|
||||
|
||||
CVE: CVE-2024-28085
|
||||
|
||||
Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/8a7b8456d1dc0e7ca557d1ac31f638986704757f]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
include/carefulputc.h | 62 +++++++++++++++++++++++++++++++------------
|
||||
login-utils/last.c | 4 +--
|
||||
term-utils/write.c | 25 +++++------------
|
||||
3 files changed, 53 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/include/carefulputc.h b/include/carefulputc.h
|
||||
index 66a0f15..2506614 100644
|
||||
--- a/include/carefulputc.h
|
||||
+++ b/include/carefulputc.h
|
||||
@@ -1,31 +1,59 @@
|
||||
#ifndef UTIL_LINUX_CAREFULPUTC_H
|
||||
#define UTIL_LINUX_CAREFULPUTC_H
|
||||
|
||||
-/*
|
||||
- * A putc() for use in write and wall (that sometimes are sgid tty).
|
||||
- * It avoids control characters in our locale, and also ASCII control
|
||||
- * characters. Note that the locale of the recipient is unknown.
|
||||
-*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
+#ifdef HAVE_WIDECHAR
|
||||
+#include <wctype.h>
|
||||
+#endif
|
||||
+#include <stdbool.h>
|
||||
|
||||
#include "cctype.h"
|
||||
|
||||
-static inline int fputc_careful(int c, FILE *fp, const char fail)
|
||||
+/*
|
||||
+ * A puts() for use in write and wall (that sometimes are sgid tty).
|
||||
+ * It avoids control and invalid characters.
|
||||
+ * The locale of the recipient is nominally unknown,
|
||||
+ * but it's a solid bet that the encoding is compatible with the author's.
|
||||
+ */
|
||||
+static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf)
|
||||
{
|
||||
- int ret;
|
||||
-
|
||||
- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
|
||||
- ret = putc(c, fp);
|
||||
- else if (!c_isascii(c))
|
||||
- ret = fprintf(fp, "\\%3o", (unsigned char)c);
|
||||
- else {
|
||||
- ret = putc(fail, fp);
|
||||
- if (ret != EOF)
|
||||
- ret = putc(c ^ 0x40, fp);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ for (size_t slen = strlen(s); *s; ++s, --slen) {
|
||||
+ if (*s == '\n')
|
||||
+ ret = fputs(cr_lf ? "\r\n" : "\n", fp);
|
||||
+ else if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r')
|
||||
+ ret = putc(*s, fp);
|
||||
+ else if (!c_isascii(*s)) {
|
||||
+#ifdef HAVE_WIDECHAR
|
||||
+ wchar_t w;
|
||||
+ size_t clen = mbtowc(&w, s, slen);
|
||||
+ switch(clen) {
|
||||
+ case (size_t)-2: // incomplete
|
||||
+ case (size_t)-1: // EILSEQ
|
||||
+ mbtowc(NULL, NULL, 0);
|
||||
+ nonprint:
|
||||
+ ret = fprintf(fp, "\\%3hho", *s);
|
||||
+ break;
|
||||
+ default:
|
||||
+ if(!iswprint(w))
|
||||
+ goto nonprint;
|
||||
+ ret = fwrite(s, 1, clen, fp);
|
||||
+ s += clen - 1;
|
||||
+ slen -= clen - 1;
|
||||
+ break;
|
||||
+ }
|
||||
+#else
|
||||
+ ret = fprintf(fp, "\\%3hho", *s);
|
||||
+#endif
|
||||
+ } else
|
||||
+ ret = fputs((char[]){ ctrl, *s ^ 0x40, '\0' }, fp);
|
||||
+ if (ret < 0)
|
||||
+ return EOF;
|
||||
}
|
||||
- return (ret < 0) ? EOF : 0;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static inline void fputs_quoted_case(const char *data, FILE *out, int dir)
|
||||
diff --git a/login-utils/last.c b/login-utils/last.c
|
||||
index f3272ca..aacd1f6 100644
|
||||
--- a/login-utils/last.c
|
||||
+++ b/login-utils/last.c
|
||||
@@ -403,7 +403,6 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
|
||||
char final[512];
|
||||
char utline[sizeof(p->ut_line) + 1];
|
||||
char domain[256];
|
||||
- char *s;
|
||||
int mins, hours, days;
|
||||
int r, len;
|
||||
struct last_timefmt *fmt;
|
||||
@@ -559,8 +558,7 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
|
||||
/*
|
||||
* Print out "final" string safely.
|
||||
*/
|
||||
- for (s = final; *s; s++)
|
||||
- fputc_careful(*s, stdout, '*');
|
||||
+ fputs_careful(final, stdout, '*', false);
|
||||
|
||||
if (len < 0 || (size_t)len >= sizeof(final))
|
||||
putchar('\n');
|
||||
diff --git a/term-utils/write.c b/term-utils/write.c
|
||||
index 50f18dc..710a58c 100644
|
||||
--- a/term-utils/write.c
|
||||
+++ b/term-utils/write.c
|
||||
@@ -223,21 +223,6 @@ static void signal_handler(int signo)
|
||||
signal_received = signo;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * write_line - like fputs(), but makes control characters visible and
|
||||
- * turns \n into \r\n.
|
||||
- */
|
||||
-static void write_line(char *s)
|
||||
-{
|
||||
- while (*s) {
|
||||
- const int c = *s++;
|
||||
-
|
||||
- if ((c == '\n' && fputc_careful('\r', stdout, '^') == EOF)
|
||||
- || fputc_careful(c, stdout, '^') == EOF)
|
||||
- err(EXIT_FAILURE, _("carefulputc failed"));
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* do_write - actually make the connection
|
||||
*/
|
||||
@@ -247,7 +232,8 @@ static void do_write(const struct write_control *ctl)
|
||||
struct passwd *pwd;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
- char *host, line[512];
|
||||
+ char *host, *line = NULL;
|
||||
+ size_t linelen = 0;
|
||||
struct sigaction sigact;
|
||||
|
||||
/* Determine our login name(s) before the we reopen() stdout */
|
||||
@@ -286,11 +272,14 @@ static void do_write(const struct write_control *ctl)
|
||||
free(host);
|
||||
printf("\r\n");
|
||||
|
||||
- while (fgets(line, sizeof(line), stdin) != NULL) {
|
||||
+ while (getline(&line, &linelen, stdin) >= 0) {
|
||||
if (signal_received)
|
||||
break;
|
||||
- write_line(line);
|
||||
+
|
||||
+ if (fputs_careful(line, stdout, '^', true) == EOF)
|
||||
+ err(EXIT_FAILURE, _("carefulputc failed"));
|
||||
}
|
||||
+ free(line);
|
||||
printf("EOF\r\n");
|
||||
}
|
||||
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,172 @@
|
||||
From 27ee6446503af7ec0c2647704ca47ac4de3852ef Mon Sep 17 00:00:00 2001
|
||||
From: наб <nabijaczleweli@nabijaczleweli.xyz>
|
||||
Date: Wed, 15 Mar 2023 16:16:43 +0100
|
||||
Subject: [PATCH] wall: convert homebrew buffering to open_memstream()
|
||||
|
||||
The struct buffer system duplicates a plethora of standard I/O
|
||||
functions (including a fork of fputc_careful())
|
||||
and adds a lot of complexity ‒ open_memstream() is standard,
|
||||
and fits perfectly into this niche
|
||||
|
||||
CVE: CVE-2024-28085
|
||||
|
||||
Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/27ee6446503af7ec0c2647704ca47ac4de3852ef]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
term-utils/wall.c | 95 ++++++++++-------------------------------------
|
||||
1 file changed, 20 insertions(+), 75 deletions(-)
|
||||
|
||||
diff --git a/term-utils/wall.c b/term-utils/wall.c
|
||||
index c601d3e..a51a928 100644
|
||||
--- a/term-utils/wall.c
|
||||
+++ b/term-utils/wall.c
|
||||
@@ -274,74 +274,22 @@ int main(int argc, char **argv)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
-struct buffer {
|
||||
- size_t sz;
|
||||
- size_t used;
|
||||
- char *data;
|
||||
-};
|
||||
-
|
||||
-static void buf_enlarge(struct buffer *bs, size_t len)
|
||||
+static void buf_putc_careful(FILE *fs, int c)
|
||||
{
|
||||
- if (bs->sz == 0 || len > bs->sz - bs->used) {
|
||||
- bs->sz += len < 128 ? 128 : len;
|
||||
- bs->data = xrealloc(bs->data, bs->sz);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static void buf_puts(struct buffer *bs, const char *s)
|
||||
-{
|
||||
- size_t len = strlen(s);
|
||||
-
|
||||
- buf_enlarge(bs, len + 1);
|
||||
- memcpy(bs->data + bs->used, s, len + 1);
|
||||
- bs->used += len;
|
||||
-}
|
||||
-
|
||||
-static void __attribute__((__format__ (__printf__, 2, 3)))
|
||||
- buf_printf(struct buffer *bs, const char *fmt, ...)
|
||||
-{
|
||||
- int rc;
|
||||
- va_list ap;
|
||||
- size_t limit;
|
||||
-
|
||||
- buf_enlarge(bs, 0); /* default size */
|
||||
- limit = bs->sz - bs->used;
|
||||
-
|
||||
- va_start(ap, fmt);
|
||||
- rc = vsnprintf(bs->data + bs->used, limit, fmt, ap);
|
||||
- va_end(ap);
|
||||
-
|
||||
- if (rc >= 0 && (size_t) rc >= limit) { /* not enough, enlarge */
|
||||
- buf_enlarge(bs, (size_t)rc + 1);
|
||||
- limit = bs->sz - bs->used;
|
||||
- va_start(ap, fmt);
|
||||
- rc = vsnprintf(bs->data + bs->used, limit, fmt, ap);
|
||||
- va_end(ap);
|
||||
- }
|
||||
-
|
||||
- if (rc > 0)
|
||||
- bs->used += rc;
|
||||
-}
|
||||
-
|
||||
-static void buf_putc_careful(struct buffer *bs, int c)
|
||||
-{
|
||||
- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n') {
|
||||
- buf_enlarge(bs, 1);
|
||||
- bs->data[bs->used++] = c;
|
||||
- } else if (!c_isascii(c))
|
||||
- buf_printf(bs, "\\%3o", (unsigned char)c);
|
||||
- else {
|
||||
- char tmp[] = { '^', c ^ 0x40, '\0' };
|
||||
- buf_puts(bs, tmp);
|
||||
- }
|
||||
+ if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
|
||||
+ fputc(c, fs);
|
||||
+ else if (!c_isascii(c))
|
||||
+ fprintf(fs, "\\%3o", (unsigned char)c);
|
||||
+ else
|
||||
+ fputs((char[]){ '^', c ^ 0x40, '\0' }, fs);
|
||||
}
|
||||
|
||||
static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
size_t *mbufsize, int print_banner)
|
||||
{
|
||||
- struct buffer _bs = {.used = 0}, *bs = &_bs;
|
||||
register int ch, cnt;
|
||||
- char *p, *lbuf;
|
||||
+ char *p, *lbuf, *retbuf;
|
||||
+ FILE * fs = open_memstream(&retbuf, mbufsize);
|
||||
long line_max;
|
||||
|
||||
line_max = sysconf(_SC_LINE_MAX);
|
||||
@@ -379,15 +327,15 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
*/
|
||||
/* snprintf is not always available, but the sprintf's here
|
||||
will not overflow as long as %d takes at most 100 chars */
|
||||
- buf_printf(bs, "\r%*s\r\n", TERM_WIDTH, " ");
|
||||
+ fprintf(fs, "\r%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
snprintf(lbuf, line_max,
|
||||
_("Broadcast message from %s@%s (%s) (%s):"),
|
||||
whom, hostname, where, date);
|
||||
- buf_printf(bs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
|
||||
+ fprintf(fs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
|
||||
free(hostname);
|
||||
}
|
||||
- buf_printf(bs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
+ fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
if (mvec) {
|
||||
/*
|
||||
@@ -396,11 +344,11 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mvecsz; i++) {
|
||||
- buf_puts(bs, mvec[i]);
|
||||
+ fputs(mvec[i], fs);
|
||||
if (i < mvecsz - 1)
|
||||
- buf_puts(bs, " ");
|
||||
+ fputc(' ', fs);
|
||||
}
|
||||
- buf_puts(bs, "\r\n");
|
||||
+ fputs("\r\n", fs);
|
||||
} else {
|
||||
/*
|
||||
* read message from <file>
|
||||
@@ -428,23 +376,20 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
while (fgets(lbuf, line_max, stdin)) {
|
||||
for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
|
||||
if (cnt == TERM_WIDTH || ch == '\n') {
|
||||
- for (; cnt < TERM_WIDTH; ++cnt)
|
||||
- buf_puts(bs, " ");
|
||||
- buf_puts(bs, "\r\n");
|
||||
+ fprintf(fs, "%*s\r\n", TERM_WIDTH - cnt, "");
|
||||
cnt = 0;
|
||||
}
|
||||
if (ch == '\t')
|
||||
cnt += (7 - (cnt % 8));
|
||||
if (ch != '\n')
|
||||
- buf_putc_careful(bs, ch);
|
||||
+ buf_putc_careful(fs, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
- buf_printf(bs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
+ fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
free(lbuf);
|
||||
|
||||
- bs->data[bs->used] = '\0'; /* be paranoid */
|
||||
- *mbufsize = bs->used;
|
||||
- return bs->data;
|
||||
+ fclose(fs);
|
||||
+ return retbuf;
|
||||
}
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,223 @@
|
||||
From aa13246a1bf1be9e4f6eb331f4d4d2dbc875e22f Mon Sep 17 00:00:00 2001
|
||||
From: наб <nabijaczleweli@nabijaczleweli.xyz>
|
||||
Date: Wed, 15 Mar 2023 16:16:48 +0100
|
||||
Subject: [PATCH] wall: use fputs_careful()
|
||||
|
||||
LINE_MAX only applies to teletypes in canonical mode: when stdin is a
|
||||
file, it could still very much tear; start off at 512 for the sprintf(),
|
||||
then use getline() like in write.
|
||||
|
||||
The line wrapping has one suboptimal edge-case:
|
||||
$ wall < all
|
||||
|
||||
Broadcast message from nabijaczleweli@tarta (pts/4) (Tue Mar 14 22:31:25
|
||||
2023):
|
||||
|
||||
^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_
|
||||
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJ
|
||||
KLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~^?\200\201\202\203\204\205\206
|
||||
\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232
|
||||
\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256
|
||||
\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302
|
||||
\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326
|
||||
\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352
|
||||
\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376
|
||||
\377
|
||||
but that's a pathological input, and the result is still infinitely
|
||||
better than it was before, so fixing that is more trouble than it's
|
||||
worth.
|
||||
|
||||
Bug-Debian: https://bugs.debian.org/826596
|
||||
|
||||
CVE: CVE-2024-28085
|
||||
|
||||
Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/aa13246a1bf1be9e4f6eb331f4d4d2dbc875e22f]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
include/carefulputc.h | 42 +++++++++++++++++++++++++++++++++---------
|
||||
login-utils/last.c | 2 +-
|
||||
term-utils/wall.c | 38 ++++++--------------------------------
|
||||
term-utils/write.c | 2 +-
|
||||
4 files changed, 41 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/include/carefulputc.h b/include/carefulputc.h
|
||||
index 2506614..89f8a99 100644
|
||||
--- a/include/carefulputc.h
|
||||
+++ b/include/carefulputc.h
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_WIDECHAR
|
||||
#include <wctype.h>
|
||||
+#include <wchar.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -15,18 +16,35 @@
|
||||
* A puts() for use in write and wall (that sometimes are sgid tty).
|
||||
* It avoids control and invalid characters.
|
||||
* The locale of the recipient is nominally unknown,
|
||||
- * but it's a solid bet that the encoding is compatible with the author's.
|
||||
+ * but it's a solid bet that it's compatible with the author's.
|
||||
+ * Use soft_width=0 to disable wrapping.
|
||||
*/
|
||||
-static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf)
|
||||
+static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool cr_lf, int soft_width)
|
||||
{
|
||||
- int ret = 0;
|
||||
+ int ret = 0, col = 0;
|
||||
|
||||
for (size_t slen = strlen(s); *s; ++s, --slen) {
|
||||
- if (*s == '\n')
|
||||
+ if (*s == '\t')
|
||||
+ col += (7 - (col % 8)) - 1;
|
||||
+ else if (*s == '\r')
|
||||
+ col = -1;
|
||||
+ else if (*s == '\a')
|
||||
+ --col;
|
||||
+
|
||||
+ if ((soft_width && col >= soft_width) || *s == '\n') {
|
||||
+ if (soft_width) {
|
||||
+ fprintf(fp, "%*s", soft_width - col, "");
|
||||
+ col = 0;
|
||||
+ }
|
||||
ret = fputs(cr_lf ? "\r\n" : "\n", fp);
|
||||
- else if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r')
|
||||
+ if (*s == '\n' || ret < 0)
|
||||
+ goto wrote;
|
||||
+ }
|
||||
+
|
||||
+ if (isprint(*s) || *s == '\a' || *s == '\t' || *s == '\r') {
|
||||
ret = putc(*s, fp);
|
||||
- else if (!c_isascii(*s)) {
|
||||
+ ++col;
|
||||
+ } else if (!c_isascii(*s)) {
|
||||
#ifdef HAVE_WIDECHAR
|
||||
wchar_t w;
|
||||
size_t clen = mbtowc(&w, s, slen);
|
||||
@@ -35,21 +53,27 @@ static inline int fputs_careful(const char * s, FILE *fp, const char ctrl, bool
|
||||
case (size_t)-1: // EILSEQ
|
||||
mbtowc(NULL, NULL, 0);
|
||||
nonprint:
|
||||
- ret = fprintf(fp, "\\%3hho", *s);
|
||||
+ col += ret = fprintf(fp, "\\%3hho", *s);
|
||||
break;
|
||||
default:
|
||||
if(!iswprint(w))
|
||||
goto nonprint;
|
||||
ret = fwrite(s, 1, clen, fp);
|
||||
+ if (soft_width)
|
||||
+ col += wcwidth(w);
|
||||
s += clen - 1;
|
||||
slen -= clen - 1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
- ret = fprintf(fp, "\\%3hho", *s);
|
||||
+ col += ret = fprintf(fp, "\\%3hho", *s);
|
||||
#endif
|
||||
- } else
|
||||
+ } else {
|
||||
ret = fputs((char[]){ ctrl, *s ^ 0x40, '\0' }, fp);
|
||||
+ col += 2;
|
||||
+ }
|
||||
+
|
||||
+ wrote:
|
||||
if (ret < 0)
|
||||
return EOF;
|
||||
}
|
||||
diff --git a/login-utils/last.c b/login-utils/last.c
|
||||
index aacd1f6..43c5429 100644
|
||||
--- a/login-utils/last.c
|
||||
+++ b/login-utils/last.c
|
||||
@@ -558,7 +558,7 @@ static int list(const struct last_control *ctl, struct utmpx *p, time_t logout_t
|
||||
/*
|
||||
* Print out "final" string safely.
|
||||
*/
|
||||
- fputs_careful(final, stdout, '*', false);
|
||||
+ fputs_careful(final, stdout, '*', false, 0);
|
||||
|
||||
if (len < 0 || (size_t)len >= sizeof(final))
|
||||
putchar('\n');
|
||||
diff --git a/term-utils/wall.c b/term-utils/wall.c
|
||||
index a51a928..377db45 100644
|
||||
--- a/term-utils/wall.c
|
||||
+++ b/term-utils/wall.c
|
||||
@@ -274,29 +274,13 @@ int main(int argc, char **argv)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
-static void buf_putc_careful(FILE *fs, int c)
|
||||
-{
|
||||
- if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n')
|
||||
- fputc(c, fs);
|
||||
- else if (!c_isascii(c))
|
||||
- fprintf(fs, "\\%3o", (unsigned char)c);
|
||||
- else
|
||||
- fputs((char[]){ '^', c ^ 0x40, '\0' }, fs);
|
||||
-}
|
||||
-
|
||||
static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
size_t *mbufsize, int print_banner)
|
||||
{
|
||||
- register int ch, cnt;
|
||||
- char *p, *lbuf, *retbuf;
|
||||
+ char *lbuf, *retbuf;
|
||||
FILE * fs = open_memstream(&retbuf, mbufsize);
|
||||
- long line_max;
|
||||
-
|
||||
- line_max = sysconf(_SC_LINE_MAX);
|
||||
- if (line_max <= 0)
|
||||
- line_max = 512;
|
||||
-
|
||||
- lbuf = xmalloc(line_max);
|
||||
+ size_t lbuflen = 512;
|
||||
+ lbuf = xmalloc(lbuflen);
|
||||
|
||||
if (print_banner == TRUE) {
|
||||
char *hostname = xgethostname();
|
||||
@@ -329,7 +313,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
will not overflow as long as %d takes at most 100 chars */
|
||||
fprintf(fs, "\r%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
- snprintf(lbuf, line_max,
|
||||
+ snprintf(lbuf, lbuflen,
|
||||
_("Broadcast message from %s@%s (%s) (%s):"),
|
||||
whom, hostname, where, date);
|
||||
fprintf(fs, "%-*.*s\007\007\r\n", TERM_WIDTH, TERM_WIDTH, lbuf);
|
||||
@@ -373,18 +357,8 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
/*
|
||||
* Read message from stdin.
|
||||
*/
|
||||
- while (fgets(lbuf, line_max, stdin)) {
|
||||
- for (cnt = 0, p = lbuf; (ch = *p) != '\0'; ++p, ++cnt) {
|
||||
- if (cnt == TERM_WIDTH || ch == '\n') {
|
||||
- fprintf(fs, "%*s\r\n", TERM_WIDTH - cnt, "");
|
||||
- cnt = 0;
|
||||
- }
|
||||
- if (ch == '\t')
|
||||
- cnt += (7 - (cnt % 8));
|
||||
- if (ch != '\n')
|
||||
- buf_putc_careful(fs, ch);
|
||||
- }
|
||||
- }
|
||||
+ while (getline(&lbuf, &lbuflen, stdin) >= 0)
|
||||
+ fputs_careful(lbuf, fs, '^', true, TERM_WIDTH);
|
||||
}
|
||||
fprintf(fs, "%*s\r\n", TERM_WIDTH, " ");
|
||||
|
||||
diff --git a/term-utils/write.c b/term-utils/write.c
|
||||
index 710a58c..1d57fce 100644
|
||||
--- a/term-utils/write.c
|
||||
+++ b/term-utils/write.c
|
||||
@@ -276,7 +276,7 @@ static void do_write(const struct write_control *ctl)
|
||||
if (signal_received)
|
||||
break;
|
||||
|
||||
- if (fputs_careful(line, stdout, '^', true) == EOF)
|
||||
+ if (fputs_careful(line, stdout, '^', true, 0) == EOF)
|
||||
err(EXIT_FAILURE, _("carefulputc failed"));
|
||||
}
|
||||
free(line);
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,36 @@
|
||||
From 07f0f0f5bd1e5e2268257ae1ff6d76a9b6c6ea8b Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Wed, 17 Jan 2024 12:37:08 +0100
|
||||
Subject: [PATCH] wall: fix calloc cal [-Werror=calloc-transposed-args]
|
||||
|
||||
term-utils/wall.c:143:37: error: xcalloc sizes specified with sizeof in the earlier argument and not in the later argument [-Werror=calloc-transposed-args]
|
||||
143 | buf->groups = xcalloc(sizeof(*buf->groups), buf->ngroups);
|
||||
| ^
|
||||
term-utils/wall.c:143:37: note: earlier argument should specify number of elements, later size of each element
|
||||
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
|
||||
CVE: CVE-2024-28085
|
||||
|
||||
Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/07f0f0f5bd1e5e2268257ae1ff6d76a9b6c6ea8b]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
term-utils/wall.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/term-utils/wall.c b/term-utils/wall.c
|
||||
index 377db45..85c006a 100644
|
||||
--- a/term-utils/wall.c
|
||||
+++ b/term-utils/wall.c
|
||||
@@ -135,7 +135,7 @@ static struct group_workspace *init_group_workspace(const char *group)
|
||||
|
||||
buf->requested_group = get_group_gid(group);
|
||||
buf->ngroups = sysconf(_SC_NGROUPS_MAX) + 1; /* room for the primary gid */
|
||||
- buf->groups = xcalloc(sizeof(*buf->groups), buf->ngroups);
|
||||
+ buf->groups = xcalloc(buf->ngroups, sizeof(*buf->groups));
|
||||
|
||||
return buf;
|
||||
}
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,34 @@
|
||||
From 404b0781f52f7c045ca811b2dceec526408ac253 Mon Sep 17 00:00:00 2001
|
||||
From: Karel Zak <kzak@redhat.com>
|
||||
Date: Thu, 21 Mar 2024 11:16:20 +0100
|
||||
Subject: [PATCH] wall: fix escape sequence Injection [CVE-2024-28085]
|
||||
|
||||
Let's use for all cases the same output function.
|
||||
|
||||
Reported-by: Skyler Ferrante <sjf5462@rit.edu>
|
||||
Signed-off-by: Karel Zak <kzak@redhat.com>
|
||||
|
||||
CVE: CVE-2024-28085
|
||||
|
||||
Upstream-Status: Backport [https://github.com/util-linux/util-linux/commit/404b0781f52f7c045ca811b2dceec526408ac253]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
term-utils/wall.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/term-utils/wall.c b/term-utils/wall.c
|
||||
index 85c006a..0212c03 100644
|
||||
--- a/term-utils/wall.c
|
||||
+++ b/term-utils/wall.c
|
||||
@@ -328,7 +328,7 @@ static char *makemsg(char *fname, char **mvec, int mvecsz,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mvecsz; i++) {
|
||||
- fputs(mvec[i], fs);
|
||||
+ fputs_careful(mvec[i], fs, '^', true, TERM_WIDTH);
|
||||
if (i < mvecsz - 1)
|
||||
fputc(' ', fs);
|
||||
}
|
||||
--
|
||||
2.40.0
|
||||
@@ -34,7 +34,7 @@ SRC_URI = "\
|
||||
file://0013-Avoid-as-info-race-condition.patch \
|
||||
file://0014-CVE-2019-1010204.patch \
|
||||
file://0015-CVE-2022-38533.patch \
|
||||
file://0016-CVE-2022-38126.patch \
|
||||
file://0016-CVE-2022-35205.patch \
|
||||
file://0017-CVE-2022-38127-1.patch \
|
||||
file://0017-CVE-2022-38127-2.patch \
|
||||
file://0017-CVE-2022-38127-3.patch \
|
||||
|
||||
@@ -9,8 +9,9 @@ Subject: [PATCH] Replace a run-time assertion failure with a warning message
|
||||
message.
|
||||
|
||||
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e3e5ae049371a27fd1737aba946fe26d06e029b5]
|
||||
|
||||
CVE: CVE-2022-35205
|
||||
Signed-off-by: Pgowda <pgowda.cve@gmail.com>
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
binutils/dwarf.c | 7 ++++++-
|
||||
|
||||
69
meta/recipes-devtools/git/git/CVE-2024-32002-0001.patch
Normal file
69
meta/recipes-devtools/git/git/CVE-2024-32002-0001.patch
Normal file
@@ -0,0 +1,69 @@
|
||||
From 21496b4c60b2327417c63fc9762096037a185be3 Mon Sep 17 00:00:00 2001
|
||||
From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
Date: Thu, 1 Sep 2022 01:17:54 +0200
|
||||
Subject: [PATCH] submodule--helper: use xstrfmt() in clone_submodule()
|
||||
|
||||
Use xstrfmt() in clone_submodule() instead of a "struct strbuf" in two
|
||||
cases where we weren't getting anything out of using the "struct
|
||||
strbuf".
|
||||
|
||||
This changes code that was was added along with other uses of "struct
|
||||
strbuf" in this function in ee8838d1577 (submodule: rewrite
|
||||
`module_clone` shell function in C, 2015-09-08).
|
||||
|
||||
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
Reviewed-by: Glen Choo <chooglen@google.com>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
|
||||
CVE: CVE-2024-32002
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/21496b4c60b2327417c63fc9762096037a185be3]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
builtin/submodule--helper.c | 17 +++++++++--------
|
||||
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
|
||||
index c5d3fc3..79868c3 100644
|
||||
--- a/builtin/submodule--helper.c
|
||||
+++ b/builtin/submodule--helper.c
|
||||
@@ -1761,12 +1761,11 @@ static int clone_submodule(struct module_clone_data *clone_data)
|
||||
sm_gitdir = absolute_pathdup(sb.buf);
|
||||
strbuf_reset(&sb);
|
||||
|
||||
- if (!is_absolute_path(clone_data->path)) {
|
||||
- strbuf_addf(&sb, "%s/%s", get_git_work_tree(), clone_data->path);
|
||||
- clone_data->path = strbuf_detach(&sb, NULL);
|
||||
- } else {
|
||||
+ if (!is_absolute_path(clone_data->path))
|
||||
+ clone_data->path = xstrfmt("%s/%s", get_git_work_tree(),
|
||||
+ clone_data->path);
|
||||
+ else
|
||||
clone_data->path = xstrdup(clone_data->path);
|
||||
- }
|
||||
|
||||
if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
|
||||
die(_("refusing to create/use '%s' in another submodule's "
|
||||
@@ -1813,14 +1812,16 @@ static int clone_submodule(struct module_clone_data *clone_data)
|
||||
die(_("clone of '%s' into submodule path '%s' failed"),
|
||||
clone_data->url, clone_data->path);
|
||||
} else {
|
||||
+ char *path;
|
||||
+
|
||||
if (clone_data->require_init && !access(clone_data->path, X_OK) &&
|
||||
!is_empty_dir(clone_data->path))
|
||||
die(_("directory not empty: '%s'"), clone_data->path);
|
||||
if (safe_create_leading_directories_const(clone_data->path) < 0)
|
||||
die(_("could not create directory '%s'"), clone_data->path);
|
||||
- strbuf_addf(&sb, "%s/index", sm_gitdir);
|
||||
- unlink_or_warn(sb.buf);
|
||||
- strbuf_reset(&sb);
|
||||
+ path = xstrfmt("%s/index", sm_gitdir);
|
||||
+ unlink_or_warn(path);
|
||||
+ free(path);
|
||||
}
|
||||
|
||||
connect_work_tree_and_git_dir(clone_data->path, sm_gitdir, 0);
|
||||
--
|
||||
2.40.0
|
||||
213
meta/recipes-devtools/git/git/CVE-2024-32002-0002.patch
Normal file
213
meta/recipes-devtools/git/git/CVE-2024-32002-0002.patch
Normal file
@@ -0,0 +1,213 @@
|
||||
From 6fac5b2f352efc8c246d6d5be63a66b7b0fc0209 Mon Sep 17 00:00:00 2001
|
||||
From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
Date: Thu, 1 Sep 2022 01:17:56 +0200
|
||||
Subject: [PATCH] submodule--helper: add "const" to passed "module_clone_data"
|
||||
|
||||
Add "const" to the "struct module_clone_data" that we pass to
|
||||
clone_submodule(), which makes the ownership clear, and stops us from
|
||||
clobbering the "clone_data->path".
|
||||
|
||||
We still need to add to the "reference" member, which is a "struct
|
||||
string_list". Let's do this by having clone_submodule() create its
|
||||
own, and copy the contents over, allowing us to pass it as a
|
||||
separate parameter.
|
||||
|
||||
This new "struct string_list" still leaks memory, just as the "struct
|
||||
module_clone_data" did before. let's not fix that for now, to fix that
|
||||
we'll need to add some "goto cleanup" to the relevant code. That will
|
||||
eventually be done in follow-up commits, this change makes it easier
|
||||
to fix the memory leak.
|
||||
|
||||
The scope of the new "reference" variable in add_submodule() could be
|
||||
narrowed to the "else" block, but as we'll eventually free it with a
|
||||
"goto cleanup" let's declare it at the start of the function.
|
||||
|
||||
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
Reviewed-by: Glen Choo <chooglen@google.com>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
|
||||
CVE: CVE-2024-32002
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/6fac5b2f352efc8c246d6d5be63a66b7b0fc0209]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
builtin/submodule--helper.c | 52 ++++++++++++++++++++-----------------
|
||||
1 file changed, 28 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
|
||||
index 79868c3..d1d64db 100644
|
||||
--- a/builtin/submodule--helper.c
|
||||
+++ b/builtin/submodule--helper.c
|
||||
@@ -1630,14 +1630,13 @@ struct module_clone_data {
|
||||
const char *name;
|
||||
const char *url;
|
||||
const char *depth;
|
||||
- struct string_list reference;
|
||||
unsigned int quiet: 1;
|
||||
unsigned int progress: 1;
|
||||
unsigned int dissociate: 1;
|
||||
unsigned int require_init: 1;
|
||||
int single_branch;
|
||||
};
|
||||
-#define MODULE_CLONE_DATA_INIT { .reference = STRING_LIST_INIT_NODUP, .single_branch = -1 }
|
||||
+#define MODULE_CLONE_DATA_INIT { .single_branch = -1 }
|
||||
|
||||
struct submodule_alternate_setup {
|
||||
const char *submodule_name;
|
||||
@@ -1750,22 +1749,24 @@ static void prepare_possible_alternates(const char *sm_name,
|
||||
free(error_strategy);
|
||||
}
|
||||
|
||||
-static int clone_submodule(struct module_clone_data *clone_data)
|
||||
+static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
+ struct string_list *reference)
|
||||
{
|
||||
char *p, *sm_gitdir;
|
||||
char *sm_alternate = NULL, *error_strategy = NULL;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
+ const char *clone_data_path;
|
||||
|
||||
submodule_name_to_gitdir(&sb, the_repository, clone_data->name);
|
||||
sm_gitdir = absolute_pathdup(sb.buf);
|
||||
strbuf_reset(&sb);
|
||||
|
||||
if (!is_absolute_path(clone_data->path))
|
||||
- clone_data->path = xstrfmt("%s/%s", get_git_work_tree(),
|
||||
- clone_data->path);
|
||||
+ clone_data_path = xstrfmt("%s/%s", get_git_work_tree(),
|
||||
+ clone_data->path);
|
||||
else
|
||||
- clone_data->path = xstrdup(clone_data->path);
|
||||
+ clone_data_path = xstrdup(clone_data->path);
|
||||
|
||||
if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
|
||||
die(_("refusing to create/use '%s' in another submodule's "
|
||||
@@ -1775,7 +1776,7 @@ static int clone_submodule(struct module_clone_data *clone_data)
|
||||
if (safe_create_leading_directories_const(sm_gitdir) < 0)
|
||||
die(_("could not create directory '%s'"), sm_gitdir);
|
||||
|
||||
- prepare_possible_alternates(clone_data->name, &clone_data->reference);
|
||||
+ prepare_possible_alternates(clone_data->name, reference);
|
||||
|
||||
strvec_push(&cp.args, "clone");
|
||||
strvec_push(&cp.args, "--no-checkout");
|
||||
@@ -1784,10 +1785,10 @@ static int clone_submodule(struct module_clone_data *clone_data)
|
||||
if (clone_data->progress)
|
||||
strvec_push(&cp.args, "--progress");
|
||||
if (clone_data->depth && *(clone_data->depth))
|
||||
- strvec_pushl(&cp.args, "--depth", clone_data->depth, NULL);
|
||||
- if (clone_data->reference.nr) {
|
||||
+ strvec_pushl(&cp.args, "--depth", clone_data->depth, NULL);
|
||||
+ if (reference->nr) {
|
||||
struct string_list_item *item;
|
||||
- for_each_string_list_item(item, &clone_data->reference)
|
||||
+ for_each_string_list_item(item, reference)
|
||||
strvec_pushl(&cp.args, "--reference",
|
||||
item->string, NULL);
|
||||
}
|
||||
@@ -1802,7 +1803,7 @@ static int clone_submodule(struct module_clone_data *clone_data)
|
||||
|
||||
strvec_push(&cp.args, "--");
|
||||
strvec_push(&cp.args, clone_data->url);
|
||||
- strvec_push(&cp.args, clone_data->path);
|
||||
+ strvec_push(&cp.args, clone_data_path);
|
||||
|
||||
cp.git_cmd = 1;
|
||||
prepare_submodule_repo_env(&cp.env_array);
|
||||
@@ -1810,25 +1811,25 @@ static int clone_submodule(struct module_clone_data *clone_data)
|
||||
|
||||
if(run_command(&cp))
|
||||
die(_("clone of '%s' into submodule path '%s' failed"),
|
||||
- clone_data->url, clone_data->path);
|
||||
+ clone_data->url, clone_data_path);
|
||||
} else {
|
||||
char *path;
|
||||
|
||||
- if (clone_data->require_init && !access(clone_data->path, X_OK) &&
|
||||
- !is_empty_dir(clone_data->path))
|
||||
- die(_("directory not empty: '%s'"), clone_data->path);
|
||||
- if (safe_create_leading_directories_const(clone_data->path) < 0)
|
||||
- die(_("could not create directory '%s'"), clone_data->path);
|
||||
+ if (clone_data->require_init && !access(clone_data_path, X_OK) &&
|
||||
+ !is_empty_dir(clone_data_path))
|
||||
+ die(_("directory not empty: '%s'"), clone_data_path);
|
||||
+ if (safe_create_leading_directories_const(clone_data_path) < 0)
|
||||
+ die(_("could not create directory '%s'"), clone_data_path);
|
||||
path = xstrfmt("%s/index", sm_gitdir);
|
||||
unlink_or_warn(path);
|
||||
free(path);
|
||||
}
|
||||
|
||||
- connect_work_tree_and_git_dir(clone_data->path, sm_gitdir, 0);
|
||||
+ connect_work_tree_and_git_dir(clone_data_path, sm_gitdir, 0);
|
||||
|
||||
- p = git_pathdup_submodule(clone_data->path, "config");
|
||||
+ p = git_pathdup_submodule(clone_data_path, "config");
|
||||
if (!p)
|
||||
- die(_("could not get submodule directory for '%s'"), clone_data->path);
|
||||
+ die(_("could not get submodule directory for '%s'"), clone_data_path);
|
||||
|
||||
/* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */
|
||||
git_config_get_string("submodule.alternateLocation", &sm_alternate);
|
||||
@@ -1853,6 +1854,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
|
||||
{
|
||||
int dissociate = 0, quiet = 0, progress = 0, require_init = 0;
|
||||
struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
|
||||
+ struct string_list reference = STRING_LIST_INIT_NODUP;
|
||||
|
||||
struct option module_clone_options[] = {
|
||||
OPT_STRING(0, "prefix", &clone_data.prefix,
|
||||
@@ -1867,7 +1869,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
|
||||
OPT_STRING(0, "url", &clone_data.url,
|
||||
N_("string"),
|
||||
N_("url where to clone the submodule from")),
|
||||
- OPT_STRING_LIST(0, "reference", &clone_data.reference,
|
||||
+ OPT_STRING_LIST(0, "reference", &reference,
|
||||
N_("repo"),
|
||||
N_("reference repository")),
|
||||
OPT_BOOL(0, "dissociate", &dissociate,
|
||||
@@ -1905,7 +1907,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
|
||||
usage_with_options(git_submodule_helper_usage,
|
||||
module_clone_options);
|
||||
|
||||
- clone_submodule(&clone_data);
|
||||
+ clone_submodule(&clone_data, &reference);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3029,6 +3031,7 @@ static int add_submodule(const struct add_data *add_data)
|
||||
{
|
||||
char *submod_gitdir_path;
|
||||
struct module_clone_data clone_data = MODULE_CLONE_DATA_INIT;
|
||||
+ struct string_list reference = STRING_LIST_INIT_NODUP;
|
||||
|
||||
/* perhaps the path already exists and is already a git repo, else clone it */
|
||||
if (is_directory(add_data->sm_path)) {
|
||||
@@ -3045,6 +3048,7 @@ static int add_submodule(const struct add_data *add_data)
|
||||
free(submod_gitdir_path);
|
||||
} else {
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
+
|
||||
submod_gitdir_path = xstrfmt(".git/modules/%s", add_data->sm_name);
|
||||
|
||||
if (is_directory(submod_gitdir_path)) {
|
||||
@@ -3084,13 +3088,13 @@ static int add_submodule(const struct add_data *add_data)
|
||||
clone_data.quiet = add_data->quiet;
|
||||
clone_data.progress = add_data->progress;
|
||||
if (add_data->reference_path)
|
||||
- string_list_append(&clone_data.reference,
|
||||
+ string_list_append(&reference,
|
||||
xstrdup(add_data->reference_path));
|
||||
clone_data.dissociate = add_data->dissociate;
|
||||
if (add_data->depth >= 0)
|
||||
clone_data.depth = xstrfmt("%d", add_data->depth);
|
||||
|
||||
- if (clone_submodule(&clone_data))
|
||||
+ if (clone_submodule(&clone_data, &reference))
|
||||
return -1;
|
||||
|
||||
prepare_submodule_repo_env(&cp.env_array);
|
||||
--
|
||||
2.40.0
|
||||
141
meta/recipes-devtools/git/git/CVE-2024-32002-0003.patch
Normal file
141
meta/recipes-devtools/git/git/CVE-2024-32002-0003.patch
Normal file
@@ -0,0 +1,141 @@
|
||||
From e77b3da6bb60e9af5963c9e42442afe53af1780b Mon Sep 17 00:00:00 2001
|
||||
From: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
Date: Thu, 1 Sep 2022 01:14:08 +0200
|
||||
Subject: [PATCH] submodule--helper: fix a leak in "clone_submodule"
|
||||
|
||||
Fix a memory leak of the "clone_data_path" variable that we copy or
|
||||
derive from the "struct module_clone_data" in clone_submodule(). This
|
||||
code was refactored in preceding commits, but the leak has been with
|
||||
us since f8eaa0ba98b (submodule--helper, module_clone: always operate
|
||||
on absolute paths, 2016-03-31).
|
||||
|
||||
For the "else" case we don't need to xstrdup() the "clone_data->path",
|
||||
and we don't need to free our own "clone_data_path". We can therefore
|
||||
assign the "clone_data->path" to our own "clone_data_path" right away,
|
||||
and only override it (and remember to free it!) if we need to
|
||||
xstrfmt() a replacement.
|
||||
|
||||
In the case of the module_clone() caller it's from "argv", and doesn't
|
||||
need to be free'd, and in the case of the add_submodule() caller we
|
||||
get a pointer to "sm_path", which doesn't need to be directly free'd
|
||||
either.
|
||||
|
||||
Fixing this leak makes several tests pass, so let's mark them as
|
||||
passing with TEST_PASSES_SANITIZE_LEAK=true.
|
||||
|
||||
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
|
||||
Reviewed-by: Glen Choo <chooglen@google.com>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
|
||||
CVE: CVE-2024-32002
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/e77b3da6bb60e9af5963c9e42442afe53af1780b]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
builtin/submodule--helper.c | 10 +++++-----
|
||||
t/t1500-rev-parse.sh | 1 +
|
||||
t/t6008-rev-list-submodule.sh | 1 +
|
||||
t/t7414-submodule-mistakes.sh | 2 ++
|
||||
t/t7506-status-submodule.sh | 1 +
|
||||
t/t7507-commit-verbose.sh | 2 ++
|
||||
6 files changed, 12 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
|
||||
index d1d64db..1158dcc 100644
|
||||
--- a/builtin/submodule--helper.c
|
||||
+++ b/builtin/submodule--helper.c
|
||||
@@ -1756,17 +1756,16 @@ static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
char *sm_alternate = NULL, *error_strategy = NULL;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
- const char *clone_data_path;
|
||||
+ const char *clone_data_path = clone_data->path;
|
||||
+ char *to_free = NULL;;
|
||||
|
||||
submodule_name_to_gitdir(&sb, the_repository, clone_data->name);
|
||||
sm_gitdir = absolute_pathdup(sb.buf);
|
||||
strbuf_reset(&sb);
|
||||
|
||||
if (!is_absolute_path(clone_data->path))
|
||||
- clone_data_path = xstrfmt("%s/%s", get_git_work_tree(),
|
||||
- clone_data->path);
|
||||
- else
|
||||
- clone_data_path = xstrdup(clone_data->path);
|
||||
+ clone_data_path = to_free = xstrfmt("%s/%s", get_git_work_tree(),
|
||||
+ clone_data->path);
|
||||
|
||||
if (validate_submodule_git_dir(sm_gitdir, clone_data->name) < 0)
|
||||
die(_("refusing to create/use '%s' in another submodule's "
|
||||
@@ -1847,6 +1846,7 @@ static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
strbuf_release(&sb);
|
||||
free(sm_gitdir);
|
||||
free(p);
|
||||
+ free(to_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
|
||||
index 2c429f9..81de584 100755
|
||||
--- a/t/t1500-rev-parse.sh
|
||||
+++ b/t/t1500-rev-parse.sh
|
||||
@@ -4,6 +4,7 @@ test_description='test git rev-parse'
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
+TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_one () {
|
||||
diff --git a/t/t6008-rev-list-submodule.sh b/t/t6008-rev-list-submodule.sh
|
||||
index a0a070b..2cdef6f 100755
|
||||
--- a/t/t6008-rev-list-submodule.sh
|
||||
+++ b/t/t6008-rev-list-submodule.sh
|
||||
@@ -8,6 +8,7 @@ test_description='git rev-list involving submodules that this repo has'
|
||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||
|
||||
+TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'setup' '
|
||||
diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
|
||||
index cf95603..101afff 100755
|
||||
--- a/t/t7414-submodule-mistakes.sh
|
||||
+++ b/t/t7414-submodule-mistakes.sh
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='handling of common mistakes people may make with submodules'
|
||||
+
|
||||
+TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'create embedded repository' '
|
||||
diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh
|
||||
index 459300c..d050091 100755
|
||||
--- a/t/t7506-status-submodule.sh
|
||||
+++ b/t/t7506-status-submodule.sh
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
test_description='git status for submodule'
|
||||
|
||||
+TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
test_create_repo_with_commit () {
|
||||
diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh
|
||||
index bd0ae4b..916470c 100755
|
||||
--- a/t/t7507-commit-verbose.sh
|
||||
+++ b/t/t7507-commit-verbose.sh
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
test_description='verbose commit template'
|
||||
+
|
||||
+TEST_PASSES_SANITIZE_LEAK=true
|
||||
. ./test-lib.sh
|
||||
|
||||
write_script "check-for-diff" <<\EOF &&
|
||||
--
|
||||
2.40.0
|
||||
150
meta/recipes-devtools/git/git/CVE-2024-32002-0004.patch
Normal file
150
meta/recipes-devtools/git/git/CVE-2024-32002-0004.patch
Normal file
@@ -0,0 +1,150 @@
|
||||
From 97065761333fd62db1912d81b489db938d8c991d Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Fri, 22 Mar 2024 11:19:22 +0100
|
||||
Subject: [PATCH] submodules: submodule paths must not contain symlinks
|
||||
|
||||
When creating a submodule path, we must be careful not to follow
|
||||
symbolic links. Otherwise we may follow a symbolic link pointing to
|
||||
a gitdir (which are valid symbolic links!) e.g. while cloning.
|
||||
|
||||
On case-insensitive filesystems, however, we blindly replace a directory
|
||||
that has been created as part of the `clone` operation with a symlink
|
||||
when the path to the latter differs only in case from the former's path.
|
||||
|
||||
Let's simply avoid this situation by expecting not ever having to
|
||||
overwrite any existing file/directory/symlink upon cloning. That way, we
|
||||
won't even replace a directory that we just created.
|
||||
|
||||
This addresses CVE-2024-32002.
|
||||
|
||||
Reported-by: Filip Hejsek <filip.hejsek@gmail.com>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
|
||||
CVE: CVE-2024-32002
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/97065761333fd62db1912d81b489db938d8c991d]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
builtin/submodule--helper.c | 35 +++++++++++++++++++++++++++++++
|
||||
t/t7406-submodule-update.sh | 42 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 77 insertions(+)
|
||||
|
||||
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
|
||||
index 1158dcc..d4147d8 100644
|
||||
--- a/builtin/submodule--helper.c
|
||||
+++ b/builtin/submodule--helper.c
|
||||
@@ -1749,11 +1749,34 @@ static void prepare_possible_alternates(const char *sm_name,
|
||||
free(error_strategy);
|
||||
}
|
||||
|
||||
+static int dir_contains_only_dotgit(const char *path)
|
||||
+{
|
||||
+ DIR *dir = opendir(path);
|
||||
+ struct dirent *e;
|
||||
+ int ret = 1;
|
||||
+
|
||||
+ if (!dir)
|
||||
+ return 0;
|
||||
+
|
||||
+ e = readdir_skip_dot_and_dotdot(dir);
|
||||
+ if (!e)
|
||||
+ ret = 0;
|
||||
+ else if (strcmp(DEFAULT_GIT_DIR_ENVIRONMENT, e->d_name) ||
|
||||
+ (e = readdir_skip_dot_and_dotdot(dir))) {
|
||||
+ error("unexpected item '%s' in '%s'", e->d_name, path);
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+
|
||||
+ closedir(dir);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
struct string_list *reference)
|
||||
{
|
||||
char *p, *sm_gitdir;
|
||||
char *sm_alternate = NULL, *error_strategy = NULL;
|
||||
+ struct stat st;
|
||||
struct strbuf sb = STRBUF_INIT;
|
||||
struct child_process cp = CHILD_PROCESS_INIT;
|
||||
const char *clone_data_path = clone_data->path;
|
||||
@@ -1772,6 +1795,10 @@ static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
"git dir"), sm_gitdir);
|
||||
|
||||
if (!file_exists(sm_gitdir)) {
|
||||
+ if (clone_data->require_init && !stat(clone_data_path, &st) &&
|
||||
+ !is_empty_dir(clone_data_path))
|
||||
+ die(_("directory not empty: '%s'"), clone_data_path);
|
||||
+
|
||||
if (safe_create_leading_directories_const(sm_gitdir) < 0)
|
||||
die(_("could not create directory '%s'"), sm_gitdir);
|
||||
|
||||
@@ -1811,6 +1838,14 @@ static int clone_submodule(const struct module_clone_data *clone_data,
|
||||
if(run_command(&cp))
|
||||
die(_("clone of '%s' into submodule path '%s' failed"),
|
||||
clone_data->url, clone_data_path);
|
||||
+
|
||||
+ if (clone_data->require_init && !stat(clone_data_path, &st) &&
|
||||
+ !dir_contains_only_dotgit(clone_data_path)) {
|
||||
+ char *dot_git = xstrfmt("%s/.git", clone_data_path);
|
||||
+ unlink(dot_git);
|
||||
+ free(dot_git);
|
||||
+ die(_("directory not empty: '%s'"), clone_data_path);
|
||||
+ }
|
||||
} else {
|
||||
char *path;
|
||||
|
||||
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
|
||||
index 53d419c..00ffdb6 100755
|
||||
--- a/t/t7406-submodule-update.sh
|
||||
+++ b/t/t7406-submodule-update.sh
|
||||
@@ -1062,4 +1062,46 @@ test_expect_success 'submodule update --quiet passes quietness to fetch with a s
|
||||
)
|
||||
'
|
||||
|
||||
+test_expect_success CASE_INSENSITIVE_FS,SYMLINKS \
|
||||
+ 'submodule paths must not follow symlinks' '
|
||||
+ # This is only needed because we want to run this in a self-contained
|
||||
+ # test without having to spin up an HTTP server; However, it would not
|
||||
+ # be needed in a real-world scenario where the submodule is simply
|
||||
+ # hosted on a public site.
|
||||
+ test_config_global protocol.file.allow always &&
|
||||
+ # Make sure that Git tries to use symlinks on Windows
|
||||
+ test_config_global core.symlinks true &&
|
||||
+ tell_tale_path="$PWD/tell.tale" &&
|
||||
+ git init hook &&
|
||||
+ (
|
||||
+ cd hook &&
|
||||
+ mkdir -p y/hooks &&
|
||||
+ write_script y/hooks/post-checkout <<-EOF &&
|
||||
+ echo HOOK-RUN >&2
|
||||
+ echo hook-run >"$tell_tale_path"
|
||||
+ EOF
|
||||
+ git add y/hooks/post-checkout &&
|
||||
+ test_tick &&
|
||||
+ git commit -m post-checkout
|
||||
+ ) &&
|
||||
+ hook_repo_path="$(pwd)/hook" &&
|
||||
+ git init captain &&
|
||||
+ (
|
||||
+ cd captain &&
|
||||
+ git submodule add --name x/y "$hook_repo_path" A/modules/x &&
|
||||
+ test_tick &&
|
||||
+ git commit -m add-submodule &&
|
||||
+ printf .git >dotgit.txt &&
|
||||
+ git hash-object -w --stdin <dotgit.txt >dot-git.hash &&
|
||||
+ printf "120000 %s 0\ta\n" "$(cat dot-git.hash)" >index.info &&
|
||||
+ git update-index --index-info <index.info &&
|
||||
+ test_tick &&
|
||||
+ git commit -m add-symlink
|
||||
+ ) &&
|
||||
+ test_path_is_missing "$tell_tale_path" &&
|
||||
+ test_must_fail git clone --recursive captain hooked 2>err &&
|
||||
+ grep "directory not empty" err &&
|
||||
+ test_path_is_missing "$tell_tale_path"
|
||||
+'
|
||||
+
|
||||
test_done
|
||||
--
|
||||
2.40.0
|
||||
95
meta/recipes-devtools/git/git/CVE-2024-32004-0001.patch
Normal file
95
meta/recipes-devtools/git/git/CVE-2024-32004-0001.patch
Normal file
@@ -0,0 +1,95 @@
|
||||
From 5c5a4a1c05932378d259b1fdd9526cab971656a2 Mon Sep 17 00:00:00 2001
|
||||
From: Filip Hejsek <filip.hejsek@gmail.com>
|
||||
Date: Sun, 28 Jan 2024 04:29:33 +0100
|
||||
Subject: [PATCH] t0411: add tests for cloning from partial repo
|
||||
|
||||
Cloning from a partial repository must not fetch missing objects into
|
||||
the partial repository, because that can lead to arbitrary code
|
||||
execution.
|
||||
|
||||
Add a couple of test cases, pretending to the `upload-pack` command (and
|
||||
to that command only) that it is working on a repository owned by
|
||||
someone else.
|
||||
|
||||
Helped-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Filip Hejsek <filip.hejsek@gmail.com>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
|
||||
CVE: CVE-2024-32004
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/5c5a4a1c05932378d259b1fdd9526cab971656a2]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
t/t0411-clone-from-partial.sh | 60 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 60 insertions(+)
|
||||
create mode 100755 t/t0411-clone-from-partial.sh
|
||||
|
||||
diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh
|
||||
new file mode 100755
|
||||
index 0000000..fb72a0a
|
||||
--- /dev/null
|
||||
+++ b/t/t0411-clone-from-partial.sh
|
||||
@@ -0,0 +1,60 @@
|
||||
+#!/bin/sh
|
||||
+
|
||||
+test_description='check that local clone does not fetch from promisor remotes'
|
||||
+
|
||||
+. ./test-lib.sh
|
||||
+
|
||||
+test_expect_success 'create evil repo' '
|
||||
+ git init tmp &&
|
||||
+ test_commit -C tmp a &&
|
||||
+ git -C tmp config uploadpack.allowfilter 1 &&
|
||||
+ git clone --filter=blob:none --no-local --no-checkout tmp evil &&
|
||||
+ rm -rf tmp &&
|
||||
+
|
||||
+ git -C evil config remote.origin.uploadpack \"\$TRASH_DIRECTORY/fake-upload-pack\" &&
|
||||
+ write_script fake-upload-pack <<-\EOF &&
|
||||
+ echo >&2 "fake-upload-pack running"
|
||||
+ >"$TRASH_DIRECTORY/script-executed"
|
||||
+ exit 1
|
||||
+ EOF
|
||||
+ export TRASH_DIRECTORY &&
|
||||
+
|
||||
+ # empty shallow file disables local clone optimization
|
||||
+ >evil/.git/shallow
|
||||
+'
|
||||
+
|
||||
+test_expect_failure 'local clone must not fetch from promisor remote and execute script' '
|
||||
+ rm -f script-executed &&
|
||||
+ test_must_fail git clone \
|
||||
+ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
+ evil clone1 2>err &&
|
||||
+ ! grep "fake-upload-pack running" err &&
|
||||
+ test_path_is_missing script-executed
|
||||
+'
|
||||
+
|
||||
+test_expect_failure 'clone from file://... must not fetch from promisor remote and execute script' '
|
||||
+ rm -f script-executed &&
|
||||
+ test_must_fail git clone \
|
||||
+ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
+ "file://$(pwd)/evil" clone2 2>err &&
|
||||
+ ! grep "fake-upload-pack running" err &&
|
||||
+ test_path_is_missing script-executed
|
||||
+'
|
||||
+
|
||||
+test_expect_failure 'fetch from file://... must not fetch from promisor remote and execute script' '
|
||||
+ rm -f script-executed &&
|
||||
+ test_must_fail git fetch \
|
||||
+ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
+ "file://$(pwd)/evil" 2>err &&
|
||||
+ ! grep "fake-upload-pack running" err &&
|
||||
+ test_path_is_missing script-executed
|
||||
+'
|
||||
+
|
||||
+test_expect_success 'pack-objects should fetch from promisor remote and execute script' '
|
||||
+ rm -f script-executed &&
|
||||
+ echo "HEAD" | test_must_fail git -C evil pack-objects --revs --stdout >/dev/null 2>err &&
|
||||
+ grep "fake-upload-pack running" err &&
|
||||
+ test_path_is_file script-executed
|
||||
+'
|
||||
+
|
||||
+test_done
|
||||
--
|
||||
2.40.0
|
||||
187
meta/recipes-devtools/git/git/CVE-2024-32004-0002.patch
Normal file
187
meta/recipes-devtools/git/git/CVE-2024-32004-0002.patch
Normal file
@@ -0,0 +1,187 @@
|
||||
From 17d3883fe9c88b823002ad9fafb42313ddc3d3d5 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Mon, 8 Aug 2022 13:27:47 +0000
|
||||
Subject: [PATCH] setup: prepare for more detailed "dubious ownership" messages
|
||||
|
||||
When verifying the ownership of the Git directory, we sometimes would
|
||||
like to say a bit more about it, e.g. when using a platform-dependent
|
||||
code path (think: Windows has the permission model that is so different
|
||||
from Unix'), but only when it is a appropriate to actually say
|
||||
something.
|
||||
|
||||
To allow for that, collect that information and hand it back to the
|
||||
caller (whose responsibility it is to show it or not).
|
||||
|
||||
Note: We do not actually fill in any platform-dependent information yet,
|
||||
this commit just adds the infrastructure to be able to do so.
|
||||
|
||||
Based-on-an-idea-by: Junio C Hamano <gitster@pobox.com>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
|
||||
CVE: CVE-2024-32004
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/17d3883fe9c88b823002ad9fafb42313ddc3d3d5]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
compat/mingw.c | 2 +-
|
||||
compat/mingw.h | 2 +-
|
||||
git-compat-util.h | 5 ++++-
|
||||
setup.c | 25 +++++++++++++++----------
|
||||
4 files changed, 21 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/compat/mingw.c b/compat/mingw.c
|
||||
index 41fc163..9306a0e 100644
|
||||
--- a/compat/mingw.c
|
||||
+++ b/compat/mingw.c
|
||||
@@ -2658,7 +2658,7 @@ static PSID get_current_user_sid(void)
|
||||
return result;
|
||||
}
|
||||
|
||||
-int is_path_owned_by_current_sid(const char *path)
|
||||
+int is_path_owned_by_current_sid(const char *path, struct strbuf *report)
|
||||
{
|
||||
WCHAR wpath[MAX_PATH];
|
||||
PSID sid = NULL;
|
||||
diff --git a/compat/mingw.h b/compat/mingw.h
|
||||
index ffa53a4..a1a69c5 100644
|
||||
--- a/compat/mingw.h
|
||||
+++ b/compat/mingw.h
|
||||
@@ -457,7 +457,7 @@ char *mingw_query_user_email(void);
|
||||
* Verifies that the specified path is owned by the user running the
|
||||
* current process.
|
||||
*/
|
||||
-int is_path_owned_by_current_sid(const char *path);
|
||||
+int is_path_owned_by_current_sid(const char *path, struct strbuf *report);
|
||||
#define is_path_owned_by_current_user is_path_owned_by_current_sid
|
||||
|
||||
/**
|
||||
diff --git a/git-compat-util.h b/git-compat-util.h
|
||||
index 1c651c8..27b84b8 100644
|
||||
--- a/git-compat-util.h
|
||||
+++ b/git-compat-util.h
|
||||
@@ -23,6 +23,9 @@
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
+struct strbuf;
|
||||
+
|
||||
+
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
|
||||
@@ -475,7 +478,7 @@ static inline void extract_id_from_env(const char *env, uid_t *id)
|
||||
}
|
||||
}
|
||||
|
||||
-static inline int is_path_owned_by_current_uid(const char *path)
|
||||
+static inline int is_path_owned_by_current_uid(const char *path, struct strbuf *report)
|
||||
{
|
||||
struct stat st;
|
||||
uid_t euid;
|
||||
diff --git a/setup.c b/setup.c
|
||||
index 8686ffe..1ad7330 100644
|
||||
--- a/setup.c
|
||||
+++ b/setup.c
|
||||
@@ -1128,16 +1128,17 @@ static int safe_directory_cb(const char *key, const char *value, void *d)
|
||||
* added, for bare ones their git directory.
|
||||
*/
|
||||
static int ensure_valid_ownership(const char *gitfile,
|
||||
- const char *worktree, const char *gitdir)
|
||||
+ const char *worktree, const char *gitdir,
|
||||
+ struct strbuf *report)
|
||||
{
|
||||
struct safe_directory_data data = {
|
||||
.path = worktree ? worktree : gitdir
|
||||
};
|
||||
|
||||
if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) &&
|
||||
- (!gitfile || is_path_owned_by_current_user(gitfile)) &&
|
||||
- (!worktree || is_path_owned_by_current_user(worktree)) &&
|
||||
- (!gitdir || is_path_owned_by_current_user(gitdir)))
|
||||
+ (!gitfile || is_path_owned_by_current_user(gitfile, report)) &&
|
||||
+ (!worktree || is_path_owned_by_current_user(worktree, report)) &&
|
||||
+ (!gitdir || is_path_owned_by_current_user(gitdir, report)))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
@@ -1177,6 +1178,7 @@ enum discovery_result {
|
||||
*/
|
||||
static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
|
||||
struct strbuf *gitdir,
|
||||
+ struct strbuf *report,
|
||||
int die_on_error)
|
||||
{
|
||||
const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
|
||||
@@ -1264,7 +1266,7 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
|
||||
|
||||
if (ensure_valid_ownership(gitfile,
|
||||
dir->buf,
|
||||
- (gitdir_path ? gitdir_path : gitdirenv))) {
|
||||
+ (gitdir_path ? gitdir_path : gitdirenv), report)) {
|
||||
strbuf_addstr(gitdir, gitdirenv);
|
||||
ret = GIT_DIR_DISCOVERED;
|
||||
} else
|
||||
@@ -1287,7 +1289,7 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
|
||||
}
|
||||
|
||||
if (is_git_directory(dir->buf)) {
|
||||
- if (!ensure_valid_ownership(NULL, NULL, dir->buf))
|
||||
+ if (!ensure_valid_ownership(NULL, NULL, dir->buf, report))
|
||||
return GIT_DIR_INVALID_OWNERSHIP;
|
||||
strbuf_addstr(gitdir, ".");
|
||||
return GIT_DIR_BARE;
|
||||
@@ -1320,7 +1322,7 @@ int discover_git_directory(struct strbuf *commondir,
|
||||
return -1;
|
||||
|
||||
cwd_len = dir.len;
|
||||
- if (setup_git_directory_gently_1(&dir, gitdir, 0) <= 0) {
|
||||
+ if (setup_git_directory_gently_1(&dir, gitdir, NULL, 0) <= 0) {
|
||||
strbuf_release(&dir);
|
||||
return -1;
|
||||
}
|
||||
@@ -1367,7 +1369,7 @@ int discover_git_directory(struct strbuf *commondir,
|
||||
const char *setup_git_directory_gently(int *nongit_ok)
|
||||
{
|
||||
static struct strbuf cwd = STRBUF_INIT;
|
||||
- struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT;
|
||||
+ struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;
|
||||
const char *prefix = NULL;
|
||||
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
|
||||
|
||||
@@ -1392,7 +1394,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
die_errno(_("Unable to read current working directory"));
|
||||
strbuf_addbuf(&dir, &cwd);
|
||||
|
||||
- switch (setup_git_directory_gently_1(&dir, &gitdir, 1)) {
|
||||
+ switch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {
|
||||
case GIT_DIR_EXPLICIT:
|
||||
prefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);
|
||||
break;
|
||||
@@ -1424,12 +1426,14 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
if (!nongit_ok) {
|
||||
struct strbuf quoted = STRBUF_INIT;
|
||||
|
||||
+ strbuf_complete(&report, '\n');
|
||||
sq_quote_buf_pretty("ed, dir.buf);
|
||||
die(_("detected dubious ownership in repository at '%s'\n"
|
||||
+ "%s"
|
||||
"To add an exception for this directory, call:\n"
|
||||
"\n"
|
||||
"\tgit config --global --add safe.directory %s"),
|
||||
- dir.buf, quoted.buf);
|
||||
+ dir.buf, report.buf, quoted.buf);
|
||||
}
|
||||
*nongit_ok = 1;
|
||||
break;
|
||||
@@ -1508,6 +1512,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
|
||||
|
||||
strbuf_release(&dir);
|
||||
strbuf_release(&gitdir);
|
||||
+ strbuf_release(&report);
|
||||
clear_repository_format(&repo_fmt);
|
||||
|
||||
return prefix;
|
||||
--
|
||||
2.40.0
|
||||
158
meta/recipes-devtools/git/git/CVE-2024-32004-0003.patch
Normal file
158
meta/recipes-devtools/git/git/CVE-2024-32004-0003.patch
Normal file
@@ -0,0 +1,158 @@
|
||||
From f4aa8c8bb11dae6e769cd930565173808cbb69c8 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
Date: Wed, 10 Apr 2024 14:39:37 +0200
|
||||
Subject: [PATCH] fetch/clone: detect dubious ownership of local repositories
|
||||
|
||||
When cloning from somebody else's repositories, it is possible that,
|
||||
say, the `upload-pack` command is overridden in the repository that is
|
||||
about to be cloned, which would then be run in the user's context who
|
||||
started the clone.
|
||||
|
||||
To remind the user that this is a potentially unsafe operation, let's
|
||||
extend the ownership checks we have already established for regular
|
||||
gitdir discovery to extend also to local repositories that are about to
|
||||
be cloned.
|
||||
|
||||
This protection extends also to file:// URLs.
|
||||
|
||||
The fixes in this commit address CVE-2024-32004.
|
||||
|
||||
Note: This commit does not touch the `fetch`/`clone` code directly, but
|
||||
instead the function used implicitly by both: `enter_repo()`. This
|
||||
function is also used by `git receive-pack` (i.e. pushes), by `git
|
||||
upload-archive`, by `git daemon` and by `git http-backend`. In setups
|
||||
that want to serve repositories owned by different users than the
|
||||
account running the service, this will require `safe.*` settings to be
|
||||
configured accordingly.
|
||||
|
||||
Also note: there are tiny time windows where a time-of-check-time-of-use
|
||||
("TOCTOU") race is possible. The real solution to those would be to work
|
||||
with `fstat()` and `openat()`. However, the latter function is not
|
||||
available on Windows (and would have to be emulated with rather
|
||||
expensive low-level `NtCreateFile()` calls), and the changes would be
|
||||
quite extensive, for my taste too extensive for the little gain given
|
||||
that embargoed releases need to pay extra attention to avoid introducing
|
||||
inadvertent bugs.
|
||||
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
|
||||
CVE: CVE-2024-32004
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/f4aa8c8bb11dae6e769cd930565173808cbb69c8]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
cache.h | 12 ++++++++++++
|
||||
path.c | 2 ++
|
||||
setup.c | 21 +++++++++++++++++++++
|
||||
t/t0411-clone-from-partial.sh | 6 +++---
|
||||
4 files changed, 38 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/cache.h b/cache.h
|
||||
index 281f00a..a59bdbe 100644
|
||||
--- a/cache.h
|
||||
+++ b/cache.h
|
||||
@@ -615,6 +615,18 @@ void set_git_work_tree(const char *tree);
|
||||
|
||||
#define ALTERNATE_DB_ENVIRONMENT "GIT_ALTERNATE_OBJECT_DIRECTORIES"
|
||||
|
||||
+/*
|
||||
+ * Check if a repository is safe and die if it is not, by verifying the
|
||||
+ * ownership of the worktree (if any), the git directory, and the gitfile (if
|
||||
+ * any).
|
||||
+ *
|
||||
+ * Exemptions for known-safe repositories can be added via `safe.directory`
|
||||
+ * config settings; for non-bare repositories, their worktree needs to be
|
||||
+ * added, for bare ones their git directory.
|
||||
+ */
|
||||
+void die_upon_dubious_ownership(const char *gitfile, const char *worktree,
|
||||
+ const char *gitdir);
|
||||
+
|
||||
void setup_work_tree(void);
|
||||
/*
|
||||
* Find the commondir and gitdir of the repository that contains the current
|
||||
diff --git a/path.c b/path.c
|
||||
index d73146b..ae1fb01 100644
|
||||
--- a/path.c
|
||||
+++ b/path.c
|
||||
@@ -840,6 +840,7 @@ const char *enter_repo(const char *path, int strict)
|
||||
if (!suffix[i])
|
||||
return NULL;
|
||||
gitfile = read_gitfile(used_path.buf);
|
||||
+ die_upon_dubious_ownership(gitfile, NULL, used_path.buf);
|
||||
if (gitfile) {
|
||||
strbuf_reset(&used_path);
|
||||
strbuf_addstr(&used_path, gitfile);
|
||||
@@ -850,6 +851,7 @@ const char *enter_repo(const char *path, int strict)
|
||||
}
|
||||
else {
|
||||
const char *gitfile = read_gitfile(path);
|
||||
+ die_upon_dubious_ownership(gitfile, NULL, path);
|
||||
if (gitfile)
|
||||
path = gitfile;
|
||||
if (chdir(path))
|
||||
diff --git a/setup.c b/setup.c
|
||||
index 1ad7330..475c92e 100644
|
||||
--- a/setup.c
|
||||
+++ b/setup.c
|
||||
@@ -1151,6 +1151,27 @@ static int ensure_valid_ownership(const char *gitfile,
|
||||
return data.is_safe;
|
||||
}
|
||||
|
||||
+void die_upon_dubious_ownership(const char *gitfile, const char *worktree,
|
||||
+ const char *gitdir)
|
||||
+{
|
||||
+ struct strbuf report = STRBUF_INIT, quoted = STRBUF_INIT;
|
||||
+ const char *path;
|
||||
+
|
||||
+ if (ensure_valid_ownership(gitfile, worktree, gitdir, &report))
|
||||
+ return;
|
||||
+
|
||||
+ strbuf_complete(&report, '\n');
|
||||
+ path = gitfile ? gitfile : gitdir;
|
||||
+ sq_quote_buf_pretty("ed, path);
|
||||
+
|
||||
+ die(_("detected dubious ownership in repository at '%s'\n"
|
||||
+ "%s"
|
||||
+ "To add an exception for this directory, call:\n"
|
||||
+ "\n"
|
||||
+ "\tgit config --global --add safe.directory %s"),
|
||||
+ path, report.buf, quoted.buf);
|
||||
+}
|
||||
+
|
||||
enum discovery_result {
|
||||
GIT_DIR_NONE = 0,
|
||||
GIT_DIR_EXPLICIT,
|
||||
diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh
|
||||
index fb72a0a..eb3360d 100755
|
||||
--- a/t/t0411-clone-from-partial.sh
|
||||
+++ b/t/t0411-clone-from-partial.sh
|
||||
@@ -23,7 +23,7 @@ test_expect_success 'create evil repo' '
|
||||
>evil/.git/shallow
|
||||
'
|
||||
|
||||
-test_expect_failure 'local clone must not fetch from promisor remote and execute script' '
|
||||
+test_expect_success 'local clone must not fetch from promisor remote and execute script' '
|
||||
rm -f script-executed &&
|
||||
test_must_fail git clone \
|
||||
--upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
@@ -32,7 +32,7 @@ test_expect_failure 'local clone must not fetch from promisor remote and execute
|
||||
test_path_is_missing script-executed
|
||||
'
|
||||
|
||||
-test_expect_failure 'clone from file://... must not fetch from promisor remote and execute script' '
|
||||
+test_expect_success 'clone from file://... must not fetch from promisor remote and execute script' '
|
||||
rm -f script-executed &&
|
||||
test_must_fail git clone \
|
||||
--upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
@@ -41,7 +41,7 @@ test_expect_failure 'clone from file://... must not fetch from promisor remote a
|
||||
test_path_is_missing script-executed
|
||||
'
|
||||
|
||||
-test_expect_failure 'fetch from file://... must not fetch from promisor remote and execute script' '
|
||||
+test_expect_success 'fetch from file://... must not fetch from promisor remote and execute script' '
|
||||
rm -f script-executed &&
|
||||
test_must_fail git fetch \
|
||||
--upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
--
|
||||
2.40.0
|
||||
114
meta/recipes-devtools/git/git/CVE-2024-32020.patch
Normal file
114
meta/recipes-devtools/git/git/CVE-2024-32020.patch
Normal file
@@ -0,0 +1,114 @@
|
||||
From 1204e1a824c34071019fe106348eaa6d88f9528d Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Mon, 15 Apr 2024 13:30:41 +0200
|
||||
Subject: [PATCH] builtin/clone: refuse local clones of unsafe repositories
|
||||
|
||||
When performing a local clone of a repository we end up either copying
|
||||
or hardlinking the source repository into the target repository. This is
|
||||
significantly more performant than if we were to use git-upload-pack(1)
|
||||
and git-fetch-pack(1) to create the new repository and preserves both
|
||||
disk space and compute time.
|
||||
|
||||
Unfortunately though, performing such a local clone of a repository that
|
||||
is not owned by the current user is inherently unsafe:
|
||||
|
||||
- It is possible that source files get swapped out underneath us while
|
||||
we are copying or hardlinking them. While we do perform some checks
|
||||
here to assert that we hardlinked the expected file, they cannot
|
||||
reliably thwart time-of-check-time-of-use (TOCTOU) style races. It
|
||||
is thus possible for an adversary to make us copy or hardlink
|
||||
unexpected files into the target directory.
|
||||
|
||||
Ideally, we would address this by starting to use openat(3P),
|
||||
fstatat(3P) and friends. Due to platform compatibility with Windows
|
||||
we cannot easily do that though. Furthermore, the scope of these
|
||||
fixes would likely be quite broad and thus not fit for an embargoed
|
||||
security release.
|
||||
|
||||
- Even if we handled TOCTOU-style races perfectly, hardlinking files
|
||||
owned by a different user into the target repository is not a good
|
||||
idea in general. It is possible for an adversary to rewrite those
|
||||
files to contain whatever data they want even after the clone has
|
||||
completed.
|
||||
|
||||
Address these issues by completely refusing local clones of a repository
|
||||
that is not owned by the current user. This reuses our existing infra we
|
||||
have in place via `ensure_valid_ownership()` and thus allows a user to
|
||||
override the safety guard by adding the source repository path to the
|
||||
"safe.directory" configuration.
|
||||
|
||||
This addresses CVE-2024-32020.
|
||||
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
|
||||
CVE: CVE-2024-32020
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/1204e1a824c34071019fe106348eaa6d88f9528d]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
builtin/clone.c | 14 ++++++++++++++
|
||||
t/t0033-safe-directory.sh | 24 ++++++++++++++++++++++++
|
||||
2 files changed, 38 insertions(+)
|
||||
|
||||
diff --git a/builtin/clone.c b/builtin/clone.c
|
||||
index 4541a55..11f6b4b 100644
|
||||
--- a/builtin/clone.c
|
||||
+++ b/builtin/clone.c
|
||||
@@ -312,6 +312,20 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
|
||||
int iter_status;
|
||||
struct strbuf realpath = STRBUF_INIT;
|
||||
|
||||
+ /*
|
||||
+ * Refuse copying directories by default which aren't owned by us. The
|
||||
+ * code that performs either the copying or hardlinking is not prepared
|
||||
+ * to handle various edge cases where an adversary may for example
|
||||
+ * racily swap out files for symlinks. This can cause us to
|
||||
+ * inadvertently use the wrong source file.
|
||||
+ *
|
||||
+ * Furthermore, even if we were prepared to handle such races safely,
|
||||
+ * creating hardlinks across user boundaries is an inherently unsafe
|
||||
+ * operation as the hardlinked files can be rewritten at will by the
|
||||
+ * potentially-untrusted user. We thus refuse to do so by default.
|
||||
+ */
|
||||
+ die_upon_dubious_ownership(NULL, NULL, src_repo);
|
||||
+
|
||||
mkdir_if_missing(dest->buf, 0777);
|
||||
|
||||
iter = dir_iterator_begin(src->buf, DIR_ITERATOR_PEDANTIC);
|
||||
diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh
|
||||
index 239d93f..751cba5 100755
|
||||
--- a/t/t0033-safe-directory.sh
|
||||
+++ b/t/t0033-safe-directory.sh
|
||||
@@ -46,4 +46,28 @@ test_expect_success 'safe.directory=*, but is reset' '
|
||||
expect_rejected_dir
|
||||
'
|
||||
|
||||
+test_expect_success 'local clone of unowned repo refused in unsafe directory' '
|
||||
+ test_when_finished "rm -rf source" &&
|
||||
+ git init source &&
|
||||
+ (
|
||||
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
|
||||
+ test_commit -C source initial
|
||||
+ ) &&
|
||||
+ test_must_fail git clone --local source target &&
|
||||
+ test_path_is_missing target
|
||||
+'
|
||||
+
|
||||
+test_expect_success 'local clone of unowned repo accepted in safe directory' '
|
||||
+ test_when_finished "rm -rf source" &&
|
||||
+ git init source &&
|
||||
+ (
|
||||
+ sane_unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
|
||||
+ test_commit -C source initial
|
||||
+ ) &&
|
||||
+ test_must_fail git clone --local source target &&
|
||||
+ git config --global --add safe.directory "$(pwd)/source/.git" &&
|
||||
+ git clone --local source target &&
|
||||
+ test_path_is_dir target
|
||||
+'
|
||||
+
|
||||
test_done
|
||||
--
|
||||
2.40.0
|
||||
89
meta/recipes-devtools/git/git/CVE-2024-32021-0001.patch
Normal file
89
meta/recipes-devtools/git/git/CVE-2024-32021-0001.patch
Normal file
@@ -0,0 +1,89 @@
|
||||
From 150e6b0aedf57d224c3c49038c306477fa159886 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Mon, 15 Apr 2024 13:30:26 +0200
|
||||
Subject: [PATCH] builtin/clone: stop resolving symlinks when copying files
|
||||
|
||||
When a user performs a local clone without `--no-local`, then we end up
|
||||
copying the source repository into the target repository directly. To
|
||||
optimize this even further, we try to hardlink files into place instead
|
||||
of copying data over, which helps both disk usage and speed.
|
||||
|
||||
There is an important edge case in this context though, namely when we
|
||||
try to hardlink symlinks from the source repository into the target
|
||||
repository. Depending on both platform and filesystem the resulting
|
||||
behaviour here can be different:
|
||||
|
||||
- On macOS and NetBSD, calling link(3P) with a symlink target creates
|
||||
a hardlink to the file pointed to by the symlink.
|
||||
|
||||
- On Linux, calling link(3P) instead creates a hardlink to the symlink
|
||||
itself.
|
||||
|
||||
To unify this behaviour, 36596fd2df (clone: better handle symlinked
|
||||
files at .git/objects/, 2019-07-10) introduced logic to resolve symlinks
|
||||
before we try to link(3P) files. Consequently, the new behaviour was to
|
||||
always create a hard link to the target of the symlink on all platforms.
|
||||
|
||||
Eventually though, we figured out that following symlinks like this can
|
||||
cause havoc when performing a local clone of a malicious repository,
|
||||
which resulted in CVE-2022-39253. This issue was fixed via 6f054f9fb3
|
||||
(builtin/clone.c: disallow `--local` clones with symlinks, 2022-07-28),
|
||||
by refusing symlinks in the source repository.
|
||||
|
||||
But even though we now shouldn't ever link symlinks anymore, the code
|
||||
that resolves symlinks still exists. In the best case the code does not
|
||||
end up doing anything because there are no symlinks anymore. In the
|
||||
worst case though this can be abused by an adversary that rewrites the
|
||||
source file after it has been checked not to be a symlink such that it
|
||||
actually is a symlink when we call link(3P). Thus, it is still possible
|
||||
to recreate CVE-2022-39253 due to this time-of-check-time-of-use bug.
|
||||
|
||||
Remove the call to `realpath()`. This doesn't yet address the actual
|
||||
vulnerability, which will be handled in a subsequent commit.
|
||||
|
||||
Reported-by: Apple Product Security <product-security@apple.com>
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
|
||||
CVE: CVE-2024-32021
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/150e6b0aedf57d224c3c49038c306477fa159886]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
builtin/clone.c | 6 +-----
|
||||
1 file changed, 1 insertion(+), 5 deletions(-)
|
||||
|
||||
diff --git a/builtin/clone.c b/builtin/clone.c
|
||||
index 11f6b4b..2778d20 100644
|
||||
--- a/builtin/clone.c
|
||||
+++ b/builtin/clone.c
|
||||
@@ -310,7 +310,6 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
|
||||
int src_len, dest_len;
|
||||
struct dir_iterator *iter;
|
||||
int iter_status;
|
||||
- struct strbuf realpath = STRBUF_INIT;
|
||||
|
||||
/*
|
||||
* Refuse copying directories by default which aren't owned by us. The
|
||||
@@ -362,8 +361,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
|
||||
if (unlink(dest->buf) && errno != ENOENT)
|
||||
die_errno(_("failed to unlink '%s'"), dest->buf);
|
||||
if (!option_no_hardlinks) {
|
||||
- strbuf_realpath(&realpath, src->buf, 1);
|
||||
- if (!link(realpath.buf, dest->buf))
|
||||
+ if (!link(src->buf, dest->buf))
|
||||
continue;
|
||||
if (option_local > 0)
|
||||
die_errno(_("failed to create link '%s'"), dest->buf);
|
||||
@@ -377,8 +375,6 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
|
||||
strbuf_setlen(src, src_len);
|
||||
die(_("failed to iterate over '%s'"), src->buf);
|
||||
}
|
||||
-
|
||||
- strbuf_release(&realpath);
|
||||
}
|
||||
|
||||
static void clone_local(const char *src_repo, const char *dest_repo)
|
||||
--
|
||||
2.40.0
|
||||
65
meta/recipes-devtools/git/git/CVE-2024-32021-0002.patch
Normal file
65
meta/recipes-devtools/git/git/CVE-2024-32021-0002.patch
Normal file
@@ -0,0 +1,65 @@
|
||||
From d1bb66a546b4bb46005d17ba711caaad26f26c1e Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
Date: Mon, 15 Apr 2024 13:30:31 +0200
|
||||
Subject: [PATCH] builtin/clone: abort when hardlinked source and target file
|
||||
differ
|
||||
|
||||
When performing local clones with hardlinks we refuse to copy source
|
||||
files which are symlinks as a mitigation for CVE-2022-39253. This check
|
||||
can be raced by an adversary though by changing the file to a symlink
|
||||
after we have checked it.
|
||||
|
||||
Fix the issue by checking whether the hardlinked destination file
|
||||
matches the source file and abort in case it doesn't.
|
||||
|
||||
This addresses CVE-2024-32021.
|
||||
|
||||
Reported-by: Apple Product Security <product-security@apple.com>
|
||||
Suggested-by: Linus Torvalds <torvalds@linuxfoundation.org>
|
||||
Signed-off-by: Patrick Steinhardt <ps@pks.im>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
|
||||
CVE: CVE-2024-32021
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/d1bb66a546b4bb46005d17ba711caaad26f26c1e]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
builtin/clone.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/builtin/clone.c b/builtin/clone.c
|
||||
index 2778d20..54eb441 100644
|
||||
--- a/builtin/clone.c
|
||||
+++ b/builtin/clone.c
|
||||
@@ -361,8 +361,27 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
|
||||
if (unlink(dest->buf) && errno != ENOENT)
|
||||
die_errno(_("failed to unlink '%s'"), dest->buf);
|
||||
if (!option_no_hardlinks) {
|
||||
- if (!link(src->buf, dest->buf))
|
||||
+ if (!link(src->buf, dest->buf)) {
|
||||
+ struct stat st;
|
||||
+
|
||||
+ /*
|
||||
+ * Sanity-check whether the created hardlink
|
||||
+ * actually links to the expected file now. This
|
||||
+ * catches time-of-check-time-of-use bugs in
|
||||
+ * case the source file was meanwhile swapped.
|
||||
+ */
|
||||
+ if (lstat(dest->buf, &st))
|
||||
+ die(_("hardlink cannot be checked at '%s'"), dest->buf);
|
||||
+ if (st.st_mode != iter->st.st_mode ||
|
||||
+ st.st_ino != iter->st.st_ino ||
|
||||
+ st.st_dev != iter->st.st_dev ||
|
||||
+ st.st_size != iter->st.st_size ||
|
||||
+ st.st_uid != iter->st.st_uid ||
|
||||
+ st.st_gid != iter->st.st_gid)
|
||||
+ die(_("hardlink different from source at '%s'"), dest->buf);
|
||||
+
|
||||
continue;
|
||||
+ }
|
||||
if (option_local > 0)
|
||||
die_errno(_("failed to create link '%s'"), dest->buf);
|
||||
option_no_hardlinks = 1;
|
||||
--
|
||||
2.40.0
|
||||
206
meta/recipes-devtools/git/git/CVE-2024-32465.patch
Normal file
206
meta/recipes-devtools/git/git/CVE-2024-32465.patch
Normal file
@@ -0,0 +1,206 @@
|
||||
From 7b70e9efb18c2cc3f219af399bd384c5801ba1d7 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff King <peff@peff.net>
|
||||
Date: Tue, 16 Apr 2024 04:35:33 -0400
|
||||
Subject: [PATCH] upload-pack: disable lazy-fetching by default
|
||||
|
||||
The upload-pack command tries to avoid trusting the repository in which
|
||||
it's run (e.g., by not running any hooks and not using any config that
|
||||
contains arbitrary commands). But if the server side of a fetch or a
|
||||
clone is a partial clone, then either upload-pack or its child
|
||||
pack-objects may run a lazy "git fetch" under the hood. And it is very
|
||||
easy to convince fetch to run arbitrary commands.
|
||||
|
||||
The "server" side can be a local repository owned by someone else, who
|
||||
would be able to configure commands that are run during a clone with the
|
||||
current user's permissions. This issue has been designated
|
||||
CVE-2024-32004.
|
||||
|
||||
The fix in this commit's parent helps in this scenario, as well as in
|
||||
related scenarios using SSH to clone, where the untrusted .git directory
|
||||
is owned by a different user id. But if you received one as a zip file,
|
||||
on a USB stick, etc, it may be owned by your user but still untrusted.
|
||||
|
||||
This has been designated CVE-2024-32465.
|
||||
|
||||
To mitigate the issue more completely, let's disable lazy fetching
|
||||
entirely during `upload-pack`. While fetching from a partial repository
|
||||
should be relatively rare, it is certainly not an unreasonable workflow.
|
||||
And thus we need to provide an escape hatch.
|
||||
|
||||
This commit works by respecting a GIT_NO_LAZY_FETCH environment variable
|
||||
(to skip the lazy-fetch), and setting it in upload-pack, but only when
|
||||
the user has not already done so (which gives us the escape hatch).
|
||||
|
||||
The name of the variable is specifically chosen to match what has
|
||||
already been added in 'master' via e6d5479e7a (git: extend
|
||||
--no-lazy-fetch to work across subprocesses, 2024-02-27). Since we're
|
||||
building this fix as a backport for older versions, we could cherry-pick
|
||||
that patch and its earlier steps. However, we don't really need the
|
||||
niceties (like a "--no-lazy-fetch" option) that it offers. By using the
|
||||
same name, everything should just work when the two are eventually
|
||||
merged, but here are a few notes:
|
||||
|
||||
- the blocking of the fetch in e6d5479e7a is incomplete! It sets
|
||||
fetch_if_missing to 0 when we setup the repository variable, but
|
||||
that isn't enough. pack-objects in particular will call
|
||||
prefetch_to_pack() even if that variable is 0. This patch by
|
||||
contrast checks the environment variable at the lowest level before
|
||||
we call the lazy fetch, where we can be sure to catch all code
|
||||
paths.
|
||||
|
||||
Possibly the setting of fetch_if_missing from e6d5479e7a can be
|
||||
reverted, but it may be useful to have. For example, some code may
|
||||
want to use that flag to change behavior before it gets to the point
|
||||
of trying to start the fetch. At any rate, that's all outside the
|
||||
scope of this patch.
|
||||
|
||||
- there's documentation for GIT_NO_LAZY_FETCH in e6d5479e7a. We can
|
||||
live without that here, because for the most part the user shouldn't
|
||||
need to set it themselves. The exception is if they do want to
|
||||
override upload-pack's default, and that requires a separate
|
||||
documentation section (which is added here)
|
||||
|
||||
- it would be nice to use the NO_LAZY_FETCH_ENVIRONMENT macro added by
|
||||
e6d5479e7a, but those definitions have moved from cache.h to
|
||||
environment.h between 2.39.3 and master. I just used the raw string
|
||||
literals, and we can replace them with the macro once this topic is
|
||||
merged to master.
|
||||
|
||||
At least with respect to CVE-2024-32004, this does render this commit's
|
||||
parent commit somewhat redundant. However, it is worth retaining that
|
||||
commit as defense in depth, and because it may help other issues (e.g.,
|
||||
symlink/hardlink TOCTOU races, where zip files are not really an
|
||||
interesting attack vector).
|
||||
|
||||
The tests in t0411 still pass, but now we have _two_ mechanisms ensuring
|
||||
that the evil command is not run. Let's beef up the existing ones to
|
||||
check that they failed for the expected reason, that we refused to run
|
||||
upload-pack at all with an alternate user id. And add two new ones for
|
||||
the same-user case that both the restriction and its escape hatch.
|
||||
|
||||
Signed-off-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
||||
|
||||
CVE: CVE-2024-32465
|
||||
|
||||
Upstream-Status: Backport [https://github.com/git/git/commit/7b70e9efb18c2cc3f219af399bd384c5801ba1d7]
|
||||
|
||||
Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
|
||||
---
|
||||
Documentation/git-upload-pack.txt | 16 ++++++++++++++++
|
||||
builtin/upload-pack.c | 2 ++
|
||||
promisor-remote.c | 10 ++++++++++
|
||||
t/t0411-clone-from-partial.sh | 18 ++++++++++++++++++
|
||||
4 files changed, 46 insertions(+)
|
||||
|
||||
diff --git a/Documentation/git-upload-pack.txt b/Documentation/git-upload-pack.txt
|
||||
index 8f87b23..eba0e81 100644
|
||||
--- a/Documentation/git-upload-pack.txt
|
||||
+++ b/Documentation/git-upload-pack.txt
|
||||
@@ -56,6 +56,22 @@ ENVIRONMENT
|
||||
admins may need to configure some transports to allow this
|
||||
variable to be passed. See the discussion in linkgit:git[1].
|
||||
|
||||
+`GIT_NO_LAZY_FETCH`::
|
||||
+ When cloning or fetching from a partial repository (i.e., one
|
||||
+ itself cloned with `--filter`), the server-side `upload-pack`
|
||||
+ may need to fetch extra objects from its upstream in order to
|
||||
+ complete the request. By default, `upload-pack` will refuse to
|
||||
+ perform such a lazy fetch, because `git fetch` may run arbitrary
|
||||
+ commands specified in configuration and hooks of the source
|
||||
+ repository (and `upload-pack` tries to be safe to run even in
|
||||
+ untrusted `.git` directories).
|
||||
++
|
||||
+This is implemented by having `upload-pack` internally set the
|
||||
+`GIT_NO_LAZY_FETCH` variable to `1`. If you want to override it
|
||||
+(because you are fetching from a partial clone, and you are sure
|
||||
+you trust it), you can explicitly set `GIT_NO_LAZY_FETCH` to
|
||||
+`0`.
|
||||
+
|
||||
SEE ALSO
|
||||
--------
|
||||
linkgit:gitnamespaces[7]
|
||||
diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c
|
||||
index 125af53..9ecaafe 100644
|
||||
--- a/builtin/upload-pack.c
|
||||
+++ b/builtin/upload-pack.c
|
||||
@@ -34,6 +34,8 @@ int cmd_upload_pack(int argc, const char **argv, const char *prefix)
|
||||
|
||||
packet_trace_identity("upload-pack");
|
||||
read_replace_refs = 0;
|
||||
+ /* TODO: This should use NO_LAZY_FETCH_ENVIRONMENT */
|
||||
+ xsetenv("GIT_NO_LAZY_FETCH", "1", 0);
|
||||
|
||||
argc = parse_options(argc, argv, prefix, options, upload_pack_usage, 0);
|
||||
|
||||
diff --git a/promisor-remote.c b/promisor-remote.c
|
||||
index db2ebdc..e73df68 100644
|
||||
--- a/promisor-remote.c
|
||||
+++ b/promisor-remote.c
|
||||
@@ -19,6 +19,16 @@ static int fetch_objects(struct repository *repo,
|
||||
int i;
|
||||
FILE *child_in;
|
||||
|
||||
+ /* TODO: This should use NO_LAZY_FETCH_ENVIRONMENT */
|
||||
+ if (git_env_bool("GIT_NO_LAZY_FETCH", 0)) {
|
||||
+ static int warning_shown;
|
||||
+ if (!warning_shown) {
|
||||
+ warning_shown = 1;
|
||||
+ warning(_("lazy fetching disabled; some objects may not be available"));
|
||||
+ }
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
child.git_cmd = 1;
|
||||
child.in = -1;
|
||||
if (repo != the_repository)
|
||||
diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh
|
||||
index eb3360d..b3d6ddc 100755
|
||||
--- a/t/t0411-clone-from-partial.sh
|
||||
+++ b/t/t0411-clone-from-partial.sh
|
||||
@@ -28,6 +28,7 @@ test_expect_success 'local clone must not fetch from promisor remote and execute
|
||||
test_must_fail git clone \
|
||||
--upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
evil clone1 2>err &&
|
||||
+ grep "detected dubious ownership" err &&
|
||||
! grep "fake-upload-pack running" err &&
|
||||
test_path_is_missing script-executed
|
||||
'
|
||||
@@ -37,6 +38,7 @@ test_expect_success 'clone from file://... must not fetch from promisor remote a
|
||||
test_must_fail git clone \
|
||||
--upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
"file://$(pwd)/evil" clone2 2>err &&
|
||||
+ grep "detected dubious ownership" err &&
|
||||
! grep "fake-upload-pack running" err &&
|
||||
test_path_is_missing script-executed
|
||||
'
|
||||
@@ -46,6 +48,7 @@ test_expect_success 'fetch from file://... must not fetch from promisor remote a
|
||||
test_must_fail git fetch \
|
||||
--upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \
|
||||
"file://$(pwd)/evil" 2>err &&
|
||||
+ grep "detected dubious ownership" err &&
|
||||
! grep "fake-upload-pack running" err &&
|
||||
test_path_is_missing script-executed
|
||||
'
|
||||
@@ -57,4 +60,19 @@ test_expect_success 'pack-objects should fetch from promisor remote and execute
|
||||
test_path_is_file script-executed
|
||||
'
|
||||
|
||||
+test_expect_success 'clone from promisor remote does not lazy-fetch by default' '
|
||||
+ rm -f script-executed &&
|
||||
+ test_must_fail git clone evil no-lazy 2>err &&
|
||||
+ grep "lazy fetching disabled" err &&
|
||||
+ test_path_is_missing script-executed
|
||||
+'
|
||||
+
|
||||
+test_expect_success 'promisor lazy-fetching can be re-enabled' '
|
||||
+ rm -f script-executed &&
|
||||
+ test_must_fail env GIT_NO_LAZY_FETCH=0 \
|
||||
+ git clone evil lazy-ok 2>err &&
|
||||
+ grep "fake-upload-pack running" err &&
|
||||
+ test_path_is_file script-executed
|
||||
+'
|
||||
+
|
||||
test_done
|
||||
--
|
||||
2.40.0
|
||||
@@ -12,6 +12,17 @@ SRC_URI = "${KERNELORG_MIRROR}/software/scm/git/git-${PV}.tar.gz;name=tarball \
|
||||
file://0001-config.mak.uname-do-not-force-RHEL-7-specific-build-.patch \
|
||||
file://CVE-2023-29007.patch \
|
||||
file://CVE-2023-25652.patch \
|
||||
file://CVE-2024-32002-0001.patch \
|
||||
file://CVE-2024-32002-0002.patch \
|
||||
file://CVE-2024-32002-0003.patch \
|
||||
file://CVE-2024-32002-0004.patch \
|
||||
file://CVE-2024-32004-0001.patch \
|
||||
file://CVE-2024-32004-0002.patch \
|
||||
file://CVE-2024-32004-0003.patch \
|
||||
file://CVE-2024-32020.patch \
|
||||
file://CVE-2024-32021-0001.patch \
|
||||
file://CVE-2024-32021-0002.patch \
|
||||
file://CVE-2024-32465.patch \
|
||||
"
|
||||
|
||||
S = "${WORKDIR}/git-${PV}"
|
||||
|
||||
@@ -55,6 +55,7 @@ SRC_URI += "\
|
||||
file://CVE-2023-45290.patch \
|
||||
file://CVE-2024-24784.patch \
|
||||
file://CVE-2024-24785.patch \
|
||||
file://CVE-2023-45288.patch \
|
||||
"
|
||||
SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd"
|
||||
|
||||
|
||||
95
meta/recipes-devtools/go/go-1.18/CVE-2023-45288.patch
Normal file
95
meta/recipes-devtools/go/go-1.18/CVE-2023-45288.patch
Normal file
@@ -0,0 +1,95 @@
|
||||
From e55d7cf8435ba4e58d4a5694e63b391821d4ee9b Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Thu, 28 Mar 2024 16:57:51 -0700
|
||||
Subject: [PATCH] [release-branch.go1.22] net/http: update bundled
|
||||
golang.org/x/net/http2
|
||||
|
||||
Disable cmd/internal/moddeps test, since this update includes PRIVATE
|
||||
track fixes.
|
||||
|
||||
Fixes CVE-2023-45288
|
||||
For #65051
|
||||
Fixes #66298
|
||||
|
||||
Change-Id: I5bbf774ebe7651e4bb7e55139d3794bd2b8e8fa8
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2197227
|
||||
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||
Run-TryBot: Damien Neil <dneil@google.com>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/576076
|
||||
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
|
||||
TryBot-Bypass: Dmitri Shuralyov <dmitshur@google.com>
|
||||
Reviewed-by: Than McIntosh <thanm@google.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/e55d7cf8435ba4e58d4a5694e63b391821d4ee9b]
|
||||
CVE: CVE-2023-45288
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/cmd/internal/moddeps/moddeps_test.go | 1 +
|
||||
src/net/http/h2_bundle.go | 31 ++++++++++++++++++++++++
|
||||
2 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/src/cmd/internal/moddeps/moddeps_test.go b/src/cmd/internal/moddeps/moddeps_test.go
|
||||
index d48d43f..250bde4 100644
|
||||
--- a/src/cmd/internal/moddeps/moddeps_test.go
|
||||
+++ b/src/cmd/internal/moddeps/moddeps_test.go
|
||||
@@ -34,6 +34,7 @@ import (
|
||||
// See issues 36852, 41409, and 43687.
|
||||
// (Also see golang.org/issue/27348.)
|
||||
func TestAllDependencies(t *testing.T) {
|
||||
+ t.Skip("TODO(#65051): 1.22.2 contains unreleased changes from vendored modules")
|
||||
t.Skip("TODO(#57009): 1.19.4 contains unreleased changes from vendored modules")
|
||||
t.Skip("TODO(#53977): 1.18.5 contains unreleased changes from vendored modules")
|
||||
|
||||
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
|
||||
index 9d6abd8..10ff193 100644
|
||||
--- a/src/net/http/h2_bundle.go
|
||||
+++ b/src/net/http/h2_bundle.go
|
||||
@@ -2842,6 +2842,7 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr
|
||||
if size > remainSize {
|
||||
hdec.SetEmitEnabled(false)
|
||||
mh.Truncated = true
|
||||
+ remainSize = 0
|
||||
return
|
||||
}
|
||||
remainSize -= size
|
||||
@@ -2854,6 +2855,36 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr
|
||||
var hc http2headersOrContinuation = hf
|
||||
for {
|
||||
frag := hc.HeaderBlockFragment()
|
||||
+
|
||||
+ // Avoid parsing large amounts of headers that we will then discard.
|
||||
+ // If the sender exceeds the max header list size by too much,
|
||||
+ // skip parsing the fragment and close the connection.
|
||||
+ //
|
||||
+ // "Too much" is either any CONTINUATION frame after we've already
|
||||
+ // exceeded the max header list size (in which case remainSize is 0),
|
||||
+ // or a frame whose encoded size is more than twice the remaining
|
||||
+ // header list bytes we're willing to accept.
|
||||
+ if int64(len(frag)) > int64(2*remainSize) {
|
||||
+ if http2VerboseLogs {
|
||||
+ log.Printf("http2: header list too large")
|
||||
+ }
|
||||
+ // It would be nice to send a RST_STREAM before sending the GOAWAY,
|
||||
+ // but the struture of the server's frame writer makes this difficult.
|
||||
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
|
||||
+ }
|
||||
+
|
||||
+ // Also close the connection after any CONTINUATION frame following an
|
||||
+ // invalid header, since we stop tracking the size of the headers after
|
||||
+ // an invalid one.
|
||||
+ if invalid != nil {
|
||||
+ if http2VerboseLogs {
|
||||
+ log.Printf("http2: invalid header: %v", invalid)
|
||||
+ }
|
||||
+ // It would be nice to send a RST_STREAM before sending the GOAWAY,
|
||||
+ // but the struture of the server's frame writer makes this difficult.
|
||||
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
|
||||
+ }
|
||||
+
|
||||
if _, err := hdec.Write(frag); err != nil {
|
||||
return nil, http2ConnectionError(http2ErrCodeCompression)
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -44,7 +44,7 @@ SRC_URI:append:class-native = " \
|
||||
file://12-distutils-prefix-is-inside-staging-area.patch \
|
||||
file://0001-Don-t-search-system-for-headers-libraries.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "5c88848668640d3e152b35b4536ef1c23b2ca4bd2c957ef1ecbb053f571dd3f6"
|
||||
SRC_URI[sha256sum] = "9c50481faa8c2832329ba0fc8868d0a606a680fc4f60ec48d26ce8e076751fda"
|
||||
|
||||
# exclude pre-releases for both python 2.x and 3.x
|
||||
UPSTREAM_CHECK_REGEX = "[Pp]ython-(?P<pver>\d+(\.\d+)+).tar"
|
||||
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
|
||||
@@ -34,6 +34,7 @@ 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 \
|
||||
"
|
||||
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,43 @@
|
||||
From 1ff9a695947967d2d327c45bf5145dd381fc1745 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Liddell <chris.liddell@artifex.com>
|
||||
Date: Tue, 12 Sep 2023 10:46:10 +0100
|
||||
Subject: [PATCH 5/5] In SAFER (default) don't allow eexec seeds other than the
|
||||
Type 1 standard
|
||||
|
||||
CVE: CVE-2023-52722
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=1ff9a695947967d2d327]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
psi/zmisc1.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/psi/zmisc1.c b/psi/zmisc1.c
|
||||
index 3c47e99..81556ac 100644
|
||||
--- a/psi/zmisc1.c
|
||||
+++ b/psi/zmisc1.c
|
||||
@@ -93,6 +93,9 @@ zexE(i_ctx_t *i_ctx_p)
|
||||
|
||||
if (code < 0)
|
||||
return code;
|
||||
+ if (gs_is_path_control_active(imemory) != 0 && state.cstate != 55665) {
|
||||
+ return_error(gs_error_rangecheck);
|
||||
+ }
|
||||
return filter_write(i_ctx_p, code, &s_exE_template, (stream_state *)&state, 0);
|
||||
}
|
||||
|
||||
@@ -130,6 +133,11 @@ zexD(i_ctx_t *i_ctx_p)
|
||||
}
|
||||
if (code < 0)
|
||||
return code;
|
||||
+
|
||||
+ if (gs_is_path_control_active(imemory) != 0 && state.cstate != 55665) {
|
||||
+ return_error(gs_error_rangecheck);
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* If we're reading a .PFB file, let the filter know about it,
|
||||
* so it can read recklessly to the end of the binary section.
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,84 @@
|
||||
From 3b1735085ecef20b29e8db3416ab36de93e86d1f Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Thu, 21 Mar 2024 09:01:15 +0000
|
||||
Subject: [PATCH 4/5] Uniprint device - prevent string configuration changes
|
||||
when SAFER
|
||||
|
||||
Bug #707662
|
||||
|
||||
We cannot sanitise the string arguments used by the Uniprint device
|
||||
because they can potentially include anything.
|
||||
|
||||
This commit ensures that these strings are locked and cannot be
|
||||
changed by PostScript once SAFER is activated. Full configuration from
|
||||
the command line is still possible (see the *.upp files in lib).
|
||||
|
||||
This addresses CVE-2024-29510
|
||||
|
||||
CVE: CVE-2024-29510
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=3b1735085ecef20b29e]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
devices/gdevupd.c | 31 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 31 insertions(+)
|
||||
|
||||
diff --git a/devices/gdevupd.c b/devices/gdevupd.c
|
||||
index 6635984..7952165 100644
|
||||
--- a/devices/gdevupd.c
|
||||
+++ b/devices/gdevupd.c
|
||||
@@ -1886,6 +1886,16 @@ out on this copies.
|
||||
if(!upd_strings[i]) continue;
|
||||
UPD_PARAM_READ(param_read_string,upd_strings[i],value,udev->memory);
|
||||
if(0 == code) {
|
||||
+ if (gs_is_path_control_active(udev->memory)) {
|
||||
+ if (strings[i].size != value.size)
|
||||
+ error = gs_error_invalidaccess;
|
||||
+ else {
|
||||
+ if (strings[i].data && memcmp(strings[i].data, value.data, strings[i].size) != 0)
|
||||
+ error = gs_error_invalidaccess;
|
||||
+ }
|
||||
+ if (error < 0)
|
||||
+ goto exit;
|
||||
+ }
|
||||
if(0 <= error) error |= UPD_PUT_STRINGS;
|
||||
UPD_MM_DEL_PARAM(udev->memory, strings[i]);
|
||||
if(!value.size) {
|
||||
@@ -1903,6 +1913,26 @@ out on this copies.
|
||||
if(!upd_string_a[i]) continue;
|
||||
UPD_PARAM_READ(param_read_string_array,upd_string_a[i],value,udev->memory);
|
||||
if(0 == code) {
|
||||
+ if (gs_is_path_control_active(udev->memory)) {
|
||||
+ if (string_a[i].size != value.size)
|
||||
+ error = gs_error_invalidaccess;
|
||||
+ else {
|
||||
+ int loop;
|
||||
+ for (loop = 0;loop < string_a[i].size;loop++) {
|
||||
+ gs_param_string *tmp1 = (gs_param_string *)&(string_a[i].data[loop]);
|
||||
+ gs_param_string *tmp2 = (gs_param_string *)&value.data[loop];
|
||||
+
|
||||
+ if (tmp1->size != tmp2->size)
|
||||
+ error = gs_error_invalidaccess;
|
||||
+ else {
|
||||
+ if (tmp1->data && memcmp(tmp1->data, tmp2->data, tmp1->size) != 0)
|
||||
+ error = gs_error_invalidaccess;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (error < 0)
|
||||
+ goto exit;
|
||||
+ }
|
||||
if(0 <= error) error |= UPD_PUT_STRING_A;
|
||||
UPD_MM_DEL_APARAM(udev->memory, string_a[i]);
|
||||
if(!value.size) {
|
||||
@@ -2097,6 +2127,7 @@ transferred into the device-structure. In the case of "uniprint", this may
|
||||
if(0 > code) error = code;
|
||||
}
|
||||
|
||||
+exit:
|
||||
if(0 < error) { /* Actually something loaded without error */
|
||||
|
||||
if(!(upd = udev->upd)) {
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,39 @@
|
||||
From 5ae2e320d69a7d0973011796bd388cd5befa1a43 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Tue, 26 Mar 2024 12:02:57 +0000
|
||||
Subject: [PATCH 2/5] Bug #707691
|
||||
|
||||
Part 1; when stripping a potential Current Working Dirctory specifier
|
||||
from a path, make certain it really is a CWD, and not simply large
|
||||
ebough to be a CWD.
|
||||
|
||||
Reasons are in the bug thread, this is not (IMO) serious.
|
||||
|
||||
This is part of the fix for CVE-2024-33869
|
||||
|
||||
CVE: CVE-2024-33869
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=5ae2e320d69a7d0973]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
base/gpmisc.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/base/gpmisc.c b/base/gpmisc.c
|
||||
index 3b6fffa..a0b58c8 100644
|
||||
--- a/base/gpmisc.c
|
||||
+++ b/base/gpmisc.c
|
||||
@@ -1162,8 +1162,8 @@ gp_validate_path_len(const gs_memory_t *mem,
|
||||
|
||||
continue;
|
||||
}
|
||||
- else if (code < 0 && cdirstrl > 0 && prefix_len == 0 && buffer == bufferfull) {
|
||||
- buffer = bufferfull + cdirstrl + dirsepstrl;
|
||||
+ else if (code < 0 && cdirstrl > 0 && prefix_len == 0 && buffer == bufferfull
|
||||
+ && memcmp(buffer, cdirstr, cdirstrl) && !memcmp(buffer + cdirstrl, dirsepstr, dirsepstrl)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,52 @@
|
||||
From f5336e5b4154f515ac83bc5b9eba94302e6618d4 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Tue, 26 Mar 2024 12:07:18 +0000
|
||||
Subject: [PATCH 3/5] Bug 707691 part 2
|
||||
|
||||
See bug thread for details
|
||||
|
||||
This is the second part of the fix for CVE-2024-33869
|
||||
|
||||
CVE: CVE-2024-33869
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=f5336e5b4154f515ac83]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
base/gpmisc.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/base/gpmisc.c b/base/gpmisc.c
|
||||
index a0b58c8..69bee47 100644
|
||||
--- a/base/gpmisc.c
|
||||
+++ b/base/gpmisc.c
|
||||
@@ -1089,6 +1089,27 @@ gp_validate_path_len(const gs_memory_t *mem,
|
||||
rlen = len;
|
||||
}
|
||||
else {
|
||||
+ char *test = (char *)path, *test1;
|
||||
+ uint tlen = len, slen;
|
||||
+
|
||||
+ /* Look for any pipe (%pipe% or '|' specifications between path separators
|
||||
+ * Reject any path spec which has a %pipe% or '|' anywhere except at the start.
|
||||
+ */
|
||||
+ while (tlen > 0) {
|
||||
+ if (test[0] == '|' || (tlen > 5 && memcmp(test, "%pipe", 5) == 0)) {
|
||||
+ code = gs_note_error(gs_error_invalidfileaccess);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ test1 = test;
|
||||
+ slen = search_separator((const char **)&test, path + len, test1, 1);
|
||||
+ if(slen == 0)
|
||||
+ break;
|
||||
+ test += slen;
|
||||
+ tlen -= test - test1;
|
||||
+ if (test >= path + len)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
rlen = len+1;
|
||||
bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path");
|
||||
if (bufferfull == NULL)
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,92 @@
|
||||
From 79aef19c685984dc3da2dc090450407d9fbcff80 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <Ken.Sharp@artifex.com>
|
||||
Date: Tue, 26 Mar 2024 12:00:14 +0000
|
||||
Subject: [PATCH 1/5] Bug #707686
|
||||
|
||||
See bug thread for details
|
||||
|
||||
In addition to the noted bug; an error path (return from
|
||||
gp_file_name_reduce not successful) could elad to a memory leak as we
|
||||
did not free 'bufferfull'. Fix that too.
|
||||
|
||||
This addresses CVE-2024-33870
|
||||
|
||||
CVE: CVE-2024-33870
|
||||
|
||||
Upstream-Status: Backport [https://cgit.ghostscript.com/cgi-bin/cgit.cgi/ghostpdl.git/commit/?id=79aef19c685984dc]
|
||||
|
||||
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
|
||||
---
|
||||
base/gpmisc.c | 33 ++++++++++++++++++++++++++++++---
|
||||
1 file changed, 30 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/base/gpmisc.c b/base/gpmisc.c
|
||||
index f9a9230..3b6fffa 100644
|
||||
--- a/base/gpmisc.c
|
||||
+++ b/base/gpmisc.c
|
||||
@@ -1042,7 +1042,7 @@ gp_validate_path_len(const gs_memory_t *mem,
|
||||
const uint len,
|
||||
const char *mode)
|
||||
{
|
||||
- char *buffer, *bufferfull;
|
||||
+ char *buffer, *bufferfull = NULL;
|
||||
uint rlen;
|
||||
int code = 0;
|
||||
const char *cdirstr = gp_file_name_current();
|
||||
@@ -1095,8 +1095,10 @@ gp_validate_path_len(const gs_memory_t *mem,
|
||||
return gs_error_VMerror;
|
||||
|
||||
buffer = bufferfull + prefix_len;
|
||||
- if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
|
||||
- return gs_error_invalidfileaccess;
|
||||
+ if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) {
|
||||
+ code = gs_note_error(gs_error_invalidfileaccess);
|
||||
+ goto exit;
|
||||
+ }
|
||||
buffer[rlen] = 0;
|
||||
}
|
||||
while (1) {
|
||||
@@ -1131,9 +1133,33 @@ gp_validate_path_len(const gs_memory_t *mem,
|
||||
code = gs_note_error(gs_error_invalidfileaccess);
|
||||
}
|
||||
if (code < 0 && prefix_len > 0 && buffer > bufferfull) {
|
||||
+ uint newlen = rlen + cdirstrl + dirsepstrl;
|
||||
+ char *newbuffer;
|
||||
+ int code;
|
||||
+
|
||||
buffer = bufferfull;
|
||||
memcpy(buffer, cdirstr, cdirstrl);
|
||||
memcpy(buffer + cdirstrl, dirsepstr, dirsepstrl);
|
||||
+ /* We've prepended a './' or similar for the current working directory. We need
|
||||
+ * to execute file_name_reduce on that, to eliminate any '../' or similar from
|
||||
+ * the (new) full path.
|
||||
+ */
|
||||
+ newbuffer = (char *)gs_alloc_bytes(mem->thread_safe_memory, newlen + 1, "gp_validate_path");
|
||||
+ if (newbuffer == NULL) {
|
||||
+ code = gs_note_error(gs_error_VMerror);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
+ memcpy(newbuffer, buffer, rlen + cdirstrl + dirsepstrl);
|
||||
+ newbuffer[newlen] = 0x00;
|
||||
+
|
||||
+ code = gp_file_name_reduce(newbuffer, (uint)newlen, buffer, &newlen);
|
||||
+ gs_free_object(mem->thread_safe_memory, newbuffer, "gp_validate_path");
|
||||
+ if (code != gp_combine_success) {
|
||||
+ code = gs_note_error(gs_error_invalidfileaccess);
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
continue;
|
||||
}
|
||||
else if (code < 0 && cdirstrl > 0 && prefix_len == 0 && buffer == bufferfull) {
|
||||
@@ -1152,6 +1178,7 @@ gp_validate_path_len(const gs_memory_t *mem,
|
||||
gs_path_control_flag_is_scratch_file);
|
||||
}
|
||||
|
||||
+exit:
|
||||
gs_free_object(mem->thread_safe_memory, bufferfull, "gp_validate_path");
|
||||
#ifdef EACCES
|
||||
if (code == gs_error_invalidfileaccess)
|
||||
--
|
||||
2.40.0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user