mirror of
https://git.yoctoproject.org/poky
synced 2026-02-21 17:09:42 +01:00
Compare commits
130 Commits
yocto-3.1.
...
dunfell-23
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
926eb08fe3 | ||
|
|
6d6d43248e | ||
|
|
b222a20f8f | ||
|
|
55b09cdc1c | ||
|
|
87f18a42d4 | ||
|
|
3978003135 | ||
|
|
7fc94c93bf | ||
|
|
02356ecdca | ||
|
|
0cbec779f5 | ||
|
|
a1886b3532 | ||
|
|
9e2099f2a8 | ||
|
|
c3d7af5d16 | ||
|
|
a0615a08c5 | ||
|
|
b347ccc7ce | ||
|
|
c58cd65c96 | ||
|
|
ea56bba866 | ||
|
|
1b52dc0663 | ||
|
|
b48424988a | ||
|
|
0485ee7a6b | ||
|
|
90175073f6 | ||
|
|
0121cb4bd1 | ||
|
|
2f978be9e2 | ||
|
|
471e51b18a | ||
|
|
1a6ed0befd | ||
|
|
3fdec9fd90 | ||
|
|
b1fdc92450 | ||
|
|
02cfe361d6 | ||
|
|
8ae48ddf5e | ||
|
|
9fa49f817d | ||
|
|
84c0692d57 | ||
|
|
b1f23e404c | ||
|
|
b4da5c4df4 | ||
|
|
c06bf61270 | ||
|
|
827548d7f7 | ||
|
|
c314fe22fd | ||
|
|
6351d145ba | ||
|
|
268614c13d | ||
|
|
d148690f1d | ||
|
|
bce2280258 | ||
|
|
995f3a6243 | ||
|
|
98d8fdd7ea | ||
|
|
6b17a4af6a | ||
|
|
5e47346311 | ||
|
|
d76406934a | ||
|
|
9ffd5243e9 | ||
|
|
e33ce6f1af | ||
|
|
3b52050443 | ||
|
|
959e7b1432 | ||
|
|
729e5e306f | ||
|
|
3e0bb5455b | ||
|
|
3afaf243ba | ||
|
|
00ba8af956 | ||
|
|
3c6a02f04a | ||
|
|
ebca640cbb | ||
|
|
b5f81a875d | ||
|
|
2ff427ee40 | ||
|
|
0de5f6a27a | ||
|
|
f7f7d5514c | ||
|
|
762bfb5fc5 | ||
|
|
dcc4dbf463 | ||
|
|
91feb9b975 | ||
|
|
32da5ee951 | ||
|
|
88bec50206 | ||
|
|
aa5a1adb60 | ||
|
|
df86cc15d0 | ||
|
|
9c828566b2 | ||
|
|
d7ef6fd67c | ||
|
|
6e42635ae0 | ||
|
|
f8a370159b | ||
|
|
7ac47c90cc | ||
|
|
5de95d9c29 | ||
|
|
a022b1abef | ||
|
|
228d031f73 | ||
|
|
a04b507d39 | ||
|
|
0bf993da8b | ||
|
|
5b0daa0061 | ||
|
|
fcb0381657 | ||
|
|
1adc1600f2 | ||
|
|
218ca73cab | ||
|
|
ed4a2d3d41 | ||
|
|
8b1211f81f | ||
|
|
87f16e1f3b | ||
|
|
579797adab | ||
|
|
9faca1f692 | ||
|
|
6c5b006a10 | ||
|
|
5e9e50e544 | ||
|
|
60cd2c29ea | ||
|
|
122c106794 | ||
|
|
65c2f76dca | ||
|
|
a16a21af9a | ||
|
|
84ef58ae39 | ||
|
|
e146653c21 | ||
|
|
b30e81df2b | ||
|
|
0a24a5bb3b | ||
|
|
f506b0c057 | ||
|
|
4cfb4fc8ed | ||
|
|
e211a16fb5 | ||
|
|
82fd9eb08f | ||
|
|
f3a78fecc2 | ||
|
|
8c4bad844f | ||
|
|
2ae4aff0a6 | ||
|
|
55750ffd78 | ||
|
|
70d75e8996 | ||
|
|
b994c2d4f5 | ||
|
|
eb7bb5b589 | ||
|
|
bc3497092e | ||
|
|
642040373e | ||
|
|
a6f3173407 | ||
|
|
00277476e3 | ||
|
|
8f837940fd | ||
|
|
74b8f9ee39 | ||
|
|
7256436957 | ||
|
|
f25b363233 | ||
|
|
2474c30274 | ||
|
|
5ca4b2a548 | ||
|
|
a84a25acc5 | ||
|
|
c8f5ff0ffe | ||
|
|
822d364542 | ||
|
|
b01dd27a8d | ||
|
|
42a4f98ab5 | ||
|
|
756bae9bf9 | ||
|
|
ec29356556 | ||
|
|
f6f1b85384 | ||
|
|
6dcf266eb4 | ||
|
|
5ea3190383 | ||
|
|
5127d99785 | ||
|
|
ff22728dd5 | ||
|
|
af419f2429 | ||
|
|
04003b36bf | ||
|
|
800b69b78b |
@@ -1975,11 +1975,19 @@ class RunQueueExecute:
|
||||
self.setbuildable(revdep)
|
||||
logger.debug(1, "Marking task %s as buildable", revdep)
|
||||
|
||||
for t in self.sq_deferred.copy():
|
||||
found = None
|
||||
for t in sorted(self.sq_deferred.copy()):
|
||||
if self.sq_deferred[t] == task:
|
||||
logger.debug(2, "Deferred task %s now buildable" % t)
|
||||
del self.sq_deferred[t]
|
||||
update_scenequeue_data([t], self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self, summary=False)
|
||||
# Allow the next deferred task to run. Any other deferred tasks should be deferred after that task.
|
||||
# We shouldn't allow all to run at once as it is prone to races.
|
||||
if not found:
|
||||
bb.note("Deferred task %s now buildable" % t)
|
||||
del self.sq_deferred[t]
|
||||
update_scenequeue_data([t], self.sqdata, self.rqdata, self.rq, self.cooker, self.stampcache, self, summary=False)
|
||||
found = t
|
||||
else:
|
||||
bb.note("Deferring %s after %s" % (t, found))
|
||||
self.sq_deferred[t] = found
|
||||
|
||||
def task_complete(self, task):
|
||||
self.stats.taskCompleted()
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
DISTRO : "3.1.26"
|
||||
DISTRO : "3.1.28"
|
||||
DISTRO_NAME_NO_CAP : "dunfell"
|
||||
DISTRO_NAME : "Dunfell"
|
||||
DISTRO_NAME_NO_CAP_MINUS_ONE : "zeus"
|
||||
YOCTO_DOC_VERSION : "3.1.26"
|
||||
YOCTO_DOC_VERSION : "3.1.28"
|
||||
YOCTO_DOC_VERSION_MINUS_ONE : "3.0.4"
|
||||
DISTRO_REL_TAG : "yocto-3.1.26"
|
||||
DOCCONF_VERSION : "3.1.26"
|
||||
DISTRO_REL_TAG : "yocto-3.1.28"
|
||||
DOCCONF_VERSION : "3.1.28"
|
||||
BITBAKE_SERIES : "1.46"
|
||||
POKYVERSION : "23.0.26"
|
||||
POKYVERSION : "23.0.28"
|
||||
YOCTO_POKY : "poky-&DISTRO_NAME_NO_CAP;-&POKYVERSION;"
|
||||
YOCTO_DL_URL : "https://downloads.yoctoproject.org"
|
||||
YOCTO_AB_URL : "https://autobuilder.yoctoproject.org"
|
||||
|
||||
@@ -14,16 +14,17 @@ image you want.
|
||||
Building an image without GNU General Public License Version 3
|
||||
(GPLv3), GNU Lesser General Public License Version 3 (LGPLv3), and
|
||||
the GNU Affero General Public License Version 3 (AGPL-3.0) components
|
||||
is only supported for minimal and base images. Furthermore, if you
|
||||
are going to build an image using non-GPLv3 and similarly licensed
|
||||
components, you must make the following changes in the ``local.conf``
|
||||
file before using the BitBake command to build the minimal or base
|
||||
image:
|
||||
::
|
||||
is only tested for core-image-minimal image. Furthermore, if you would like to
|
||||
build an image and verify that it does not include GPLv3 and similarly licensed
|
||||
components, you must make the following changes in the image recipe
|
||||
file before using the BitBake command to build the image:
|
||||
|
||||
1. Comment out the EXTRA_IMAGE_FEATURES line
|
||||
2. Set INCOMPATIBLE_LICENSE = "GPL-3.0 LGPL-3.0 AGPL-3.0"
|
||||
INCOMPATIBLE_LICENSE = "GPL-3.0* LGPL-3.0*"
|
||||
|
||||
Alternatively, you can adjust ``local.conf`` file, repeating and adjusting the line
|
||||
for all images where the license restriction must apply:
|
||||
|
||||
INCOMPATIBLE_LICENSE_pn-your-image-name = "GPL-3.0* LGPL-3.0*"
|
||||
|
||||
From within the ``poky`` Git repository, you can use the following
|
||||
command to display the list of directories within the :term:`Source Directory`
|
||||
|
||||
@@ -34,19 +34,35 @@ and conceptual information in the :doc:`../overview-manual/overview-manual`.
|
||||
Supported Linux Distributions
|
||||
=============================
|
||||
|
||||
Currently, the Yocto Project is supported on the following
|
||||
distributions:
|
||||
Currently, the &DISTRO; release ("&DISTRO_NAME;") of the Yocto Project is
|
||||
supported on the following distributions:
|
||||
|
||||
- Ubuntu 16.04 (LTS)
|
||||
|
||||
- Ubuntu 20.04 (LTS)
|
||||
|
||||
- Ubuntu 22.04 (LTS)
|
||||
|
||||
- Fedora 37
|
||||
|
||||
- Debian GNU/Linux 11.x (Bullseye)
|
||||
|
||||
- AlmaLinux 8.8
|
||||
|
||||
The following distribution versions are still tested (being listed
|
||||
in :term:`SANITY_TESTED_DISTROS`), even though the organizations
|
||||
publishing them no longer make updates publicly available:
|
||||
|
||||
- Ubuntu 18.04 (LTS)
|
||||
|
||||
- OpenSUSE Leap 15.3
|
||||
|
||||
Finally, here are the distribution versions which were previously
|
||||
tested on former revisions of "&DISTRO_NAME;", but no longer are:
|
||||
|
||||
- Ubuntu 16.04 (LTS)
|
||||
|
||||
- Ubuntu 19.04
|
||||
|
||||
- Ubuntu 20.04
|
||||
|
||||
- Ubuntu 22.04
|
||||
|
||||
- Fedora 28
|
||||
|
||||
- Fedora 29
|
||||
@@ -67,20 +83,18 @@ distributions:
|
||||
|
||||
- CentOS 7.x
|
||||
|
||||
- CentOS 8.x
|
||||
|
||||
- Debian GNU/Linux 8.x (Jessie)
|
||||
|
||||
- Debian GNU/Linux 9.x (Stretch)
|
||||
|
||||
- Debian GNU/Linux 10.x (Buster)
|
||||
|
||||
- Debian GNU/Linux 11.x (Bullseye)
|
||||
|
||||
- OpenSUSE Leap 15.1
|
||||
|
||||
- OpenSUSE Leap 15.2
|
||||
|
||||
- OpenSUSE Leap 15.3
|
||||
|
||||
- AlmaLinux 8.5
|
||||
|
||||
- AlmaLinux 8.7
|
||||
|
||||
@@ -3337,9 +3337,18 @@ system and gives an overview of their function and contents.
|
||||
:term:`INCOMPATIBLE_LICENSE`
|
||||
Specifies a space-separated list of license names (as they would
|
||||
appear in :term:`LICENSE`) that should be excluded
|
||||
from the build. Recipes that provide no alternatives to listed
|
||||
from the build (if set globally), or from an image (if set locally
|
||||
in an image recipe).
|
||||
|
||||
When the variable is set globally, recipes that provide no alternatives to listed
|
||||
incompatible licenses are not built. Packages that are individually
|
||||
licensed with the specified incompatible licenses will be deleted.
|
||||
Most of the time this does not allow a feasible build (because it becomes impossible
|
||||
to satisfy build time dependencies), so the recommended way to
|
||||
implement license restrictions is to set the variable in specific
|
||||
image recipes where the restrictions must apply. That way there
|
||||
are no build time restrictions, but the license check is still
|
||||
performed when the image's filesystem is assembled from packages.
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
DISTRO = "poky"
|
||||
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
|
||||
DISTRO_VERSION = "3.1.26"
|
||||
DISTRO_VERSION = "3.1.28"
|
||||
DISTRO_CODENAME = "dunfell"
|
||||
SDK_VENDOR = "-pokysdk"
|
||||
SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${DATE}', 'snapshot')}"
|
||||
@@ -43,29 +43,13 @@ SANITY_TESTED_DISTROS ?= " \
|
||||
poky-2.7 \n \
|
||||
poky-3.0 \n \
|
||||
poky-3.1 \n \
|
||||
ubuntu-16.04 \n \
|
||||
ubuntu-18.04 \n \
|
||||
ubuntu-19.04 \n \
|
||||
ubuntu-20.04 \n \
|
||||
ubuntu-22.04 \n \
|
||||
fedora-30 \n \
|
||||
fedora-31 \n \
|
||||
fedora-32 \n \
|
||||
fedora-33 \n \
|
||||
fedora-34 \n \
|
||||
fedora-35 \n \
|
||||
fedora-36 \n \
|
||||
centos-7 \n \
|
||||
centos-8 \n \
|
||||
debian-8 \n \
|
||||
debian-9 \n \
|
||||
debian-10 \n \
|
||||
fedora-37 \n \
|
||||
debian-11 \n \
|
||||
opensuseleap-15.1 \n \
|
||||
opensuseleap-15.2 \n \
|
||||
opensuseleap-15.3 \n \
|
||||
almalinux-8.5 \n \
|
||||
almalinux-8.7 \n \
|
||||
almalinux-8.8 \n \
|
||||
"
|
||||
# add poky sanity bbclass
|
||||
INHERIT += "poky-sanity"
|
||||
|
||||
@@ -26,7 +26,7 @@ CVE_PRODUCT ??= "${BPN}"
|
||||
CVE_VERSION ??= "${PV}"
|
||||
|
||||
CVE_CHECK_DB_DIR ?= "${DL_DIR}/CVE_CHECK"
|
||||
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve_1.1.db"
|
||||
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve_2.db"
|
||||
CVE_CHECK_DB_FILE_LOCK ?= "${CVE_CHECK_DB_FILE}.lock"
|
||||
|
||||
CVE_CHECK_LOG ?= "${T}/cve.log"
|
||||
@@ -154,7 +154,7 @@ python do_cve_check () {
|
||||
}
|
||||
|
||||
addtask cve_check before do_build
|
||||
do_cve_check[depends] = "cve-update-db-native:do_fetch"
|
||||
do_cve_check[depends] = "cve-update-nvd2-native:do_fetch"
|
||||
do_cve_check[nostamp] = "1"
|
||||
|
||||
python cve_check_cleanup () {
|
||||
|
||||
@@ -118,7 +118,7 @@ go_do_install() {
|
||||
tar -C ${B} -cf - --exclude-vcs --exclude '*.test' --exclude 'testdata' pkg | \
|
||||
tar -C ${D}${libdir}/go --no-same-owner -xf -
|
||||
|
||||
if [ -n "`ls ${B}/${GO_BUILD_BINDIR}/`" ]; then
|
||||
if ls ${B}/${GO_BUILD_BINDIR}/* >/dev/null 2>/dev/null ; then
|
||||
install -d ${D}${bindir}
|
||||
install -m 0755 ${B}/${GO_BUILD_BINDIR}/* ${D}${bindir}/
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
inherit kernel-uboot kernel-artifact-names uboot-sign
|
||||
|
||||
KERNEL_IMAGETYPE_REPLACEMENT = ""
|
||||
|
||||
python __anonymous () {
|
||||
kerneltypes = d.getVar('KERNEL_IMAGETYPES') or ""
|
||||
if 'fitImage' in kerneltypes.split():
|
||||
@@ -21,6 +23,8 @@ python __anonymous () {
|
||||
else:
|
||||
replacementtype = "zImage"
|
||||
|
||||
d.setVar("KERNEL_IMAGETYPE_REPLACEMENT", replacementtype)
|
||||
|
||||
# Override KERNEL_IMAGETYPE_FOR_MAKE variable, which is internal
|
||||
# to kernel.bbclass . We have to override it, since we pack zImage
|
||||
# (at least for now) into the fitImage .
|
||||
@@ -45,6 +49,8 @@ python __anonymous () {
|
||||
if d.getVar('UBOOT_SIGN_ENABLE') == "1" and d.getVar('UBOOT_DTB_BINARY'):
|
||||
uboot_pn = d.getVar('PREFERRED_PROVIDER_u-boot') or 'u-boot'
|
||||
d.appendVarFlag('do_assemble_fitimage', 'depends', ' %s:do_populate_sysroot' % uboot_pn)
|
||||
if d.getVar('INITRAMFS_IMAGE_BUNDLE') == "1":
|
||||
d.appendVarFlag('do_assemble_fitimage_initramfs', 'depends', ' %s:do_populate_sysroot' % uboot_pn)
|
||||
}
|
||||
|
||||
# Options for the device tree compiler passed to mkimage '-D' feature:
|
||||
@@ -180,6 +186,43 @@ fitimage_emit_section_dtb() {
|
||||
EOF
|
||||
}
|
||||
|
||||
#
|
||||
# Emit the fitImage ITS u-boot script section
|
||||
#
|
||||
# $1 ... .its filename
|
||||
# $2 ... Image counter
|
||||
# $3 ... Path to boot script image
|
||||
fitimage_emit_section_boot_script() {
|
||||
|
||||
bootscr_csum="${FIT_HASH_ALG}"
|
||||
bootscr_sign_algo="${FIT_SIGN_ALG}"
|
||||
bootscr_sign_keyname="${UBOOT_SIGN_IMG_KEYNAME}"
|
||||
|
||||
cat << EOF >> $1
|
||||
bootscr-$2 {
|
||||
description = "U-boot script";
|
||||
data = /incbin/("$3");
|
||||
type = "script";
|
||||
arch = "${UBOOT_ARCH}";
|
||||
compression = "none";
|
||||
hash-1 {
|
||||
algo = "$bootscr_csum";
|
||||
};
|
||||
};
|
||||
EOF
|
||||
|
||||
if [ "${UBOOT_SIGN_ENABLE}" = "1" -a "${FIT_SIGN_INDIVIDUAL}" = "1" -a -n "$bootscr_sign_keyname" ] ; then
|
||||
sed -i '$ d' $1
|
||||
cat << EOF >> $1
|
||||
signature-1 {
|
||||
algo = "$bootscr_csum,$bootscr_sign_algo";
|
||||
key-name-hint = "$bootscr_sign_keyname";
|
||||
};
|
||||
};
|
||||
EOF
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Emit the fitImage ITS setup section
|
||||
#
|
||||
@@ -250,8 +293,9 @@ EOF
|
||||
# $2 ... Linux kernel ID
|
||||
# $3 ... DTB image name
|
||||
# $4 ... ramdisk ID
|
||||
# $5 ... config ID
|
||||
# $6 ... default flag
|
||||
# $5 ... u-boot script ID
|
||||
# $6 ... config ID
|
||||
# $7 ... default flag
|
||||
fitimage_emit_section_config() {
|
||||
|
||||
conf_csum="${FIT_HASH_ALG}"
|
||||
@@ -267,6 +311,7 @@ fitimage_emit_section_config() {
|
||||
kernel_line=""
|
||||
fdt_line=""
|
||||
ramdisk_line=""
|
||||
bootscr_line=""
|
||||
setup_line=""
|
||||
default_line=""
|
||||
|
||||
@@ -289,21 +334,28 @@ fitimage_emit_section_config() {
|
||||
fi
|
||||
|
||||
if [ -n "${5}" ]; then
|
||||
conf_desc="${conf_desc}${sep}setup"
|
||||
setup_line="setup = \"setup-${5}\";"
|
||||
conf_desc="${conf_desc}${sep}u-boot script"
|
||||
sep=", "
|
||||
bootscr_line="bootscr = \"bootscr-${5}\";"
|
||||
fi
|
||||
|
||||
if [ "${6}" = "1" ]; then
|
||||
if [ -n "${6}" ]; then
|
||||
conf_desc="${conf_desc}${sep}setup"
|
||||
setup_line="setup = \"setup-${6}\";"
|
||||
fi
|
||||
|
||||
if [ "${7}" = "1" ]; then
|
||||
default_line="default = \"conf-${3}\";"
|
||||
fi
|
||||
|
||||
cat << EOF >> ${1}
|
||||
${default_line}
|
||||
conf-${3} {
|
||||
description = "${6} ${conf_desc}";
|
||||
description = "${7} ${conf_desc}";
|
||||
${kernel_line}
|
||||
${fdt_line}
|
||||
${ramdisk_line}
|
||||
${bootscr_line}
|
||||
${setup_line}
|
||||
hash-1 {
|
||||
algo = "${conf_csum}";
|
||||
@@ -331,6 +383,11 @@ EOF
|
||||
fi
|
||||
|
||||
if [ -n "${5}" ]; then
|
||||
sign_line="${sign_line}${sep}\"bootscr\""
|
||||
sep=", "
|
||||
fi
|
||||
|
||||
if [ -n "${6}" ]; then
|
||||
sign_line="${sign_line}${sep}\"setup\""
|
||||
fi
|
||||
|
||||
@@ -363,6 +420,7 @@ fitimage_assemble() {
|
||||
DTBS=""
|
||||
ramdiskcount=${3}
|
||||
setupcount=""
|
||||
bootscr_id=""
|
||||
rm -f ${1} arch/${ARCH}/boot/${2}
|
||||
|
||||
fitimage_emit_fit_header ${1}
|
||||
@@ -373,7 +431,7 @@ fitimage_assemble() {
|
||||
fitimage_emit_section_maint ${1} imagestart
|
||||
|
||||
uboot_prep_kimage
|
||||
fitimage_emit_section_kernel ${1} "${kernelcount}" linux.bin "${linux_comp}"
|
||||
fitimage_emit_section_kernel $1 $kernelcount linux.bin "$linux_comp"
|
||||
|
||||
#
|
||||
# Step 2: Prepare a DTB image section
|
||||
@@ -407,7 +465,21 @@ fitimage_assemble() {
|
||||
fi
|
||||
|
||||
#
|
||||
# Step 3: Prepare a setup section. (For x86)
|
||||
# Step 3: Prepare a u-boot script section
|
||||
#
|
||||
|
||||
if [ -n "${UBOOT_ENV}" ] && [ -d "${STAGING_DIR_HOST}/boot" ]; then
|
||||
if [ -e "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY}" ]; then
|
||||
cp ${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} ${B}
|
||||
bootscr_id="${UBOOT_ENV_BINARY}"
|
||||
fitimage_emit_section_boot_script ${1} "${bootscr_id}" ${UBOOT_ENV_BINARY}
|
||||
else
|
||||
bbwarn "${STAGING_DIR_HOST}/boot/${UBOOT_ENV_BINARY} not found."
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Step 4: Prepare a setup section. (For x86)
|
||||
#
|
||||
if [ -e arch/${ARCH}/boot/setup.bin ]; then
|
||||
setupcount=1
|
||||
@@ -415,9 +487,9 @@ fitimage_assemble() {
|
||||
fi
|
||||
|
||||
#
|
||||
# Step 4: Prepare a ramdisk section.
|
||||
# Step 5: Prepare a ramdisk section.
|
||||
#
|
||||
if [ "x${ramdiskcount}" = "x1" ] ; then
|
||||
if [ "x${ramdiskcount}" = "x1" ] && [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
|
||||
# Find and use the first initramfs image archive type we find
|
||||
for img in cpio.lz4 cpio.lzo cpio.lzma cpio.xz cpio.gz ext2.gz cpio; do
|
||||
initramfs_path="${DEPLOY_DIR_IMAGE}/${INITRAMFS_IMAGE_NAME}.${img}"
|
||||
@@ -438,7 +510,7 @@ fitimage_assemble() {
|
||||
fi
|
||||
|
||||
#
|
||||
# Step 5: Prepare a configurations section
|
||||
# Step 6: Prepare a configurations section
|
||||
#
|
||||
fitimage_emit_section_maint ${1} confstart
|
||||
|
||||
@@ -447,9 +519,9 @@ fitimage_assemble() {
|
||||
for DTB in ${DTBS}; do
|
||||
dtb_ext=${DTB##*.}
|
||||
if [ "${dtb_ext}" = "dtbo" ]; then
|
||||
fitimage_emit_section_config ${1} "" "${DTB}" "" "" "`expr ${i} = ${dtbcount}`"
|
||||
fitimage_emit_section_config ${1} "" "${DTB}" "" "${bootscr_id}" "" "`expr ${i} = ${dtbcount}`"
|
||||
else
|
||||
fitimage_emit_section_config ${1} "${kernelcount}" "${DTB}" "${ramdiskcount}" "${setupcount}" "`expr ${i} = ${dtbcount}`"
|
||||
fitimage_emit_section_config ${1} "${kernelcount}" "${DTB}" "${ramdiskcount}" "${bootscr_id}" "${setupcount}" "`expr ${i} = ${dtbcount}`"
|
||||
fi
|
||||
i=`expr ${i} + 1`
|
||||
done
|
||||
@@ -460,7 +532,7 @@ fitimage_assemble() {
|
||||
fitimage_emit_section_maint ${1} fitend
|
||||
|
||||
#
|
||||
# Step 6: Assemble the image
|
||||
# Step 7: Assemble the image
|
||||
#
|
||||
uboot-mkimage \
|
||||
${@'-D "${UBOOT_MKIMAGE_DTCOPTS}"' if len('${UBOOT_MKIMAGE_DTCOPTS}') else ''} \
|
||||
@@ -468,7 +540,7 @@ fitimage_assemble() {
|
||||
arch/${ARCH}/boot/${2}
|
||||
|
||||
#
|
||||
# Step 7: Sign the image and add public key to U-Boot dtb
|
||||
# Step 8: Sign the image and add public key to U-Boot dtb
|
||||
#
|
||||
if [ "x${UBOOT_SIGN_ENABLE}" = "x1" ] ; then
|
||||
add_key_to_u_boot=""
|
||||
@@ -500,7 +572,11 @@ do_assemble_fitimage_initramfs() {
|
||||
if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage" && \
|
||||
test -n "${INITRAMFS_IMAGE}" ; then
|
||||
cd ${B}
|
||||
fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1
|
||||
if [ "${INITRAMFS_IMAGE_BUNDLE}" = "1" ]; then
|
||||
fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage ""
|
||||
else
|
||||
fitimage_assemble fit-image-${INITRAMFS_IMAGE}.its fitImage-${INITRAMFS_IMAGE} 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -511,22 +587,32 @@ kernel_do_deploy[vardepsexclude] = "DATETIME"
|
||||
kernel_do_deploy_append() {
|
||||
# Update deploy directory
|
||||
if echo ${KERNEL_IMAGETYPES} | grep -wq "fitImage"; then
|
||||
echo "Copying fit-image.its source file..."
|
||||
install -m 0644 ${B}/fit-image.its "$deployDir/fitImage-its-${KERNEL_FIT_NAME}.its"
|
||||
ln -snf fitImage-its-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${KERNEL_FIT_LINK_NAME}"
|
||||
if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
|
||||
echo "Copying fit-image.its source file..."
|
||||
install -m 0644 ${B}/fit-image.its "$deployDir/fitImage-its-${KERNEL_FIT_NAME}.its"
|
||||
if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
|
||||
ln -snf fitImage-its-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${KERNEL_FIT_LINK_NAME}"
|
||||
fi
|
||||
|
||||
echo "Copying linux.bin file..."
|
||||
install -m 0644 ${B}/linux.bin $deployDir/fitImage-linux.bin-${KERNEL_FIT_NAME}.bin
|
||||
ln -snf fitImage-linux.bin-${KERNEL_FIT_NAME}.bin "$deployDir/fitImage-linux.bin-${KERNEL_FIT_LINK_NAME}"
|
||||
echo "Copying linux.bin file..."
|
||||
install -m 0644 ${B}/linux.bin $deployDir/fitImage-linux.bin-${KERNEL_FIT_NAME}.bin
|
||||
if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
|
||||
ln -snf fitImage-linux.bin-${KERNEL_FIT_NAME}.bin "$deployDir/fitImage-linux.bin-${KERNEL_FIT_LINK_NAME}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${INITRAMFS_IMAGE}" ]; then
|
||||
echo "Copying fit-image-${INITRAMFS_IMAGE}.its source file..."
|
||||
install -m 0644 ${B}/fit-image-${INITRAMFS_IMAGE}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its"
|
||||
ln -snf fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.its "$deployDir/fitImage-its-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
|
||||
|
||||
echo "Copying fitImage-${INITRAMFS_IMAGE} file..."
|
||||
install -m 0644 ${B}/arch/${ARCH}/boot/fitImage-${INITRAMFS_IMAGE} "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.bin"
|
||||
ln -snf fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.bin "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
|
||||
if [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ]; then
|
||||
echo "Copying fitImage-${INITRAMFS_IMAGE} file..."
|
||||
install -m 0644 ${B}/arch/${ARCH}/boot/fitImage-${INITRAMFS_IMAGE} "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.bin"
|
||||
if [ -n "${KERNEL_FIT_LINK_NAME}" ] ; then
|
||||
ln -snf fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_NAME}.bin "$deployDir/fitImage-${INITRAMFS_IMAGE_NAME}-${KERNEL_FIT_LINK_NAME}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [ "${UBOOT_SIGN_ENABLE}" = "1" -a -n "${UBOOT_DTB_BINARY}" ] ; then
|
||||
# UBOOT_DTB_IMAGE is a realfile, but we can't use
|
||||
@@ -536,3 +622,13 @@ kernel_do_deploy_append() {
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# The function below performs the following in case of initramfs bundles:
|
||||
# - Removes do_assemble_fitimage. FIT generation is done through
|
||||
# do_assemble_fitimage_initramfs. do_assemble_fitimage is not needed
|
||||
# and should not be part of the tasks to be executed.
|
||||
python () {
|
||||
d.appendVarFlag('do_compile', 'vardeps', ' INITRAMFS_IMAGE_BUNDLE')
|
||||
if d.getVar('INITRAMFS_IMAGE_BUNDLE') == "1":
|
||||
bb.build.deltask('do_assemble_fitimage', d)
|
||||
}
|
||||
|
||||
@@ -143,13 +143,14 @@ do_unpack[cleandirs] += " ${S} ${STAGING_KERNEL_DIR} ${B} ${STAGING_KERNEL_BUILD
|
||||
do_clean[cleandirs] += " ${S} ${STAGING_KERNEL_DIR} ${B} ${STAGING_KERNEL_BUILDDIR}"
|
||||
python do_symlink_kernsrc () {
|
||||
s = d.getVar("S")
|
||||
if s[-1] == '/':
|
||||
# drop trailing slash, so that os.symlink(kernsrc, s) doesn't use s as directory name and fail
|
||||
s=s[:-1]
|
||||
kernsrc = d.getVar("STAGING_KERNEL_DIR")
|
||||
if s != kernsrc:
|
||||
bb.utils.mkdirhier(kernsrc)
|
||||
bb.utils.remove(kernsrc, recurse=True)
|
||||
if s[-1] == '/':
|
||||
# drop trailing slash, so that os.symlink(kernsrc, s) doesn't use s as
|
||||
# directory name and fail
|
||||
s = s[:-1]
|
||||
if d.getVar("EXTERNALSRC"):
|
||||
# With EXTERNALSRC S will not be wiped so we can symlink to it
|
||||
os.symlink(s, kernsrc)
|
||||
@@ -417,12 +418,26 @@ kernel_do_install() {
|
||||
#
|
||||
install -d ${D}/${KERNEL_IMAGEDEST}
|
||||
install -d ${D}/boot
|
||||
|
||||
#
|
||||
# When including an initramfs bundle inside a FIT image, the fitImage is created after the install task
|
||||
# by do_assemble_fitimage_initramfs.
|
||||
# This happens after the generation of the initramfs bundle (done by do_bundle_initramfs).
|
||||
# So, at the level of the install task we should not try to install the fitImage. fitImage is still not
|
||||
# generated yet.
|
||||
# After the generation of the fitImage, the deploy task copies the fitImage from the build directory to
|
||||
# the deploy folder.
|
||||
#
|
||||
|
||||
for imageType in ${KERNEL_IMAGETYPES} ; do
|
||||
install -m 0644 ${KERNEL_OUTPUT_DIR}/${imageType} ${D}/${KERNEL_IMAGEDEST}/${imageType}-${KERNEL_VERSION}
|
||||
if [ "${KERNEL_PACKAGE_NAME}" = "kernel" ]; then
|
||||
ln -sf ${imageType}-${KERNEL_VERSION} ${D}/${KERNEL_IMAGEDEST}/${imageType}
|
||||
if [ $imageType != "fitImage" ] || [ "${INITRAMFS_IMAGE_BUNDLE}" != "1" ] ; then
|
||||
install -m 0644 ${KERNEL_OUTPUT_DIR}/${imageType} ${D}/${KERNEL_IMAGEDEST}/${imageType}-${KERNEL_VERSION}
|
||||
if [ "${KERNEL_PACKAGE_NAME}" = "kernel" ]; then
|
||||
ln -sf ${imageType}-${KERNEL_VERSION} ${D}/${KERNEL_IMAGEDEST}/${imageType}
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
install -m 0644 System.map ${D}/boot/System.map-${KERNEL_VERSION}
|
||||
install -m 0644 .config ${D}/boot/config-${KERNEL_VERSION}
|
||||
install -m 0644 vmlinux ${D}/boot/vmlinux-${KERNEL_VERSION}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
# Zap the root password if debug-tweaks feature is not enabled
|
||||
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'empty-root-password' ], "", "zap_empty_root_password ; ",d)}'
|
||||
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'empty-root-password' ], "", "zap_empty_root_password; ",d)}'
|
||||
|
||||
# Allow dropbear/openssh to accept logins from accounts with an empty password string if debug-tweaks or allow-empty-password is enabled
|
||||
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'allow-empty-password' ], "ssh_allow_empty_password; ", "",d)}'
|
||||
@@ -12,7 +12,7 @@ ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'deb
|
||||
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'post-install-logging' ], "postinst_enable_logging; ", "",d)}'
|
||||
|
||||
# Create /etc/timestamp during image construction to give a reasonably sane default time setting
|
||||
ROOTFS_POSTPROCESS_COMMAND += "rootfs_update_timestamp ; "
|
||||
ROOTFS_POSTPROCESS_COMMAND += "rootfs_update_timestamp; "
|
||||
|
||||
# Tweak the mount options for rootfs in /etc/fstab if read-only-rootfs is enabled
|
||||
ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", "read_only_rootfs_hook; ", "",d)}'
|
||||
@@ -26,7 +26,7 @@ ROOTFS_POSTPROCESS_COMMAND += '${@bb.utils.contains("IMAGE_FEATURES", "read-only
|
||||
APPEND_append = '${@bb.utils.contains("IMAGE_FEATURES", "read-only-rootfs", " ro", "", d)}'
|
||||
|
||||
# Generates test data file with data store variables expanded in json format
|
||||
ROOTFS_POSTPROCESS_COMMAND += "write_image_test_data ; "
|
||||
ROOTFS_POSTPROCESS_COMMAND += "write_image_test_data; "
|
||||
|
||||
# Write manifest
|
||||
IMAGE_MANIFEST = "${IMGDEPLOYDIR}/${IMAGE_NAME}${IMAGE_NAME_SUFFIX}.manifest"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
ROOTFS_DEBUG_FILES ?= ""
|
||||
ROOTFS_DEBUG_FILES[doc] = "Lists additional files or directories to be installed with 'cp -a' in the format 'source1 target1;source2 target2;...'"
|
||||
|
||||
ROOTFS_POSTPROCESS_COMMAND += "rootfs_debug_files ;"
|
||||
ROOTFS_POSTPROCESS_COMMAND += "rootfs_debug_files;"
|
||||
rootfs_debug_files () {
|
||||
#!/bin/sh -e
|
||||
echo "${ROOTFS_DEBUG_FILES}" | sed -e 's/;/\n/g' | while read source target mode; do
|
||||
|
||||
@@ -34,6 +34,8 @@ python uninative_event_fetchloader() {
|
||||
with open(loaderchksum, "r") as f:
|
||||
readchksum = f.read().strip()
|
||||
if readchksum == chksum:
|
||||
if "uninative" not in d.getVar("SSTATEPOSTUNPACKFUNCS"):
|
||||
enable_uninative(d)
|
||||
return
|
||||
|
||||
import subprocess
|
||||
@@ -167,5 +169,7 @@ python uninative_changeinterp () {
|
||||
if not elf.isDynamic():
|
||||
continue
|
||||
|
||||
os.chmod(f, s[stat.ST_MODE] | stat.S_IWUSR)
|
||||
subprocess.check_output(("patchelf-uninative", "--set-interpreter", d.getVar("UNINATIVE_LOADER"), f), stderr=subprocess.STDOUT)
|
||||
os.chmod(f, s[stat.ST_MODE])
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ def update_useradd_static_config(d):
|
||||
def handle_missing_id(id, type, pkg, files, var, value):
|
||||
# For backwards compatibility we accept "1" in addition to "error"
|
||||
error_dynamic = d.getVar('USERADD_ERROR_DYNAMIC')
|
||||
msg = "%s - %s: %sname %s does not have a static ID defined." % (d.getVar('PN'), pkg, type, id)
|
||||
msg = 'Recipe %s, package %s: %sname "%s" does not have a static ID defined.' % (d.getVar('PN'), pkg, type, id)
|
||||
if files:
|
||||
msg += " Add %s to one of these files: %s" % (id, files)
|
||||
else:
|
||||
|
||||
@@ -897,7 +897,7 @@ BB_HASHCONFIG_WHITELIST ?= "${BB_HASHEXCLUDE_COMMON} DATE TIME SSH_AGENT_PID \
|
||||
PARALLEL_MAKE BB_NUMBER_THREADS BB_ORIGENV BB_INVALIDCONF BBINCLUDED \
|
||||
GIT_PROXY_COMMAND ALL_PROXY all_proxy NO_PROXY no_proxy FTP_PROXY ftp_proxy \
|
||||
HTTP_PROXY http_proxy HTTPS_PROXY https_proxy SOCKS5_USER SOCKS5_PASSWD \
|
||||
BB_SETSCENE_ENFORCE BB_CMDLINE BB_SERVER_TIMEOUT"
|
||||
BB_SETSCENE_ENFORCE BB_CMDLINE BB_SERVER_TIMEOUT BB_NICE_LEVEL"
|
||||
BB_SIGNATURE_EXCLUDE_FLAGS ?= "doc deps depends \
|
||||
lockfiles type vardepsexclude vardeps vardepvalue vardepvalueexclude \
|
||||
file-checksums python func task export unexport noexec nostamp dirs cleandirs \
|
||||
|
||||
@@ -26,6 +26,7 @@ PTESTS_FAST = "\
|
||||
liberror-perl-ptest \
|
||||
libmodule-build-perl-ptest \
|
||||
libpcre-ptest \
|
||||
libpng-ptest \
|
||||
libtimedate-perl-ptest \
|
||||
libtest-needs-perl-ptest \
|
||||
liburi-perl-ptest \
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
# to the distro running on the build machine.
|
||||
#
|
||||
|
||||
UNINATIVE_MAXGLIBCVERSION = "2.36"
|
||||
UNINATIVE_VERSION = "3.7"
|
||||
UNINATIVE_MAXGLIBCVERSION = "2.38"
|
||||
UNINATIVE_VERSION = "4.3"
|
||||
|
||||
UNINATIVE_URL ?= "http://downloads.yoctoproject.org/releases/uninative/${UNINATIVE_VERSION}/"
|
||||
UNINATIVE_CHECKSUM[aarch64] ?= "6a29bcae4b5b716d2d520e18800b33943b65f8a835eac1ff8793fc5ee65b4be6"
|
||||
UNINATIVE_CHECKSUM[i686] ?= "3f6d52e64996570c716108d49f8108baccf499a283bbefae438c7266b7a93305"
|
||||
UNINATIVE_CHECKSUM[x86_64] ?= "b110bf2e10fe420f5ca2f3ec55f048ee5f0a54c7e34856a3594e51eb2aea0570"
|
||||
UNINATIVE_CHECKSUM[aarch64] ?= "8df05f4a41455018b4303b2e0ea4eac5c960b5a13713f6dbb33dfdb3e32753ec"
|
||||
UNINATIVE_CHECKSUM[i686] ?= "bea76b4a97c9ba0077c0dd1295f519cd599dbf71f0ca1c964471c4cdb043addd"
|
||||
UNINATIVE_CHECKSUM[x86_64] ?= "1c35f09a75c4096749bbe1e009df4e3968cde151424062cf4aa3ed89db22b030"
|
||||
|
||||
@@ -102,6 +102,10 @@ class Rxvt(XTerminal):
|
||||
command = 'rxvt -T "{title}" -e {command}'
|
||||
priority = 1
|
||||
|
||||
class URxvt(XTerminal):
|
||||
command = 'urxvt -T "{title}" -e {command}'
|
||||
priority = 1
|
||||
|
||||
class Screen(Terminal):
|
||||
command = 'screen -D -m -t "{title}" -S devshell {command}'
|
||||
|
||||
|
||||
@@ -226,6 +226,9 @@ def SSHCall(command, logger, timeout=None, **opts):
|
||||
endtime = time.time() + timeout
|
||||
except InterruptedError:
|
||||
continue
|
||||
except BlockingIOError:
|
||||
logger.debug('BlockingIOError')
|
||||
continue
|
||||
|
||||
# process hasn't returned yet
|
||||
if not eof:
|
||||
|
||||
@@ -67,7 +67,7 @@ class LtpTest(LtpTestBase):
|
||||
def runltp(self, ltp_group):
|
||||
cmd = '/opt/ltp/runltp -f %s -p -q -r /opt/ltp -l /opt/ltp/results/%s -I 1 -d /opt/ltp' % (ltp_group, ltp_group)
|
||||
starttime = time.time()
|
||||
(status, output) = self.target.run(cmd)
|
||||
(status, output) = self.target.run(cmd, timeout=1200)
|
||||
endtime = time.time()
|
||||
|
||||
with open(os.path.join(self.ltptest_log_dir, "%s-raw.log" % ltp_group), 'w') as f:
|
||||
|
||||
@@ -57,8 +57,8 @@ class RpmBasicTest(OERuntimeTestCase):
|
||||
return
|
||||
time.sleep(1)
|
||||
user_pss = [ps for ps in output.split("\n") if u + ' ' in ps]
|
||||
msg = "There're %s 's process(es) still running: %s".format(u, "\n".join(user_pss))
|
||||
assertTrue(True, msg=msg)
|
||||
msg = "User %s has processes still running: %s" % (u, "\n".join(user_pss))
|
||||
self.fail(msg=msg)
|
||||
|
||||
def unset_up_test_user(u):
|
||||
# ensure no test1 process in running
|
||||
|
||||
@@ -185,6 +185,10 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\"
|
||||
self.assertTrue(find, "No version returned for searched recipe. bitbake output: %s" % result.output)
|
||||
|
||||
def test_prefile(self):
|
||||
# Test when the prefile does not exist
|
||||
result = runCmd('bitbake -r conf/prefile.conf', ignore_status=True)
|
||||
self.assertEqual(1, result.status, "bitbake didn't error and should have when a specified prefile didn't exist: %s" % result.output)
|
||||
# Test when the prefile exists
|
||||
preconf = os.path.join(self.builddir, 'conf/prefile.conf')
|
||||
self.track_for_cleanup(preconf)
|
||||
ftools.write_file(preconf ,"TEST_PREFILE=\"prefile\"")
|
||||
@@ -195,6 +199,10 @@ SSTATE_DIR = \"${TOPDIR}/download-selftest\"
|
||||
self.assertIn('localconf', result.output)
|
||||
|
||||
def test_postfile(self):
|
||||
# Test when the postfile does not exist
|
||||
result = runCmd('bitbake -R conf/postfile.conf', ignore_status=True)
|
||||
self.assertEqual(1, result.status, "bitbake didn't error and should have when a specified postfile didn't exist: %s" % result.output)
|
||||
# Test when the postfile exists
|
||||
postconf = os.path.join(self.builddir, 'conf/postfile.conf')
|
||||
self.track_for_cleanup(postconf)
|
||||
ftools.write_file(postconf , "TEST_POSTFILE=\"postfile\"")
|
||||
|
||||
@@ -8,6 +8,7 @@ import shutil
|
||||
import tempfile
|
||||
import glob
|
||||
import fnmatch
|
||||
import unittest
|
||||
|
||||
import oeqa.utils.ftools as ftools
|
||||
from oeqa.selftest.case import OESelftestTestCase
|
||||
@@ -38,6 +39,13 @@ def setUpModule():
|
||||
canonical_layerpath = os.path.realpath(canonical_layerpath) + '/'
|
||||
edited_layers.append(layerpath)
|
||||
oldmetapath = os.path.realpath(layerpath)
|
||||
|
||||
# when downloading poky from tar.gz some tests will be skipped (BUG 12389)
|
||||
try:
|
||||
runCmd('git rev-parse --is-inside-work-tree', cwd=canonical_layerpath)
|
||||
except:
|
||||
raise unittest.SkipTest("devtool tests require folder to be a git repo")
|
||||
|
||||
result = runCmd('git rev-parse --show-toplevel', cwd=canonical_layerpath)
|
||||
oldreporoot = result.output.rstrip()
|
||||
newmetapath = os.path.join(corecopydir, os.path.relpath(oldmetapath, oldreporoot))
|
||||
|
||||
@@ -41,7 +41,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase):
|
||||
with contextlib.ExitStack() as s:
|
||||
# use the base work dir, as the nfs mount, since the recipe directory may not exist
|
||||
tmpdir = get_bb_var("BASE_WORKDIR")
|
||||
nfsport, mountport = s.enter_context(unfs_server(tmpdir))
|
||||
nfsport, mountport = s.enter_context(unfs_server(tmpdir, udp = False))
|
||||
|
||||
# build core-image-minimal with required packages
|
||||
default_installed_packages = [
|
||||
@@ -61,7 +61,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase):
|
||||
bitbake("core-image-minimal")
|
||||
|
||||
# start runqemu
|
||||
qemu = s.enter_context(runqemu("core-image-minimal", runqemuparams = "nographic"))
|
||||
qemu = s.enter_context(runqemu("core-image-minimal", runqemuparams = "nographic", qemuparams = "-m 1024"))
|
||||
|
||||
# validate that SSH is working
|
||||
status, _ = qemu.run("uname")
|
||||
@@ -70,7 +70,7 @@ class GlibcSelfTestBase(OESelftestTestCase, OEPTestResultTestCase):
|
||||
# setup nfs mount
|
||||
if qemu.run("mkdir -p \"{0}\"".format(tmpdir))[0] != 0:
|
||||
raise Exception("Failed to setup NFS mount directory on target")
|
||||
mountcmd = "mount -o noac,nfsvers=3,port={0},udp,mountport={1} \"{2}:{3}\" \"{3}\"".format(nfsport, mountport, qemu.server_ip, tmpdir)
|
||||
mountcmd = "mount -o noac,nfsvers=3,port={0},mountport={1} \"{2}:{3}\" \"{3}\"".format(nfsport, mountport, qemu.server_ip, tmpdir)
|
||||
status, output = qemu.run(mountcmd)
|
||||
if status != 0:
|
||||
raise Exception("Failed to setup NFS mount on target ({})".format(repr(output)))
|
||||
|
||||
@@ -8,7 +8,7 @@ from oeqa.utils.commands import bitbake, get_bb_var, Command
|
||||
from oeqa.utils.network import get_free_port
|
||||
|
||||
@contextlib.contextmanager
|
||||
def unfs_server(directory, logger = None):
|
||||
def unfs_server(directory, logger = None, udp = True):
|
||||
unfs_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "unfs3-native")
|
||||
if not os.path.exists(os.path.join(unfs_sysroot, "usr", "bin", "unfsd")):
|
||||
# build native tool
|
||||
@@ -22,7 +22,7 @@ def unfs_server(directory, logger = None):
|
||||
exports.write("{0} (rw,no_root_squash,no_all_squash,insecure)\n".format(directory).encode())
|
||||
|
||||
# find some ports for the server
|
||||
nfsport, mountport = get_free_port(udp = True), get_free_port(udp = True)
|
||||
nfsport, mountport = get_free_port(udp), get_free_port(udp)
|
||||
|
||||
nenv = dict(os.environ)
|
||||
nenv['PATH'] = "{0}/sbin:{0}/usr/sbin:{0}/usr/bin:".format(unfs_sysroot) + nenv.get('PATH', '')
|
||||
|
||||
609
meta/recipes-bsp/grub/files/CVE-2020-27749.patch
Normal file
609
meta/recipes-bsp/grub/files/CVE-2020-27749.patch
Normal file
@@ -0,0 +1,609 @@
|
||||
From 4ea7bae51f97e49c84dc67ea30b466ca8633b9f6 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Thu, 7 Jan 2021 19:21:03 +0000
|
||||
Subject: kern/parser: Fix a stack buffer overflow
|
||||
|
||||
grub_parser_split_cmdline() expands variable names present in the supplied
|
||||
command line in to their corresponding variable contents and uses a 1 kiB
|
||||
stack buffer for temporary storage without sufficient bounds checking. If
|
||||
the function is called with a command line that references a variable with
|
||||
a sufficiently large payload, it is possible to overflow the stack
|
||||
buffer via tab completion, corrupt the stack frame and potentially
|
||||
control execution.
|
||||
|
||||
Fixes: CVE-2020-27749
|
||||
|
||||
Reported-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=c6c426e5ab6ea715153b72584de6bd8c82f698ec && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=b1c9e9e889e4273fb15712051c887e6078511448 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=3d157bbd06506b170fde5ec23980c4bf9f7660e2 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=8bc817014ce3d7a498db44eae33c8b90e2430926 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=030fb6c4fa354cdbd6a8d6903dfed5d36eaf3cb2 && https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=4ea7bae51f97e49c84dc67ea30b466ca8633b9f6]
|
||||
CVE: CVE-2020-27749
|
||||
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/buffer.c | 117 +++++++++++++++++++++
|
||||
grub-core/kern/parser.c | 204 +++++++++++++++++++++++-------------
|
||||
include/grub/buffer.h | 144 +++++++++++++++++++++++++
|
||||
4 files changed, 395 insertions(+), 71 deletions(-)
|
||||
create mode 100644 grub-core/kern/buffer.c
|
||||
create mode 100644 include/grub/buffer.h
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 651ea2a..823cd57 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -123,6 +123,7 @@ kernel = {
|
||||
riscv32_efi_startup = kern/riscv/efi/startup.S;
|
||||
riscv64_efi_startup = kern/riscv/efi/startup.S;
|
||||
|
||||
+ common = kern/buffer.c;
|
||||
common = kern/command.c;
|
||||
common = kern/corecmd.c;
|
||||
common = kern/device.c;
|
||||
diff --git a/grub-core/kern/buffer.c b/grub-core/kern/buffer.c
|
||||
new file mode 100644
|
||||
index 0000000..9f5f8b8
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/buffer.c
|
||||
@@ -0,0 +1,117 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * GRUB is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/buffer.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/safemath.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+grub_buffer_t
|
||||
+grub_buffer_new (grub_size_t sz)
|
||||
+{
|
||||
+ struct grub_buffer *ret;
|
||||
+
|
||||
+ ret = (struct grub_buffer *) grub_malloc (sizeof (*ret));
|
||||
+ if (ret == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ ret->data = (grub_uint8_t *) grub_malloc (sz);
|
||||
+ if (ret->data == NULL)
|
||||
+ {
|
||||
+ grub_free (ret);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ret->sz = sz;
|
||||
+ ret->pos = 0;
|
||||
+ ret->used = 0;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_buffer_free (grub_buffer_t buf)
|
||||
+{
|
||||
+ grub_free (buf->data);
|
||||
+ grub_free (buf);
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req)
|
||||
+{
|
||||
+ grub_uint8_t *d;
|
||||
+ grub_size_t newsz = 1;
|
||||
+
|
||||
+ /* Is the current buffer size adequate? */
|
||||
+ if (buf->sz >= req)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ /* Find the smallest power-of-2 size that satisfies the request. */
|
||||
+ while (newsz < req)
|
||||
+ {
|
||||
+ if (newsz == 0)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("requested buffer size is too large"));
|
||||
+ newsz <<= 1;
|
||||
+ }
|
||||
+
|
||||
+ d = (grub_uint8_t *) grub_realloc (buf->data, newsz);
|
||||
+ if (d == NULL)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ buf->data = d;
|
||||
+ buf->sz = newsz;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+void *
|
||||
+grub_buffer_take_data (grub_buffer_t buf)
|
||||
+{
|
||||
+ void *data = buf->data;
|
||||
+
|
||||
+ buf->data = NULL;
|
||||
+ buf->sz = buf->pos = buf->used = 0;
|
||||
+
|
||||
+ return data;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_buffer_reset (grub_buffer_t buf)
|
||||
+{
|
||||
+ buf->pos = buf->used = 0;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n)
|
||||
+{
|
||||
+ grub_size_t newpos;
|
||||
+
|
||||
+ if (grub_add (buf->pos, n, &newpos))
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
+
|
||||
+ if (newpos > buf->used)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("new read is position beyond the end of the written data"));
|
||||
+
|
||||
+ buf->pos = newpos;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
diff --git a/grub-core/kern/parser.c b/grub-core/kern/parser.c
|
||||
index d1cf061..6ab7aa4 100644
|
||||
--- a/grub-core/kern/parser.c
|
||||
+++ b/grub-core/kern/parser.c
|
||||
@@ -1,7 +1,7 @@
|
||||
/* parser.c - the part of the parser that can return partial tokens */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
- * Copyright (C) 2005,2007,2009 Free Software Foundation, Inc.
|
||||
+ * Copyright (C) 2005,2007,2009,2021 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <grub/parser.h>
|
||||
+#include <grub/buffer.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
@@ -107,8 +108,8 @@ check_varstate (grub_parser_state_t s)
|
||||
}
|
||||
|
||||
|
||||
-static void
|
||||
-add_var (char *varname, char **bp, char **vp,
|
||||
+static grub_err_t
|
||||
+add_var (grub_buffer_t varname, grub_buffer_t buf,
|
||||
grub_parser_state_t state, grub_parser_state_t newstate)
|
||||
{
|
||||
const char *val;
|
||||
@@ -116,17 +117,74 @@ add_var (char *varname, char **bp, char **vp,
|
||||
/* Check if a variable was being read in and the end of the name
|
||||
was reached. */
|
||||
if (!(check_varstate (state) && !check_varstate (newstate)))
|
||||
- return;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ if (grub_buffer_append_char (varname, '\0') != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
|
||||
- *((*vp)++) = '\0';
|
||||
- val = grub_env_get (varname);
|
||||
- *vp = varname;
|
||||
+ val = grub_env_get ((const char *) grub_buffer_peek_data (varname));
|
||||
+ grub_buffer_reset (varname);
|
||||
if (!val)
|
||||
- return;
|
||||
+ return GRUB_ERR_NONE;
|
||||
|
||||
/* Insert the contents of the variable in the buffer. */
|
||||
- for (; *val; val++)
|
||||
- *((*bp)++) = *val;
|
||||
+ return grub_buffer_append_data (buf, val, grub_strlen (val));
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+terminate_arg (grub_buffer_t buffer, int *argc)
|
||||
+{
|
||||
+ grub_size_t unread = grub_buffer_get_unread_bytes (buffer);
|
||||
+
|
||||
+ if (unread == 0)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ if (*(const char *) grub_buffer_peek_data_at (buffer, unread - 1) == '\0')
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ if (grub_buffer_append_char (buffer, '\0') != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ (*argc)++;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+process_char (char c, grub_buffer_t buffer, grub_buffer_t varname,
|
||||
+ grub_parser_state_t state, int *argc,
|
||||
+ grub_parser_state_t *newstate)
|
||||
+{
|
||||
+ char use;
|
||||
+
|
||||
+ *newstate = grub_parser_cmdline_state (state, c, &use);
|
||||
+
|
||||
+ /*
|
||||
+ * If a variable was being processed and this character does
|
||||
+ * not describe the variable anymore, write the variable to
|
||||
+ * the buffer.
|
||||
+ */
|
||||
+ if (add_var (varname, buffer, state, *newstate) != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ if (check_varstate (*newstate))
|
||||
+ {
|
||||
+ if (use)
|
||||
+ return grub_buffer_append_char (varname, use);
|
||||
+ }
|
||||
+ else if (*newstate == GRUB_PARSER_STATE_TEXT &&
|
||||
+ state != GRUB_PARSER_STATE_ESC && grub_isspace (use))
|
||||
+ {
|
||||
+ /*
|
||||
+ * Don't add more than one argument if multiple
|
||||
+ * spaces are used.
|
||||
+ */
|
||||
+ return terminate_arg (buffer, argc);
|
||||
+ }
|
||||
+ else if (use)
|
||||
+ return grub_buffer_append_char (buffer, use);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
@@ -135,24 +193,36 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
int *argc, char ***argv)
|
||||
{
|
||||
grub_parser_state_t state = GRUB_PARSER_STATE_TEXT;
|
||||
- /* XXX: Fixed size buffer, perhaps this buffer should be dynamically
|
||||
- allocated. */
|
||||
- char buffer[1024];
|
||||
- char *bp = buffer;
|
||||
+ grub_buffer_t buffer, varname;
|
||||
char *rd = (char *) cmdline;
|
||||
- char varname[200];
|
||||
- char *vp = varname;
|
||||
- char *args;
|
||||
+ char *rp = rd;
|
||||
int i;
|
||||
|
||||
*argc = 0;
|
||||
*argv = NULL;
|
||||
+
|
||||
+ buffer = grub_buffer_new (1024);
|
||||
+ if (buffer == NULL)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ varname = grub_buffer_new (200);
|
||||
+ if (varname == NULL)
|
||||
+ goto fail;
|
||||
+
|
||||
do
|
||||
{
|
||||
- if (!rd || !*rd)
|
||||
+ if (rp == NULL || *rp == '\0')
|
||||
{
|
||||
+ if (rd != cmdline)
|
||||
+ {
|
||||
+ grub_free (rd);
|
||||
+ rd = rp = NULL;
|
||||
+ }
|
||||
if (getline)
|
||||
- getline (&rd, 1, getline_data);
|
||||
+ {
|
||||
+ getline (&rd, 1, getline_data);
|
||||
+ rp = rd;
|
||||
+ }
|
||||
else
|
||||
break;
|
||||
}
|
||||
@@ -160,39 +230,14 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
if (!rd)
|
||||
break;
|
||||
|
||||
- for (; *rd; rd++)
|
||||
+ for (; *rp != '\0'; rp++)
|
||||
{
|
||||
grub_parser_state_t newstate;
|
||||
- char use;
|
||||
|
||||
- newstate = grub_parser_cmdline_state (state, *rd, &use);
|
||||
+ if (process_char (*rp, buffer, varname, state, argc,
|
||||
+ &newstate) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
|
||||
- /* If a variable was being processed and this character does
|
||||
- not describe the variable anymore, write the variable to
|
||||
- the buffer. */
|
||||
- add_var (varname, &bp, &vp, state, newstate);
|
||||
-
|
||||
- if (check_varstate (newstate))
|
||||
- {
|
||||
- if (use)
|
||||
- *(vp++) = use;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- if (newstate == GRUB_PARSER_STATE_TEXT
|
||||
- && state != GRUB_PARSER_STATE_ESC && grub_isspace (use))
|
||||
- {
|
||||
- /* Don't add more than one argument if multiple
|
||||
- spaces are used. */
|
||||
- if (bp != buffer && *(bp - 1))
|
||||
- {
|
||||
- *(bp++) = '\0';
|
||||
- (*argc)++;
|
||||
- }
|
||||
- }
|
||||
- else if (use)
|
||||
- *(bp++) = use;
|
||||
- }
|
||||
state = newstate;
|
||||
}
|
||||
}
|
||||
@@ -200,43 +245,60 @@ grub_parser_split_cmdline (const char *cmdline,
|
||||
|
||||
/* A special case for when the last character was part of a
|
||||
variable. */
|
||||
- add_var (varname, &bp, &vp, state, GRUB_PARSER_STATE_TEXT);
|
||||
+ if (add_var (varname, buffer, state, GRUB_PARSER_STATE_TEXT) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
|
||||
- if (bp != buffer && *(bp - 1))
|
||||
- {
|
||||
- *(bp++) = '\0';
|
||||
- (*argc)++;
|
||||
- }
|
||||
+ /* Ensure that the last argument is terminated. */
|
||||
+ if (terminate_arg (buffer, argc) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
|
||||
/* If there are no args, then we're done. */
|
||||
if (!*argc)
|
||||
- return 0;
|
||||
-
|
||||
- /* Reserve memory for the return values. */
|
||||
- args = grub_malloc (bp - buffer);
|
||||
- if (!args)
|
||||
- return grub_errno;
|
||||
- grub_memcpy (args, buffer, bp - buffer);
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
*argv = grub_calloc (*argc + 1, sizeof (char *));
|
||||
if (!*argv)
|
||||
- {
|
||||
- grub_free (args);
|
||||
- return grub_errno;
|
||||
- }
|
||||
+ goto fail;
|
||||
|
||||
/* The arguments are separated with 0's, setup argv so it points to
|
||||
the right values. */
|
||||
- bp = args;
|
||||
for (i = 0; i < *argc; i++)
|
||||
{
|
||||
- (*argv)[i] = bp;
|
||||
- while (*bp)
|
||||
- bp++;
|
||||
- bp++;
|
||||
+ char *arg;
|
||||
+
|
||||
+ if (i > 0)
|
||||
+ {
|
||||
+ if (grub_buffer_advance_read_pos (buffer, 1) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ arg = (char *) grub_buffer_peek_data (buffer);
|
||||
+ if (arg == NULL ||
|
||||
+ grub_buffer_advance_read_pos (buffer, grub_strlen (arg)) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+
|
||||
+ (*argv)[i] = arg;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ /* Keep memory for the return values. */
|
||||
+ grub_buffer_take_data (buffer);
|
||||
+
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+
|
||||
+ out:
|
||||
+ if (rd != cmdline)
|
||||
+ grub_free (rd);
|
||||
+ grub_buffer_free (buffer);
|
||||
+ grub_buffer_free (varname);
|
||||
+
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ fail:
|
||||
+ grub_free (*argv);
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
/* Helper for grub_parser_execute. */
|
||||
diff --git a/include/grub/buffer.h b/include/grub/buffer.h
|
||||
new file mode 100644
|
||||
index 0000000..f4b10cf
|
||||
--- /dev/null
|
||||
+++ b/include/grub/buffer.h
|
||||
@@ -0,0 +1,144 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * GRUB is free software: you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License as published by
|
||||
+ * the Free Software Foundation, either version 3 of the License, or
|
||||
+ * (at your option) any later version.
|
||||
+ *
|
||||
+ * GRUB is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_BUFFER_H
|
||||
+#define GRUB_BUFFER_H 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/safemath.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+struct grub_buffer
|
||||
+{
|
||||
+ grub_uint8_t *data;
|
||||
+ grub_size_t sz;
|
||||
+ grub_size_t pos;
|
||||
+ grub_size_t used;
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * grub_buffer_t represents a simple variable sized byte buffer with
|
||||
+ * read and write cursors. It currently only implements
|
||||
+ * functionality required by the only user in GRUB (append byte[s],
|
||||
+ * peeking data at a specified position and updating the read cursor.
|
||||
+ * Some things that this doesn't do yet are:
|
||||
+ * - Reading a portion of the buffer by copying data from the current
|
||||
+ * read position in to a caller supplied destination buffer and then
|
||||
+ * automatically updating the read cursor.
|
||||
+ * - Dropping the read part at the start of the buffer when an append
|
||||
+ * requires more space.
|
||||
+ */
|
||||
+typedef struct grub_buffer *grub_buffer_t;
|
||||
+
|
||||
+/* Allocate a new buffer with the specified initial size. */
|
||||
+extern grub_buffer_t grub_buffer_new (grub_size_t sz);
|
||||
+
|
||||
+/* Free the buffer and its resources. */
|
||||
+extern void grub_buffer_free (grub_buffer_t buf);
|
||||
+
|
||||
+/* Return the number of unread bytes in this buffer. */
|
||||
+static inline grub_size_t
|
||||
+grub_buffer_get_unread_bytes (grub_buffer_t buf)
|
||||
+{
|
||||
+ return buf->used - buf->pos;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Ensure that the buffer size is at least the requested
|
||||
+ * number of bytes.
|
||||
+ */
|
||||
+extern grub_err_t grub_buffer_ensure_space (grub_buffer_t buf, grub_size_t req);
|
||||
+
|
||||
+/*
|
||||
+ * Append the specified number of bytes from the supplied
|
||||
+ * data to the buffer.
|
||||
+ */
|
||||
+static inline grub_err_t
|
||||
+grub_buffer_append_data (grub_buffer_t buf, const void *data, grub_size_t len)
|
||||
+{
|
||||
+ grub_size_t req;
|
||||
+
|
||||
+ if (grub_add (buf->used, len, &req))
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
+
|
||||
+ if (grub_buffer_ensure_space (buf, req) != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ grub_memcpy (&buf->data[buf->used], data, len);
|
||||
+ buf->used = req;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/* Append the supplied character to the buffer. */
|
||||
+static inline grub_err_t
|
||||
+grub_buffer_append_char (grub_buffer_t buf, char c)
|
||||
+{
|
||||
+ return grub_buffer_append_data (buf, &c, 1);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Forget and return the underlying data buffer. The caller
|
||||
+ * becomes the owner of this buffer, and must free it when it
|
||||
+ * is no longer required.
|
||||
+ */
|
||||
+extern void *grub_buffer_take_data (grub_buffer_t buf);
|
||||
+
|
||||
+/* Reset this buffer. Note that this does not deallocate any resources. */
|
||||
+void grub_buffer_reset (grub_buffer_t buf);
|
||||
+
|
||||
+/*
|
||||
+ * Return a pointer to the underlying data buffer at the specified
|
||||
+ * offset from the current read position. Note that this pointer may
|
||||
+ * become invalid if the buffer is mutated further.
|
||||
+ */
|
||||
+static inline void *
|
||||
+grub_buffer_peek_data_at (grub_buffer_t buf, grub_size_t off)
|
||||
+{
|
||||
+ if (grub_add (buf->pos, off, &off))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected."));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (off >= buf->used)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("peek out of range"));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return &buf->data[off];
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Return a pointer to the underlying data buffer at the current
|
||||
+ * read position. Note that this pointer may become invalid if the
|
||||
+ * buffer is mutated further.
|
||||
+ */
|
||||
+static inline void *
|
||||
+grub_buffer_peek_data (grub_buffer_t buf)
|
||||
+{
|
||||
+ return grub_buffer_peek_data_at (buf, 0);
|
||||
+}
|
||||
+
|
||||
+/* Advance the read position by the specified number of bytes. */
|
||||
+extern grub_err_t grub_buffer_advance_read_pos (grub_buffer_t buf, grub_size_t n);
|
||||
+
|
||||
+#endif /* GRUB_BUFFER_H */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
58
meta/recipes-bsp/grub/files/CVE-2021-20225.patch
Normal file
58
meta/recipes-bsp/grub/files/CVE-2021-20225.patch
Normal file
@@ -0,0 +1,58 @@
|
||||
From 2a330dba93ff11bc00eda76e9419bc52b0c7ead6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Fri, 22 Jan 2021 16:07:29 +1100
|
||||
Subject: lib/arg: Block repeated short options that require an argument
|
||||
|
||||
Fuzzing found the following crash:
|
||||
|
||||
search -hhhhhhhhhhhhhf
|
||||
|
||||
We didn't allocate enough option space for 13 hints because the
|
||||
allocation code counts the number of discrete arguments (i.e. argc).
|
||||
However, the shortopt parsing code will happily keep processing
|
||||
a combination of short options without checking if those short
|
||||
options require an argument. This means you can easily end writing
|
||||
past the allocated option space.
|
||||
|
||||
This fixes a OOB write which can cause heap corruption.
|
||||
|
||||
Fixes: CVE-2021-20225
|
||||
|
||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=2a330dba93ff11bc00eda76e9419bc52b0c7ead6]
|
||||
CVE: CVE-2021-20225
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
grub-core/lib/arg.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/grub-core/lib/arg.c b/grub-core/lib/arg.c
|
||||
index 3288609..537c5e9 100644
|
||||
--- a/grub-core/lib/arg.c
|
||||
+++ b/grub-core/lib/arg.c
|
||||
@@ -299,6 +299,19 @@ grub_arg_parse (grub_extcmd_t cmd, int argc, char **argv,
|
||||
it can have an argument value. */
|
||||
if (*curshort)
|
||||
{
|
||||
+ /*
|
||||
+ * Only permit further short opts if this one doesn't
|
||||
+ * require a value.
|
||||
+ */
|
||||
+ if (opt->type != ARG_TYPE_NONE &&
|
||||
+ !(opt->flags & GRUB_ARG_OPTION_OPTIONAL))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("missing mandatory option for `%s'"),
|
||||
+ opt->longarg);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (parse_option (cmd, opt, 0, usr) || grub_errno)
|
||||
goto fail;
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
50
meta/recipes-bsp/grub/files/CVE-2021-20233.patch
Normal file
50
meta/recipes-bsp/grub/files/CVE-2021-20233.patch
Normal file
@@ -0,0 +1,50 @@
|
||||
From 2f533a89a8dfcacbf2c9dbc77d910f111f24bf33 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Fri, 22 Jan 2021 17:10:48 +1100
|
||||
Subject: commands/menuentry: Fix quoting in setparams_prefix()
|
||||
|
||||
Commit 9acdcbf32542 (use single quotes in menuentry setparams command)
|
||||
says that expressing a quoted single quote will require 3 characters. It
|
||||
actually requires (and always did require!) 4 characters:
|
||||
|
||||
str: a'b => a'\''b
|
||||
len: 3 => 6 (2 for the letters + 4 for the quote)
|
||||
|
||||
This leads to not allocating enough memory and thus out of bounds writes
|
||||
that have been observed to cause heap corruption.
|
||||
|
||||
Allocate 4 bytes for each single quote.
|
||||
|
||||
Commit 22e7dbb2bb81 (Fix quoting in legacy parser.) does the same
|
||||
quoting, but it adds 3 as extra overhead on top of the single byte that
|
||||
the quote already needs. So it's correct.
|
||||
|
||||
Fixes: 9acdcbf32542 (use single quotes in menuentry setparams command)
|
||||
Fixes: CVE-2021-20233
|
||||
|
||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?h=grub-2.06&id=2f533a89a8dfcacbf2c9dbc77d910f111f24bf33]
|
||||
CVE: CVE-2021-20233
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
grub-core/commands/menuentry.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c
|
||||
index 9164df7..720e6d8 100644
|
||||
--- a/grub-core/commands/menuentry.c
|
||||
+++ b/grub-core/commands/menuentry.c
|
||||
@@ -230,7 +230,7 @@ setparams_prefix (int argc, char **args)
|
||||
len += 3; /* 3 = 1 space + 2 quotes */
|
||||
p = args[i];
|
||||
while (*p)
|
||||
- len += (*p++ == '\'' ? 3 : 1);
|
||||
+ len += (*p++ == '\'' ? 4 : 1);
|
||||
}
|
||||
|
||||
result = grub_malloc (len + 2);
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -11,7 +11,7 @@ missing sorting of the list used to generate it. Add such a sort.
|
||||
Also ensure the generated unidata.c file is deterministic by sorting the
|
||||
keys of the dict.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Upstream-Status: Submitted [https://lists.gnu.org/archive/html/grub-devel/2023-06/index.html]
|
||||
Richard Purdie <richard.purdie@linuxfoundation.org>
|
||||
|
||||
Index: grub-2.04/grub-core/genmoddep.awk
|
||||
|
||||
@@ -106,6 +106,9 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \
|
||||
file://font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch \
|
||||
file://CVE-2022-2601.patch \
|
||||
file://CVE-2022-3775.patch \
|
||||
file://CVE-2020-27749.patch \
|
||||
file://CVE-2021-20225.patch \
|
||||
file://CVE-2021-20233.patch \
|
||||
"
|
||||
SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934"
|
||||
SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea"
|
||||
@@ -125,6 +128,8 @@ GRUBPLATFORM ??= "pc"
|
||||
|
||||
inherit autotools gettext texinfo pkgconfig
|
||||
|
||||
CFLAGS_remove = "-O2"
|
||||
|
||||
EXTRA_OECONF = "--with-platform=${GRUBPLATFORM} \
|
||||
--disable-grub-mkfont \
|
||||
--program-prefix="" \
|
||||
|
||||
@@ -19,9 +19,12 @@ PACKAGECONFIG[manpages] = "--enable-doc, --disable-doc, libxslt-native xmlto-nat
|
||||
|
||||
RDEPENDS_${PN} = "grep bash"
|
||||
|
||||
EXTRA_OECONF = "--libdir=${nonarch_libdir}"
|
||||
|
||||
do_configure_prepend () {
|
||||
( cd ${S}; autoreconf -f -i -s )
|
||||
}
|
||||
|
||||
FILES_${PN} += "${libdir}/${BPN}/*"
|
||||
FILES_${PN} += "${nonarch_libdir}/${BPN}/*"
|
||||
FILES_${PN}-dbg += "${datadir}/doc/pm-utils/README.debugging"
|
||||
FILES_${PN}-dev += "${nonarch_libdir}/pkgconfig/pm-utils.pc"
|
||||
|
||||
166
meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch
Normal file
166
meta/recipes-connectivity/bind/bind/CVE-2023-2828.patch
Normal file
@@ -0,0 +1,166 @@
|
||||
|
||||
Upstream-Status: Backport [import from debian security.debian.org/debian-security/pool/updates/main/b/bind9/bind9_9.11.5.P4+dfsg-5.1+deb10u9.debian.tar.xz
|
||||
Upstream patch https://downloads.isc.org/isc/bind9/9.16.42/patches/0001-CVE-2023-2828.patch]
|
||||
Upstream Commit: https://github.com/isc-projects/bind9/commit/da0eafcdee52147e72d407cc3b9f179378ee1d3a
|
||||
CVE: CVE-2023-2828
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
|
||||
---
|
||||
lib/dns/rbtdb.c | 106 +++++++++++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 63 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
|
||||
index b1b928c..3165e26 100644
|
||||
--- a/lib/dns/rbtdb.c
|
||||
+++ b/lib/dns/rbtdb.c
|
||||
@@ -792,7 +792,7 @@ static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
|
||||
static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
|
||||
bool tree_locked, expire_t reason);
|
||||
static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
|
||||
- isc_stdtime_t now, bool tree_locked);
|
||||
+ size_t purgesize, bool tree_locked);
|
||||
static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
|
||||
rdatasetheader_t *newheader);
|
||||
static void resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
|
||||
@@ -6784,6 +6784,16 @@ addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
|
||||
|
||||
static dns_dbmethods_t zone_methods;
|
||||
|
||||
+static size_t
|
||||
+rdataset_size(rdatasetheader_t *header) {
|
||||
+ if (!NONEXISTENT(header)) {
|
||||
+ return (dns_rdataslab_size((unsigned char *)header,
|
||||
+ sizeof(*header)));
|
||||
+ }
|
||||
+
|
||||
+ return (sizeof(*header));
|
||||
+}
|
||||
+
|
||||
static isc_result_t
|
||||
addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
isc_stdtime_t now, dns_rdataset_t *rdataset, unsigned int options,
|
||||
@@ -6932,7 +6942,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
}
|
||||
|
||||
if (cache_is_overmem)
|
||||
- overmem_purge(rbtdb, rbtnode->locknum, now, tree_locked);
|
||||
+ overmem_purge(rbtdb, rbtnode->locknum, rdataset_size(newheader),
|
||||
+ tree_locked);
|
||||
|
||||
NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
@@ -6947,9 +6958,14 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
|
||||
cleanup_dead_nodes(rbtdb, rbtnode->locknum);
|
||||
|
||||
header = isc_heap_element(rbtdb->heaps[rbtnode->locknum], 1);
|
||||
- if (header && header->rdh_ttl < now - RBTDB_VIRTUAL)
|
||||
- expire_header(rbtdb, header, tree_locked,
|
||||
- expire_ttl);
|
||||
+ if (header != NULL) {
|
||||
+ dns_ttl_t rdh_ttl = header->rdh_ttl;
|
||||
+
|
||||
+ if (rdh_ttl < now - RBTDB_VIRTUAL) {
|
||||
+ expire_header(rbtdb, header, tree_locked,
|
||||
+ expire_ttl);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/*
|
||||
* If we've been holding a write lock on the tree just for
|
||||
@@ -10388,54 +10404,58 @@ update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
|
||||
ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link);
|
||||
}
|
||||
|
||||
+static size_t
|
||||
+expire_lru_headers(dns_rbtdb_t *rbtdb, unsigned int locknum, size_t purgesize,
|
||||
+ bool tree_locked) {
|
||||
+ rdatasetheader_t *header, *header_prev;
|
||||
+ size_t purged = 0;
|
||||
+
|
||||
+ for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
|
||||
+ header != NULL && purged <= purgesize; header = header_prev)
|
||||
+ {
|
||||
+ header_prev = ISC_LIST_PREV(header, link);
|
||||
+ /*
|
||||
+ * Unlink the entry at this point to avoid checking it
|
||||
+ * again even if it's currently used someone else and
|
||||
+ * cannot be purged at this moment. This entry won't be
|
||||
+ * referenced any more (so unlinking is safe) since the
|
||||
+ * TTL was reset to 0.
|
||||
+ */
|
||||
+ ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, link);
|
||||
+ size_t header_size = rdataset_size(header);
|
||||
+ expire_header(rbtdb, header, tree_locked, expire_lru);
|
||||
+ purged += header_size;
|
||||
+ }
|
||||
+
|
||||
+ return (purged);
|
||||
+}
|
||||
+
|
||||
/*%
|
||||
- * Purge some expired and/or stale (i.e. unused for some period) cache entries
|
||||
- * under an overmem condition. To recover from this condition quickly, up to
|
||||
- * 2 entries will be purged. This process is triggered while adding a new
|
||||
- * entry, and we specifically avoid purging entries in the same LRU bucket as
|
||||
- * the one to which the new entry will belong. Otherwise, we might purge
|
||||
- * entries of the same name of different RR types while adding RRsets from a
|
||||
- * single response (consider the case where we're adding A and AAAA glue records
|
||||
- * of the same NS name).
|
||||
- */
|
||||
+ * Purge some stale (i.e. unused for some period - LRU based cleaning) cache
|
||||
+ * entries under the overmem condition. To recover from this condition quickly,
|
||||
+ * we cleanup entries up to the size of newly added rdata (passed as purgesize).
|
||||
+ *
|
||||
+ * This process is triggered while adding a new entry, and we specifically avoid
|
||||
+ * purging entries in the same LRU bucket as the one to which the new entry will
|
||||
+ * belong. Otherwise, we might purge entries of the same name of different RR
|
||||
+ * types while adding RRsets from a single response (consider the case where
|
||||
+ * we're adding A and AAAA glue records of the same NS name).
|
||||
+*/
|
||||
static void
|
||||
-overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
|
||||
- isc_stdtime_t now, bool tree_locked)
|
||||
+overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, size_t purgesize,
|
||||
+ bool tree_locked)
|
||||
{
|
||||
- rdatasetheader_t *header, *header_prev;
|
||||
unsigned int locknum;
|
||||
- int purgecount = 2;
|
||||
+ size_t purged = 0;
|
||||
|
||||
for (locknum = (locknum_start + 1) % rbtdb->node_lock_count;
|
||||
- locknum != locknum_start && purgecount > 0;
|
||||
+ locknum != locknum_start && purged <= purgesize;
|
||||
locknum = (locknum + 1) % rbtdb->node_lock_count) {
|
||||
NODE_LOCK(&rbtdb->node_locks[locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
|
||||
- header = isc_heap_element(rbtdb->heaps[locknum], 1);
|
||||
- if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) {
|
||||
- expire_header(rbtdb, header, tree_locked,
|
||||
- expire_ttl);
|
||||
- purgecount--;
|
||||
- }
|
||||
-
|
||||
- for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
|
||||
- header != NULL && purgecount > 0;
|
||||
- header = header_prev) {
|
||||
- header_prev = ISC_LIST_PREV(header, link);
|
||||
- /*
|
||||
- * Unlink the entry at this point to avoid checking it
|
||||
- * again even if it's currently used someone else and
|
||||
- * cannot be purged at this moment. This entry won't be
|
||||
- * referenced any more (so unlinking is safe) since the
|
||||
- * TTL was reset to 0.
|
||||
- */
|
||||
- ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header,
|
||||
- link);
|
||||
- expire_header(rbtdb, header, tree_locked,
|
||||
- expire_lru);
|
||||
- purgecount--;
|
||||
- }
|
||||
+ purged += expire_lru_headers(rbtdb, locknum, purgesize - purged,
|
||||
+ tree_locked);
|
||||
|
||||
NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
|
||||
isc_rwlocktype_write);
|
||||
@@ -22,6 +22,7 @@ SRC_URI = "https://ftp.isc.org/isc/bind9/${PV}/${BPN}-${PV}.tar.gz \
|
||||
file://CVE-2022-2795.patch \
|
||||
file://CVE-2022-38177.patch \
|
||||
file://CVE-2022-38178.patch \
|
||||
file://CVE-2023-2828.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "0d8efbe7ec166ada90e46add4267b7e7c934790cba9bd5af6b8380a4fbfb5aff"
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
From 703418fe9d2e3b1e8d594df5788d8001a8116265 Mon Sep 17 00:00:00 2001
|
||||
From: Jeffrey Bencteux <jeffbencteux@gmail.com>
|
||||
Date: Fri, 30 Jun 2023 19:02:45 +0200
|
||||
Subject: [PATCH] CVE-2023-40303: ftpd,rcp,rlogin,rsh,rshd,uucpd: fix: check
|
||||
set*id() return values
|
||||
|
||||
Several setuid(), setgid(), seteuid() and setguid() return values
|
||||
were not checked in ftpd/rcp/rlogin/rsh/rshd/uucpd code potentially
|
||||
leading to potential security issues.
|
||||
|
||||
CVE: CVE-2023-40303
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=e4e65c03f4c11292a3e40ef72ca3f194c8bffdd6]
|
||||
Signed-off-by: Jeffrey Bencteux <jeffbencteux@gmail.com>
|
||||
Signed-off-by: Simon Josefsson <simon@josefsson.org>
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
ftpd/ftpd.c | 10 +++++++---
|
||||
src/rcp.c | 39 +++++++++++++++++++++++++++++++++------
|
||||
src/rlogin.c | 11 +++++++++--
|
||||
src/rsh.c | 25 +++++++++++++++++++++----
|
||||
src/rshd.c | 20 +++++++++++++++++---
|
||||
src/uucpd.c | 15 +++++++++++++--
|
||||
6 files changed, 100 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/ftpd/ftpd.c b/ftpd/ftpd.c
|
||||
index 5db88d0..b52b122 100644
|
||||
--- a/ftpd/ftpd.c
|
||||
+++ b/ftpd/ftpd.c
|
||||
@@ -862,7 +862,9 @@ end_login (struct credentials *pcred)
|
||||
char *remotehost = pcred->remotehost;
|
||||
int atype = pcred->auth_type;
|
||||
|
||||
- seteuid ((uid_t) 0);
|
||||
+ if (seteuid ((uid_t) 0) == -1)
|
||||
+ _exit (EXIT_FAILURE);
|
||||
+
|
||||
if (pcred->logged_in)
|
||||
{
|
||||
logwtmp_keep_open (ttyline, "", "");
|
||||
@@ -1151,7 +1153,8 @@ getdatasock (const char *mode)
|
||||
|
||||
if (data >= 0)
|
||||
return fdopen (data, mode);
|
||||
- seteuid ((uid_t) 0);
|
||||
+ if (seteuid ((uid_t) 0) == -1)
|
||||
+ _exit (EXIT_FAILURE);
|
||||
s = socket (ctrl_addr.ss_family, SOCK_STREAM, 0);
|
||||
if (s < 0)
|
||||
goto bad;
|
||||
@@ -1978,7 +1981,8 @@ passive (int epsv, int af)
|
||||
else /* !AF_INET6 */
|
||||
((struct sockaddr_in *) &pasv_addr)->sin_port = 0;
|
||||
|
||||
- seteuid ((uid_t) 0);
|
||||
+ if (seteuid ((uid_t) 0) == -1)
|
||||
+ _exit (EXIT_FAILURE);
|
||||
if (bind (pdata, (struct sockaddr *) &pasv_addr, pasv_addrlen) < 0)
|
||||
{
|
||||
if (seteuid ((uid_t) cred.uid))
|
||||
diff --git a/src/rcp.c b/src/rcp.c
|
||||
index bafa35f..366295c 100644
|
||||
--- a/src/rcp.c
|
||||
+++ b/src/rcp.c
|
||||
@@ -347,14 +347,23 @@ main (int argc, char *argv[])
|
||||
if (from_option)
|
||||
{ /* Follow "protocol", send data. */
|
||||
response ();
|
||||
- setuid (userid);
|
||||
+
|
||||
+ if (setuid (userid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
+
|
||||
source (argc, argv);
|
||||
exit (errs);
|
||||
}
|
||||
|
||||
if (to_option)
|
||||
{ /* Receive data. */
|
||||
- setuid (userid);
|
||||
+ if (setuid (userid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
+
|
||||
sink (argc, argv);
|
||||
exit (errs);
|
||||
}
|
||||
@@ -539,7 +548,11 @@ toremote (char *targ, int argc, char *argv[])
|
||||
if (response () < 0)
|
||||
exit (EXIT_FAILURE);
|
||||
free (bp);
|
||||
- setuid (userid);
|
||||
+
|
||||
+ if (setuid (userid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
}
|
||||
source (1, argv + i);
|
||||
close (rem);
|
||||
@@ -634,7 +647,12 @@ tolocal (int argc, char *argv[])
|
||||
++errs;
|
||||
continue;
|
||||
}
|
||||
- seteuid (userid);
|
||||
+
|
||||
+ if (seteuid (userid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (seteuid() failed)");
|
||||
+ }
|
||||
+
|
||||
#if defined IP_TOS && defined IPPROTO_IP && defined IPTOS_THROUGHPUT
|
||||
sslen = sizeof (ss);
|
||||
(void) getpeername (rem, (struct sockaddr *) &ss, &sslen);
|
||||
@@ -647,7 +665,12 @@ tolocal (int argc, char *argv[])
|
||||
#endif
|
||||
vect[0] = target;
|
||||
sink (1, vect);
|
||||
- seteuid (effuid);
|
||||
+
|
||||
+ if (seteuid (effuid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (seteuid() failed)");
|
||||
+ }
|
||||
+
|
||||
close (rem);
|
||||
rem = -1;
|
||||
#ifdef SHISHI
|
||||
@@ -1453,7 +1476,11 @@ susystem (char *s, int userid)
|
||||
return (127);
|
||||
|
||||
case 0:
|
||||
- setuid (userid);
|
||||
+ if (setuid (userid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
+
|
||||
execl (PATH_BSHELL, "sh", "-c", s, NULL);
|
||||
_exit (127);
|
||||
}
|
||||
diff --git a/src/rlogin.c b/src/rlogin.c
|
||||
index e5e11a7..6b38901 100644
|
||||
--- a/src/rlogin.c
|
||||
+++ b/src/rlogin.c
|
||||
@@ -649,8 +649,15 @@ try_connect:
|
||||
/* Now change to the real user ID. We have to be set-user-ID root
|
||||
to get the privileged port that rcmd () uses. We now want, however,
|
||||
to run as the real user who invoked us. */
|
||||
- seteuid (uid);
|
||||
- setuid (uid);
|
||||
+ if (seteuid (uid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (seteuid() failed)");
|
||||
+ }
|
||||
+
|
||||
+ if (setuid (uid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
|
||||
doit (&osmask); /* The old mask will activate SIGURG and SIGUSR1! */
|
||||
|
||||
diff --git a/src/rsh.c b/src/rsh.c
|
||||
index bd70372..b451a70 100644
|
||||
--- a/src/rsh.c
|
||||
+++ b/src/rsh.c
|
||||
@@ -278,8 +278,17 @@ main (int argc, char **argv)
|
||||
{
|
||||
if (asrsh)
|
||||
*argv = (char *) "rlogin";
|
||||
- seteuid (getuid ());
|
||||
- setuid (getuid ());
|
||||
+
|
||||
+ if (seteuid (getuid ()) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "seteuid() failed");
|
||||
+ }
|
||||
+
|
||||
+ if (setuid (getuid ()) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "setuid() failed");
|
||||
+ }
|
||||
+
|
||||
execv (PATH_RLOGIN, argv);
|
||||
error (EXIT_FAILURE, errno, "cannot execute %s", PATH_RLOGIN);
|
||||
}
|
||||
@@ -543,8 +552,16 @@ try_connect:
|
||||
error (0, errno, "setsockopt DEBUG (ignored)");
|
||||
}
|
||||
|
||||
- seteuid (uid);
|
||||
- setuid (uid);
|
||||
+ if (seteuid (uid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "seteuid() failed");
|
||||
+ }
|
||||
+
|
||||
+ if (setuid (uid) == -1)
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "setuid() failed");
|
||||
+ }
|
||||
+
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigemptyset (&sigs);
|
||||
sigaddset (&sigs, SIGINT);
|
||||
diff --git a/src/rshd.c b/src/rshd.c
|
||||
index b824a10..8cdcd06 100644
|
||||
--- a/src/rshd.c
|
||||
+++ b/src/rshd.c
|
||||
@@ -1848,8 +1848,18 @@ doit (int sockfd, struct sockaddr *fromp, socklen_t fromlen)
|
||||
pwd->pw_shell = PATH_BSHELL;
|
||||
|
||||
/* Set the gid, then uid to become the user specified by "locuser" */
|
||||
- setegid ((gid_t) pwd->pw_gid);
|
||||
- setgid ((gid_t) pwd->pw_gid);
|
||||
+ if (setegid ((gid_t) pwd->pw_gid) == -1)
|
||||
+ {
|
||||
+ rshd_error ("Cannot drop privileges (setegid() failed)\n");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ if (setgid ((gid_t) pwd->pw_gid) == -1)
|
||||
+ {
|
||||
+ rshd_error ("Cannot drop privileges (setgid() failed)\n");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
#ifdef HAVE_INITGROUPS
|
||||
initgroups (pwd->pw_name, pwd->pw_gid); /* BSD groups */
|
||||
#endif
|
||||
@@ -1871,7 +1881,11 @@ doit (int sockfd, struct sockaddr *fromp, socklen_t fromlen)
|
||||
}
|
||||
#endif /* WITH_PAM */
|
||||
|
||||
- setuid ((uid_t) pwd->pw_uid);
|
||||
+ if (setuid ((uid_t) pwd->pw_uid) == -1)
|
||||
+ {
|
||||
+ rshd_error ("Cannot drop privileges (setuid() failed)\n");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
|
||||
/* We'll execute the client's command in the home directory
|
||||
* of locuser. Note, that the chdir must be executed after
|
||||
diff --git a/src/uucpd.c b/src/uucpd.c
|
||||
index 55c3d44..6aba294 100644
|
||||
--- a/src/uucpd.c
|
||||
+++ b/src/uucpd.c
|
||||
@@ -254,7 +254,12 @@ doit (struct sockaddr *sap, socklen_t salen)
|
||||
sprintf (Username, "USER=%s", user);
|
||||
sprintf (Logname, "LOGNAME=%s", user);
|
||||
dologin (pw, sap, salen);
|
||||
- setgid (pw->pw_gid);
|
||||
+
|
||||
+ if (setgid (pw->pw_gid) == -1)
|
||||
+ {
|
||||
+ fprintf (stderr, "setgid() failed");
|
||||
+ return;
|
||||
+ }
|
||||
#ifdef HAVE_INITGROUPS
|
||||
initgroups (pw->pw_name, pw->pw_gid);
|
||||
#endif
|
||||
@@ -263,7 +268,13 @@ doit (struct sockaddr *sap, socklen_t salen)
|
||||
fprintf (stderr, "Login incorrect.");
|
||||
return;
|
||||
}
|
||||
- setuid (pw->pw_uid);
|
||||
+
|
||||
+ if (setuid (pw->pw_uid) == -1)
|
||||
+ {
|
||||
+ fprintf (stderr, "setuid() failed");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
execl (uucico_location, "uucico", NULL);
|
||||
perror ("uucico server: execl");
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
From 70fe022f9dac760eaece0228cad17e3d29a57fb8 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Josefsson <simon@josefsson.org>
|
||||
Date: Mon, 31 Jul 2023 13:59:05 +0200
|
||||
Subject: [PATCH] CVE-2023-40303: Indent changes in previous commit.
|
||||
|
||||
CVE: CVE-2023-40303
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=9122999252c7e21eb7774de11d539748e7bdf46d]
|
||||
Signed-off-by: Khem Raj <raj.khem@gmail.com>
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/rcp.c | 42 ++++++++++++++++++++++++------------------
|
||||
src/rlogin.c | 12 ++++++------
|
||||
src/rsh.c | 24 ++++++++++++------------
|
||||
src/rshd.c | 24 ++++++++++++------------
|
||||
src/uucpd.c | 16 ++++++++--------
|
||||
5 files changed, 62 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/src/rcp.c b/src/rcp.c
|
||||
index cdcf8500..652f22e6 100644
|
||||
--- a/src/rcp.c
|
||||
+++ b/src/rcp.c
|
||||
@@ -347,9 +347,10 @@ main (int argc, char *argv[])
|
||||
response ();
|
||||
|
||||
if (setuid (userid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
|
||||
source (argc, argv);
|
||||
exit (errs);
|
||||
@@ -358,9 +359,10 @@ main (int argc, char *argv[])
|
||||
if (to_option)
|
||||
{ /* Receive data. */
|
||||
if (setuid (userid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
|
||||
sink (argc, argv);
|
||||
exit (errs);
|
||||
@@ -548,9 +550,10 @@ toremote (char *targ, int argc, char *argv[])
|
||||
free (bp);
|
||||
|
||||
if (setuid (userid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
}
|
||||
source (1, argv + i);
|
||||
close (rem);
|
||||
@@ -645,9 +648,10 @@ tolocal (int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (seteuid (userid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (seteuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ "Could not drop privileges (seteuid() failed)");
|
||||
+ }
|
||||
|
||||
#if defined IP_TOS && defined IPPROTO_IP && defined IPTOS_THROUGHPUT
|
||||
sslen = sizeof (ss);
|
||||
@@ -663,9 +667,10 @@ tolocal (int argc, char *argv[])
|
||||
sink (1, vect);
|
||||
|
||||
if (seteuid (effuid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (seteuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ "Could not drop privileges (seteuid() failed)");
|
||||
+ }
|
||||
|
||||
close (rem);
|
||||
rem = -1;
|
||||
@@ -1465,9 +1470,10 @@ susystem (char *s, int userid)
|
||||
|
||||
case 0:
|
||||
if (setuid (userid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0,
|
||||
+ "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
|
||||
execl (PATH_BSHELL, "sh", "-c", s, NULL);
|
||||
_exit (127);
|
||||
diff --git a/src/rlogin.c b/src/rlogin.c
|
||||
index c543de0c..4360202f 100644
|
||||
--- a/src/rlogin.c
|
||||
+++ b/src/rlogin.c
|
||||
@@ -648,14 +648,14 @@ try_connect:
|
||||
to get the privileged port that rcmd () uses. We now want, however,
|
||||
to run as the real user who invoked us. */
|
||||
if (seteuid (uid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (seteuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (seteuid() failed)");
|
||||
+ }
|
||||
|
||||
if (setuid (uid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, 0, "Could not drop privileges (setuid() failed)");
|
||||
+ }
|
||||
|
||||
doit (&osmask); /* The old mask will activate SIGURG and SIGUSR1! */
|
||||
|
||||
diff --git a/src/rsh.c b/src/rsh.c
|
||||
index 6f60667d..179b47cd 100644
|
||||
--- a/src/rsh.c
|
||||
+++ b/src/rsh.c
|
||||
@@ -278,14 +278,14 @@ main (int argc, char **argv)
|
||||
*argv = (char *) "rlogin";
|
||||
|
||||
if (seteuid (getuid ()) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, errno, "seteuid() failed");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "seteuid() failed");
|
||||
+ }
|
||||
|
||||
if (setuid (getuid ()) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, errno, "setuid() failed");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "setuid() failed");
|
||||
+ }
|
||||
|
||||
execv (PATH_RLOGIN, argv);
|
||||
error (EXIT_FAILURE, errno, "cannot execute %s", PATH_RLOGIN);
|
||||
@@ -551,14 +551,14 @@ try_connect:
|
||||
}
|
||||
|
||||
if (seteuid (uid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, errno, "seteuid() failed");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "seteuid() failed");
|
||||
+ }
|
||||
|
||||
if (setuid (uid) == -1)
|
||||
- {
|
||||
- error (EXIT_FAILURE, errno, "setuid() failed");
|
||||
- }
|
||||
+ {
|
||||
+ error (EXIT_FAILURE, errno, "setuid() failed");
|
||||
+ }
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigemptyset (&sigs);
|
||||
diff --git a/src/rshd.c b/src/rshd.c
|
||||
index 707790e7..3a153a18 100644
|
||||
--- a/src/rshd.c
|
||||
+++ b/src/rshd.c
|
||||
@@ -1848,16 +1848,16 @@ doit (int sockfd, struct sockaddr *fromp, socklen_t fromlen)
|
||||
|
||||
/* Set the gid, then uid to become the user specified by "locuser" */
|
||||
if (setegid ((gid_t) pwd->pw_gid) == -1)
|
||||
- {
|
||||
- rshd_error ("Cannot drop privileges (setegid() failed)\n");
|
||||
- exit (EXIT_FAILURE);
|
||||
- }
|
||||
+ {
|
||||
+ rshd_error ("Cannot drop privileges (setegid() failed)\n");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
|
||||
if (setgid ((gid_t) pwd->pw_gid) == -1)
|
||||
- {
|
||||
- rshd_error ("Cannot drop privileges (setgid() failed)\n");
|
||||
- exit (EXIT_FAILURE);
|
||||
- }
|
||||
+ {
|
||||
+ rshd_error ("Cannot drop privileges (setgid() failed)\n");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
|
||||
#ifdef HAVE_INITGROUPS
|
||||
initgroups (pwd->pw_name, pwd->pw_gid); /* BSD groups */
|
||||
@@ -1881,10 +1881,10 @@ doit (int sockfd, struct sockaddr *fromp, socklen_t fromlen)
|
||||
#endif /* WITH_PAM */
|
||||
|
||||
if (setuid ((uid_t) pwd->pw_uid) == -1)
|
||||
- {
|
||||
- rshd_error ("Cannot drop privileges (setuid() failed)\n");
|
||||
- exit (EXIT_FAILURE);
|
||||
- }
|
||||
+ {
|
||||
+ rshd_error ("Cannot drop privileges (setuid() failed)\n");
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
|
||||
/* We'll execute the client's command in the home directory
|
||||
* of locuser. Note, that the chdir must be executed after
|
||||
diff --git a/src/uucpd.c b/src/uucpd.c
|
||||
index 29cfce35..fde7b9c9 100644
|
||||
--- a/src/uucpd.c
|
||||
+++ b/src/uucpd.c
|
||||
@@ -254,10 +254,10 @@ doit (struct sockaddr *sap, socklen_t salen)
|
||||
dologin (pw, sap, salen);
|
||||
|
||||
if (setgid (pw->pw_gid) == -1)
|
||||
- {
|
||||
- fprintf (stderr, "setgid() failed");
|
||||
- return;
|
||||
- }
|
||||
+ {
|
||||
+ fprintf (stderr, "setgid() failed");
|
||||
+ return;
|
||||
+ }
|
||||
#ifdef HAVE_INITGROUPS
|
||||
initgroups (pw->pw_name, pw->pw_gid);
|
||||
#endif
|
||||
@@ -268,10 +268,10 @@ doit (struct sockaddr *sap, socklen_t salen)
|
||||
}
|
||||
|
||||
if (setuid (pw->pw_uid) == -1)
|
||||
- {
|
||||
- fprintf (stderr, "setuid() failed");
|
||||
- return;
|
||||
- }
|
||||
+ {
|
||||
+ fprintf (stderr, "setuid() failed");
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
execl (uucico_location, "uucico", NULL);
|
||||
perror ("uucico server: execl");
|
||||
@@ -25,6 +25,8 @@ SRC_URI = "${GNU_MIRROR}/inetutils/inetutils-${PV}.tar.gz \
|
||||
file://fix-buffer-fortify-tfpt.patch \
|
||||
file://CVE-2021-40491.patch \
|
||||
file://CVE-2022-39028.patch \
|
||||
file://0001-CVE-2023-40303-ftpd-rcp-rlogin-rsh-rshd-uucpd-fix-ch.patch \
|
||||
file://0002-CVE-2023-40303-Indent-changes-in-previous-commit.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "04852c26c47cc8c6b825f2b74f191f52"
|
||||
|
||||
@@ -5,8 +5,8 @@ SECTION = "network"
|
||||
LICENSE = "PD"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=87964579b2a8ece4bc6744d2dc9a8b04"
|
||||
|
||||
SRCREV = "22a5de3ef637990ce03141f786fbdb327e9c5a3f"
|
||||
PV = "20221107"
|
||||
SRCREV = "aae7c68671d225e6d35224613d5b98192b9b2ffe"
|
||||
PV = "20230416"
|
||||
PE = "1"
|
||||
|
||||
SRC_URI = "git://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git;protocol=https;branch=main"
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
From f6213e03887237714eb5bcfc9089c707069f87c5 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Miller <djm@mindrot.org>
|
||||
Date: Fri, 1 Oct 2021 16:35:49 +1000
|
||||
Subject: [PATCH 01/12] make OPENSSL_HAS_ECC checks more thorough
|
||||
|
||||
ok dtucker
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/dee22129bbc61e25b1003adfa2bc584c5406ef2d]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-pkcs11-client.c | 16 ++++++++--------
|
||||
ssh-pkcs11.c | 26 +++++++++++++-------------
|
||||
2 files changed, 21 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
|
||||
index 8a0ffef..41114c7 100644
|
||||
--- a/ssh-pkcs11-client.c
|
||||
+++ b/ssh-pkcs11-client.c
|
||||
@@ -163,7 +163,7 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
static ECDSA_SIG *
|
||||
ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
const BIGNUM *rp, EC_KEY *ec)
|
||||
@@ -220,12 +220,12 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
sshbuf_free(msg);
|
||||
return (ret);
|
||||
}
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
static RSA_METHOD *helper_rsa;
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
static EC_KEY_METHOD *helper_ecdsa;
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
/* redirect private key crypto operations to the ssh-pkcs11-helper */
|
||||
static void
|
||||
@@ -233,10 +233,10 @@ wrap_key(struct sshkey *k)
|
||||
{
|
||||
if (k->type == KEY_RSA)
|
||||
RSA_set_method(k->rsa, helper_rsa);
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
else if (k->type == KEY_ECDSA)
|
||||
EC_KEY_set_method(k->ecdsa, helper_ecdsa);
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
else
|
||||
fatal("%s: unknown key type", __func__);
|
||||
}
|
||||
@@ -247,7 +247,7 @@ pkcs11_start_helper_methods(void)
|
||||
if (helper_rsa != NULL)
|
||||
return (0);
|
||||
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
|
||||
unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
|
||||
if (helper_ecdsa != NULL)
|
||||
@@ -257,7 +257,7 @@ pkcs11_start_helper_methods(void)
|
||||
return (-1);
|
||||
EC_KEY_METHOD_get_sign(helper_ecdsa, &orig_sign, NULL, NULL);
|
||||
EC_KEY_METHOD_set_sign(helper_ecdsa, orig_sign, NULL, ecdsa_do_sign);
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
|
||||
fatal("%s: RSA_meth_dup failed", __func__);
|
||||
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
|
||||
index a302c79..b56a41b 100644
|
||||
--- a/ssh-pkcs11.c
|
||||
+++ b/ssh-pkcs11.c
|
||||
@@ -78,7 +78,7 @@ struct pkcs11_key {
|
||||
|
||||
int pkcs11_interactive = 0;
|
||||
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
static void
|
||||
ossl_error(const char *msg)
|
||||
{
|
||||
@@ -89,7 +89,7 @@ ossl_error(const char *msg)
|
||||
error("%s: libcrypto error: %.100s", __func__,
|
||||
ERR_error_string(e, NULL));
|
||||
}
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
int
|
||||
pkcs11_init(int interactive)
|
||||
@@ -190,10 +190,10 @@ pkcs11_del_provider(char *provider_id)
|
||||
|
||||
static RSA_METHOD *rsa_method;
|
||||
static int rsa_idx = 0;
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
static EC_KEY_METHOD *ec_key_method;
|
||||
static int ec_key_idx = 0;
|
||||
-#endif
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
/* release a wrapped object */
|
||||
static void
|
||||
@@ -492,7 +492,7 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
|
||||
return (0);
|
||||
}
|
||||
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
/* openssl callback doing the actual signing operation */
|
||||
static ECDSA_SIG *
|
||||
ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
@@ -604,7 +604,7 @@ pkcs11_ecdsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
|
||||
|
||||
return (0);
|
||||
}
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
/* remove trailing spaces */
|
||||
static void
|
||||
@@ -679,7 +679,7 @@ pkcs11_key_included(struct sshkey ***keysp, int *nkeys, struct sshkey *key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
static struct sshkey *
|
||||
pkcs11_fetch_ecdsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
CK_OBJECT_HANDLE *obj)
|
||||
@@ -802,7 +802,7 @@ fail:
|
||||
|
||||
return (key);
|
||||
}
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
static struct sshkey *
|
||||
pkcs11_fetch_rsa_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
@@ -910,7 +910,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
#endif
|
||||
struct sshkey *key = NULL;
|
||||
int i;
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
int nid;
|
||||
#endif
|
||||
const u_char *cp;
|
||||
@@ -999,7 +999,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
key->type = KEY_RSA;
|
||||
key->flags |= SSHKEY_FLAG_EXT;
|
||||
rsa = NULL; /* now owned by key */
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
} else if (EVP_PKEY_base_id(evp) == EVP_PKEY_EC) {
|
||||
if (EVP_PKEY_get0_EC_KEY(evp) == NULL) {
|
||||
error("invalid x509; no ec key");
|
||||
@@ -1030,7 +1030,7 @@ pkcs11_fetch_x509_pubkey(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
key->type = KEY_ECDSA;
|
||||
key->flags |= SSHKEY_FLAG_EXT;
|
||||
ec = NULL; /* now owned by key */
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
} else {
|
||||
error("unknown certificate key type");
|
||||
goto out;
|
||||
@@ -1237,11 +1237,11 @@ pkcs11_fetch_keys(struct pkcs11_provider *p, CK_ULONG slotidx,
|
||||
case CKK_RSA:
|
||||
key = pkcs11_fetch_rsa_pubkey(p, slotidx, &obj);
|
||||
break;
|
||||
-#ifdef HAVE_EC_KEY_METHOD_NEW
|
||||
+#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
case CKK_ECDSA:
|
||||
key = pkcs11_fetch_ecdsa_pubkey(p, slotidx, &obj);
|
||||
break;
|
||||
-#endif /* HAVE_EC_KEY_METHOD_NEW */
|
||||
+#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
default:
|
||||
/* XXX print key type? */
|
||||
key = NULL;
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,581 @@
|
||||
From 92cebfbcc221c9ef3f6bbb78da3d7699c0ae56be Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Wed, 19 Jul 2023 14:03:45 +0000
|
||||
Subject: [PATCH 02/12] upstream: Separate ssh-pkcs11-helpers for each p11
|
||||
module
|
||||
|
||||
Make ssh-pkcs11-client start an independent helper for each provider,
|
||||
providing better isolation between modules and reliability if a single
|
||||
module misbehaves.
|
||||
|
||||
This also implements reference counting of PKCS#11-hosted keys,
|
||||
allowing ssh-pkcs11-helper subprocesses to be automatically reaped
|
||||
when no remaining keys reference them. This fixes some bugs we have
|
||||
that make PKCS11 keys unusable after they have been deleted, e.g.
|
||||
https://bugzilla.mindrot.org/show_bug.cgi?id=3125
|
||||
|
||||
ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: 0ce188b14fe271ab0568f4500070d96c5657244e
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/099cdf59ce1e72f55d421c8445bf6321b3004755]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-pkcs11-client.c | 372 +++++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 282 insertions(+), 90 deletions(-)
|
||||
|
||||
diff --git a/ssh-pkcs11-client.c b/ssh-pkcs11-client.c
|
||||
index 41114c7..4f3c6ed 100644
|
||||
--- a/ssh-pkcs11-client.c
|
||||
+++ b/ssh-pkcs11-client.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-pkcs11-client.c,v 1.16 2020/01/25 00:03:36 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-pkcs11-client.c,v 1.18 2023/07/19 14:03:45 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2010 Markus Friedl. All rights reserved.
|
||||
* Copyright (c) 2014 Pedro Martelletto. All rights reserved.
|
||||
@@ -30,12 +30,11 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
+#include <limits.h>
|
||||
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
-#include "openbsd-compat/openssl-compat.h"
|
||||
-
|
||||
#include "pathnames.h"
|
||||
#include "xmalloc.h"
|
||||
#include "sshbuf.h"
|
||||
@@ -47,18 +46,140 @@
|
||||
#include "ssh-pkcs11.h"
|
||||
#include "ssherr.h"
|
||||
|
||||
+#include "openbsd-compat/openssl-compat.h"
|
||||
+
|
||||
/* borrows code from sftp-server and ssh-agent */
|
||||
|
||||
-static int fd = -1;
|
||||
-static pid_t pid = -1;
|
||||
+/*
|
||||
+ * Maintain a list of ssh-pkcs11-helper subprocesses. These may be looked up
|
||||
+ * by provider path or their unique EC/RSA METHOD pointers.
|
||||
+ */
|
||||
+struct helper {
|
||||
+ char *path;
|
||||
+ pid_t pid;
|
||||
+ int fd;
|
||||
+ RSA_METHOD *rsa_meth;
|
||||
+ EC_KEY_METHOD *ec_meth;
|
||||
+ int (*rsa_finish)(RSA *rsa);
|
||||
+ void (*ec_finish)(EC_KEY *key);
|
||||
+ size_t nrsa, nec; /* number of active keys of each type */
|
||||
+};
|
||||
+static struct helper **helpers;
|
||||
+static size_t nhelpers;
|
||||
+
|
||||
+static struct helper *
|
||||
+helper_by_provider(const char *path)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; i < nhelpers; i++) {
|
||||
+ if (helpers[i] == NULL || helpers[i]->path == NULL ||
|
||||
+ helpers[i]->fd == -1)
|
||||
+ continue;
|
||||
+ if (strcmp(helpers[i]->path, path) == 0)
|
||||
+ return helpers[i];
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static struct helper *
|
||||
+helper_by_rsa(const RSA *rsa)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ const RSA_METHOD *meth;
|
||||
+
|
||||
+ if ((meth = RSA_get_method(rsa)) == NULL)
|
||||
+ return NULL;
|
||||
+ for (i = 0; i < nhelpers; i++) {
|
||||
+ if (helpers[i] != NULL && helpers[i]->rsa_meth == meth)
|
||||
+ return helpers[i];
|
||||
+ }
|
||||
+ return NULL;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static struct helper *
|
||||
+helper_by_ec(const EC_KEY *ec)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ const EC_KEY_METHOD *meth;
|
||||
+
|
||||
+ if ((meth = EC_KEY_get_method(ec)) == NULL)
|
||||
+ return NULL;
|
||||
+ for (i = 0; i < nhelpers; i++) {
|
||||
+ if (helpers[i] != NULL && helpers[i]->ec_meth == meth)
|
||||
+ return helpers[i];
|
||||
+ }
|
||||
+ return NULL;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+helper_free(struct helper *helper)
|
||||
+{
|
||||
+ size_t i;
|
||||
+ int found = 0;
|
||||
+
|
||||
+ if (helper == NULL)
|
||||
+ return;
|
||||
+ if (helper->path == NULL || helper->ec_meth == NULL ||
|
||||
+ helper->rsa_meth == NULL)
|
||||
+ fatal("%s: inconsistent helper", __func__);
|
||||
+ debug3("%s: free helper for provider %s", __func__ , helper->path);
|
||||
+ for (i = 0; i < nhelpers; i++) {
|
||||
+ if (helpers[i] == helper) {
|
||||
+ if (found)
|
||||
+ fatal("%s: helper recorded more than once", __func__);
|
||||
+ found = 1;
|
||||
+ }
|
||||
+ else if (found)
|
||||
+ helpers[i - 1] = helpers[i];
|
||||
+ }
|
||||
+ if (found) {
|
||||
+ helpers = xrecallocarray(helpers, nhelpers,
|
||||
+ nhelpers - 1, sizeof(*helpers));
|
||||
+ nhelpers--;
|
||||
+ }
|
||||
+ free(helper->path);
|
||||
+ EC_KEY_METHOD_free(helper->ec_meth);
|
||||
+ RSA_meth_free(helper->rsa_meth);
|
||||
+ free(helper);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+helper_terminate(struct helper *helper)
|
||||
+{
|
||||
+ if (helper == NULL) {
|
||||
+ return;
|
||||
+ } else if (helper->fd == -1) {
|
||||
+ debug3("%s: already terminated", __func__);
|
||||
+ } else {
|
||||
+ debug3("terminating helper for %s; "
|
||||
+ "remaining %zu RSA %zu ECDSA", __func__,
|
||||
+ helper->path, helper->nrsa, helper->nec);
|
||||
+ close(helper->fd);
|
||||
+ /* XXX waitpid() */
|
||||
+ helper->fd = -1;
|
||||
+ helper->pid = -1;
|
||||
+ }
|
||||
+ /*
|
||||
+ * Don't delete the helper entry until there are no remaining keys
|
||||
+ * that reference it. Otherwise, any signing operation would call
|
||||
+ * a free'd METHOD pointer and that would be bad.
|
||||
+ */
|
||||
+ if (helper->nrsa == 0 && helper->nec == 0)
|
||||
+ helper_free(helper);
|
||||
+}
|
||||
|
||||
static void
|
||||
-send_msg(struct sshbuf *m)
|
||||
+send_msg(int fd, struct sshbuf *m)
|
||||
{
|
||||
u_char buf[4];
|
||||
size_t mlen = sshbuf_len(m);
|
||||
int r;
|
||||
|
||||
+ if (fd == -1)
|
||||
+ return;
|
||||
POKE_U32(buf, mlen);
|
||||
if (atomicio(vwrite, fd, buf, 4) != 4 ||
|
||||
atomicio(vwrite, fd, sshbuf_mutable_ptr(m),
|
||||
@@ -69,12 +190,15 @@ send_msg(struct sshbuf *m)
|
||||
}
|
||||
|
||||
static int
|
||||
-recv_msg(struct sshbuf *m)
|
||||
+recv_msg(int fd, struct sshbuf *m)
|
||||
{
|
||||
u_int l, len;
|
||||
u_char c, buf[1024];
|
||||
int r;
|
||||
|
||||
+ sshbuf_reset(m);
|
||||
+ if (fd == -1)
|
||||
+ return 0; /* XXX */
|
||||
if ((len = atomicio(read, fd, buf, 4)) != 4) {
|
||||
error("read from helper failed: %u", len);
|
||||
return (0); /* XXX */
|
||||
@@ -83,7 +207,6 @@ recv_msg(struct sshbuf *m)
|
||||
if (len > 256 * 1024)
|
||||
fatal("response too long: %u", len);
|
||||
/* read len bytes into m */
|
||||
- sshbuf_reset(m);
|
||||
while (len > 0) {
|
||||
l = len;
|
||||
if (l > sizeof(buf))
|
||||
@@ -104,14 +227,17 @@ recv_msg(struct sshbuf *m)
|
||||
int
|
||||
pkcs11_init(int interactive)
|
||||
{
|
||||
- return (0);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pkcs11_terminate(void)
|
||||
{
|
||||
- if (fd >= 0)
|
||||
- close(fd);
|
||||
+ size_t i;
|
||||
+
|
||||
+ debug3("%s: terminating %zu helpers", __func__, nhelpers);
|
||||
+ for (i = 0; i < nhelpers; i++)
|
||||
+ helper_terminate(helpers[i]);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -122,7 +248,11 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
u_char *blob = NULL, *signature = NULL;
|
||||
size_t blen, slen = 0;
|
||||
int r, ret = -1;
|
||||
+ struct helper *helper;
|
||||
|
||||
+ if ((helper = helper_by_rsa(rsa)) == NULL || helper->fd == -1)
|
||||
+ fatal("%s: no helper for PKCS11 key", __func__);
|
||||
+ debug3("%s: signing with PKCS11 provider %s", __func__, helper->path);
|
||||
if (padding != RSA_PKCS1_PADDING)
|
||||
goto fail;
|
||||
key = sshkey_new(KEY_UNSPEC);
|
||||
@@ -144,10 +274,10 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
(r = sshbuf_put_string(msg, from, flen)) != 0 ||
|
||||
(r = sshbuf_put_u32(msg, 0)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
- send_msg(msg);
|
||||
+ send_msg(helper->fd, msg);
|
||||
sshbuf_reset(msg);
|
||||
|
||||
- if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
|
||||
+ if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) {
|
||||
if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
if (slen <= (size_t)RSA_size(rsa)) {
|
||||
@@ -163,7 +293,26 @@ rsa_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
+static int
|
||||
+rsa_finish(RSA *rsa)
|
||||
+{
|
||||
+ struct helper *helper;
|
||||
+
|
||||
+ if ((helper = helper_by_rsa(rsa)) == NULL)
|
||||
+ fatal("%s: no helper for PKCS11 key", __func__);
|
||||
+ debug3("%s: free PKCS11 RSA key for provider %s", __func__, helper->path);
|
||||
+ if (helper->rsa_finish != NULL)
|
||||
+ helper->rsa_finish(rsa);
|
||||
+ if (helper->nrsa == 0)
|
||||
+ fatal("%s: RSA refcount error", __func__);
|
||||
+ helper->nrsa--;
|
||||
+ debug3("%s: provider %s remaining keys: %zu RSA %zu ECDSA", __func__,
|
||||
+ helper->path, helper->nrsa, helper->nec);
|
||||
+ if (helper->nrsa == 0 && helper->nec == 0)
|
||||
+ helper_terminate(helper);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static ECDSA_SIG *
|
||||
ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
const BIGNUM *rp, EC_KEY *ec)
|
||||
@@ -175,7 +324,11 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
u_char *blob = NULL, *signature = NULL;
|
||||
size_t blen, slen = 0;
|
||||
int r, nid;
|
||||
+ struct helper *helper;
|
||||
|
||||
+ if ((helper = helper_by_ec(ec)) == NULL || helper->fd == -1)
|
||||
+ fatal("%s: no helper for PKCS11 key", __func__);
|
||||
+ debug3("%s: signing with PKCS11 provider %s", __func__, helper->path);
|
||||
nid = sshkey_ecdsa_key_to_nid(ec);
|
||||
if (nid < 0) {
|
||||
error("%s: couldn't get curve nid", __func__);
|
||||
@@ -203,10 +356,10 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
(r = sshbuf_put_string(msg, dgst, dgst_len)) != 0 ||
|
||||
(r = sshbuf_put_u32(msg, 0)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
- send_msg(msg);
|
||||
+ send_msg(helper->fd, msg);
|
||||
sshbuf_reset(msg);
|
||||
|
||||
- if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
|
||||
+ if (recv_msg(helper->fd, msg) == SSH2_AGENT_SIGN_RESPONSE) {
|
||||
if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
cp = signature;
|
||||
@@ -220,75 +373,110 @@ ecdsa_do_sign(const unsigned char *dgst, int dgst_len, const BIGNUM *inv,
|
||||
sshbuf_free(msg);
|
||||
return (ret);
|
||||
}
|
||||
-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
|
||||
-static RSA_METHOD *helper_rsa;
|
||||
-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
-static EC_KEY_METHOD *helper_ecdsa;
|
||||
-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
+static void
|
||||
+ecdsa_do_finish(EC_KEY *ec)
|
||||
+{
|
||||
+ struct helper *helper;
|
||||
+
|
||||
+ if ((helper = helper_by_ec(ec)) == NULL)
|
||||
+ fatal("%s: no helper for PKCS11 key", __func__);
|
||||
+ debug3("%s: free PKCS11 ECDSA key for provider %s", __func__, helper->path);
|
||||
+ if (helper->ec_finish != NULL)
|
||||
+ helper->ec_finish(ec);
|
||||
+ if (helper->nec == 0)
|
||||
+ fatal("%s: ECDSA refcount error", __func__);
|
||||
+ helper->nec--;
|
||||
+ debug3("%s: provider %s remaining keys: %zu RSA %zu ECDSA", __func__,
|
||||
+ helper->path, helper->nrsa, helper->nec);
|
||||
+ if (helper->nrsa == 0 && helper->nec == 0)
|
||||
+ helper_terminate(helper);
|
||||
+}
|
||||
|
||||
/* redirect private key crypto operations to the ssh-pkcs11-helper */
|
||||
static void
|
||||
-wrap_key(struct sshkey *k)
|
||||
+wrap_key(struct helper *helper, struct sshkey *k)
|
||||
{
|
||||
- if (k->type == KEY_RSA)
|
||||
- RSA_set_method(k->rsa, helper_rsa);
|
||||
-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
- else if (k->type == KEY_ECDSA)
|
||||
- EC_KEY_set_method(k->ecdsa, helper_ecdsa);
|
||||
-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
- else
|
||||
+ debug3("%s: wrap %s for provider %s", __func__, sshkey_type(k), helper->path);
|
||||
+ if (k->type == KEY_RSA) {
|
||||
+ RSA_set_method(k->rsa, helper->rsa_meth);
|
||||
+ if (helper->nrsa++ >= INT_MAX)
|
||||
+ fatal("%s: RSA refcount error", __func__);
|
||||
+ } else if (k->type == KEY_ECDSA) {
|
||||
+ EC_KEY_set_method(k->ecdsa, helper->ec_meth);
|
||||
+ if (helper->nec++ >= INT_MAX)
|
||||
+ fatal("%s: EC refcount error", __func__);
|
||||
+ } else
|
||||
fatal("%s: unknown key type", __func__);
|
||||
+ k->flags |= SSHKEY_FLAG_EXT;
|
||||
+ debug3("%s: provider %s remaining keys: %zu RSA %zu ECDSA", __func__,
|
||||
+ helper->path, helper->nrsa, helper->nec);
|
||||
}
|
||||
|
||||
static int
|
||||
-pkcs11_start_helper_methods(void)
|
||||
+pkcs11_start_helper_methods(struct helper *helper)
|
||||
{
|
||||
- if (helper_rsa != NULL)
|
||||
- return (0);
|
||||
-
|
||||
-#if defined(OPENSSL_HAS_ECC) && defined(HAVE_EC_KEY_METHOD_NEW)
|
||||
- int (*orig_sign)(int, const unsigned char *, int, unsigned char *,
|
||||
+ int (*ec_init)(EC_KEY *key);
|
||||
+ int (*ec_copy)(EC_KEY *dest, const EC_KEY *src);
|
||||
+ int (*ec_set_group)(EC_KEY *key, const EC_GROUP *grp);
|
||||
+ int (*ec_set_private)(EC_KEY *key, const BIGNUM *priv_key);
|
||||
+ int (*ec_set_public)(EC_KEY *key, const EC_POINT *pub_key);
|
||||
+ int (*ec_sign)(int, const unsigned char *, int, unsigned char *,
|
||||
unsigned int *, const BIGNUM *, const BIGNUM *, EC_KEY *) = NULL;
|
||||
- if (helper_ecdsa != NULL)
|
||||
- return (0);
|
||||
- helper_ecdsa = EC_KEY_METHOD_new(EC_KEY_OpenSSL());
|
||||
- if (helper_ecdsa == NULL)
|
||||
- return (-1);
|
||||
- EC_KEY_METHOD_get_sign(helper_ecdsa, &orig_sign, NULL, NULL);
|
||||
- EC_KEY_METHOD_set_sign(helper_ecdsa, orig_sign, NULL, ecdsa_do_sign);
|
||||
-#endif /* OPENSSL_HAS_ECC && HAVE_EC_KEY_METHOD_NEW */
|
||||
-
|
||||
- if ((helper_rsa = RSA_meth_dup(RSA_get_default_method())) == NULL)
|
||||
+ RSA_METHOD *rsa_meth;
|
||||
+ EC_KEY_METHOD *ec_meth;
|
||||
+
|
||||
+ if ((ec_meth = EC_KEY_METHOD_new(EC_KEY_OpenSSL())) == NULL)
|
||||
+ return -1;
|
||||
+ EC_KEY_METHOD_get_sign(ec_meth, &ec_sign, NULL, NULL);
|
||||
+ EC_KEY_METHOD_set_sign(ec_meth, ec_sign, NULL, ecdsa_do_sign);
|
||||
+ EC_KEY_METHOD_get_init(ec_meth, &ec_init, &helper->ec_finish,
|
||||
+ &ec_copy, &ec_set_group, &ec_set_private, &ec_set_public);
|
||||
+ EC_KEY_METHOD_set_init(ec_meth, ec_init, ecdsa_do_finish,
|
||||
+ ec_copy, ec_set_group, ec_set_private, ec_set_public);
|
||||
+
|
||||
+ if ((rsa_meth = RSA_meth_dup(RSA_get_default_method())) == NULL)
|
||||
fatal("%s: RSA_meth_dup failed", __func__);
|
||||
- if (!RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper") ||
|
||||
- !RSA_meth_set_priv_enc(helper_rsa, rsa_encrypt))
|
||||
+ helper->rsa_finish = RSA_meth_get_finish(rsa_meth);
|
||||
+ if (!RSA_meth_set1_name(rsa_meth, "ssh-pkcs11-helper") ||
|
||||
+ !RSA_meth_set_priv_enc(rsa_meth, rsa_encrypt) ||
|
||||
+ !RSA_meth_set_finish(rsa_meth, rsa_finish))
|
||||
fatal("%s: failed to prepare method", __func__);
|
||||
|
||||
- return (0);
|
||||
+ helper->ec_meth = ec_meth;
|
||||
+ helper->rsa_meth = rsa_meth;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
-static int
|
||||
-pkcs11_start_helper(void)
|
||||
+static struct helper *
|
||||
+pkcs11_start_helper(const char *path)
|
||||
{
|
||||
int pair[2];
|
||||
- char *helper, *verbosity = NULL;
|
||||
-
|
||||
- if (log_level_get() >= SYSLOG_LEVEL_DEBUG1)
|
||||
- verbosity = "-vvv";
|
||||
-
|
||||
- if (pkcs11_start_helper_methods() == -1) {
|
||||
- error("pkcs11_start_helper_methods failed");
|
||||
- return (-1);
|
||||
- }
|
||||
+ char *prog, *verbosity = NULL;
|
||||
+ struct helper *helper;
|
||||
+ pid_t pid;
|
||||
|
||||
+ if (nhelpers >= INT_MAX)
|
||||
+ fatal("%s: too many helpers", __func__);
|
||||
+ debug3("%s: start helper for %s", __func__, path);
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {
|
||||
error("socketpair: %s", strerror(errno));
|
||||
- return (-1);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ helper = xcalloc(1, sizeof(*helper));
|
||||
+ if (pkcs11_start_helper_methods(helper) == -1) {
|
||||
+ error("pkcs11_start_helper_methods failed");
|
||||
+ goto fail;
|
||||
}
|
||||
if ((pid = fork()) == -1) {
|
||||
error("fork: %s", strerror(errno));
|
||||
- return (-1);
|
||||
+ fail:
|
||||
+ close(pair[0]);
|
||||
+ close(pair[1]);
|
||||
+ RSA_meth_free(helper->rsa_meth);
|
||||
+ EC_KEY_METHOD_free(helper->ec_meth);
|
||||
+ free(helper);
|
||||
+ return NULL;
|
||||
} else if (pid == 0) {
|
||||
if ((dup2(pair[1], STDIN_FILENO) == -1) ||
|
||||
(dup2(pair[1], STDOUT_FILENO) == -1)) {
|
||||
@@ -297,18 +485,27 @@ pkcs11_start_helper(void)
|
||||
}
|
||||
close(pair[0]);
|
||||
close(pair[1]);
|
||||
- helper = getenv("SSH_PKCS11_HELPER");
|
||||
- if (helper == NULL || strlen(helper) == 0)
|
||||
- helper = _PATH_SSH_PKCS11_HELPER;
|
||||
+ prog = getenv("SSH_PKCS11_HELPER");
|
||||
+ if (prog == NULL || strlen(prog) == 0)
|
||||
+ prog = _PATH_SSH_PKCS11_HELPER;
|
||||
+ if (log_level_get() >= SYSLOG_LEVEL_DEBUG1)
|
||||
+ verbosity = "-vvv";
|
||||
debug("%s: starting %s %s", __func__, helper,
|
||||
verbosity == NULL ? "" : verbosity);
|
||||
- execlp(helper, helper, verbosity, (char *)NULL);
|
||||
- fprintf(stderr, "exec: %s: %s\n", helper, strerror(errno));
|
||||
+ execlp(prog, prog, verbosity, (char *)NULL);
|
||||
+ fprintf(stderr, "exec: %s: %s\n", prog, strerror(errno));
|
||||
_exit(1);
|
||||
}
|
||||
close(pair[1]);
|
||||
- fd = pair[0];
|
||||
- return (0);
|
||||
+ helper->fd = pair[0];
|
||||
+ helper->path = xstrdup(path);
|
||||
+ helper->pid = pid;
|
||||
+ debug3("%s: helper %zu for \"%s\" on fd %d pid %ld", __func__, nhelpers,
|
||||
+ helper->path, helper->fd, (long)helper->pid);
|
||||
+ helpers = xrecallocarray(helpers, nhelpers,
|
||||
+ nhelpers + 1, sizeof(*helpers));
|
||||
+ helpers[nhelpers++] = helper;
|
||||
+ return helper;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -322,9 +519,11 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
|
||||
size_t blen;
|
||||
u_int nkeys, i;
|
||||
struct sshbuf *msg;
|
||||
+ struct helper *helper;
|
||||
|
||||
- if (fd < 0 && pkcs11_start_helper() < 0)
|
||||
- return (-1);
|
||||
+ if ((helper = helper_by_provider(name)) == NULL &&
|
||||
+ (helper = pkcs11_start_helper(name)) == NULL)
|
||||
+ return -1;
|
||||
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
@@ -332,10 +531,10 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
|
||||
(r = sshbuf_put_cstring(msg, name)) != 0 ||
|
||||
(r = sshbuf_put_cstring(msg, pin)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
- send_msg(msg);
|
||||
+ send_msg(helper->fd, msg);
|
||||
sshbuf_reset(msg);
|
||||
|
||||
- type = recv_msg(msg);
|
||||
+ type = recv_msg(helper->fd, msg);
|
||||
if (type == SSH2_AGENT_IDENTITIES_ANSWER) {
|
||||
if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
@@ -350,7 +549,7 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
|
||||
__func__, ssh_err(r));
|
||||
if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
|
||||
fatal("%s: bad key: %s", __func__, ssh_err(r));
|
||||
- wrap_key(k);
|
||||
+ wrap_key(helper, k);
|
||||
(*keysp)[i] = k;
|
||||
if (labelsp)
|
||||
(*labelsp)[i] = label;
|
||||
@@ -371,22 +570,15 @@ pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp,
|
||||
int
|
||||
pkcs11_del_provider(char *name)
|
||||
{
|
||||
- int r, ret = -1;
|
||||
- struct sshbuf *msg;
|
||||
-
|
||||
- if ((msg = sshbuf_new()) == NULL)
|
||||
- fatal("%s: sshbuf_new failed", __func__);
|
||||
- if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY)) != 0 ||
|
||||
- (r = sshbuf_put_cstring(msg, name)) != 0 ||
|
||||
- (r = sshbuf_put_cstring(msg, "")) != 0)
|
||||
- fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
- send_msg(msg);
|
||||
- sshbuf_reset(msg);
|
||||
-
|
||||
- if (recv_msg(msg) == SSH_AGENT_SUCCESS)
|
||||
- ret = 0;
|
||||
- sshbuf_free(msg);
|
||||
- return (ret);
|
||||
+ struct helper *helper;
|
||||
+
|
||||
+ /*
|
||||
+ * ssh-agent deletes keys before calling this, so the helper entry
|
||||
+ * should be gone before we get here.
|
||||
+ */
|
||||
+ debug3("%s: delete %s", __func__, name);
|
||||
+ if ((helper = helper_by_provider(name)) != NULL)
|
||||
+ helper_terminate(helper);
|
||||
+ return 0;
|
||||
}
|
||||
-
|
||||
#endif /* ENABLE_PKCS11 */
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,171 @@
|
||||
From 2f1be98e83feb90665b9292eff8bb734537fd491 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Wed, 19 Jul 2023 14:02:27 +0000
|
||||
Subject: [PATCH 03/12] upstream: Ensure FIDO/PKCS11 libraries contain expected
|
||||
symbols
|
||||
|
||||
This checks via nlist(3) that candidate provider libraries contain one
|
||||
of the symbols that we will require prior to dlopen(), which can cause
|
||||
a number of side effects, including execution of constructors.
|
||||
|
||||
Feedback deraadt; ok markus
|
||||
|
||||
OpenBSD-Commit-ID: 1508a5fbd74e329e69a55b56c453c292029aefbe
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/29ef8a04866ca14688d5b7fed7b8b9deab851f77]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
misc.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
misc.h | 1 +
|
||||
ssh-pkcs11.c | 4 +++
|
||||
ssh-sk.c | 6 ++--
|
||||
4 files changed, 86 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/misc.c b/misc.c
|
||||
index 3a31d5c..8a107e4 100644
|
||||
--- a/misc.c
|
||||
+++ b/misc.c
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
+#include <sys/mman.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
@@ -41,6 +42,9 @@
|
||||
#ifdef HAVE_POLL_H
|
||||
#include <poll.h>
|
||||
#endif
|
||||
+#ifdef HAVE_NLIST_H
|
||||
+#include <nlist.h>
|
||||
+#endif
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@@ -2266,3 +2270,76 @@ ssh_signal(int signum, sshsig_t handler)
|
||||
}
|
||||
return osa.sa_handler;
|
||||
}
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * Returns zero if the library at 'path' contains symbol 's', nonzero
|
||||
+ * otherwise.
|
||||
+ */
|
||||
+int
|
||||
+lib_contains_symbol(const char *path, const char *s)
|
||||
+{
|
||||
+#ifdef HAVE_NLIST_H
|
||||
+ struct nlist nl[2];
|
||||
+ int ret = -1, r;
|
||||
+
|
||||
+ memset(nl, 0, sizeof(nl));
|
||||
+ nl[0].n_name = xstrdup(s);
|
||||
+ nl[1].n_name = NULL;
|
||||
+ if ((r = nlist(path, nl)) == -1) {
|
||||
+ error("%s: nlist failed for %s", __func__, path);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (r != 0 || nl[0].n_value == 0 || nl[0].n_type == 0) {
|
||||
+ error("%s: library %s does not contain symbol %s", __func__, path, s);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* success */
|
||||
+ ret = 0;
|
||||
+ out:
|
||||
+ free(nl[0].n_name);
|
||||
+ return ret;
|
||||
+#else /* HAVE_NLIST_H */
|
||||
+ int fd, ret = -1;
|
||||
+ struct stat st;
|
||||
+ void *m = NULL;
|
||||
+ size_t sz = 0;
|
||||
+
|
||||
+ memset(&st, 0, sizeof(st));
|
||||
+ if ((fd = open(path, O_RDONLY)) < 0) {
|
||||
+ error("%s: open %s: %s", __func__, path, strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (fstat(fd, &st) != 0) {
|
||||
+ error("%s: fstat %s: %s", __func__, path, strerror(errno));
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (!S_ISREG(st.st_mode)) {
|
||||
+ error("%s: %s is not a regular file", __func__, path);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (st.st_size < 0 ||
|
||||
+ (size_t)st.st_size < strlen(s) ||
|
||||
+ st.st_size >= INT_MAX/2) {
|
||||
+ error("%s: %s bad size %lld", __func__, path, (long long)st.st_size);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ sz = (size_t)st.st_size;
|
||||
+ if ((m = mmap(NULL, sz, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED ||
|
||||
+ m == NULL) {
|
||||
+ error("%s: mmap %s: %s", __func__, path, strerror(errno));
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (memmem(m, sz, s, strlen(s)) == NULL) {
|
||||
+ error("%s: %s does not contain expected string %s", __func__, path, s);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* success */
|
||||
+ ret = 0;
|
||||
+ out:
|
||||
+ if (m != NULL && m != MAP_FAILED)
|
||||
+ munmap(m, sz);
|
||||
+ close(fd);
|
||||
+ return ret;
|
||||
+#endif /* HAVE_NLIST_H */
|
||||
+}
|
||||
diff --git a/misc.h b/misc.h
|
||||
index 4a05db2..3f9f4db 100644
|
||||
--- a/misc.h
|
||||
+++ b/misc.h
|
||||
@@ -86,6 +86,7 @@ const char *atoi_err(const char *, int *);
|
||||
int parse_absolute_time(const char *, uint64_t *);
|
||||
void format_absolute_time(uint64_t, char *, size_t);
|
||||
int path_absolute(const char *);
|
||||
+int lib_contains_symbol(const char *, const char *);
|
||||
|
||||
void sock_set_v6only(int);
|
||||
|
||||
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
|
||||
index b56a41b..639a6f7 100644
|
||||
--- a/ssh-pkcs11.c
|
||||
+++ b/ssh-pkcs11.c
|
||||
@@ -1499,6 +1499,10 @@ pkcs11_register_provider(char *provider_id, char *pin,
|
||||
__func__, provider_id);
|
||||
goto fail;
|
||||
}
|
||||
+ if (lib_contains_symbol(provider_id, "C_GetFunctionList") != 0) {
|
||||
+ error("provider %s is not a PKCS11 library", provider_id);
|
||||
+ goto fail;
|
||||
+ }
|
||||
/* open shared pkcs11-library */
|
||||
if ((handle = dlopen(provider_id, RTLD_NOW)) == NULL) {
|
||||
error("dlopen %s failed: %s", provider_id, dlerror());
|
||||
diff --git a/ssh-sk.c b/ssh-sk.c
|
||||
index 5ff9381..9df12cc 100644
|
||||
--- a/ssh-sk.c
|
||||
+++ b/ssh-sk.c
|
||||
@@ -119,10 +119,12 @@ sshsk_open(const char *path)
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
- if ((ret->dlhandle = dlopen(path, RTLD_NOW)) == NULL) {
|
||||
- error("Provider \"%s\" dlopen failed: %s", path, dlerror());
|
||||
+ if (lib_contains_symbol(path, "sk_api_version") != 0) {
|
||||
+ error("provider %s is not an OpenSSH FIDO library", path);
|
||||
goto fail;
|
||||
}
|
||||
+ if ((ret->dlhandle = dlopen(path, RTLD_NOW)) == NULL)
|
||||
+ fatal("Provider \"%s\" dlopen failed: %s", path, dlerror());
|
||||
if ((ret->sk_api_version = dlsym(ret->dlhandle,
|
||||
"sk_api_version")) == NULL) {
|
||||
error("Provider \"%s\" dlsym(sk_api_version) failed: %s",
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,34 @@
|
||||
From 0862f338941bfdfb2cadee87de6d5fdca1b8f457 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Wed, 19 Jul 2023 13:55:53 +0000
|
||||
Subject: [PATCH 04/12] upstream: terminate process if requested to load a
|
||||
PKCS#11 provider that isn't a PKCS#11 provider; from / ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: 39532cf18b115881bb4cfaee32084497aadfa05c
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/892506b13654301f69f9545f48213fc210e5c5cc]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-pkcs11.c | 6 ++----
|
||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ssh-pkcs11.c b/ssh-pkcs11.c
|
||||
index 639a6f7..7530acc 100644
|
||||
--- a/ssh-pkcs11.c
|
||||
+++ b/ssh-pkcs11.c
|
||||
@@ -1508,10 +1508,8 @@ pkcs11_register_provider(char *provider_id, char *pin,
|
||||
error("dlopen %s failed: %s", provider_id, dlerror());
|
||||
goto fail;
|
||||
}
|
||||
- if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL) {
|
||||
- error("dlsym(C_GetFunctionList) failed: %s", dlerror());
|
||||
- goto fail;
|
||||
- }
|
||||
+ if ((getfunctionlist = dlsym(handle, "C_GetFunctionList")) == NULL)
|
||||
+ fatal("dlsym(C_GetFunctionList) failed: %s", dlerror());
|
||||
p = xcalloc(1, sizeof(*p));
|
||||
p->name = xstrdup(provider_id);
|
||||
p->handle = handle;
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,194 @@
|
||||
From a6cee3905edf070c0de135d3f2ee5b74da1dbd28 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Tue, 26 May 2020 01:26:58 +0000
|
||||
Subject: [PATCH 05/12] upstream: Restrict ssh-agent from signing web
|
||||
challenges for FIDO
|
||||
|
||||
keys.
|
||||
|
||||
When signing messages in ssh-agent using a FIDO key that has an
|
||||
application string that does not start with "ssh:", ensure that the
|
||||
message being signed is one of the forms expected for the SSH protocol
|
||||
(currently pubkey authentication and sshsig signatures).
|
||||
|
||||
This prevents ssh-agent forwarding on a host that has FIDO keys
|
||||
attached granting the ability for the remote side to sign challenges
|
||||
for web authentication using those keys too.
|
||||
|
||||
Note that the converse case of web browsers signing SSH challenges is
|
||||
already precluded because no web RP can have the "ssh:" prefix in the
|
||||
application string that we require.
|
||||
|
||||
ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: 9ab6012574ed0352d2f097d307f4a988222d1b19
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/0c111eb84efba7c2a38b2cc3278901a0123161b9]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-agent.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 100 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index ceb348c..1794f35 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.255 2020/02/06 22:30:54 naddy Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.258 2020/05/26 01:26:58 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -77,6 +77,7 @@
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "ssh.h"
|
||||
+#include "ssh2.h"
|
||||
#include "sshbuf.h"
|
||||
#include "sshkey.h"
|
||||
#include "authfd.h"
|
||||
@@ -167,6 +168,9 @@ static long lifetime = 0;
|
||||
|
||||
static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
|
||||
|
||||
+/* Refuse signing of non-SSH messages for web-origin FIDO keys */
|
||||
+static int restrict_websafe = 1;
|
||||
+
|
||||
static void
|
||||
close_socket(SocketEntry *e)
|
||||
{
|
||||
@@ -282,6 +286,80 @@ agent_decode_alg(struct sshkey *key, u_int flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * This function inspects a message to be signed by a FIDO key that has a
|
||||
+ * web-like application string (i.e. one that does not begin with "ssh:".
|
||||
+ * It checks that the message is one of those expected for SSH operations
|
||||
+ * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
|
||||
+ * for the web.
|
||||
+ */
|
||||
+static int
|
||||
+check_websafe_message_contents(struct sshkey *key,
|
||||
+ const u_char *msg, size_t len)
|
||||
+{
|
||||
+ int matched = 0;
|
||||
+ struct sshbuf *b;
|
||||
+ u_char m, n;
|
||||
+ char *cp1 = NULL, *cp2 = NULL;
|
||||
+ int r;
|
||||
+ struct sshkey *mkey = NULL;
|
||||
+
|
||||
+ if ((b = sshbuf_from(msg, len)) == NULL)
|
||||
+ fatal("%s: sshbuf_new", __func__);
|
||||
+
|
||||
+ /* SSH userauth request */
|
||||
+ if ((r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* sess_id */
|
||||
+ (r = sshbuf_get_u8(b, &m)) == 0 && /* SSH2_MSG_USERAUTH_REQUEST */
|
||||
+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* server user */
|
||||
+ (r = sshbuf_get_cstring(b, &cp1, NULL)) == 0 && /* service */
|
||||
+ (r = sshbuf_get_cstring(b, &cp2, NULL)) == 0 && /* method */
|
||||
+ (r = sshbuf_get_u8(b, &n)) == 0 && /* sig-follows */
|
||||
+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* alg */
|
||||
+ (r = sshkey_froms(b, &mkey)) == 0 && /* key */
|
||||
+ sshbuf_len(b) == 0) {
|
||||
+ debug("%s: parsed userauth", __func__);
|
||||
+ if (m == SSH2_MSG_USERAUTH_REQUEST && n == 1 &&
|
||||
+ strcmp(cp1, "ssh-connection") == 0 &&
|
||||
+ strcmp(cp2, "publickey") == 0 &&
|
||||
+ sshkey_equal(key, mkey)) {
|
||||
+ debug("%s: well formed userauth", __func__);
|
||||
+ matched = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ free(cp1);
|
||||
+ free(cp2);
|
||||
+ sshkey_free(mkey);
|
||||
+ sshbuf_free(b);
|
||||
+ if (matched)
|
||||
+ return 1;
|
||||
+
|
||||
+ if ((b = sshbuf_from(msg, len)) == NULL)
|
||||
+ fatal("%s: sshbuf_new", __func__);
|
||||
+ cp1 = cp2 = NULL;
|
||||
+ mkey = NULL;
|
||||
+
|
||||
+ /* SSHSIG */
|
||||
+ if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) == 0 &&
|
||||
+ (r = sshbuf_consume(b, 6)) == 0 &&
|
||||
+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* namespace */
|
||||
+ (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* reserved */
|
||||
+ (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* hashalg */
|
||||
+ (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* H(msg) */
|
||||
+ sshbuf_len(b) == 0) {
|
||||
+ debug("%s: parsed sshsig", __func__);
|
||||
+ matched = 1;
|
||||
+ }
|
||||
+
|
||||
+ sshbuf_free(b);
|
||||
+ if (matched)
|
||||
+ return 1;
|
||||
+
|
||||
+ /* XXX CA signature operation */
|
||||
+
|
||||
+ error("web-origin key attempting to sign non-SSH message");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* ssh2 only */
|
||||
static void
|
||||
process_sign_request2(SocketEntry *e)
|
||||
@@ -314,14 +392,20 @@ process_sign_request2(SocketEntry *e)
|
||||
verbose("%s: user refused key", __func__);
|
||||
goto send;
|
||||
}
|
||||
- if (sshkey_is_sk(id->key) &&
|
||||
- (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
|
||||
- if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
|
||||
- SSH_FP_DEFAULT)) == NULL)
|
||||
- fatal("%s: fingerprint failed", __func__);
|
||||
- notifier = notify_start(0,
|
||||
- "Confirm user presence for key %s %s",
|
||||
- sshkey_type(id->key), fp);
|
||||
+ if (sshkey_is_sk(id->key)) {
|
||||
+ if (strncmp(id->key->sk_application, "ssh:", 4) != 0 &&
|
||||
+ !check_websafe_message_contents(key, data, dlen)) {
|
||||
+ /* error already logged */
|
||||
+ goto send;
|
||||
+ }
|
||||
+ if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
|
||||
+ if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
|
||||
+ SSH_FP_DEFAULT)) == NULL)
|
||||
+ fatal("%s: fingerprint failed", __func__);
|
||||
+ notifier = notify_start(0,
|
||||
+ "Confirm user presence for key %s %s",
|
||||
+ sshkey_type(id->key), fp);
|
||||
+ }
|
||||
}
|
||||
if ((r = sshkey_sign(id->key, &signature, &slen,
|
||||
data, dlen, agent_decode_alg(key, flags),
|
||||
@@ -1214,7 +1298,7 @@ main(int ac, char **av)
|
||||
__progname = ssh_get_progname(av[0]);
|
||||
seed_rng();
|
||||
|
||||
- while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {
|
||||
+ while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) {
|
||||
switch (ch) {
|
||||
case 'E':
|
||||
fingerprint_hash = ssh_digest_alg_by_name(optarg);
|
||||
@@ -1229,6 +1313,12 @@ main(int ac, char **av)
|
||||
case 'k':
|
||||
k_flag++;
|
||||
break;
|
||||
+ case 'O':
|
||||
+ if (strcmp(optarg, "no-restrict-websafe") == 0)
|
||||
+ restrict_websafe = 0;
|
||||
+ else
|
||||
+ fatal("Unknown -O option");
|
||||
+ break;
|
||||
case 'P':
|
||||
if (provider_whitelist != NULL)
|
||||
fatal("-P option already specified");
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,73 @@
|
||||
From a5d845b7b42861d18f43e83de9f24c7374d1b458 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Fri, 18 Sep 2020 08:16:38 +0000
|
||||
Subject: [PATCH 06/12] upstream: handle multiple messages in a single read()
|
||||
|
||||
PR#183 by Dennis Kaarsemaker; feedback and ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: 8570bb4d02d00cf70b98590716ea6a7d1cce68d1
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/52a03e9fca2d74eef953ddd4709250f365ca3975]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-agent.c | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 1794f35..78f7268 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.258 2020/05/26 01:26:58 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.264 2020/09/18 08:16:38 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -853,8 +853,10 @@ send:
|
||||
}
|
||||
#endif /* ENABLE_PKCS11 */
|
||||
|
||||
-/* dispatch incoming messages */
|
||||
-
|
||||
+/*
|
||||
+ * dispatch incoming message.
|
||||
+ * returns 1 on success, 0 for incomplete messages or -1 on error.
|
||||
+ */
|
||||
static int
|
||||
process_message(u_int socknum)
|
||||
{
|
||||
@@ -908,7 +910,7 @@ process_message(u_int socknum)
|
||||
/* send a fail message for all other request types */
|
||||
send_status(e, 0);
|
||||
}
|
||||
- return 0;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
@@ -952,7 +954,7 @@ process_message(u_int socknum)
|
||||
send_status(e, 0);
|
||||
break;
|
||||
}
|
||||
- return 0;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1043,7 +1045,12 @@ handle_conn_read(u_int socknum)
|
||||
if ((r = sshbuf_put(sockets[socknum].input, buf, len)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
explicit_bzero(buf, sizeof(buf));
|
||||
- process_message(socknum);
|
||||
+ for (;;) {
|
||||
+ if ((r = process_message(socknum)) == -1)
|
||||
+ return -1;
|
||||
+ else if (r == 0)
|
||||
+ break;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,125 @@
|
||||
From 653cc18c922fc387b3d3aa1b081c5e5283cce28a Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Tue, 26 Jan 2021 00:47:47 +0000
|
||||
Subject: [PATCH 07/12] upstream: use recallocarray to allocate the agent
|
||||
sockets table;
|
||||
|
||||
also clear socket entries that are being marked as unused.
|
||||
|
||||
spinkle in some debug2() spam to make it easier to watch an agent
|
||||
do its thing.
|
||||
|
||||
ok markus
|
||||
|
||||
OpenBSD-Commit-ID: 74582c8e82e96afea46f6c7b6813a429cbc75922
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/1fe16fd61bb53944ec510882acc0491abd66ff76]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-agent.c | 20 ++++++++++++++++----
|
||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 78f7268..2635bc5 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.264 2020/09/18 08:16:38 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.269 2021/01/26 00:47:47 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -175,11 +175,12 @@ static void
|
||||
close_socket(SocketEntry *e)
|
||||
{
|
||||
close(e->fd);
|
||||
- e->fd = -1;
|
||||
- e->type = AUTH_UNUSED;
|
||||
sshbuf_free(e->input);
|
||||
sshbuf_free(e->output);
|
||||
sshbuf_free(e->request);
|
||||
+ memset(e, '\0', sizeof(*e));
|
||||
+ e->fd = -1;
|
||||
+ e->type = AUTH_UNUSED;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -249,6 +250,8 @@ process_request_identities(SocketEntry *e)
|
||||
struct sshbuf *msg;
|
||||
int r;
|
||||
|
||||
+ debug2("%s: entering", __func__);
|
||||
+
|
||||
if ((msg = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
|
||||
@@ -441,6 +444,7 @@ process_remove_identity(SocketEntry *e)
|
||||
struct sshkey *key = NULL;
|
||||
Identity *id;
|
||||
|
||||
+ debug2("%s: entering", __func__);
|
||||
if ((r = sshkey_froms(e->request, &key)) != 0) {
|
||||
error("%s: get key: %s", __func__, ssh_err(r));
|
||||
goto done;
|
||||
@@ -467,6 +471,7 @@ process_remove_all_identities(SocketEntry *e)
|
||||
{
|
||||
Identity *id;
|
||||
|
||||
+ debug2("%s: entering", __func__);
|
||||
/* Loop over all identities and clear the keys. */
|
||||
for (id = TAILQ_FIRST(&idtab->idlist); id;
|
||||
id = TAILQ_FIRST(&idtab->idlist)) {
|
||||
@@ -520,6 +525,7 @@ process_add_identity(SocketEntry *e)
|
||||
u_char ctype;
|
||||
int r = SSH_ERR_INTERNAL_ERROR;
|
||||
|
||||
+ debug2("%s: entering", __func__);
|
||||
if ((r = sshkey_private_deserialize(e->request, &k)) != 0 ||
|
||||
k == NULL ||
|
||||
(r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
|
||||
@@ -667,6 +673,7 @@ process_lock_agent(SocketEntry *e, int lock)
|
||||
static u_int fail_count = 0;
|
||||
size_t pwlen;
|
||||
|
||||
+ debug2("%s: entering", __func__);
|
||||
/*
|
||||
* This is deliberately fatal: the user has requested that we lock,
|
||||
* but we can't parse their request properly. The only safe thing to
|
||||
@@ -738,6 +745,7 @@ process_add_smartcard_key(SocketEntry *e)
|
||||
struct sshkey **keys = NULL, *k;
|
||||
Identity *id;
|
||||
|
||||
+ debug2("%s: entering", __func__);
|
||||
if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
|
||||
error("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
@@ -818,6 +826,7 @@ process_remove_smartcard_key(SocketEntry *e)
|
||||
int r, success = 0;
|
||||
Identity *id, *nxt;
|
||||
|
||||
+ debug2("%s: entering", __func__);
|
||||
if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
|
||||
(r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) {
|
||||
error("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
@@ -962,6 +971,8 @@ new_socket(sock_type type, int fd)
|
||||
{
|
||||
u_int i, old_alloc, new_alloc;
|
||||
|
||||
+ debug("%s: type = %s", __func__, type == AUTH_CONNECTION ? "CONNECTION" :
|
||||
+ (type == AUTH_SOCKET ? "SOCKET" : "UNKNOWN"));
|
||||
set_nonblock(fd);
|
||||
|
||||
if (fd > max_fd)
|
||||
@@ -981,7 +992,8 @@ new_socket(sock_type type, int fd)
|
||||
}
|
||||
old_alloc = sockets_alloc;
|
||||
new_alloc = sockets_alloc + 10;
|
||||
- sockets = xreallocarray(sockets, new_alloc, sizeof(sockets[0]));
|
||||
+ sockets = xrecallocarray(sockets, old_alloc, new_alloc,
|
||||
+ sizeof(sockets[0]));
|
||||
for (i = old_alloc; i < new_alloc; i++)
|
||||
sockets[i].type = AUTH_UNUSED;
|
||||
sockets_alloc = new_alloc;
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,315 @@
|
||||
From c30158ea225cf8ad67c3dcc88fa9e4afbf8959a7 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Tue, 26 Jan 2021 00:53:31 +0000
|
||||
Subject: [PATCH 08/12] upstream: more ssh-agent refactoring
|
||||
|
||||
Allow confirm_key() to accept an additional reason suffix
|
||||
|
||||
Factor publickey userauth parsing out into its own function and allow
|
||||
it to optionally return things it parsed out of the message to its
|
||||
caller.
|
||||
|
||||
feedback/ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: 29006515617d1aa2d8b85cd2bf667e849146477e
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/e0e8bee8024fa9e31974244d14f03d799e5c0775]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-agent.c | 197 ++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 130 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 2635bc5..7ad323c 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.269 2021/01/26 00:47:47 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.270 2021/01/26 00:53:31 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -216,15 +216,16 @@ lookup_identity(struct sshkey *key)
|
||||
|
||||
/* Check confirmation of keysign request */
|
||||
static int
|
||||
-confirm_key(Identity *id)
|
||||
+confirm_key(Identity *id, const char *extra)
|
||||
{
|
||||
char *p;
|
||||
int ret = -1;
|
||||
|
||||
p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
|
||||
if (p != NULL &&
|
||||
- ask_permission("Allow use of key %s?\nKey fingerprint %s.",
|
||||
- id->comment, p))
|
||||
+ ask_permission("Allow use of key %s?\nKey fingerprint %s.%s%s",
|
||||
+ id->comment, p,
|
||||
+ extra == NULL ? "" : "\n", extra == NULL ? "" : extra))
|
||||
ret = 0;
|
||||
free(p);
|
||||
|
||||
@@ -290,74 +291,133 @@ agent_decode_alg(struct sshkey *key, u_int flags)
|
||||
}
|
||||
|
||||
/*
|
||||
- * This function inspects a message to be signed by a FIDO key that has a
|
||||
- * web-like application string (i.e. one that does not begin with "ssh:".
|
||||
- * It checks that the message is one of those expected for SSH operations
|
||||
- * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
|
||||
- * for the web.
|
||||
+ * Attempt to parse the contents of a buffer as a SSH publickey userauth
|
||||
+ * request, checking its contents for consistency and matching the embedded
|
||||
+ * key against the one that is being used for signing.
|
||||
+ * Note: does not modify msg buffer.
|
||||
+ * Optionally extract the username and session ID from the request.
|
||||
*/
|
||||
static int
|
||||
-check_websafe_message_contents(struct sshkey *key,
|
||||
- const u_char *msg, size_t len)
|
||||
+parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key,
|
||||
+ char **userp, struct sshbuf **sess_idp)
|
||||
{
|
||||
- int matched = 0;
|
||||
- struct sshbuf *b;
|
||||
- u_char m, n;
|
||||
- char *cp1 = NULL, *cp2 = NULL;
|
||||
+ struct sshbuf *b = NULL, *sess_id = NULL;
|
||||
+ char *user = NULL, *service = NULL, *method = NULL, *pkalg = NULL;
|
||||
int r;
|
||||
+ u_char t, sig_follows;
|
||||
struct sshkey *mkey = NULL;
|
||||
|
||||
- if ((b = sshbuf_from(msg, len)) == NULL)
|
||||
- fatal("%s: sshbuf_new", __func__);
|
||||
+ if (userp != NULL)
|
||||
+ *userp = NULL;
|
||||
+ if (sess_idp != NULL)
|
||||
+ *sess_idp = NULL;
|
||||
+ if ((b = sshbuf_fromb(msg)) == NULL)
|
||||
+ fatal("%s: sshbuf_fromb", __func__);
|
||||
|
||||
/* SSH userauth request */
|
||||
- if ((r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* sess_id */
|
||||
- (r = sshbuf_get_u8(b, &m)) == 0 && /* SSH2_MSG_USERAUTH_REQUEST */
|
||||
- (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* server user */
|
||||
- (r = sshbuf_get_cstring(b, &cp1, NULL)) == 0 && /* service */
|
||||
- (r = sshbuf_get_cstring(b, &cp2, NULL)) == 0 && /* method */
|
||||
- (r = sshbuf_get_u8(b, &n)) == 0 && /* sig-follows */
|
||||
- (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* alg */
|
||||
- (r = sshkey_froms(b, &mkey)) == 0 && /* key */
|
||||
- sshbuf_len(b) == 0) {
|
||||
- debug("%s: parsed userauth", __func__);
|
||||
- if (m == SSH2_MSG_USERAUTH_REQUEST && n == 1 &&
|
||||
- strcmp(cp1, "ssh-connection") == 0 &&
|
||||
- strcmp(cp2, "publickey") == 0 &&
|
||||
- sshkey_equal(key, mkey)) {
|
||||
- debug("%s: well formed userauth", __func__);
|
||||
- matched = 1;
|
||||
- }
|
||||
+ if ((r = sshbuf_froms(b, &sess_id)) != 0)
|
||||
+ goto out;
|
||||
+ if (sshbuf_len(sess_id) == 0) {
|
||||
+ r = SSH_ERR_INVALID_FORMAT;
|
||||
+ goto out;
|
||||
}
|
||||
- free(cp1);
|
||||
- free(cp2);
|
||||
- sshkey_free(mkey);
|
||||
+ if ((r = sshbuf_get_u8(b, &t)) != 0 || /* SSH2_MSG_USERAUTH_REQUEST */
|
||||
+ (r = sshbuf_get_cstring(b, &user, NULL)) != 0 || /* server user */
|
||||
+ (r = sshbuf_get_cstring(b, &service, NULL)) != 0 || /* service */
|
||||
+ (r = sshbuf_get_cstring(b, &method, NULL)) != 0 || /* method */
|
||||
+ (r = sshbuf_get_u8(b, &sig_follows)) != 0 || /* sig-follows */
|
||||
+ (r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || /* alg */
|
||||
+ (r = sshkey_froms(b, &mkey)) != 0) /* key */
|
||||
+ goto out;
|
||||
+ if (t != SSH2_MSG_USERAUTH_REQUEST ||
|
||||
+ sig_follows != 1 ||
|
||||
+ strcmp(service, "ssh-connection") != 0 ||
|
||||
+ !sshkey_equal(expected_key, mkey) ||
|
||||
+ sshkey_type_from_name(pkalg) != expected_key->type) {
|
||||
+ r = SSH_ERR_INVALID_FORMAT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (strcmp(method, "publickey") != 0) {
|
||||
+ r = SSH_ERR_INVALID_FORMAT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (sshbuf_len(b) != 0) {
|
||||
+ r = SSH_ERR_INVALID_FORMAT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* success */
|
||||
+ r = 0;
|
||||
+ debug("%s: well formed userauth", __func__);
|
||||
+ if (userp != NULL) {
|
||||
+ *userp = user;
|
||||
+ user = NULL;
|
||||
+ }
|
||||
+ if (sess_idp != NULL) {
|
||||
+ *sess_idp = sess_id;
|
||||
+ sess_id = NULL;
|
||||
+ }
|
||||
+ out:
|
||||
sshbuf_free(b);
|
||||
- if (matched)
|
||||
- return 1;
|
||||
+ sshbuf_free(sess_id);
|
||||
+ free(user);
|
||||
+ free(service);
|
||||
+ free(method);
|
||||
+ free(pkalg);
|
||||
+ sshkey_free(mkey);
|
||||
+ return r;
|
||||
+}
|
||||
|
||||
- if ((b = sshbuf_from(msg, len)) == NULL)
|
||||
- fatal("%s: sshbuf_new", __func__);
|
||||
- cp1 = cp2 = NULL;
|
||||
- mkey = NULL;
|
||||
-
|
||||
- /* SSHSIG */
|
||||
- if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) == 0 &&
|
||||
- (r = sshbuf_consume(b, 6)) == 0 &&
|
||||
- (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* namespace */
|
||||
- (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* reserved */
|
||||
- (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* hashalg */
|
||||
- (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* H(msg) */
|
||||
- sshbuf_len(b) == 0) {
|
||||
- debug("%s: parsed sshsig", __func__);
|
||||
- matched = 1;
|
||||
- }
|
||||
+/*
|
||||
+ * Attempt to parse the contents of a buffer as a SSHSIG signature request.
|
||||
+ * Note: does not modify buffer.
|
||||
+ */
|
||||
+static int
|
||||
+parse_sshsig_request(struct sshbuf *msg)
|
||||
+{
|
||||
+ int r;
|
||||
+ struct sshbuf *b;
|
||||
|
||||
+ if ((b = sshbuf_fromb(msg)) == NULL)
|
||||
+ fatal("%s: sshbuf_fromb", __func__);
|
||||
+
|
||||
+ if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) != 0 ||
|
||||
+ (r = sshbuf_consume(b, 6)) != 0 ||
|
||||
+ (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* namespace */
|
||||
+ (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || /* reserved */
|
||||
+ (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* hashalg */
|
||||
+ (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) /* H(msg) */
|
||||
+ goto out;
|
||||
+ if (sshbuf_len(b) != 0) {
|
||||
+ r = SSH_ERR_INVALID_FORMAT;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* success */
|
||||
+ r = 0;
|
||||
+ out:
|
||||
sshbuf_free(b);
|
||||
- if (matched)
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * This function inspects a message to be signed by a FIDO key that has a
|
||||
+ * web-like application string (i.e. one that does not begin with "ssh:".
|
||||
+ * It checks that the message is one of those expected for SSH operations
|
||||
+ * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
|
||||
+ * for the web.
|
||||
+ */
|
||||
+static int
|
||||
+check_websafe_message_contents(struct sshkey *key, struct sshbuf *data)
|
||||
+{
|
||||
+ if (parse_userauth_request(data, key, NULL, NULL) == 0) {
|
||||
+ debug("%s: signed data matches public key userauth request", __func__);
|
||||
return 1;
|
||||
+ }
|
||||
+ if (parse_sshsig_request(data) == 0) {
|
||||
+ debug("%s: signed data matches SSHSIG signature request", __func__);
|
||||
+ return 1;
|
||||
+ }
|
||||
|
||||
- /* XXX CA signature operation */
|
||||
+ /* XXX check CA signature operation */
|
||||
|
||||
error("web-origin key attempting to sign non-SSH message");
|
||||
return 0;
|
||||
@@ -367,21 +427,22 @@ check_websafe_message_contents(struct sshkey *key,
|
||||
static void
|
||||
process_sign_request2(SocketEntry *e)
|
||||
{
|
||||
- const u_char *data;
|
||||
u_char *signature = NULL;
|
||||
- size_t dlen, slen = 0;
|
||||
+ size_t i, slen = 0;
|
||||
u_int compat = 0, flags;
|
||||
int r, ok = -1;
|
||||
char *fp = NULL;
|
||||
- struct sshbuf *msg;
|
||||
+ struct sshbuf *msg = NULL, *data = NULL;
|
||||
struct sshkey *key = NULL;
|
||||
struct identity *id;
|
||||
struct notifier_ctx *notifier = NULL;
|
||||
|
||||
- if ((msg = sshbuf_new()) == NULL)
|
||||
+ debug("%s: entering", __func__);
|
||||
+
|
||||
+ if ((msg = sshbuf_new()) == NULL | (data = sshbuf_new()) == NULL)
|
||||
fatal("%s: sshbuf_new failed", __func__);
|
||||
if ((r = sshkey_froms(e->request, &key)) != 0 ||
|
||||
- (r = sshbuf_get_string_direct(e->request, &data, &dlen)) != 0 ||
|
||||
+ (r = sshbuf_get_stringb(e->request, data)) != 0 ||
|
||||
(r = sshbuf_get_u32(e->request, &flags)) != 0) {
|
||||
error("%s: couldn't parse request: %s", __func__, ssh_err(r));
|
||||
goto send;
|
||||
@@ -391,13 +452,13 @@ process_sign_request2(SocketEntry *e)
|
||||
verbose("%s: %s key not found", __func__, sshkey_type(key));
|
||||
goto send;
|
||||
}
|
||||
- if (id->confirm && confirm_key(id) != 0) {
|
||||
+ if (id->confirm && confirm_key(id, NULL) != 0) {
|
||||
verbose("%s: user refused key", __func__);
|
||||
goto send;
|
||||
}
|
||||
if (sshkey_is_sk(id->key)) {
|
||||
if (strncmp(id->key->sk_application, "ssh:", 4) != 0 &&
|
||||
- !check_websafe_message_contents(key, data, dlen)) {
|
||||
+ !check_websafe_message_contents(key, data)) {
|
||||
/* error already logged */
|
||||
goto send;
|
||||
}
|
||||
@@ -411,7 +472,7 @@ process_sign_request2(SocketEntry *e)
|
||||
}
|
||||
}
|
||||
if ((r = sshkey_sign(id->key, &signature, &slen,
|
||||
- data, dlen, agent_decode_alg(key, flags),
|
||||
+ sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags),
|
||||
id->sk_provider, compat)) != 0) {
|
||||
error("%s: sshkey_sign: %s", __func__, ssh_err(r));
|
||||
goto send;
|
||||
@@ -420,8 +481,7 @@ process_sign_request2(SocketEntry *e)
|
||||
ok = 0;
|
||||
send:
|
||||
notify_complete(notifier);
|
||||
- sshkey_free(key);
|
||||
- free(fp);
|
||||
+
|
||||
if (ok == 0) {
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
|
||||
(r = sshbuf_put_string(msg, signature, slen)) != 0)
|
||||
@@ -432,7 +492,10 @@ process_sign_request2(SocketEntry *e)
|
||||
if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
+ sshbuf_free(data);
|
||||
sshbuf_free(msg);
|
||||
+ sshkey_free(key);
|
||||
+ free(fp);
|
||||
free(signature);
|
||||
}
|
||||
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,38 @@
|
||||
From 7adba46611e5d076d7d12d9f4162dd4cabd5ff50 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Fri, 29 Jan 2021 06:28:10 +0000
|
||||
Subject: [PATCH 09/12] upstream: give typedef'd struct a struct name; makes
|
||||
the fuzzer I'm
|
||||
|
||||
writing a bit easier
|
||||
|
||||
OpenBSD-Commit-ID: 1052ab521505a4d8384d67acb3974ef81b8896cb
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/8afaa7d7918419d3da6c0477b83db2159879cb33]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-agent.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 7ad323c..c99927c 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.270 2021/01/26 00:53:31 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.274 2021/01/29 06:28:10 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -108,7 +108,7 @@ typedef enum {
|
||||
AUTH_CONNECTION
|
||||
} sock_type;
|
||||
|
||||
-typedef struct {
|
||||
+typedef struct socket_entry {
|
||||
int fd;
|
||||
sock_type type;
|
||||
struct sshbuf *input;
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,39 @@
|
||||
From 343e2a2c0ef754a7a86118016b248f7a73f8d510 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Fri, 29 Jan 2021 06:29:46 +0000
|
||||
Subject: [PATCH 10/12] upstream: fix the values of enum sock_type
|
||||
|
||||
OpenBSD-Commit-ID: 18d048f4dbfbb159ff500cfc2700b8fb1407facd
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/1a4b92758690faa12f49079dd3b72567f909466d]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-agent.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index c99927c..7f1e14b 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.274 2021/01/29 06:28:10 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.275 2021/01/29 06:29:46 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -103,9 +103,9 @@
|
||||
#define AGENT_RBUF_LEN (4096)
|
||||
|
||||
typedef enum {
|
||||
- AUTH_UNUSED,
|
||||
- AUTH_SOCKET,
|
||||
- AUTH_CONNECTION
|
||||
+ AUTH_UNUSED = 0,
|
||||
+ AUTH_SOCKET = 1,
|
||||
+ AUTH_CONNECTION = 2,
|
||||
} sock_type;
|
||||
|
||||
typedef struct socket_entry {
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,307 @@
|
||||
From 2b3b369c8cf71f9ef5942a5e074e6f86e7ca1e0c Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Sun, 19 Dec 2021 22:09:23 +0000
|
||||
Subject: [PATCH 11/12] upstream: ssh-agent side of binding
|
||||
|
||||
record session ID/hostkey/forwarding status for each active socket.
|
||||
|
||||
Attempt to parse data-to-be-signed at signature request time and extract
|
||||
session ID from the blob if it is a pubkey userauth request.
|
||||
|
||||
ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: a80fd41e292b18b67508362129e9fed549abd318
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/4c1e3ce85e183a9d0c955c88589fed18e4d6a058]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
authfd.h | 3 +
|
||||
ssh-agent.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 170 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/authfd.h b/authfd.h
|
||||
index c3bf625..9cc9807 100644
|
||||
--- a/authfd.h
|
||||
+++ b/authfd.h
|
||||
@@ -76,6 +76,9 @@ int ssh_agent_sign(int sock, const struct sshkey *key,
|
||||
#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
|
||||
#define SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED 26
|
||||
|
||||
+/* generic extension mechanism */
|
||||
+#define SSH_AGENTC_EXTENSION 27
|
||||
+
|
||||
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
|
||||
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
|
||||
#define SSH_AGENT_CONSTRAIN_MAXSIGN 3
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 7f1e14b..01c7f2b 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.275 2021/01/29 06:29:46 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.280 2021/12/19 22:09:23 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -98,9 +98,15 @@
|
||||
#endif
|
||||
|
||||
/* Maximum accepted message length */
|
||||
-#define AGENT_MAX_LEN (256*1024)
|
||||
+#define AGENT_MAX_LEN (256*1024)
|
||||
/* Maximum bytes to read from client socket */
|
||||
-#define AGENT_RBUF_LEN (4096)
|
||||
+#define AGENT_RBUF_LEN (4096)
|
||||
+/* Maximum number of recorded session IDs/hostkeys per connection */
|
||||
+#define AGENT_MAX_SESSION_IDS 16
|
||||
+/* Maximum size of session ID */
|
||||
+#define AGENT_MAX_SID_LEN 128
|
||||
+
|
||||
+/* XXX store hostkey_sid in a refcounted tree */
|
||||
|
||||
typedef enum {
|
||||
AUTH_UNUSED = 0,
|
||||
@@ -108,12 +114,20 @@ typedef enum {
|
||||
AUTH_CONNECTION = 2,
|
||||
} sock_type;
|
||||
|
||||
+struct hostkey_sid {
|
||||
+ struct sshkey *key;
|
||||
+ struct sshbuf *sid;
|
||||
+ int forwarded;
|
||||
+};
|
||||
+
|
||||
typedef struct socket_entry {
|
||||
int fd;
|
||||
sock_type type;
|
||||
struct sshbuf *input;
|
||||
struct sshbuf *output;
|
||||
struct sshbuf *request;
|
||||
+ size_t nsession_ids;
|
||||
+ struct hostkey_sid *session_ids;
|
||||
} SocketEntry;
|
||||
|
||||
u_int sockets_alloc = 0;
|
||||
@@ -174,10 +188,17 @@ static int restrict_websafe = 1;
|
||||
static void
|
||||
close_socket(SocketEntry *e)
|
||||
{
|
||||
+ size_t i;
|
||||
+
|
||||
close(e->fd);
|
||||
sshbuf_free(e->input);
|
||||
sshbuf_free(e->output);
|
||||
sshbuf_free(e->request);
|
||||
+ for (i = 0; i < e->nsession_ids; i++) {
|
||||
+ sshkey_free(e->session_ids[i].key);
|
||||
+ sshbuf_free(e->session_ids[i].sid);
|
||||
+ }
|
||||
+ free(e->session_ids);
|
||||
memset(e, '\0', sizeof(*e));
|
||||
e->fd = -1;
|
||||
e->type = AUTH_UNUSED;
|
||||
@@ -423,6 +444,18 @@ check_websafe_message_contents(struct sshkey *key, struct sshbuf *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+buf_equal(const struct sshbuf *a, const struct sshbuf *b)
|
||||
+{
|
||||
+ if (sshbuf_ptr(a) == NULL || sshbuf_ptr(b) == NULL)
|
||||
+ return SSH_ERR_INVALID_ARGUMENT;
|
||||
+ if (sshbuf_len(a) != sshbuf_len(b))
|
||||
+ return SSH_ERR_INVALID_FORMAT;
|
||||
+ if (timingsafe_bcmp(sshbuf_ptr(a), sshbuf_ptr(b), sshbuf_len(a)) != 0)
|
||||
+ return SSH_ERR_INVALID_FORMAT;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* ssh2 only */
|
||||
static void
|
||||
process_sign_request2(SocketEntry *e)
|
||||
@@ -431,8 +464,8 @@ process_sign_request2(SocketEntry *e)
|
||||
size_t i, slen = 0;
|
||||
u_int compat = 0, flags;
|
||||
int r, ok = -1;
|
||||
- char *fp = NULL;
|
||||
- struct sshbuf *msg = NULL, *data = NULL;
|
||||
+ char *fp = NULL, *user = NULL, *sig_dest = NULL;
|
||||
+ struct sshbuf *msg = NULL, *data = NULL, *sid = NULL;
|
||||
struct sshkey *key = NULL;
|
||||
struct identity *id;
|
||||
struct notifier_ctx *notifier = NULL;
|
||||
@@ -452,7 +485,33 @@ process_sign_request2(SocketEntry *e)
|
||||
verbose("%s: %s key not found", __func__, sshkey_type(key));
|
||||
goto send;
|
||||
}
|
||||
- if (id->confirm && confirm_key(id, NULL) != 0) {
|
||||
+ /*
|
||||
+ * If session IDs were recorded for this socket, then use them to
|
||||
+ * annotate the confirmation messages with the host keys.
|
||||
+ */
|
||||
+ if (e->nsession_ids > 0 &&
|
||||
+ parse_userauth_request(data, key, &user, &sid) == 0) {
|
||||
+ /*
|
||||
+ * session ID from userauth request should match the final
|
||||
+ * ID in the list recorded in the socket, unless the ssh
|
||||
+ * client at that point lacks the binding extension (or if
|
||||
+ * an attacker is trying to steal use of the agent).
|
||||
+ */
|
||||
+ i = e->nsession_ids - 1;
|
||||
+ if (buf_equal(sid, e->session_ids[i].sid) == 0) {
|
||||
+ if ((fp = sshkey_fingerprint(e->session_ids[i].key,
|
||||
+ SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL)
|
||||
+ fatal("%s: fingerprint failed", __func__);
|
||||
+ debug3("%s: destination %s %s (slot %zu)", __func__,
|
||||
+ sshkey_type(e->session_ids[i].key), fp, i);
|
||||
+ xasprintf(&sig_dest, "public key request for "
|
||||
+ "target user \"%s\" to %s %s", user,
|
||||
+ sshkey_type(e->session_ids[i].key), fp);
|
||||
+ free(fp);
|
||||
+ fp = NULL;
|
||||
+ }
|
||||
+ }//
|
||||
+ if (id->confirm && confirm_key(id, sig_dest) != 0) {
|
||||
verbose("%s: user refused key", __func__);
|
||||
goto send;
|
||||
}
|
||||
@@ -467,8 +526,10 @@ process_sign_request2(SocketEntry *e)
|
||||
SSH_FP_DEFAULT)) == NULL)
|
||||
fatal("%s: fingerprint failed", __func__);
|
||||
notifier = notify_start(0,
|
||||
- "Confirm user presence for key %s %s",
|
||||
- sshkey_type(id->key), fp);
|
||||
+ "Confirm user presence for key %s %s%s%s",
|
||||
+ sshkey_type(id->key), fp,
|
||||
+ sig_dest == NULL ? "" : "\n",
|
||||
+ sig_dest == NULL ? "" : sig_dest);
|
||||
}
|
||||
}
|
||||
if ((r = sshkey_sign(id->key, &signature, &slen,
|
||||
@@ -492,11 +553,14 @@ process_sign_request2(SocketEntry *e)
|
||||
if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
|
||||
fatal("%s: buffer error: %s", __func__, ssh_err(r));
|
||||
|
||||
+ sshbuf_free(sid);
|
||||
sshbuf_free(data);
|
||||
sshbuf_free(msg);
|
||||
sshkey_free(key);
|
||||
free(fp);
|
||||
free(signature);
|
||||
+ free(sig_dest);
|
||||
+ free(user);
|
||||
}
|
||||
|
||||
/* shared */
|
||||
@@ -925,6 +989,98 @@ send:
|
||||
}
|
||||
#endif /* ENABLE_PKCS11 */
|
||||
|
||||
+static int
|
||||
+process_ext_session_bind(SocketEntry *e)
|
||||
+{
|
||||
+ int r, sid_match, key_match;
|
||||
+ struct sshkey *key = NULL;
|
||||
+ struct sshbuf *sid = NULL, *sig = NULL;
|
||||
+ char *fp = NULL;
|
||||
+ u_char fwd;
|
||||
+ size_t i;
|
||||
+
|
||||
+ debug2("%s: entering", __func__);
|
||||
+ if ((r = sshkey_froms(e->request, &key)) != 0 ||
|
||||
+ (r = sshbuf_froms(e->request, &sid)) != 0 ||
|
||||
+ (r = sshbuf_froms(e->request, &sig)) != 0 ||
|
||||
+ (r = sshbuf_get_u8(e->request, &fwd)) != 0) {
|
||||
+ error("%s: parse: %s", __func__, ssh_err(r));
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
|
||||
+ SSH_FP_DEFAULT)) == NULL)
|
||||
+ fatal("%s: fingerprint failed", __func__);
|
||||
+ /* check signature with hostkey on session ID */
|
||||
+ if ((r = sshkey_verify(key, sshbuf_ptr(sig), sshbuf_len(sig),
|
||||
+ sshbuf_ptr(sid), sshbuf_len(sid), NULL, 0, NULL)) != 0) {
|
||||
+ error("%s: sshkey_verify for %s %s: %s", __func__, sshkey_type(key), fp, ssh_err(r));
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /* check whether sid/key already recorded */
|
||||
+ for (i = 0; i < e->nsession_ids; i++) {
|
||||
+ sid_match = buf_equal(sid, e->session_ids[i].sid) == 0;
|
||||
+ key_match = sshkey_equal(key, e->session_ids[i].key);
|
||||
+ if (sid_match && key_match) {
|
||||
+ debug("%s: session ID already recorded for %s %s", __func__,
|
||||
+ sshkey_type(key), fp);
|
||||
+ r = 0;
|
||||
+ goto out;
|
||||
+ } else if (sid_match) {
|
||||
+ error("%s: session ID recorded against different key "
|
||||
+ "for %s %s", __func__, sshkey_type(key), fp);
|
||||
+ r = -1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ /*
|
||||
+ * new sid with previously-seen key can happen, e.g. multiple
|
||||
+ * connections to the same host.
|
||||
+ */
|
||||
+ }
|
||||
+ /* record new key/sid */
|
||||
+ if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) {
|
||||
+ error("%s: too many session IDs recorded", __func__);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ e->session_ids = xrecallocarray(e->session_ids, e->nsession_ids,
|
||||
+ e->nsession_ids + 1, sizeof(*e->session_ids));
|
||||
+ i = e->nsession_ids++;
|
||||
+ debug("%s: recorded %s %s (slot %zu of %d)", __func__, sshkey_type(key), fp, i,
|
||||
+ AGENT_MAX_SESSION_IDS);
|
||||
+ e->session_ids[i].key = key;
|
||||
+ e->session_ids[i].forwarded = fwd != 0;
|
||||
+ key = NULL; /* transferred */
|
||||
+ /* can't transfer sid; it's refcounted and scoped to request's life */
|
||||
+ if ((e->session_ids[i].sid = sshbuf_new()) == NULL)
|
||||
+ fatal("%s: sshbuf_new", __func__);
|
||||
+ if ((r = sshbuf_putb(e->session_ids[i].sid, sid)) != 0)
|
||||
+ fatal("%s: sshbuf_putb session ID: %s", __func__, ssh_err(r));
|
||||
+ /* success */
|
||||
+ r = 0;
|
||||
+ out:
|
||||
+ sshkey_free(key);
|
||||
+ sshbuf_free(sid);
|
||||
+ sshbuf_free(sig);
|
||||
+ return r == 0 ? 1 : 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+process_extension(SocketEntry *e)
|
||||
+{
|
||||
+ int r, success = 0;
|
||||
+ char *name;
|
||||
+
|
||||
+ debug2("%s: entering", __func__);
|
||||
+ if ((r = sshbuf_get_cstring(e->request, &name, NULL)) != 0) {
|
||||
+ error("%s: parse: %s", __func__, ssh_err(r));
|
||||
+ goto send;
|
||||
+ }
|
||||
+ if (strcmp(name, "session-bind@openssh.com") == 0)
|
||||
+ success = process_ext_session_bind(e);
|
||||
+ else
|
||||
+ debug("%s: unsupported extension \"%s\"", __func__, name);
|
||||
+send:
|
||||
+ send_status(e, success);
|
||||
+}
|
||||
/*
|
||||
* dispatch incoming message.
|
||||
* returns 1 on success, 0 for incomplete messages or -1 on error.
|
||||
@@ -1019,6 +1175,9 @@ process_message(u_int socknum)
|
||||
process_remove_smartcard_key(e);
|
||||
break;
|
||||
#endif /* ENABLE_PKCS11 */
|
||||
+ case SSH_AGENTC_EXTENSION:
|
||||
+ process_extension(e);
|
||||
+ break;
|
||||
default:
|
||||
/* Unknown message. Respond with failure. */
|
||||
error("Unknown message %d", type);
|
||||
--
|
||||
2.41.0
|
||||
@@ -0,0 +1,120 @@
|
||||
From 4fe3d0fbd3d6dc1f19354e0d73a3231c461ed044 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Wed, 19 Jul 2023 13:56:33 +0000
|
||||
Subject: [PATCH 12/12] upstream: Disallow remote addition of FIDO/PKCS11
|
||||
provider libraries to ssh-agent by default.
|
||||
|
||||
The old behaviour of allowing remote clients from loading providers
|
||||
can be restored using `ssh-agent -O allow-remote-pkcs11`.
|
||||
|
||||
Detection of local/remote clients requires a ssh(1) that supports
|
||||
the `session-bind@openssh.com` extension. Forwarding access to a
|
||||
ssh-agent socket using non-OpenSSH tools may circumvent this control.
|
||||
|
||||
ok markus@
|
||||
|
||||
OpenBSD-Commit-ID: 4c2bdf79b214ae7e60cc8c39a45501344fa7bd7c
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/1f2731f5d7a8f8a8385c6031667ed29072c0d92a]
|
||||
CVE: CVE-2023-38408
|
||||
Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com>
|
||||
---
|
||||
ssh-agent.1 | 20 ++++++++++++++++++++
|
||||
ssh-agent.c | 26 ++++++++++++++++++++++++--
|
||||
2 files changed, 44 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/ssh-agent.1 b/ssh-agent.1
|
||||
index fff0db6..a0f1e21 100644
|
||||
--- a/ssh-agent.1
|
||||
+++ b/ssh-agent.1
|
||||
@@ -97,6 +97,26 @@ The default is
|
||||
Kill the current agent (given by the
|
||||
.Ev SSH_AGENT_PID
|
||||
environment variable).
|
||||
+Currently two options are supported:
|
||||
+.Cm allow-remote-pkcs11
|
||||
+and
|
||||
+.Pp
|
||||
+The
|
||||
+.Cm allow-remote-pkcs11
|
||||
+option allows clients of a forwarded
|
||||
+.Nm
|
||||
+to load PKCS#11 or FIDO provider libraries.
|
||||
+By default only local clients may perform this operation.
|
||||
+Note that signalling that a
|
||||
+.Nm
|
||||
+client remote is performed by
|
||||
+.Xr ssh 1 ,
|
||||
+and use of other tools to forward access to the agent socket may circumvent
|
||||
+this restriction.
|
||||
+.Pp
|
||||
+The
|
||||
+.Cm no-restrict-websafe ,
|
||||
+instructs
|
||||
.It Fl P Ar provider_whitelist
|
||||
Specify a pattern-list of acceptable paths for PKCS#11 and FIDO authenticator
|
||||
shared libraries that may be used with the
|
||||
diff --git a/ssh-agent.c b/ssh-agent.c
|
||||
index 01c7f2b..40c1b6b 100644
|
||||
--- a/ssh-agent.c
|
||||
+++ b/ssh-agent.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* $OpenBSD: ssh-agent.c,v 1.280 2021/12/19 22:09:23 djm Exp $ */
|
||||
+/* $OpenBSD: ssh-agent.c,v 1.300 2023/07/19 13:56:33 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -167,6 +167,12 @@ char socket_dir[PATH_MAX];
|
||||
/* PKCS#11/Security key path whitelist */
|
||||
static char *provider_whitelist;
|
||||
|
||||
+/*
|
||||
+ * Allows PKCS11 providers or SK keys that use non-internal providers to
|
||||
+ * be added over a remote connection (identified by session-bind@openssh.com).
|
||||
+ */
|
||||
+static int remote_add_provider;
|
||||
+
|
||||
/* locking */
|
||||
#define LOCK_SIZE 32
|
||||
#define LOCK_SALT_SIZE 16
|
||||
@@ -736,6 +742,15 @@ process_add_identity(SocketEntry *e)
|
||||
if (strcasecmp(sk_provider, "internal") == 0) {
|
||||
debug("%s: internal provider", __func__);
|
||||
} else {
|
||||
+ if (e->nsession_ids != 0 && !remote_add_provider) {
|
||||
+ verbose("failed add of SK provider \"%.100s\": "
|
||||
+ "remote addition of providers is disabled",
|
||||
+ sk_provider);
|
||||
+ free(sk_provider);
|
||||
+ free(comment);
|
||||
+ sshkey_free(k);
|
||||
+ goto send;
|
||||
+ }
|
||||
if (realpath(sk_provider, canonical_provider) == NULL) {
|
||||
verbose("failed provider \"%.100s\": "
|
||||
"realpath: %s", sk_provider,
|
||||
@@ -901,6 +916,11 @@ process_add_smartcard_key(SocketEntry *e)
|
||||
goto send;
|
||||
}
|
||||
}
|
||||
+ if (e->nsession_ids != 0 && !remote_add_provider) {
|
||||
+ verbose("failed PKCS#11 add of \"%.100s\": remote addition of "
|
||||
+ "providers is disabled", provider);
|
||||
+ goto send;
|
||||
+ }
|
||||
if (realpath(provider, canonical_provider) == NULL) {
|
||||
verbose("failed PKCS#11 add of \"%.100s\": realpath: %s",
|
||||
provider, strerror(errno));
|
||||
@@ -1556,7 +1576,9 @@ main(int ac, char **av)
|
||||
break;
|
||||
case 'O':
|
||||
if (strcmp(optarg, "no-restrict-websafe") == 0)
|
||||
- restrict_websafe = 0;
|
||||
+ restrict_websafe = 0;
|
||||
+ else if (strcmp(optarg, "allow-remote-pkcs11") == 0)
|
||||
+ remote_add_provider = 1;
|
||||
else
|
||||
fatal("Unknown -O option");
|
||||
break;
|
||||
--
|
||||
2.41.0
|
||||
@@ -27,6 +27,18 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar
|
||||
file://CVE-2020-14145.patch \
|
||||
file://CVE-2021-28041.patch \
|
||||
file://CVE-2021-41617.patch \
|
||||
file://CVE-2023-38408-01.patch \
|
||||
file://CVE-2023-38408-02.patch \
|
||||
file://CVE-2023-38408-03.patch \
|
||||
file://CVE-2023-38408-04.patch \
|
||||
file://CVE-2023-38408-05.patch \
|
||||
file://CVE-2023-38408-06.patch \
|
||||
file://CVE-2023-38408-07.patch \
|
||||
file://CVE-2023-38408-08.patch \
|
||||
file://CVE-2023-38408-09.patch \
|
||||
file://CVE-2023-38408-10.patch \
|
||||
file://CVE-2023-38408-11.patch \
|
||||
file://CVE-2023-38408-12.patch \
|
||||
"
|
||||
SRC_URI[md5sum] = "3076e6413e8dbe56d33848c1054ac091"
|
||||
SRC_URI[sha256sum] = "43925151e6cf6cee1450190c0e9af4dc36b41c12737619edff8bcebdff64e671"
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 679ae2f72ef8cf37609cb0eff5de3b98aa85e395 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Thu, 20 Jul 2023 04:14:42 -1000
|
||||
Subject: [PATCH] Configure: add 2 missing key sorts in generation of unified_info
|
||||
|
||||
Otherwise generation of this section in configdata.pm is not reproducible
|
||||
|
||||
Signed-off-by: Steve Sakoman <steve@sakoman.com>
|
||||
Upstream-Status: Backport [adapted from 3.x commit https://github.com/openssl/openssl/commit/764cf5b26306a8712e8b3d41599c44dc5ed07a25]
|
||||
---
|
||||
Configure | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Configure b/Configure
|
||||
index 2a01746..8fc5a2c 100755
|
||||
--- a/Configure
|
||||
+++ b/Configure
|
||||
@@ -2326,7 +2326,7 @@ EOF
|
||||
"dso" => [ @{$unified_info{engines}} ],
|
||||
"bin" => [ @{$unified_info{programs}} ],
|
||||
"script" => [ @{$unified_info{scripts}} ] );
|
||||
- foreach my $type (keys %loopinfo) {
|
||||
+ foreach my $type (sort keys %loopinfo) {
|
||||
foreach my $product (@{$loopinfo{$type}}) {
|
||||
my %dirs = ();
|
||||
my $pd = dirname($product);
|
||||
@@ -2347,7 +2347,7 @@ EOF
|
||||
push @{$unified_info{dirinfo}->{$d}->{deps}}, $_
|
||||
if $d ne $pd;
|
||||
}
|
||||
- foreach (keys %dirs) {
|
||||
+ foreach (sort keys %dirs) {
|
||||
push @{$unified_info{dirinfo}->{$_}->{products}->{$type}},
|
||||
$product;
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 326909baf81a638d51fa8be1d8227518784f5cc4 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Kanavin <alex@linutronix.de>
|
||||
Date: Tue, 14 Sep 2021 12:18:25 +0200
|
||||
Subject: [PATCH] Configure: do not tweak mips cflags
|
||||
|
||||
This conflicts with mips machine definitons from yocto,
|
||||
e.g.
|
||||
| Error: -mips3 conflicts with the other architecture options, which imply -mips64r2
|
||||
|
||||
Upstream-Status: Inappropriate [oe-core specific]
|
||||
Signed-off-by: Alexander Kanavin <alex@linutronix.de>
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
Configure | 10 ----------
|
||||
1 file changed, 10 deletions(-)
|
||||
|
||||
Index: openssl-3.0.4/Configure
|
||||
===================================================================
|
||||
--- openssl-3.0.4.orig/Configure
|
||||
+++ openssl-3.0.4/Configure
|
||||
@@ -1243,16 +1243,6 @@ if ($target =~ /^mingw/ && `$config{CC} --target-help 2>&1` =~ m/-mno-cygwin/m)
|
||||
push @{$config{shared_ldflag}}, "-mno-cygwin";
|
||||
}
|
||||
|
||||
-if ($target =~ /linux.*-mips/ && !$disabled{asm}
|
||||
- && !grep { $_ =~ /-m(ips|arch=)/ } (@{$config{CFLAGS}})) {
|
||||
- # minimally required architecture flags for assembly modules
|
||||
- my $value;
|
||||
- $value = '-mips2' if ($target =~ /mips32/);
|
||||
- $value = '-mips3' if ($target =~ /mips64/);
|
||||
- unshift @{$config{cflags}}, $value;
|
||||
- unshift @{$config{cxxflags}}, $value if $config{CXX};
|
||||
-}
|
||||
-
|
||||
# If threads aren't disabled, check how possible they are
|
||||
unless ($disabled{threads}) {
|
||||
if ($auto_threads) {
|
||||
@@ -1,226 +0,0 @@
|
||||
From 879f7080d7e141f415c79eaa3a8ac4a3dad0348b Mon Sep 17 00:00:00 2001
|
||||
From: Pauli <pauli@openssl.org>
|
||||
Date: Wed, 8 Mar 2023 15:28:20 +1100
|
||||
Subject: [PATCH] x509: excessive resource use verifying policy constraints
|
||||
|
||||
A security vulnerability has been identified in all supported versions
|
||||
of OpenSSL related to the verification of X.509 certificate chains
|
||||
that include policy constraints. Attackers may be able to exploit this
|
||||
vulnerability by creating a malicious certificate chain that triggers
|
||||
exponential use of computational resources, leading to a denial-of-service
|
||||
(DoS) attack on affected systems.
|
||||
|
||||
Fixes CVE-2023-0464
|
||||
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
|
||||
(Merged from https://github.com/openssl/openssl/pull/20569)
|
||||
|
||||
CVE: CVE-2023-0464
|
||||
Upstream-Status: Backport [https://git.openssl.org/gitweb/?p=openssl.git;a=patch;h=879f7080d7e141f415c79eaa3a8ac4a3dad0348b]
|
||||
Signed-off-by: Nikhil R <nikhil.r@kpit.com>
|
||||
|
||||
---
|
||||
crypto/x509v3/pcy_local.h | 8 +++++++-
|
||||
crypto/x509v3/pcy_node.c | 12 +++++++++---
|
||||
crypto/x509v3/pcy_tree.c | 37 +++++++++++++++++++++++++++----------
|
||||
3 files changed, 43 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/crypto/x509v3/pcy_local.h b/crypto/x509v3/pcy_local.h
|
||||
index 5daf78de45..344aa06765 100644
|
||||
--- a/crypto/x509v3/pcy_local.h
|
||||
+++ b/crypto/x509v3/pcy_local.h
|
||||
@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st {
|
||||
};
|
||||
|
||||
struct X509_POLICY_TREE_st {
|
||||
+ /* The number of nodes in the tree */
|
||||
+ size_t node_count;
|
||||
+ /* The maximum number of nodes in the tree */
|
||||
+ size_t node_maximum;
|
||||
+
|
||||
/* This is the tree 'level' data */
|
||||
X509_POLICY_LEVEL *levels;
|
||||
int nlevel;
|
||||
@@ -159,7 +164,8 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
|
||||
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
|
||||
X509_POLICY_DATA *data,
|
||||
X509_POLICY_NODE *parent,
|
||||
- X509_POLICY_TREE *tree);
|
||||
+ X509_POLICY_TREE *tree,
|
||||
+ int extra_data);
|
||||
void policy_node_free(X509_POLICY_NODE *node);
|
||||
int policy_node_match(const X509_POLICY_LEVEL *lvl,
|
||||
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
|
||||
diff --git a/crypto/x509v3/pcy_node.c b/crypto/x509v3/pcy_node.c
|
||||
index e2d7b15322..d574fb9d66 100644
|
||||
--- a/crypto/x509v3/pcy_node.c
|
||||
+++ b/crypto/x509v3/pcy_node.c
|
||||
@@ -59,10 +59,15 @@ X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
|
||||
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
|
||||
X509_POLICY_DATA *data,
|
||||
X509_POLICY_NODE *parent,
|
||||
- X509_POLICY_TREE *tree)
|
||||
+ X509_POLICY_TREE *tree,
|
||||
+ int extra_data)
|
||||
{
|
||||
X509_POLICY_NODE *node;
|
||||
|
||||
+ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */
|
||||
+ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum)
|
||||
+ return NULL;
|
||||
+
|
||||
node = OPENSSL_zalloc(sizeof(*node));
|
||||
if (node == NULL) {
|
||||
X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE);
|
||||
@@ -70,7 +75,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
|
||||
}
|
||||
node->data = data;
|
||||
node->parent = parent;
|
||||
- if (level) {
|
||||
+ if (level != NULL) {
|
||||
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
|
||||
if (level->anyPolicy)
|
||||
goto node_error;
|
||||
@@ -90,7 +95,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
|
||||
}
|
||||
}
|
||||
|
||||
- if (tree) {
|
||||
+ if (extra_data) {
|
||||
if (tree->extra_data == NULL)
|
||||
tree->extra_data = sk_X509_POLICY_DATA_new_null();
|
||||
if (tree->extra_data == NULL){
|
||||
@@ -103,6 +108,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
|
||||
}
|
||||
}
|
||||
|
||||
+ tree->node_count++;
|
||||
if (parent)
|
||||
parent->nchild++;
|
||||
|
||||
diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c
|
||||
index 6e8322cbc5..6c7fd35405 100644
|
||||
--- a/crypto/x509v3/pcy_tree.c
|
||||
+++ b/crypto/x509v3/pcy_tree.c
|
||||
@@ -13,6 +13,18 @@
|
||||
|
||||
#include "pcy_local.h"
|
||||
|
||||
+/*
|
||||
+ * If the maximum number of nodes in the policy tree isn't defined, set it to
|
||||
+ * a generous default of 1000 nodes.
|
||||
+ *
|
||||
+ * Defining this to be zero means unlimited policy tree growth which opens the
|
||||
+ * door on CVE-2023-0464.
|
||||
+ */
|
||||
+
|
||||
+#ifndef OPENSSL_POLICY_TREE_NODES_MAX
|
||||
+# define OPENSSL_POLICY_TREE_NODES_MAX 1000
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Enable this to print out the complete policy tree at various point during
|
||||
* evaluation.
|
||||
@@ -168,6 +180,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
|
||||
return X509_PCY_TREE_INTERNAL;
|
||||
}
|
||||
|
||||
+ /* Limit the growth of the tree to mitigate CVE-2023-0464 */
|
||||
+ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX;
|
||||
+
|
||||
/*
|
||||
* http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3.
|
||||
*
|
||||
@@ -184,7 +199,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
|
||||
level = tree->levels;
|
||||
if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL)
|
||||
goto bad_tree;
|
||||
- if (level_add_node(level, data, NULL, tree) == NULL) {
|
||||
+ if (level_add_node(level, data, NULL, tree, 1) == NULL) {
|
||||
policy_data_free(data);
|
||||
goto bad_tree;
|
||||
}
|
||||
@@ -243,7 +258,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
|
||||
* Return value: 1 on success, 0 otherwise
|
||||
*/
|
||||
static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
|
||||
- X509_POLICY_DATA *data)
|
||||
+ X509_POLICY_DATA *data,
|
||||
+ X509_POLICY_TREE *tree)
|
||||
{
|
||||
X509_POLICY_LEVEL *last = curr - 1;
|
||||
int i, matched = 0;
|
||||
@@ -253,13 +269,13 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
|
||||
X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i);
|
||||
|
||||
if (policy_node_match(last, node, data->valid_policy)) {
|
||||
- if (level_add_node(curr, data, node, NULL) == NULL)
|
||||
+ if (level_add_node(curr, data, node, tree, 0) == NULL)
|
||||
return 0;
|
||||
matched = 1;
|
||||
}
|
||||
}
|
||||
if (!matched && last->anyPolicy) {
|
||||
- if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL)
|
||||
+ if (level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -272,7 +288,8 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
|
||||
* Return value: 1 on success, 0 otherwise.
|
||||
*/
|
||||
static int tree_link_nodes(X509_POLICY_LEVEL *curr,
|
||||
- const X509_POLICY_CACHE *cache)
|
||||
+ const X509_POLICY_CACHE *cache,
|
||||
+ X509_POLICY_TREE *tree)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -280,7 +297,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
|
||||
X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i);
|
||||
|
||||
/* Look for matching nodes in previous level */
|
||||
- if (!tree_link_matching_nodes(curr, data))
|
||||
+ if (!tree_link_matching_nodes(curr, data, tree))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -311,7 +328,7 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
|
||||
/* Curr may not have anyPolicy */
|
||||
data->qualifier_set = cache->anyPolicy->qualifier_set;
|
||||
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
|
||||
- if (level_add_node(curr, data, node, tree) == NULL) {
|
||||
+ if (level_add_node(curr, data, node, tree, 1) == NULL) {
|
||||
policy_data_free(data);
|
||||
return 0;
|
||||
}
|
||||
@@ -373,7 +390,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
|
||||
}
|
||||
/* Finally add link to anyPolicy */
|
||||
if (last->anyPolicy &&
|
||||
- level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL)
|
||||
+ level_add_node(curr, cache->anyPolicy, last->anyPolicy, tree, 0) == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
@@ -555,7 +572,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree,
|
||||
extra->qualifier_set = anyPolicy->data->qualifier_set;
|
||||
extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
|
||||
| POLICY_DATA_FLAG_EXTRA_NODE;
|
||||
- node = level_add_node(NULL, extra, anyPolicy->parent, tree);
|
||||
+ node = level_add_node(NULL, extra, anyPolicy->parent, tree, 1);
|
||||
}
|
||||
if (!tree->user_policies) {
|
||||
tree->user_policies = sk_X509_POLICY_NODE_new_null();
|
||||
@@ -582,7 +599,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree)
|
||||
|
||||
for (i = 1; i < tree->nlevel; i++, curr++) {
|
||||
cache = policy_cache_set(curr->cert);
|
||||
- if (!tree_link_nodes(curr, cache))
|
||||
+ if (!tree_link_nodes(curr, cache, tree))
|
||||
return X509_PCY_TREE_INTERNAL;
|
||||
|
||||
if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)
|
||||
--
|
||||
2.34.1
|
||||
@@ -1,60 +0,0 @@
|
||||
From b013765abfa80036dc779dd0e50602c57bb3bf95 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Tue, 7 Mar 2023 16:52:55 +0000
|
||||
Subject: [PATCH] Ensure that EXFLAG_INVALID_POLICY is checked even in leaf
|
||||
certs
|
||||
|
||||
Even though we check the leaf cert to confirm it is valid, we
|
||||
later ignored the invalid flag and did not notice that the leaf
|
||||
cert was bad.
|
||||
|
||||
Fixes: CVE-2023-0465
|
||||
|
||||
Reviewed-by: Hugo Landau <hlandau@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/20588)
|
||||
|
||||
CVE: CVE-2023-0465
|
||||
Upstream-Status: Backport [https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=b013765abfa80036dc779dd0e50602c57bb3bf95]
|
||||
Comment: Refreshed first hunk
|
||||
Signed-off-by: Omkar Patil <omkar.patil@kpit.com>
|
||||
|
||||
---
|
||||
crypto/x509/x509_vfy.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
|
||||
index 925fbb5412..1dfe4f9f31 100644
|
||||
--- a/crypto/x509/x509_vfy.c
|
||||
+++ b/crypto/x509/x509_vfy.c
|
||||
@@ -1649,18 +1649,25 @@
|
||||
}
|
||||
/* Invalid or inconsistent extensions */
|
||||
if (ret == X509_PCY_TREE_INVALID) {
|
||||
- int i;
|
||||
+ int i, cbcalled = 0;
|
||||
|
||||
/* Locate certificates with bad extensions and notify callback. */
|
||||
- for (i = 1; i < sk_X509_num(ctx->chain); i++) {
|
||||
+ for (i = 0; i < sk_X509_num(ctx->chain); i++) {
|
||||
X509 *x = sk_X509_value(ctx->chain, i);
|
||||
|
||||
if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
|
||||
continue;
|
||||
+ cbcalled = 1;
|
||||
if (!verify_cb_cert(ctx, x, i,
|
||||
X509_V_ERR_INVALID_POLICY_EXTENSION))
|
||||
return 0;
|
||||
}
|
||||
+ if (!cbcalled) {
|
||||
+ /* Should not be able to get here */
|
||||
+ X509err(X509_F_CHECK_POLICY, ERR_R_INTERNAL_ERROR);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ /* The callback ignored the error so we return success */
|
||||
return 1;
|
||||
}
|
||||
if (ret == X509_PCY_TREE_FAILURE) {
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
From 0d16b7e99aafc0b4a6d729eec65a411a7e025f0a Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tomas@openssl.org>
|
||||
Date: Tue, 21 Mar 2023 16:15:47 +0100
|
||||
Subject: [PATCH] Fix documentation of X509_VERIFY_PARAM_add0_policy()
|
||||
|
||||
The function was incorrectly documented as enabling policy checking.
|
||||
|
||||
Fixes: CVE-2023-0466
|
||||
|
||||
Reviewed-by: Matt Caswell <matt@openssl.org>
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/20564)
|
||||
|
||||
CVE: CVE-2023-0466
|
||||
Upstream-Status: Backport [https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=0d16b7e99aafc0b4a6d729eec65a411a7e025f0a]
|
||||
Comment: Refreshed first hunk from CHANGE and NEWS
|
||||
Signed-off-by: Omkar Patil <omkar.patil@kpit.com>
|
||||
|
||||
---
|
||||
CHANGES | 5 +++++
|
||||
NEWS | 1 +
|
||||
doc/man3/X509_VERIFY_PARAM_set_flags.pod | 9 +++++++--
|
||||
3 files changed, 13 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/CHANGES b/CHANGES
|
||||
index efccf7838e..b19f1429bb 100644
|
||||
--- a/CHANGES
|
||||
+++ b/CHANGES
|
||||
@@ -9,6 +9,11 @@
|
||||
|
||||
Changes between 1.1.1s and 1.1.1t [7 Feb 2023]
|
||||
|
||||
+ *) Corrected documentation of X509_VERIFY_PARAM_add0_policy() to mention
|
||||
+ that it does not enable policy checking. Thanks to
|
||||
+ David Benjamin for discovering this issue. (CVE-2023-0466)
|
||||
+ [Tomas Mraz]
|
||||
+
|
||||
*) Fixed X.400 address type confusion in X.509 GeneralName.
|
||||
|
||||
There is a type confusion vulnerability relating to X.400 address processing
|
||||
diff --git a/NEWS b/NEWS
|
||||
index 36a9bb6890..62615693fa 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
Major changes between OpenSSL 1.1.1s and OpenSSL 1.1.1t [7 Feb 2023]
|
||||
|
||||
+ o Fixed documentation of X509_VERIFY_PARAM_add0_policy() (CVE-2023-0466)
|
||||
o Fixed X.400 address type confusion in X.509 GeneralName (CVE-2023-0286)
|
||||
o Fixed Use-after-free following BIO_new_NDEF (CVE-2023-0215)
|
||||
o Fixed Double free after calling PEM_read_bio_ex (CVE-2022-4450)
|
||||
diff --git a/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/doc/man3/X509_VERIFY_PARAM_set_flags.pod
|
||||
index f6f304bf7b..aa292f9336 100644
|
||||
--- a/doc/man3/X509_VERIFY_PARAM_set_flags.pod
|
||||
+++ b/doc/man3/X509_VERIFY_PARAM_set_flags.pod
|
||||
@@ -92,8 +92,9 @@ B<trust>.
|
||||
X509_VERIFY_PARAM_set_time() sets the verification time in B<param> to
|
||||
B<t>. Normally the current time is used.
|
||||
|
||||
-X509_VERIFY_PARAM_add0_policy() enables policy checking (it is disabled
|
||||
-by default) and adds B<policy> to the acceptable policy set.
|
||||
+X509_VERIFY_PARAM_add0_policy() adds B<policy> to the acceptable policy set.
|
||||
+Contrary to preexisting documentation of this function it does not enable
|
||||
+policy checking.
|
||||
|
||||
X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled
|
||||
by default) and sets the acceptable policy set to B<policies>. Any existing
|
||||
@@ -377,6 +378,10 @@ and has no effect.
|
||||
|
||||
The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i.
|
||||
|
||||
+The function X509_VERIFY_PARAM_add0_policy() was historically documented as
|
||||
+enabling policy checking however the implementation has never done this.
|
||||
+The documentation was changed to align with the implementation.
|
||||
+
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright 2009-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@@ -18,16 +18,15 @@ SRC_URI = "http://www.openssl.org/source/openssl-${PV}.tar.gz \
|
||||
file://afalg.patch \
|
||||
file://reproducible.patch \
|
||||
file://reproducibility.patch \
|
||||
file://CVE-2023-0464.patch \
|
||||
file://CVE-2023-0465.patch \
|
||||
file://CVE-2023-0466.patch \
|
||||
file://0001-Configure-add-2-missing-key-sorts.patch \
|
||||
file://0001-Configure-do-not-tweak-mips-cflags.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_class-nativesdk = " \
|
||||
file://environment.d-openssl.sh \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b"
|
||||
SRC_URI[sha256sum] = "d6697e2871e77238460402e9362d47d18382b15ef9f246aba6c7bd780d38a6b0"
|
||||
|
||||
inherit lib_package multilib_header multilib_script ptest
|
||||
MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash"
|
||||
@@ -1,6 +1,6 @@
|
||||
SRCBRANCH ?= "release/2.31/master"
|
||||
PV = "2.31+git${SRCPV}"
|
||||
SRCREV_glibc ?= "d4b75594574ab8a9c2c41209cd8c62aac76b5a04"
|
||||
SRCREV_glibc ?= "2d4f26e5cfda682f9ce61444b81533b83f6381af"
|
||||
SRCREV_localedef ?= "cd9f958c4c94a638fa7b2b4e21627364f1a1a655"
|
||||
|
||||
GLIBC_GIT_URI ?= "git://sourceware.org/git/glibc.git"
|
||||
|
||||
@@ -58,7 +58,7 @@ elif targettype == "ssh":
|
||||
user = os.environ.get("SSH_HOST_USER", None)
|
||||
port = os.environ.get("SSH_HOST_PORT", None)
|
||||
|
||||
command = ["ssh", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no"]
|
||||
command = ["ssh", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-o", "LogLevel=quiet"]
|
||||
if port:
|
||||
command += ["-p", str(port)]
|
||||
if not host:
|
||||
|
||||
@@ -24,7 +24,7 @@ IMAGE_FSTYPES = "wic.vmdk"
|
||||
|
||||
inherit core-image setuptools3
|
||||
|
||||
SRCREV ?= "d91c3c124231b6094cd797de5d11110f80153ebb"
|
||||
SRCREV ?= "6d6d43248e003895aa02103b2d239238e97d6167"
|
||||
SRC_URI = "git://git.yoctoproject.org/poky;branch=dunfell \
|
||||
file://Yocto_Build_Appliance.vmx \
|
||||
file://Yocto_Build_Appliance.vmxf \
|
||||
|
||||
342
meta/recipes-core/meta/cve-update-nvd2-native.bb
Normal file
342
meta/recipes-core/meta/cve-update-nvd2-native.bb
Normal file
@@ -0,0 +1,342 @@
|
||||
SUMMARY = "Updates the NVD CVE database"
|
||||
LICENSE = "MIT"
|
||||
|
||||
# Important note:
|
||||
# This product uses the NVD API but is not endorsed or certified by the NVD.
|
||||
|
||||
INHIBIT_DEFAULT_DEPS = "1"
|
||||
|
||||
inherit native
|
||||
|
||||
deltask do_unpack
|
||||
deltask do_patch
|
||||
deltask do_configure
|
||||
deltask do_compile
|
||||
deltask do_install
|
||||
deltask do_populate_sysroot
|
||||
|
||||
NVDCVE_URL ?= "https://services.nvd.nist.gov/rest/json/cves/2.0"
|
||||
|
||||
# If you have a NVD API key (https://nvd.nist.gov/developers/request-an-api-key)
|
||||
# then setting this to get higher rate limits.
|
||||
NVDCVE_API_KEY ?= ""
|
||||
|
||||
# CVE database update interval, in seconds. By default: once a day (24*60*60).
|
||||
# Use 0 to force the update
|
||||
# Use a negative value to skip the update
|
||||
CVE_DB_UPDATE_INTERVAL ?= "86400"
|
||||
|
||||
# Timeout for blocking socket operations, such as the connection attempt.
|
||||
CVE_SOCKET_TIMEOUT ?= "60"
|
||||
|
||||
CVE_DB_TEMP_FILE ?= "${CVE_CHECK_DB_DIR}/temp_nvdcve_2.db"
|
||||
|
||||
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve_2.db"
|
||||
|
||||
python () {
|
||||
if not bb.data.inherits_class("cve-check", d):
|
||||
raise bb.parse.SkipRecipe("Skip recipe when cve-check class is not loaded.")
|
||||
}
|
||||
|
||||
python do_fetch() {
|
||||
"""
|
||||
Update NVD database with API 2.0
|
||||
"""
|
||||
import bb.utils
|
||||
import bb.progress
|
||||
import shutil
|
||||
|
||||
bb.utils.export_proxies(d)
|
||||
|
||||
db_file = d.getVar("CVE_CHECK_DB_FILE")
|
||||
db_dir = os.path.dirname(db_file)
|
||||
db_tmp_file = d.getVar("CVE_DB_TEMP_FILE")
|
||||
|
||||
cleanup_db_download(db_file, db_tmp_file)
|
||||
# By default let's update the whole database (since time 0)
|
||||
database_time = 0
|
||||
|
||||
# The NVD database changes once a day, so no need to update more frequently
|
||||
# Allow the user to force-update
|
||||
try:
|
||||
import time
|
||||
update_interval = int(d.getVar("CVE_DB_UPDATE_INTERVAL"))
|
||||
if update_interval < 0:
|
||||
bb.note("CVE database update skipped")
|
||||
return
|
||||
if time.time() - os.path.getmtime(db_file) < update_interval:
|
||||
bb.note("CVE database recently updated, skipping")
|
||||
return
|
||||
database_time = os.path.getmtime(db_file)
|
||||
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
bb.utils.mkdirhier(db_dir)
|
||||
if os.path.exists(db_file):
|
||||
shutil.copy2(db_file, db_tmp_file)
|
||||
|
||||
if update_db_file(db_tmp_file, d, database_time) == True:
|
||||
# Update downloaded correctly, can swap files
|
||||
shutil.move(db_tmp_file, db_file)
|
||||
else:
|
||||
# Update failed, do not modify the database
|
||||
bb.warn("CVE database update failed")
|
||||
os.remove(db_tmp_file)
|
||||
}
|
||||
|
||||
do_fetch[lockfiles] += "${CVE_CHECK_DB_FILE_LOCK}"
|
||||
do_fetch[file-checksums] = ""
|
||||
do_fetch[vardeps] = ""
|
||||
|
||||
def cleanup_db_download(db_file, db_tmp_file):
|
||||
"""
|
||||
Cleanup the download space from possible failed downloads
|
||||
"""
|
||||
|
||||
# Clean up the updates done on the main file
|
||||
# Remove it only if a journal file exists - it means a complete re-download
|
||||
if os.path.exists("{0}-journal".format(db_file)):
|
||||
# If a journal is present the last update might have been interrupted. In that case,
|
||||
# just wipe any leftovers and force the DB to be recreated.
|
||||
os.remove("{0}-journal".format(db_file))
|
||||
|
||||
if os.path.exists(db_file):
|
||||
os.remove(db_file)
|
||||
|
||||
# Clean-up the temporary file downloads, we can remove both journal
|
||||
# and the temporary database
|
||||
if os.path.exists("{0}-journal".format(db_tmp_file)):
|
||||
# If a journal is present the last update might have been interrupted. In that case,
|
||||
# just wipe any leftovers and force the DB to be recreated.
|
||||
os.remove("{0}-journal".format(db_tmp_file))
|
||||
|
||||
if os.path.exists(db_tmp_file):
|
||||
os.remove(db_tmp_file)
|
||||
|
||||
def nvd_request_next(url, api_key, args):
|
||||
"""
|
||||
Request next part of the NVD dabase
|
||||
"""
|
||||
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import gzip
|
||||
import http
|
||||
import time
|
||||
|
||||
request = urllib.request.Request(url + "?" + urllib.parse.urlencode(args))
|
||||
if api_key:
|
||||
request.add_header("apiKey", api_key)
|
||||
bb.note("Requesting %s" % request.full_url)
|
||||
|
||||
for attempt in range(5):
|
||||
try:
|
||||
r = urllib.request.urlopen(request)
|
||||
|
||||
if (r.headers['content-encoding'] == 'gzip'):
|
||||
buf = r.read()
|
||||
raw_data = gzip.decompress(buf).decode("utf-8")
|
||||
else:
|
||||
raw_data = r.read().decode("utf-8")
|
||||
|
||||
r.close()
|
||||
|
||||
except Exception as e:
|
||||
bb.note("CVE database: received error (%s), retrying" % (e))
|
||||
time.sleep(6)
|
||||
pass
|
||||
else:
|
||||
return raw_data
|
||||
else:
|
||||
# We failed at all attempts
|
||||
return None
|
||||
|
||||
def update_db_file(db_tmp_file, d, database_time):
|
||||
"""
|
||||
Update the given database file
|
||||
"""
|
||||
import bb.utils, bb.progress
|
||||
import datetime
|
||||
import sqlite3
|
||||
import json
|
||||
|
||||
# Connect to database
|
||||
conn = sqlite3.connect(db_tmp_file)
|
||||
initialize_db(conn)
|
||||
|
||||
req_args = {'startIndex' : 0}
|
||||
|
||||
# The maximum range for time is 120 days
|
||||
# Force a complete update if our range is longer
|
||||
if (database_time != 0):
|
||||
database_date = datetime.datetime.fromtimestamp(database_time, tz=datetime.timezone.utc)
|
||||
today_date = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
delta = today_date - database_date
|
||||
if delta.days < 120:
|
||||
bb.note("CVE database: performing partial update")
|
||||
req_args['lastModStartDate'] = database_date.isoformat()
|
||||
req_args['lastModEndDate'] = today_date.isoformat()
|
||||
else:
|
||||
bb.note("CVE database: file too old, forcing a full update")
|
||||
|
||||
with bb.progress.ProgressHandler(d) as ph, open(os.path.join(d.getVar("TMPDIR"), 'cve_check'), 'a') as cve_f:
|
||||
|
||||
bb.note("Updating entries")
|
||||
index = 0
|
||||
url = d.getVar("NVDCVE_URL")
|
||||
api_key = d.getVar("NVDCVE_API_KEY") or None
|
||||
|
||||
while True:
|
||||
req_args['startIndex'] = index
|
||||
raw_data = nvd_request_next(url, api_key, req_args)
|
||||
if raw_data is None:
|
||||
# We haven't managed to download data
|
||||
return False
|
||||
|
||||
data = json.loads(raw_data)
|
||||
|
||||
index = data["startIndex"]
|
||||
total = data["totalResults"]
|
||||
per_page = data["resultsPerPage"]
|
||||
bb.note("Got %d entries" % per_page)
|
||||
for cve in data["vulnerabilities"]:
|
||||
update_db(conn, cve)
|
||||
|
||||
index += per_page
|
||||
ph.update((float(index) / (total+1)) * 100)
|
||||
if index >= total:
|
||||
break
|
||||
|
||||
# Recommended by NVD
|
||||
time.sleep(6)
|
||||
|
||||
# Update success, set the date to cve_check file.
|
||||
cve_f.write('CVE database update : %s\n\n' % datetime.date.today())
|
||||
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return True
|
||||
|
||||
def initialize_db(conn):
|
||||
with conn:
|
||||
c = conn.cursor()
|
||||
|
||||
c.execute("CREATE TABLE IF NOT EXISTS META (YEAR INTEGER UNIQUE, DATE TEXT)")
|
||||
|
||||
c.execute("CREATE TABLE IF NOT EXISTS NVD (ID TEXT UNIQUE, SUMMARY TEXT, \
|
||||
SCOREV2 TEXT, SCOREV3 TEXT, MODIFIED INTEGER, VECTOR TEXT)")
|
||||
|
||||
c.execute("CREATE TABLE IF NOT EXISTS PRODUCTS (ID TEXT, \
|
||||
VENDOR TEXT, PRODUCT TEXT, VERSION_START TEXT, OPERATOR_START TEXT, \
|
||||
VERSION_END TEXT, OPERATOR_END TEXT)")
|
||||
c.execute("CREATE INDEX IF NOT EXISTS PRODUCT_ID_IDX on PRODUCTS(ID);")
|
||||
|
||||
c.close()
|
||||
|
||||
def parse_node_and_insert(conn, node, cveId):
|
||||
|
||||
def cpe_generator():
|
||||
for cpe in node.get('cpeMatch', ()):
|
||||
if not cpe['vulnerable']:
|
||||
return
|
||||
cpe23 = cpe.get('criteria')
|
||||
if not cpe23:
|
||||
return
|
||||
cpe23 = cpe23.split(':')
|
||||
if len(cpe23) < 6:
|
||||
return
|
||||
vendor = cpe23[3]
|
||||
product = cpe23[4]
|
||||
version = cpe23[5]
|
||||
|
||||
if cpe23[6] == '*' or cpe23[6] == '-':
|
||||
version_suffix = ""
|
||||
else:
|
||||
version_suffix = "_" + cpe23[6]
|
||||
|
||||
if version != '*' and version != '-':
|
||||
# Version is defined, this is a '=' match
|
||||
yield [cveId, vendor, product, version + version_suffix, '=', '', '']
|
||||
elif version == '-':
|
||||
# no version information is available
|
||||
yield [cveId, vendor, product, version, '', '', '']
|
||||
else:
|
||||
# Parse start version, end version and operators
|
||||
op_start = ''
|
||||
op_end = ''
|
||||
v_start = ''
|
||||
v_end = ''
|
||||
|
||||
if 'versionStartIncluding' in cpe:
|
||||
op_start = '>='
|
||||
v_start = cpe['versionStartIncluding']
|
||||
|
||||
if 'versionStartExcluding' in cpe:
|
||||
op_start = '>'
|
||||
v_start = cpe['versionStartExcluding']
|
||||
|
||||
if 'versionEndIncluding' in cpe:
|
||||
op_end = '<='
|
||||
v_end = cpe['versionEndIncluding']
|
||||
|
||||
if 'versionEndExcluding' in cpe:
|
||||
op_end = '<'
|
||||
v_end = cpe['versionEndExcluding']
|
||||
|
||||
if op_start or op_end or v_start or v_end:
|
||||
yield [cveId, vendor, product, v_start, op_start, v_end, op_end]
|
||||
else:
|
||||
# This is no version information, expressed differently.
|
||||
# Save processing by representing as -.
|
||||
yield [cveId, vendor, product, '-', '', '', '']
|
||||
|
||||
conn.executemany("insert into PRODUCTS values (?, ?, ?, ?, ?, ?, ?)", cpe_generator()).close()
|
||||
|
||||
def update_db(conn, elt):
|
||||
"""
|
||||
Update a single entry in the on-disk database
|
||||
"""
|
||||
|
||||
accessVector = None
|
||||
cveId = elt['cve']['id']
|
||||
if elt['cve']['vulnStatus'] == "Rejected":
|
||||
return
|
||||
cveDesc = ""
|
||||
for desc in elt['cve']['descriptions']:
|
||||
if desc['lang'] == 'en':
|
||||
cveDesc = desc['value']
|
||||
date = elt['cve']['lastModified']
|
||||
try:
|
||||
accessVector = elt['cve']['metrics']['cvssMetricV2'][0]['cvssData']['accessVector']
|
||||
cvssv2 = elt['cve']['metrics']['cvssMetricV2'][0]['cvssData']['baseScore']
|
||||
except KeyError:
|
||||
cvssv2 = 0.0
|
||||
cvssv3 = None
|
||||
try:
|
||||
accessVector = accessVector or elt['cve']['metrics']['cvssMetricV30'][0]['cvssData']['attackVector']
|
||||
cvssv3 = elt['cve']['metrics']['cvssMetricV30'][0]['cvssData']['baseScore']
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
accessVector = accessVector or elt['cve']['metrics']['cvssMetricV31'][0]['cvssData']['attackVector']
|
||||
cvssv3 = cvssv3 or elt['cve']['metrics']['cvssMetricV31'][0]['cvssData']['baseScore']
|
||||
except KeyError:
|
||||
pass
|
||||
accessVector = accessVector or "UNKNOWN"
|
||||
cvssv3 = cvssv3 or 0.0
|
||||
|
||||
conn.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?)",
|
||||
[cveId, cveDesc, cvssv2, cvssv3, date, accessVector]).close()
|
||||
|
||||
try:
|
||||
for config in elt['cve']['configurations']:
|
||||
# This is suboptimal as it doesn't handle AND/OR and negate, but is better than nothing
|
||||
for node in config["nodes"]:
|
||||
parse_node_and_insert(conn, node, cveId)
|
||||
except KeyError:
|
||||
bb.note("CVE %s has no configurations" % cveId)
|
||||
|
||||
do_fetch[nostamp] = "1"
|
||||
|
||||
EXCLUDE_FROM_WORLD = "1"
|
||||
@@ -182,12 +182,14 @@ class SystemdUnit():
|
||||
|
||||
raise SystemdUnitNotFoundError(self.root, unit)
|
||||
|
||||
def _process_deps(self, config, service, location, prop, dirstem):
|
||||
def _process_deps(self, config, service, location, prop, dirstem, instance):
|
||||
systemdir = self.root / SYSCONFDIR / "systemd" / "system"
|
||||
|
||||
target = ROOT / location.relative_to(self.root)
|
||||
try:
|
||||
for dependent in config.get('Install', prop):
|
||||
# expand any %i to instance (ignoring escape sequence %%)
|
||||
dependent = re.sub("([^%](%%)*)%i", "\\g<1>{}".format(instance), dependent)
|
||||
wants = systemdir / "{}.{}".format(dependent, dirstem) / service
|
||||
add_link(wants, target)
|
||||
|
||||
@@ -227,8 +229,8 @@ class SystemdUnit():
|
||||
else:
|
||||
service = self.unit
|
||||
|
||||
self._process_deps(config, service, path, 'WantedBy', 'wants')
|
||||
self._process_deps(config, service, path, 'RequiredBy', 'requires')
|
||||
self._process_deps(config, service, path, 'WantedBy', 'wants', instance)
|
||||
self._process_deps(config, service, path, 'RequiredBy', 'requires', instance)
|
||||
|
||||
try:
|
||||
for also in config.get('Install', 'Also'):
|
||||
|
||||
@@ -12,10 +12,7 @@ set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY )
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX "$ENV{OE_CMAKE_FIND_LIBRARY_CUSTOM_LIB_SUFFIX}")
|
||||
|
||||
# Set CMAKE_SYSTEM_PROCESSOR from the sysroot name (assuming processor-distro-os).
|
||||
if ($ENV{SDKTARGETSYSROOT} MATCHES "/sysroots/([a-zA-Z0-9_-]+)-.+-.+")
|
||||
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_MATCH_1})
|
||||
endif()
|
||||
set( CMAKE_SYSTEM_PROCESSOR $ENV{OECORE_TARGET_ARCH} )
|
||||
|
||||
# Include the toolchain configuration subscripts
|
||||
file( GLOB toolchain_config_files "${CMAKE_TOOLCHAIN_FILE}.d/*.cmake" )
|
||||
|
||||
@@ -0,0 +1,236 @@
|
||||
From 24def311c6168d0dfb7c5f0f183b72b709c49265 Mon Sep 17 00:00:00 2001
|
||||
From: Jean Delvare <jdelvare@suse.de>
|
||||
Date: Mon, 20 Feb 2023 14:53:21 +0100
|
||||
Subject: [PATCH] dmidecode: Split table fetching from decoding
|
||||
|
||||
Clean up function dmi_table so that it does only one thing:
|
||||
* dmi_table() is renamed to dmi_table_get(). It now retrieves the
|
||||
DMI table, but does not process it any longer.
|
||||
* Decoding or dumping the table is now done in smbios3_decode(),
|
||||
smbios_decode() and legacy_decode().
|
||||
No functional change.
|
||||
|
||||
A side effect of this change is that writing the header and body of
|
||||
dump files is now done in a single location. This is required to
|
||||
further consolidate the writing of dump files.
|
||||
|
||||
CVE-ID: CVE-2023-30630
|
||||
Upstream-Status: Backport [https://git.savannah.nongnu.org/cgit/dmidecode.git/commit/?id=39b2dd7b6ab7]
|
||||
|
||||
Backport Changes:
|
||||
- In the file dmidecode.c, the commit [dd593d2] in v3.3 introduces
|
||||
pr_info(). This is backported to printf() as per v3.2.
|
||||
|
||||
Signed-off-by: Jean Delvare <jdelvare@suse.de>
|
||||
Reviewed-by: Jerry Hoemann <jerry.hoemann@hpe.com>
|
||||
(cherry picked from commit 39b2dd7b6ab719b920e96ed832cfb4bdd664e808)
|
||||
Signed-off-by: Dhairya Nagodra <dnagodra@cisco.com>
|
||||
---
|
||||
dmidecode.c | 86 ++++++++++++++++++++++++++++++++++++++---------------
|
||||
1 file changed, 62 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/dmidecode.c b/dmidecode.c
|
||||
index a3e9d6c..d6eedd1 100644
|
||||
--- a/dmidecode.c
|
||||
+++ b/dmidecode.c
|
||||
@@ -5211,8 +5211,9 @@ static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
|
||||
}
|
||||
}
|
||||
|
||||
-static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem,
|
||||
- u32 flags)
|
||||
+/* Allocates a buffer for the table, must be freed by the caller */
|
||||
+static u8 *dmi_table_get(off_t base, u32 *len, u16 num, u32 ver,
|
||||
+ const char *devmem, u32 flags)
|
||||
{
|
||||
u8 *buf;
|
||||
|
||||
@@ -5231,7 +5232,7 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem,
|
||||
{
|
||||
if (num)
|
||||
printf("%u structures occupying %u bytes.\n",
|
||||
- num, len);
|
||||
+ num, *len);
|
||||
if (!(opt.flags & FLAG_FROM_DUMP))
|
||||
printf("Table at 0x%08llX.\n",
|
||||
(unsigned long long)base);
|
||||
@@ -5249,19 +5250,19 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem,
|
||||
* would be the result of the kernel truncating the table on
|
||||
* parse error.
|
||||
*/
|
||||
- size_t size = len;
|
||||
+ size_t size = *len;
|
||||
buf = read_file(flags & FLAG_NO_FILE_OFFSET ? 0 : base,
|
||||
&size, devmem);
|
||||
- if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)len)
|
||||
+ if (!(opt.flags & FLAG_QUIET) && num && size != (size_t)*len)
|
||||
{
|
||||
fprintf(stderr, "Wrong DMI structures length: %u bytes "
|
||||
"announced, only %lu bytes available.\n",
|
||||
- len, (unsigned long)size);
|
||||
+ *len, (unsigned long)size);
|
||||
}
|
||||
- len = size;
|
||||
+ *len = size;
|
||||
}
|
||||
else
|
||||
- buf = mem_chunk(base, len, devmem);
|
||||
+ buf = mem_chunk(base, *len, devmem);
|
||||
|
||||
if (buf == NULL)
|
||||
{
|
||||
@@ -5271,15 +5272,9 @@ static void dmi_table(off_t base, u32 len, u16 num, u32 ver, const char *devmem,
|
||||
fprintf(stderr,
|
||||
"Try compiling dmidecode with -DUSE_MMAP.\n");
|
||||
#endif
|
||||
- return;
|
||||
}
|
||||
|
||||
- if (opt.flags & FLAG_DUMP_BIN)
|
||||
- dmi_table_dump(buf, len);
|
||||
- else
|
||||
- dmi_table_decode(buf, len, num, ver >> 8, flags);
|
||||
-
|
||||
- free(buf);
|
||||
+ return buf;
|
||||
}
|
||||
|
||||
|
||||
@@ -5314,8 +5309,9 @@ static void overwrite_smbios3_address(u8 *buf)
|
||||
|
||||
static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
{
|
||||
- u32 ver;
|
||||
+ u32 ver, len;
|
||||
u64 offset;
|
||||
+ u8 *table;
|
||||
|
||||
/* Don't let checksum run beyond the buffer */
|
||||
if (buf[0x06] > 0x20)
|
||||
@@ -5341,8 +5337,12 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- dmi_table(((off_t)offset.h << 32) | offset.l,
|
||||
- DWORD(buf + 0x0C), 0, ver, devmem, flags | FLAG_STOP_AT_EOT);
|
||||
+ /* Maximum length, may get trimmed */
|
||||
+ len = DWORD(buf + 0x0C);
|
||||
+ table = dmi_table_get(((off_t)offset.h << 32) | offset.l, &len, 0, ver,
|
||||
+ devmem, flags | FLAG_STOP_AT_EOT);
|
||||
+ if (table == NULL)
|
||||
+ return 1;
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
{
|
||||
@@ -5351,18 +5351,28 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
memcpy(crafted, buf, 32);
|
||||
overwrite_smbios3_address(crafted);
|
||||
|
||||
+ dmi_table_dump(table, len);
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# Writing %d bytes to %s.\n", crafted[0x06],
|
||||
opt.dumpfile);
|
||||
write_dump(0, crafted[0x06], crafted, opt.dumpfile, 1);
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ dmi_table_decode(table, len, 0, ver >> 8,
|
||||
+ flags | FLAG_STOP_AT_EOT);
|
||||
+ }
|
||||
+
|
||||
+ free(table);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
{
|
||||
- u16 ver;
|
||||
+ u16 ver, num;
|
||||
+ u32 len;
|
||||
+ u8 *table;
|
||||
|
||||
/* Don't let checksum run beyond the buffer */
|
||||
if (buf[0x05] > 0x20)
|
||||
@@ -5402,8 +5412,13 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
printf("SMBIOS %u.%u present.\n",
|
||||
ver >> 8, ver & 0xFF);
|
||||
|
||||
- dmi_table(DWORD(buf + 0x18), WORD(buf + 0x16), WORD(buf + 0x1C),
|
||||
- ver << 8, devmem, flags);
|
||||
+ /* Maximum length, may get trimmed */
|
||||
+ len = WORD(buf + 0x16);
|
||||
+ num = WORD(buf + 0x1C);
|
||||
+ table = dmi_table_get(DWORD(buf + 0x18), &len, num, ver << 8,
|
||||
+ devmem, flags);
|
||||
+ if (table == NULL)
|
||||
+ return 1;
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
{
|
||||
@@ -5412,27 +5427,43 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
memcpy(crafted, buf, 32);
|
||||
overwrite_dmi_address(crafted + 0x10);
|
||||
|
||||
+ dmi_table_dump(table, len);
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# Writing %d bytes to %s.\n", crafted[0x05],
|
||||
opt.dumpfile);
|
||||
write_dump(0, crafted[0x05], crafted, opt.dumpfile, 1);
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ dmi_table_decode(table, len, num, ver, flags);
|
||||
+ }
|
||||
+
|
||||
+ free(table);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int legacy_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
{
|
||||
+ u16 ver, num;
|
||||
+ u32 len;
|
||||
+ u8 *table;
|
||||
+
|
||||
if (!checksum(buf, 0x0F))
|
||||
return 0;
|
||||
|
||||
+ ver = ((buf[0x0E] & 0xF0) << 4) + (buf[0x0E] & 0x0F);
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("Legacy DMI %u.%u present.\n",
|
||||
buf[0x0E] >> 4, buf[0x0E] & 0x0F);
|
||||
|
||||
- dmi_table(DWORD(buf + 0x08), WORD(buf + 0x06), WORD(buf + 0x0C),
|
||||
- ((buf[0x0E] & 0xF0) << 12) + ((buf[0x0E] & 0x0F) << 8),
|
||||
- devmem, flags);
|
||||
+ /* Maximum length, may get trimmed */
|
||||
+ len = WORD(buf + 0x06);
|
||||
+ num = WORD(buf + 0x0C);
|
||||
+ table = dmi_table_get(DWORD(buf + 0x08), &len, num, ver << 8,
|
||||
+ devmem, flags);
|
||||
+ if (table == NULL)
|
||||
+ return 1;
|
||||
|
||||
if (opt.flags & FLAG_DUMP_BIN)
|
||||
{
|
||||
@@ -5441,11 +5472,18 @@ static int legacy_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
memcpy(crafted, buf, 16);
|
||||
overwrite_dmi_address(crafted);
|
||||
|
||||
+ dmi_table_dump(table, len);
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
printf("# Writing %d bytes to %s.\n", 0x0F,
|
||||
opt.dumpfile);
|
||||
write_dump(0, 0x0F, crafted, opt.dumpfile, 1);
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ dmi_table_decode(table, len, num, ver, flags);
|
||||
+ }
|
||||
+
|
||||
+ free(table);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
From 58e8a07b1aef0e53af1642b30248255e53e42790 Mon Sep 17 00:00:00 2001
|
||||
From: Jean Delvare <jdelvare@suse.de>
|
||||
Date: Mon, 20 Feb 2023 14:53:25 +0100
|
||||
Subject: [PATCH] dmidecode: Write the whole dump file at once
|
||||
|
||||
When option --dump-bin is used, write the whole dump file at once,
|
||||
instead of opening and closing the file separately for the table
|
||||
and then for the entry point.
|
||||
|
||||
As the file writing function is no longer generic, it gets moved
|
||||
from util.c to dmidecode.c.
|
||||
|
||||
One minor functional change resulting from the new implementation is
|
||||
that the entry point is written first now, so the messages printed
|
||||
are swapped.
|
||||
|
||||
CVE: CVE-2023-30630
|
||||
Upstream-Status: Backport [https://git.savannah.nongnu.org/cgit/dmidecode.git/commit/?id=d8cfbc808f38]
|
||||
|
||||
Backport Changes:
|
||||
- In the file dmidecode.c, the commit [2241f1d] in v3.3 introduces
|
||||
pr_info(). This is backported to printf() as per v3.2.
|
||||
|
||||
Signed-off-by: Jean Delvare <jdelvare@suse.de>
|
||||
Reviewed-by: Jerry Hoemann <jerry.hoemann@hpe.com>
|
||||
(cherry picked from commit d8cfbc808f387e87091c25e7d5b8c2bb348bb206)
|
||||
Signed-off-by: Dhairya Nagodra <dnagodra@cisco.com>
|
||||
|
||||
---
|
||||
dmidecode.c | 69 +++++++++++++++++++++++++++++++++++++++--------------
|
||||
util.c | 40 -------------------------------
|
||||
util.h | 1 -
|
||||
3 files changed, 51 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/dmidecode.c b/dmidecode.c
|
||||
index d6eedd1..b91e53b 100644
|
||||
--- a/dmidecode.c
|
||||
+++ b/dmidecode.c
|
||||
@@ -5094,11 +5094,56 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver
|
||||
}
|
||||
}
|
||||
|
||||
-static void dmi_table_dump(const u8 *buf, u32 len)
|
||||
+static int dmi_table_dump(const u8 *ep, u32 ep_len, const u8 *table,
|
||||
+ u32 table_len)
|
||||
{
|
||||
+ FILE *f;
|
||||
+
|
||||
+ f = fopen(opt.dumpfile, "wb");
|
||||
+ if (!f)
|
||||
+ {
|
||||
+ fprintf(stderr, "%s: ", opt.dumpfile);
|
||||
+ perror("fopen");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!(opt.flags & FLAG_QUIET))
|
||||
+ printf("# Writing %d bytes to %s.\n", ep_len, opt.dumpfile);
|
||||
+ if (fwrite(ep, ep_len, 1, f) != 1)
|
||||
+ {
|
||||
+ fprintf(stderr, "%s: ", opt.dumpfile);
|
||||
+ perror("fwrite");
|
||||
+ goto err_close;
|
||||
+ }
|
||||
+
|
||||
+ if (fseek(f, 32, SEEK_SET) != 0)
|
||||
+ {
|
||||
+ fprintf(stderr, "%s: ", opt.dumpfile);
|
||||
+ perror("fseek");
|
||||
+ goto err_close;
|
||||
+ }
|
||||
+
|
||||
if (!(opt.flags & FLAG_QUIET))
|
||||
- printf("# Writing %d bytes to %s.\n", len, opt.dumpfile);
|
||||
- write_dump(32, len, buf, opt.dumpfile, 0);
|
||||
+ printf("# Writing %d bytes to %s.\n", table_len, opt.dumpfile);
|
||||
+ if (fwrite(table, table_len, 1, f) != 1)
|
||||
+ {
|
||||
+ fprintf(stderr, "%s: ", opt.dumpfile);
|
||||
+ perror("fwrite");
|
||||
+ goto err_close;
|
||||
+ }
|
||||
+
|
||||
+ if (fclose(f))
|
||||
+ {
|
||||
+ fprintf(stderr, "%s: ", opt.dumpfile);
|
||||
+ perror("fclose");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_close:
|
||||
+ fclose(f);
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
static void dmi_table_decode(u8 *buf, u32 len, u16 num, u16 ver, u32 flags)
|
||||
@@ -5351,11 +5396,7 @@ static int smbios3_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
memcpy(crafted, buf, 32);
|
||||
overwrite_smbios3_address(crafted);
|
||||
|
||||
- dmi_table_dump(table, len);
|
||||
- if (!(opt.flags & FLAG_QUIET))
|
||||
- printf("# Writing %d bytes to %s.\n", crafted[0x06],
|
||||
- opt.dumpfile);
|
||||
- write_dump(0, crafted[0x06], crafted, opt.dumpfile, 1);
|
||||
+ dmi_table_dump(crafted, crafted[0x06], table, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5427,11 +5468,7 @@ static int smbios_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
memcpy(crafted, buf, 32);
|
||||
overwrite_dmi_address(crafted + 0x10);
|
||||
|
||||
- dmi_table_dump(table, len);
|
||||
- if (!(opt.flags & FLAG_QUIET))
|
||||
- printf("# Writing %d bytes to %s.\n", crafted[0x05],
|
||||
- opt.dumpfile);
|
||||
- write_dump(0, crafted[0x05], crafted, opt.dumpfile, 1);
|
||||
+ dmi_table_dump(crafted, crafted[0x05], table, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5472,11 +5509,7 @@ static int legacy_decode(u8 *buf, const char *devmem, u32 flags)
|
||||
memcpy(crafted, buf, 16);
|
||||
overwrite_dmi_address(crafted);
|
||||
|
||||
- dmi_table_dump(table, len);
|
||||
- if (!(opt.flags & FLAG_QUIET))
|
||||
- printf("# Writing %d bytes to %s.\n", 0x0F,
|
||||
- opt.dumpfile);
|
||||
- write_dump(0, 0x0F, crafted, opt.dumpfile, 1);
|
||||
+ dmi_table_dump(crafted, 0x0F, table, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
diff --git a/util.c b/util.c
|
||||
index eeffdae..2e1931c 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -247,46 +247,6 @@ out:
|
||||
return p;
|
||||
}
|
||||
|
||||
-int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add)
|
||||
-{
|
||||
- FILE *f;
|
||||
-
|
||||
- f = fopen(dumpfile, add ? "r+b" : "wb");
|
||||
- if (!f)
|
||||
- {
|
||||
- fprintf(stderr, "%s: ", dumpfile);
|
||||
- perror("fopen");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (fseek(f, base, SEEK_SET) != 0)
|
||||
- {
|
||||
- fprintf(stderr, "%s: ", dumpfile);
|
||||
- perror("fseek");
|
||||
- goto err_close;
|
||||
- }
|
||||
-
|
||||
- if (fwrite(data, len, 1, f) != 1)
|
||||
- {
|
||||
- fprintf(stderr, "%s: ", dumpfile);
|
||||
- perror("fwrite");
|
||||
- goto err_close;
|
||||
- }
|
||||
-
|
||||
- if (fclose(f))
|
||||
- {
|
||||
- fprintf(stderr, "%s: ", dumpfile);
|
||||
- perror("fclose");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-
|
||||
-err_close:
|
||||
- fclose(f);
|
||||
- return -1;
|
||||
-}
|
||||
-
|
||||
/* Returns end - start + 1, assuming start < end */
|
||||
u64 u64_range(u64 start, u64 end)
|
||||
{
|
||||
diff --git a/util.h b/util.h
|
||||
index 3094cf8..ef24eb9 100644
|
||||
--- a/util.h
|
||||
+++ b/util.h
|
||||
@@ -27,5 +27,4 @@
|
||||
int checksum(const u8 *buf, size_t len);
|
||||
void *read_file(off_t base, size_t *len, const char *filename);
|
||||
void *mem_chunk(off_t base, size_t len, const char *devmem);
|
||||
-int write_dump(size_t base, size_t len, const void *data, const char *dumpfile, int add);
|
||||
u64 u64_range(u64 start, u64 end);
|
||||
@@ -0,0 +1,62 @@
|
||||
From b7dacccff32294ea522df32a9391d0218e7600ea Mon Sep 17 00:00:00 2001
|
||||
From: Jean Delvare <jdelvare@suse.de>
|
||||
Date: Mon, 20 Feb 2023 14:53:31 +0100
|
||||
Subject: [PATCH] dmidecode: Do not let --dump-bin overwrite an existing file
|
||||
|
||||
Make sure that the file passed to option --dump-bin does not already
|
||||
exist. In practice, it is rather unlikely that an honest user would
|
||||
want to overwrite an existing dump file, while this possibility
|
||||
could be used by a rogue user to corrupt a system file.
|
||||
|
||||
CVE: CVE-2023-30630
|
||||
Upstream-Status: Backport [https://git.savannah.nongnu.org/cgit/dmidecode.git/commit/?id=6ca381c1247c]
|
||||
|
||||
Backport Changes:
|
||||
- Ignored changes in man/dmidecode.8 file.
|
||||
|
||||
Signed-off-by: Jean Delvare <jdelvare@suse.de>
|
||||
Reviewed-by: Jerry Hoemann <jerry.hoemann@hpe.com>
|
||||
(cherry picked from commit 6ca381c1247c81f74e1ca4e7706f70bdda72e6f2)
|
||||
Signed-off-by: Dhairya Nagodra <dnagodra@cisco.com>
|
||||
|
||||
---
|
||||
dmidecode.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dmidecode.c b/dmidecode.c
|
||||
index b91e53b..846d9a1 100644
|
||||
--- a/dmidecode.c
|
||||
+++ b/dmidecode.c
|
||||
@@ -60,6 +60,7 @@
|
||||
* https://www.dmtf.org/sites/default/files/DSP0270_1.0.1.pdf
|
||||
*/
|
||||
|
||||
+#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
@@ -5097,13 +5098,22 @@ static void dmi_table_string(const struct dmi_header *h, const u8 *data, u16 ver
|
||||
static int dmi_table_dump(const u8 *ep, u32 ep_len, const u8 *table,
|
||||
u32 table_len)
|
||||
{
|
||||
+ int fd;
|
||||
FILE *f;
|
||||
|
||||
- f = fopen(opt.dumpfile, "wb");
|
||||
+ fd = open(opt.dumpfile, O_WRONLY|O_CREAT|O_EXCL, 0666);
|
||||
+ if (fd == -1)
|
||||
+ {
|
||||
+ fprintf(stderr, "%s: ", opt.dumpfile);
|
||||
+ perror("open");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ f = fdopen(fd, "wb");
|
||||
if (!f)
|
||||
{
|
||||
fprintf(stderr, "%s: ", opt.dumpfile);
|
||||
- perror("fopen");
|
||||
+ perror("fdopen");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263"
|
||||
|
||||
SRC_URI = "${SAVANNAH_NONGNU_MIRROR}/dmidecode/${BP}.tar.xz \
|
||||
file://0001-Committing-changes-from-do_unpack_extra.patch \
|
||||
file://CVE-2023-30630-dependent_p1.patch \
|
||||
file://CVE-2023-30630-dependent_p2.patch \
|
||||
file://CVE-2023-30630.patch \
|
||||
"
|
||||
|
||||
COMPATIBLE_HOST = "(i.86|x86_64|aarch64|arm|powerpc|powerpc64).*-linux"
|
||||
|
||||
@@ -34,6 +34,7 @@ SRC_URI = "https://sourceware.org/elfutils/ftp/${PV}/${BP}.tar.bz2 \
|
||||
file://0001-ppc_initreg.c-Incliude-asm-ptrace.h-for-pt_regs-defi.patch \
|
||||
file://run-ptest \
|
||||
file://ptest.patch \
|
||||
file://CVE-2021-33294.patch \
|
||||
"
|
||||
SRC_URI_append_libc-musl = " \
|
||||
file://0001-musl-obstack-fts.patch \
|
||||
|
||||
72
meta/recipes-devtools/elfutils/files/CVE-2021-33294.patch
Normal file
72
meta/recipes-devtools/elfutils/files/CVE-2021-33294.patch
Normal file
@@ -0,0 +1,72 @@
|
||||
From 480b6fa3662ba8ffeee274bf0d37423413c01e55 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Wielaard <mark@klomp.org>
|
||||
Date: Wed, 3 Mar 2021 21:40:53 +0100
|
||||
Subject: [PATCH] readelf: Sanity check verneed and verdef offsets in handle_symtab.
|
||||
|
||||
We are going through vna_next, vn_next and vd_next in a while loop.
|
||||
Make sure that all offsets are sane. We don't want things to wrap
|
||||
around so we go in cycles.
|
||||
|
||||
https://sourceware.org/bugzilla/show_bug.cgi?id=27501
|
||||
|
||||
Signed-off-by: Mark Wielaard <mark@klomp.org>
|
||||
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=elfutils.git;a=commit;h=480b6fa3662ba8ffeee274bf0d37423413c01e55]
|
||||
CVE: CVE-2021-33294
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/ChangeLog | 5 +++++
|
||||
src/readelf.c | 10 +++++++++-
|
||||
2 files changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/ChangeLog b/src/ChangeLog
|
||||
index 6af977e..f0d9e39 100644
|
||||
--- a/src/ChangeLog
|
||||
+++ b/src/ChangeLog
|
||||
@@ -1,3 +1,8 @@
|
||||
+2021-03-03 Mark Wielaard <mark@klomp.org>
|
||||
+
|
||||
+ * readelf.c (handle_symtab): Sanity check verneed vna_next,
|
||||
+ vn_next and verdef vd_next offsets.
|
||||
+
|
||||
2019-11-26 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
* Makefile.am (BUILD_STATIC): Add libraries needed for libdw.
|
||||
diff --git a/src/readelf.c b/src/readelf.c
|
||||
index 5994615..ab7a1c1 100644
|
||||
--- a/src/readelf.c
|
||||
+++ b/src/readelf.c
|
||||
@@ -2550,7 +2550,9 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
&vernaux_mem);
|
||||
while (vernaux != NULL
|
||||
&& vernaux->vna_other != *versym
|
||||
- && vernaux->vna_next != 0)
|
||||
+ && vernaux->vna_next != 0
|
||||
+ && (verneed_data->d_size - vna_offset
|
||||
+ >= vernaux->vna_next))
|
||||
{
|
||||
/* Update the offset. */
|
||||
vna_offset += vernaux->vna_next;
|
||||
@@ -2567,6 +2569,9 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
/* Found it. */
|
||||
break;
|
||||
|
||||
+ if (verneed_data->d_size - vn_offset < verneed->vn_next)
|
||||
+ break;
|
||||
+
|
||||
vn_offset += verneed->vn_next;
|
||||
verneed = (verneed->vn_next == 0
|
||||
? NULL
|
||||
@@ -2602,6 +2607,9 @@ handle_symtab (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr)
|
||||
/* Found the definition. */
|
||||
break;
|
||||
|
||||
+ if (verdef_data->d_size - vd_offset < verdef->vd_next)
|
||||
+ break;
|
||||
+
|
||||
vd_offset += verdef->vd_next;
|
||||
verdef = (verdef->vd_next == 0
|
||||
? NULL
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -75,7 +75,7 @@ S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}"
|
||||
SRC_URI[sha256sum] = "27769f64ef1d4cd5e2be8682c0c93f9887983e6cfd1a927ce5a0a2915a95cf8f"
|
||||
# For dev release snapshotting
|
||||
#S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/official-gcc-${RELEASE}"
|
||||
#B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}"
|
||||
B = "${WORKDIR}/gcc-${PV}/build.${HOST_SYS}.${TARGET_SYS}"
|
||||
|
||||
# Language Overrides
|
||||
FORTRAN = ""
|
||||
|
||||
@@ -63,6 +63,13 @@ SRC_URI += "\
|
||||
file://CVE-2023-24538-3.patch \
|
||||
file://CVE-2023-24539.patch \
|
||||
file://CVE-2023-24540.patch \
|
||||
file://CVE-2023-29405-1.patch \
|
||||
file://CVE-2023-29405-2.patch \
|
||||
file://CVE-2023-29402.patch \
|
||||
file://CVE-2023-29404.patch \
|
||||
file://CVE-2023-29400.patch \
|
||||
file://CVE-2023-29406.patch \
|
||||
file://CVE-2023-29409.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch"
|
||||
|
||||
94
meta/recipes-devtools/go/go-1.14/CVE-2023-29400.patch
Normal file
94
meta/recipes-devtools/go/go-1.14/CVE-2023-29400.patch
Normal file
@@ -0,0 +1,94 @@
|
||||
From 0d347544cbca0f42b160424f6bc2458ebcc7b3fc Mon Sep 17 00:00:00 2001
|
||||
From: Roland Shoemaker <bracewell@google.com>
|
||||
Date: Thu, 13 Apr 2023 14:01:50 -0700
|
||||
Subject: [PATCH] html/template: emit filterFailsafe for empty unquoted attr
|
||||
value
|
||||
|
||||
An unquoted action used as an attribute value can result in unsafe
|
||||
behavior if it is empty, as HTML normalization will result in unexpected
|
||||
attributes, and may allow attribute injection. If executing a template
|
||||
results in a empty unquoted attribute value, emit filterFailsafe
|
||||
instead.
|
||||
|
||||
Thanks to Juho Nurminen of Mattermost for reporting this issue.
|
||||
|
||||
Fixes #59722
|
||||
Fixes CVE-2023-29400
|
||||
|
||||
Change-Id: Ia38d1b536ae2b4af5323a6c6d861e3c057c2570a
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1826631
|
||||
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/491617
|
||||
Run-TryBot: Carlos Amedee <carlos@golang.org>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
|
||||
Upstream-Status: Backport from [https://github.com/golang/go/commit/0d347544cbca0f42b160424f6bc2458ebcc7b3fc]
|
||||
CVE: CVE-2023-29400
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
---
|
||||
src/html/template/escape.go | 5 ++---
|
||||
src/html/template/escape_test.go | 15 +++++++++++++++
|
||||
src/html/template/html.go | 3 +++
|
||||
3 files changed, 20 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/html/template/escape.go b/src/html/template/escape.go
|
||||
index 4ba1d6b31897e..a62ef159f0dcd 100644
|
||||
--- a/src/html/template/escape.go
|
||||
+++ b/src/html/template/escape.go
|
||||
@@ -382,9 +382,8 @@ func normalizeEscFn(e string) string {
|
||||
// for all x.
|
||||
var redundantFuncs = map[string]map[string]bool{
|
||||
"_html_template_commentescaper": {
|
||||
- "_html_template_attrescaper": true,
|
||||
- "_html_template_nospaceescaper": true,
|
||||
- "_html_template_htmlescaper": true,
|
||||
+ "_html_template_attrescaper": true,
|
||||
+ "_html_template_htmlescaper": true,
|
||||
},
|
||||
"_html_template_cssescaper": {
|
||||
"_html_template_attrescaper": true,
|
||||
diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
|
||||
index 3dd212bac9406..f8b2b448f2dfa 100644
|
||||
--- a/src/html/template/escape_test.go
|
||||
+++ b/src/html/template/escape_test.go
|
||||
@@ -678,6 +678,21 @@ func TestEscape(t *testing.T) {
|
||||
`<img srcset={{",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"}}>`,
|
||||
`<img srcset=,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,>`,
|
||||
},
|
||||
+ {
|
||||
+ "unquoted empty attribute value (plaintext)",
|
||||
+ "<p name={{.U}}>",
|
||||
+ "<p name=ZgotmplZ>",
|
||||
+ },
|
||||
+ {
|
||||
+ "unquoted empty attribute value (url)",
|
||||
+ "<p href={{.U}}>",
|
||||
+ "<p href=ZgotmplZ>",
|
||||
+ },
|
||||
+ {
|
||||
+ "quoted empty attribute value",
|
||||
+ "<p name=\"{{.U}}\">",
|
||||
+ "<p name=\"\">",
|
||||
+ },
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
diff --git a/src/html/template/html.go b/src/html/template/html.go
|
||||
index bcca0b51a0ef9..a181699a5bda8 100644
|
||||
--- a/src/html/template/html.go
|
||||
+++ b/src/html/template/html.go
|
||||
@@ -14,6 +14,9 @@ import (
|
||||
// htmlNospaceEscaper escapes for inclusion in unquoted attribute values.
|
||||
func htmlNospaceEscaper(args ...interface{}) string {
|
||||
s, t := stringify(args...)
|
||||
+ if s == "" {
|
||||
+ return filterFailsafe
|
||||
+ }
|
||||
if t == contentTypeHTML {
|
||||
return htmlReplacer(stripTags(s), htmlNospaceNormReplacementTable, false)
|
||||
}
|
||||
|
||||
201
meta/recipes-devtools/go/go-1.14/CVE-2023-29402.patch
Normal file
201
meta/recipes-devtools/go/go-1.14/CVE-2023-29402.patch
Normal file
@@ -0,0 +1,201 @@
|
||||
rom c160b49b6d328c86bd76ca2fff9009a71347333f Mon Sep 17 00:00:00 2001
|
||||
From: "Bryan C. Mills" <bcmills@google.com>
|
||||
Date: Fri, 12 May 2023 14:15:16 -0400
|
||||
Subject: [PATCH] [release-branch.go1.19] cmd/go: disallow package directories
|
||||
containing newlines
|
||||
|
||||
Directory or file paths containing newlines may cause tools (such as
|
||||
cmd/cgo) that emit "//line" or "#line" -directives to write part of
|
||||
the path into non-comment lines in generated source code. If those
|
||||
lines contain valid Go code, it may be injected into the resulting
|
||||
binary.
|
||||
|
||||
(Note that Go import paths and file paths within module zip files
|
||||
already could not contain newlines.)
|
||||
|
||||
Thanks to Juho Nurminen of Mattermost for reporting this issue.
|
||||
|
||||
Updates #60167.
|
||||
Fixes #60515.
|
||||
Fixes CVE-2023-29402.
|
||||
|
||||
Change-Id: If55d0400c02beb7a5da5eceac60f1abeac99f064
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1882606
|
||||
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
||||
Reviewed-by: Russ Cox <rsc@google.com>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
(cherry picked from commit 41f9046495564fc728d6f98384ab7276450ac7e2)
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902229
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904343
|
||||
Reviewed-by: Michael Knyszek <mknyszek@google.com>
|
||||
Reviewed-by: Bryan Mills <bcmills@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/501218
|
||||
Run-TryBot: David Chase <drchase@google.com>
|
||||
Auto-Submit: Michael Knyszek <mknyszek@google.com>
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/c160b49b6d328c86bd76ca2fff9009a71347333f]
|
||||
CVE: CVE-2023-29402
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
src/cmd/go/internal/load/pkg.go | 4 +
|
||||
src/cmd/go/internal/work/exec.go | 6 ++
|
||||
src/cmd/go/script_test.go | 1 +
|
||||
.../go/testdata/script/build_cwd_newline.txt | 100 ++++++++++++++++++
|
||||
4 files changed, 111 insertions(+)
|
||||
create mode 100644 src/cmd/go/testdata/script/build_cwd_newline.txt
|
||||
|
||||
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
|
||||
index 369a79b..d2b63b0 100644
|
||||
--- a/src/cmd/go/internal/load/pkg.go
|
||||
+++ b/src/cmd/go/internal/load/pkg.go
|
||||
@@ -1697,6 +1697,10 @@ func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
|
||||
setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
|
||||
return
|
||||
}
|
||||
+ if strings.ContainsAny(p.Dir, "\r\n") {
|
||||
+ setError(fmt.Errorf("invalid package directory %q", p.Dir))
|
||||
+ return
|
||||
+ }
|
||||
|
||||
// Build list of imported packages and full dependency list.
|
||||
imports := make([]*Package, 0, len(p.Imports))
|
||||
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
|
||||
index 9a9650b..050b785 100644
|
||||
--- a/src/cmd/go/internal/work/exec.go
|
||||
+++ b/src/cmd/go/internal/work/exec.go
|
||||
@@ -458,6 +458,12 @@ func (b *Builder) build(a *Action) (err error) {
|
||||
b.Print(a.Package.ImportPath + "\n")
|
||||
}
|
||||
|
||||
+ if p.Error != nil {
|
||||
+ // Don't try to build anything for packages with errors. There may be a
|
||||
+ // problem with the inputs that makes the package unsafe to build.
|
||||
+ return p.Error
|
||||
+ }
|
||||
+
|
||||
if a.Package.BinaryOnly {
|
||||
p.Stale = true
|
||||
p.StaleReason = "binary-only packages are no longer supported"
|
||||
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
|
||||
index ec498bb..a1398ad 100644
|
||||
--- a/src/cmd/go/script_test.go
|
||||
+++ b/src/cmd/go/script_test.go
|
||||
@@ -123,6 +123,7 @@ func (ts *testScript) setup() {
|
||||
"devnull=" + os.DevNull,
|
||||
"goversion=" + goVersion(ts),
|
||||
":=" + string(os.PathListSeparator),
|
||||
+ "newline=\n",
|
||||
}
|
||||
|
||||
if runtime.GOOS == "plan9" {
|
||||
diff --git a/src/cmd/go/testdata/script/build_cwd_newline.txt b/src/cmd/go/testdata/script/build_cwd_newline.txt
|
||||
new file mode 100644
|
||||
index 0000000..61c6966
|
||||
--- /dev/null
|
||||
+++ b/src/cmd/go/testdata/script/build_cwd_newline.txt
|
||||
@@ -0,0 +1,100 @@
|
||||
+[windows] skip 'filesystem normalizes / to \'
|
||||
+[plan9] skip 'filesystem disallows \n in paths'
|
||||
+
|
||||
+# If the directory path containing a package to be built includes a newline,
|
||||
+# the go command should refuse to even try to build the package.
|
||||
+
|
||||
+env DIR=$WORK${/}${newline}'package main'${newline}'func main() { panic("uh-oh")'${newline}'/*'
|
||||
+
|
||||
+mkdir $DIR
|
||||
+cd $DIR
|
||||
+exec pwd
|
||||
+cp $WORK/go.mod ./go.mod
|
||||
+cp $WORK/main.go ./main.go
|
||||
+cp $WORK/main_test.go ./main_test.go
|
||||
+
|
||||
+! go build -o $devnull .
|
||||
+stderr 'package example: invalid package directory .*uh-oh'
|
||||
+
|
||||
+! go build -o $devnull main.go
|
||||
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
||||
+
|
||||
+! go run .
|
||||
+stderr 'package example: invalid package directory .*uh-oh'
|
||||
+
|
||||
+! go run main.go
|
||||
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
||||
+
|
||||
+! go test .
|
||||
+stderr 'package example: invalid package directory .*uh-oh'
|
||||
+
|
||||
+! go test -v main.go main_test.go
|
||||
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
||||
+
|
||||
+
|
||||
+# Since we do preserve $PWD (or set it appropriately) for commands, and we do
|
||||
+# not resolve symlinks unnecessarily, referring to the contents of the unsafe
|
||||
+# directory via a safe symlink should be ok, and should not inject the data from
|
||||
+# the symlink target path.
|
||||
+
|
||||
+[!symlink] stop 'remainder of test checks symlink behavior'
|
||||
+[short] stop 'links and runs binaries'
|
||||
+
|
||||
+symlink $WORK${/}link -> $DIR
|
||||
+
|
||||
+go run $WORK${/}link${/}main.go
|
||||
+! stdout panic
|
||||
+! stderr panic
|
||||
+stderr '^ok$'
|
||||
+
|
||||
+go test -v $WORK${/}link${/}main.go $WORK${/}link${/}main_test.go
|
||||
+! stdout panic
|
||||
+! stderr panic
|
||||
+stdout '^ok$' # 'go test' combines the test's stdout into stderr
|
||||
+
|
||||
+cd $WORK/link
|
||||
+
|
||||
+! go run $DIR${/}main.go
|
||||
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
||||
+
|
||||
+go run .
|
||||
+! stdout panic
|
||||
+! stderr panic
|
||||
+stderr '^ok$'
|
||||
+
|
||||
+go run main.go
|
||||
+! stdout panic
|
||||
+! stderr panic
|
||||
+stderr '^ok$'
|
||||
+
|
||||
+go test -v
|
||||
+! stdout panic
|
||||
+! stderr panic
|
||||
+stdout '^ok$' # 'go test' combines the test's stdout into stderr
|
||||
+
|
||||
+go test -v .
|
||||
+! stdout panic
|
||||
+! stderr panic
|
||||
+stdout '^ok$' # 'go test' combines the test's stdout into stderr
|
||||
+
|
||||
+
|
||||
+-- $WORK/go.mod --
|
||||
+module example
|
||||
+go 1.19
|
||||
+-- $WORK/main.go --
|
||||
+package main
|
||||
+
|
||||
+import "C"
|
||||
+
|
||||
+func main() {
|
||||
+ /* nothing here */
|
||||
+ println("ok")
|
||||
+}
|
||||
+-- $WORK/main_test.go --
|
||||
+package main
|
||||
+
|
||||
+import "testing"
|
||||
+
|
||||
+func TestMain(*testing.M) {
|
||||
+ main()
|
||||
+}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
84
meta/recipes-devtools/go/go-1.14/CVE-2023-29404.patch
Normal file
84
meta/recipes-devtools/go/go-1.14/CVE-2023-29404.patch
Normal file
@@ -0,0 +1,84 @@
|
||||
From bf3c8ce03e175e870763901a3850bca01381a828 Mon Sep 17 00:00:00 2001
|
||||
From: Roland Shoemaker <bracewell@google.com>
|
||||
Date: Fri, 5 May 2023 13:10:34 -0700
|
||||
Subject: [PATCH] [release-branch.go1.19] cmd/go: enforce flags with
|
||||
non-optional arguments
|
||||
|
||||
Enforce that linker flags which expect arguments get them, otherwise it
|
||||
may be possible to smuggle unexpected flags through as the linker can
|
||||
consume what looks like a flag as an argument to a preceding flag (i.e.
|
||||
"-Wl,-O -Wl,-R,-bad-flag" is interpreted as "-O=-R -bad-flag"). Also be
|
||||
somewhat more restrictive in the general format of some flags.
|
||||
|
||||
Thanks to Juho Nurminen of Mattermost for reporting this issue.
|
||||
|
||||
Updates #60305
|
||||
Fixes #60511
|
||||
Fixes CVE-2023-29404
|
||||
|
||||
Change-Id: Icdffef2c0f644da50261cace6f43742783931cff
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1876275
|
||||
Reviewed-by: Ian Lance Taylor <iant@google.com>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
(cherry picked from commit 896779503cf754cbdac24b61d4cc953b50fe2dde)
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902225
|
||||
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904342
|
||||
Reviewed-by: Michael Knyszek <mknyszek@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/501217
|
||||
Auto-Submit: Michael Knyszek <mknyszek@google.com>
|
||||
Run-TryBot: David Chase <drchase@google.com>
|
||||
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/bf3c8ce03e175e870763901a3850bca01381a828]
|
||||
CVE: CVE-2023-29404
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
src/cmd/go/internal/work/security.go | 6 +++---
|
||||
src/cmd/go/internal/work/security_test.go | 5 +++++
|
||||
2 files changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/go/internal/work/security.go b/src/cmd/go/internal/work/security.go
|
||||
index a823b20..8acb6dc 100644
|
||||
--- a/src/cmd/go/internal/work/security.go
|
||||
+++ b/src/cmd/go/internal/work/security.go
|
||||
@@ -177,17 +177,17 @@ var validLinkerFlags = []*lazyregexp.Regexp{
|
||||
re(`-Wl,-Bdynamic`),
|
||||
re(`-Wl,-berok`),
|
||||
re(`-Wl,-Bstatic`),
|
||||
- re(`-WL,-O([^@,\-][^,]*)?`),
|
||||
+ re(`-Wl,-O[0-9]+`),
|
||||
re(`-Wl,-d[ny]`),
|
||||
re(`-Wl,--disable-new-dtags`),
|
||||
- re(`-Wl,-e[=,][a-zA-Z0-9]*`),
|
||||
+ re(`-Wl,-e[=,][a-zA-Z0-9]+`),
|
||||
re(`-Wl,--enable-new-dtags`),
|
||||
re(`-Wl,--end-group`),
|
||||
re(`-Wl,--(no-)?export-dynamic`),
|
||||
re(`-Wl,-framework,[^,@\-][^,]+`),
|
||||
re(`-Wl,-headerpad_max_install_names`),
|
||||
re(`-Wl,--no-undefined`),
|
||||
- re(`-Wl,-R([^@\-][^,@]*$)`),
|
||||
+ re(`-Wl,-R,?([^@\-,][^,@]*$)`),
|
||||
re(`-Wl,--just-symbols[=,]([^,@\-][^,@]+)`),
|
||||
re(`-Wl,-rpath(-link)?[=,]([^,@\-][^,]+)`),
|
||||
re(`-Wl,-s`),
|
||||
diff --git a/src/cmd/go/internal/work/security_test.go b/src/cmd/go/internal/work/security_test.go
|
||||
index bd707ff..7b0b7d3 100644
|
||||
--- a/src/cmd/go/internal/work/security_test.go
|
||||
+++ b/src/cmd/go/internal/work/security_test.go
|
||||
@@ -220,6 +220,11 @@ var badLinkerFlags = [][]string{
|
||||
{"-Wl,-R,@foo"},
|
||||
{"-Wl,--just-symbols,@foo"},
|
||||
{"../x.o"},
|
||||
+ {"-Wl,-R,"},
|
||||
+ {"-Wl,-O"},
|
||||
+ {"-Wl,-e="},
|
||||
+ {"-Wl,-e,"},
|
||||
+ {"-Wl,-R,-flag"},
|
||||
}
|
||||
|
||||
func TestCheckLinkerFlags(t *testing.T) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
112
meta/recipes-devtools/go/go-1.14/CVE-2023-29405-1.patch
Normal file
112
meta/recipes-devtools/go/go-1.14/CVE-2023-29405-1.patch
Normal file
@@ -0,0 +1,112 @@
|
||||
From fa60c381ed06c12f9c27a7b50ca44c5f84f7f0f4 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Lance Taylor <iant@golang.org>
|
||||
Date: Thu, 4 May 2023 14:06:39 -0700
|
||||
Subject: [PATCH] [release-branch.go1.20] cmd/go,cmd/cgo: in _cgo_flags use one
|
||||
line per flag
|
||||
|
||||
The flags that we recorded in _cgo_flags did not use any quoting,
|
||||
so a flag containing embedded spaces was mishandled.
|
||||
Change the _cgo_flags format to put each flag on a separate line.
|
||||
That is a simple format that does not require any quoting.
|
||||
|
||||
As far as I can tell only cmd/go uses _cgo_flags, and it is only
|
||||
used for gccgo. If this patch doesn't cause any trouble, then
|
||||
in the next release we can change to only using _cgo_flags for gccgo.
|
||||
|
||||
Thanks to Juho Nurminen of Mattermost for reporting this issue.
|
||||
|
||||
Updates #60306
|
||||
Fixes #60514
|
||||
Fixes CVE-2023-29405
|
||||
|
||||
Change-Id: I36b6e188a44c80d7b9573efa577c386770bd2ba3
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1875094
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||
(cherry picked from commit bcdfcadd5612212089d958bc352a6f6c90742dcc)
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902228
|
||||
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
||||
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904345
|
||||
Reviewed-by: Michael Knyszek <mknyszek@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/501220
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Run-TryBot: David Chase <drchase@google.com>
|
||||
Auto-Submit: Michael Knyszek <mknyszek@google.com>
|
||||
---
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/fa60c381ed06c12f9c27a7b50ca44c5f84f7f0f4]
|
||||
CVE: CVE-2023-29405
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
|
||||
src/cmd/cgo/out.go | 4 +++-
|
||||
src/cmd/go/internal/work/gccgo.go | 14 ++++++-------
|
||||
.../go/testdata/script/gccgo_link_ldflags.txt | 20 +++++++++++++++++++
|
||||
3 files changed, 29 insertions(+), 9 deletions(-)
|
||||
create mode 100644 src/cmd/go/testdata/script/gccgo_link_ldflags.txt
|
||||
|
||||
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
|
||||
index d26f9e76a374a..d0c6fe3d4c2c2 100644
|
||||
--- a/src/cmd/cgo/out.go
|
||||
+++ b/src/cmd/cgo/out.go
|
||||
@@ -47,7 +47,9 @@ func (p *Package) writeDefs() {
|
||||
|
||||
fflg := creat(*objDir + "_cgo_flags")
|
||||
for k, v := range p.CgoFlags {
|
||||
- fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " "))
|
||||
+ for _, arg := range v {
|
||||
+ fmt.Fprintf(fflg, "_CGO_%s=%s\n", arg)
|
||||
+ }
|
||||
if k == "LDFLAGS" && !*gccgo {
|
||||
for _, arg := range v {
|
||||
fmt.Fprintf(fgo2, "//go:cgo_ldflag %q\n", arg)
|
||||
diff --git a/src/cmd/go/internal/work/gccgo.go b/src/cmd/go/internal/work/gccgo.go
|
||||
index 08a4c2d8166c7..a048b7f4eecef 100644
|
||||
--- a/src/cmd/go/internal/work/gccgo.go
|
||||
+++ b/src/cmd/go/internal/work/gccgo.go
|
||||
@@ -280,14 +280,12 @@ func (tools gccgoToolchain) link(b *Builder, root *Action, out, importcfg string
|
||||
const ldflagsPrefix = "_CGO_LDFLAGS="
|
||||
for _, line := range strings.Split(string(flags), "\n") {
|
||||
if strings.HasPrefix(line, ldflagsPrefix) {
|
||||
- newFlags := strings.Fields(line[len(ldflagsPrefix):])
|
||||
- for _, flag := range newFlags {
|
||||
- // Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
|
||||
- // but they don't mean anything to the linker so filter
|
||||
- // them out.
|
||||
- if flag != "-g" && !strings.HasPrefix(flag, "-O") {
|
||||
- cgoldflags = append(cgoldflags, flag)
|
||||
- }
|
||||
+ flag := line[len(ldflagsPrefix):]
|
||||
+ // Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
|
||||
+ // but they don't mean anything to the linker so filter
|
||||
+ // them out.
|
||||
+ if flag != "-g" && !strings.HasPrefix(flag, "-O") {
|
||||
+ cgoldflags = append(cgoldflags, flag)
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/cmd/go/testdata/script/gccgo_link_ldflags.txt b/src/cmd/go/testdata/script/gccgo_link_ldflags.txt
|
||||
new file mode 100644
|
||||
index 0000000000000..4e91ae56505b6
|
||||
--- /dev/null
|
||||
+++ b/src/cmd/go/testdata/script/gccgo_link_ldflags.txt
|
||||
@@ -0,0 +1,20 @@
|
||||
+# Test that #cgo LDFLAGS are properly quoted.
|
||||
+# The #cgo LDFLAGS below should pass a string with spaces to -L,
|
||||
+# as though searching a directory with a space in its name.
|
||||
+# It should not pass --nosuchoption to the external linker.
|
||||
+
|
||||
+[!cgo] skip
|
||||
+
|
||||
+go build
|
||||
+
|
||||
+[!exec:gccgo] skip
|
||||
+
|
||||
+go build -compiler gccgo
|
||||
+
|
||||
+-- go.mod --
|
||||
+module m
|
||||
+-- cgo.go --
|
||||
+package main
|
||||
+// #cgo LDFLAGS: -L "./ -Wl,--nosuchoption"
|
||||
+import "C"
|
||||
+func main() {}
|
||||
38
meta/recipes-devtools/go/go-1.14/CVE-2023-29405-2.patch
Normal file
38
meta/recipes-devtools/go/go-1.14/CVE-2023-29405-2.patch
Normal file
@@ -0,0 +1,38 @@
|
||||
From 1008486a9ff979dbd21c7466eeb6abf378f9c637 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Lance Taylor <iant@golang.org>
|
||||
Date: Tue, 6 Jun 2023 12:51:17 -0700
|
||||
Subject: [PATCH] [release-branch.go1.20] cmd/cgo: correct _cgo_flags output
|
||||
|
||||
For #60306
|
||||
For #60514
|
||||
|
||||
Change-Id: I3f5d14aee7d7195030e8872e42b1d97aa11d3582
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/501298
|
||||
Run-TryBot: Ian Lance Taylor <iant@golang.org>
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
Reviewed-by: David Chase <drchase@google.com>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
|
||||
---
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/1008486a9ff979dbd21c7466eeb6abf378f9c637]
|
||||
CVE: CVE-2023-29405
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
|
||||
|
||||
src/cmd/cgo/out.go | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
|
||||
index d0c6fe3d4c2c2..a48f52105628a 100644
|
||||
--- a/src/cmd/cgo/out.go
|
||||
+++ b/src/cmd/cgo/out.go
|
||||
@@ -48,7 +48,7 @@ func (p *Package) writeDefs() {
|
||||
fflg := creat(*objDir + "_cgo_flags")
|
||||
for k, v := range p.CgoFlags {
|
||||
for _, arg := range v {
|
||||
- fmt.Fprintf(fflg, "_CGO_%s=%s\n", arg)
|
||||
+ fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, arg)
|
||||
}
|
||||
if k == "LDFLAGS" && !*gccgo {
|
||||
for _, arg := range v {
|
||||
212
meta/recipes-devtools/go/go-1.14/CVE-2023-29406.patch
Normal file
212
meta/recipes-devtools/go/go-1.14/CVE-2023-29406.patch
Normal file
@@ -0,0 +1,212 @@
|
||||
From 5fa6923b1ea891400153d04ddf1545e23b40041b Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Wed, 28 Jun 2023 13:20:08 -0700
|
||||
Subject: [PATCH] [release-branch.go1.19] net/http: validate Host header before
|
||||
sending
|
||||
|
||||
Verify that the Host header we send is valid.
|
||||
Avoids surprising behavior such as a Host of "go.dev\r\nX-Evil:oops"
|
||||
adding an X-Evil header to HTTP/1 requests.
|
||||
|
||||
Add a test, skip the test for HTTP/2. HTTP/2 is not vulnerable to
|
||||
header injection in the way HTTP/1 is, but x/net/http2 doesn't validate
|
||||
the header and will go into a retry loop when the server rejects it.
|
||||
CL 506995 adds the necessary validation to x/net/http2.
|
||||
|
||||
Updates #60374
|
||||
Fixes #61075
|
||||
For CVE-2023-29406
|
||||
|
||||
Change-Id: I05cb6866a9bead043101954dfded199258c6dd04
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/506996
|
||||
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Run-TryBot: Damien Neil <dneil@google.com>
|
||||
(cherry picked from commit 499458f7ca04087958987a33c2703c3ef03e27e2)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/507358
|
||||
Run-TryBot: Tatiana Bradley <tatianabradley@google.com>
|
||||
Reviewed-by: Roland Shoemaker <roland@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/5fa6923b1ea891400153d04ddf1545e23b40041b]
|
||||
CVE: CVE-2023-29406
|
||||
Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
|
||||
---
|
||||
src/net/http/http_test.go | 29 ---------------------
|
||||
src/net/http/request.go | 47 ++++++++--------------------------
|
||||
src/net/http/request_test.go | 11 ++------
|
||||
src/net/http/transport_test.go | 18 +++++++++++++
|
||||
4 files changed, 31 insertions(+), 74 deletions(-)
|
||||
|
||||
diff --git a/src/net/http/http_test.go b/src/net/http/http_test.go
|
||||
index f4ea52d..ea38cb4 100644
|
||||
--- a/src/net/http/http_test.go
|
||||
+++ b/src/net/http/http_test.go
|
||||
@@ -49,35 +49,6 @@ func TestForeachHeaderElement(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
-func TestCleanHost(t *testing.T) {
|
||||
- tests := []struct {
|
||||
- in, want string
|
||||
- }{
|
||||
- {"www.google.com", "www.google.com"},
|
||||
- {"www.google.com foo", "www.google.com"},
|
||||
- {"www.google.com/foo", "www.google.com"},
|
||||
- {" first character is a space", ""},
|
||||
- {"[1::6]:8080", "[1::6]:8080"},
|
||||
-
|
||||
- // Punycode:
|
||||
- {"гофер.рф/foo", "xn--c1ae0ajs.xn--p1ai"},
|
||||
- {"bücher.de", "xn--bcher-kva.de"},
|
||||
- {"bücher.de:8080", "xn--bcher-kva.de:8080"},
|
||||
- // Verify we convert to lowercase before punycode:
|
||||
- {"BÜCHER.de", "xn--bcher-kva.de"},
|
||||
- {"BÜCHER.de:8080", "xn--bcher-kva.de:8080"},
|
||||
- // Verify we normalize to NFC before punycode:
|
||||
- {"gophér.nfc", "xn--gophr-esa.nfc"}, // NFC input; no work needed
|
||||
- {"goph\u0065\u0301r.nfd", "xn--gophr-esa.nfd"}, // NFD input
|
||||
- }
|
||||
- for _, tt := range tests {
|
||||
- got := cleanHost(tt.in)
|
||||
- if tt.want != got {
|
||||
- t.Errorf("cleanHost(%q) = %q, want %q", tt.in, got, tt.want)
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
// Test that cmd/go doesn't link in the HTTP server.
|
||||
//
|
||||
// This catches accidental dependencies between the HTTP transport and
|
||||
diff --git a/src/net/http/request.go b/src/net/http/request.go
|
||||
index cb2edd2..2706300 100644
|
||||
--- a/src/net/http/request.go
|
||||
+++ b/src/net/http/request.go
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"io/ioutil"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
- "net"
|
||||
"net/http/httptrace"
|
||||
"net/textproto"
|
||||
"net/url"
|
||||
@@ -26,7 +25,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
-
|
||||
+
|
||||
+ "golang.org/x/net/http/httpguts"
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
@@ -557,12 +557,19 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF
|
||||
// is not given, use the host from the request URL.
|
||||
//
|
||||
// Clean the host, in case it arrives with unexpected stuff in it.
|
||||
- host := cleanHost(r.Host)
|
||||
+ host := r.Host
|
||||
if host == "" {
|
||||
if r.URL == nil {
|
||||
return errMissingHost
|
||||
}
|
||||
- host = cleanHost(r.URL.Host)
|
||||
+ host = r.URL.Host
|
||||
+ }
|
||||
+ host, err = httpguts.PunycodeHostPort(host)
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ if !httpguts.ValidHostHeader(host) {
|
||||
+ return errors.New("http: invalid Host header")
|
||||
}
|
||||
|
||||
// According to RFC 6874, an HTTP client, proxy, or other
|
||||
@@ -717,38 +724,6 @@ func idnaASCII(v string) (string, error) {
|
||||
return idna.Lookup.ToASCII(v)
|
||||
}
|
||||
|
||||
-// cleanHost cleans up the host sent in request's Host header.
|
||||
-//
|
||||
-// It both strips anything after '/' or ' ', and puts the value
|
||||
-// into Punycode form, if necessary.
|
||||
-//
|
||||
-// Ideally we'd clean the Host header according to the spec:
|
||||
-// https://tools.ietf.org/html/rfc7230#section-5.4 (Host = uri-host [ ":" port ]")
|
||||
-// https://tools.ietf.org/html/rfc7230#section-2.7 (uri-host -> rfc3986's host)
|
||||
-// https://tools.ietf.org/html/rfc3986#section-3.2.2 (definition of host)
|
||||
-// But practically, what we are trying to avoid is the situation in
|
||||
-// issue 11206, where a malformed Host header used in the proxy context
|
||||
-// would create a bad request. So it is enough to just truncate at the
|
||||
-// first offending character.
|
||||
-func cleanHost(in string) string {
|
||||
- if i := strings.IndexAny(in, " /"); i != -1 {
|
||||
- in = in[:i]
|
||||
- }
|
||||
- host, port, err := net.SplitHostPort(in)
|
||||
- if err != nil { // input was just a host
|
||||
- a, err := idnaASCII(in)
|
||||
- if err != nil {
|
||||
- return in // garbage in, garbage out
|
||||
- }
|
||||
- return a
|
||||
- }
|
||||
- a, err := idnaASCII(host)
|
||||
- if err != nil {
|
||||
- return in // garbage in, garbage out
|
||||
- }
|
||||
- return net.JoinHostPort(a, port)
|
||||
-}
|
||||
-
|
||||
// removeZone removes IPv6 zone identifier from host.
|
||||
// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080"
|
||||
func removeZone(host string) string {
|
||||
diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go
|
||||
index 461d66e..0d417ff 100644
|
||||
--- a/src/net/http/request_test.go
|
||||
+++ b/src/net/http/request_test.go
|
||||
@@ -676,15 +676,8 @@ func TestRequestBadHost(t *testing.T) {
|
||||
}
|
||||
req.Host = "foo.com with spaces"
|
||||
req.URL.Host = "foo.com with spaces"
|
||||
- req.Write(logWrites{t, &got})
|
||||
- want := []string{
|
||||
- "GET /after HTTP/1.1\r\n",
|
||||
- "Host: foo.com\r\n",
|
||||
- "User-Agent: " + DefaultUserAgent + "\r\n",
|
||||
- "\r\n",
|
||||
- }
|
||||
- if !reflect.DeepEqual(got, want) {
|
||||
- t.Errorf("Writes = %q\n Want = %q", got, want)
|
||||
+ if err := req.Write(logWrites{t, &got}); err == nil {
|
||||
+ t.Errorf("Writing request with invalid Host: succeded, want error")
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
|
||||
index fa0c370..0afb6b9 100644
|
||||
--- a/src/net/http/transport_test.go
|
||||
+++ b/src/net/http/transport_test.go
|
||||
@@ -6249,3 +6249,21 @@ func TestIssue32441(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
+
|
||||
+func TestRequestSanitization(t *testing.T) {
|
||||
+ setParallel(t)
|
||||
+ defer afterTest(t)
|
||||
+
|
||||
+ ts := newClientServerTest(t, h1Mode, HandlerFunc(func(rw ResponseWriter, req *Request) {
|
||||
+ if h, ok := req.Header["X-Evil"]; ok {
|
||||
+ t.Errorf("request has X-Evil header: %q", h)
|
||||
+ }
|
||||
+ })).ts
|
||||
+ defer ts.Close()
|
||||
+ req, _ := NewRequest("GET", ts.URL, nil)
|
||||
+ req.Host = "go.dev\r\nX-Evil:evil"
|
||||
+ resp, _ := ts.Client().Do(req)
|
||||
+ if resp != nil {
|
||||
+ resp.Body.Close()
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.25.1
|
||||
175
meta/recipes-devtools/go/go-1.14/CVE-2023-29409.patch
Normal file
175
meta/recipes-devtools/go/go-1.14/CVE-2023-29409.patch
Normal file
@@ -0,0 +1,175 @@
|
||||
From 2300f7ef07718f6be4d8aa8486c7de99836e233f Mon Sep 17 00:00:00 2001
|
||||
From: Roland Shoemaker <bracewell@google.com>
|
||||
Date: Wed, 7 Jun 2023 15:27:13 -0700
|
||||
Subject: [PATCH] [release-branch.go1.19] crypto/tls: restrict RSA keys in
|
||||
certificates to <= 8192 bits
|
||||
|
||||
Extremely large RSA keys in certificate chains can cause a client/server
|
||||
to expend significant CPU time verifying signatures. Limit this by
|
||||
restricting the size of RSA keys transmitted during handshakes to <=
|
||||
8192 bits.
|
||||
|
||||
Based on a survey of publicly trusted RSA keys, there are currently only
|
||||
three certificates in circulation with keys larger than this, and all
|
||||
three appear to be test certificates that are not actively deployed. It
|
||||
is possible there are larger keys in use in private PKIs, but we target
|
||||
the web PKI, so causing breakage here in the interests of increasing the
|
||||
default safety of users of crypto/tls seems reasonable.
|
||||
|
||||
Thanks to Mateusz Poliwczak for reporting this issue.
|
||||
|
||||
Updates #61460
|
||||
Fixes #61579
|
||||
Fixes CVE-2023-29409
|
||||
|
||||
Change-Id: Ie35038515a649199a36a12fc2c5df3af855dca6c
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1912161
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
||||
(cherry picked from commit d865c715d92887361e4bd5596e19e513f27781b7)
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1965487
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/514915
|
||||
Run-TryBot: David Chase <drchase@google.com>
|
||||
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
|
||||
TryBot-Bypass: David Chase <drchase@google.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/2300f7ef07718f6be4d8aa8486c7de99836e233f]
|
||||
CVE: CVE-2023-29409
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/crypto/tls/handshake_client.go | 8 +++
|
||||
src/crypto/tls/handshake_client_test.go | 78 +++++++++++++++++++++++++
|
||||
src/crypto/tls/handshake_server.go | 4 ++
|
||||
3 files changed, 90 insertions(+)
|
||||
|
||||
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
|
||||
index 4fb528c..ba33ea1 100644
|
||||
--- a/src/crypto/tls/handshake_client.go
|
||||
+++ b/src/crypto/tls/handshake_client.go
|
||||
@@ -788,6 +788,10 @@ func (hs *clientHandshakeState) sendFinished(out []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
+// maxRSAKeySize is the maximum RSA key size in bits that we are willing
|
||||
+// to verify the signatures of during a TLS handshake.
|
||||
+const maxRSAKeySize = 8192
|
||||
+
|
||||
// verifyServerCertificate parses and verifies the provided chain, setting
|
||||
// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
|
||||
func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
||||
@@ -798,6 +802,10 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
return errors.New("tls: failed to parse certificate from server: " + err.Error())
|
||||
}
|
||||
+ if cert.PublicKeyAlgorithm == x509.RSA && cert.PublicKey.(*rsa.PublicKey).N.BitLen() > maxRSAKeySize {
|
||||
+ c.sendAlert(alertBadCertificate)
|
||||
+ return fmt.Errorf("tls: server sent certificate containing RSA key larger than %d bits", maxRSAKeySize)
|
||||
+ }
|
||||
certs[i] = cert
|
||||
}
|
||||
|
||||
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
|
||||
index 6bd3c37..8d20b2b 100644
|
||||
--- a/src/crypto/tls/handshake_client_test.go
|
||||
+++ b/src/crypto/tls/handshake_client_test.go
|
||||
@@ -1984,3 +1984,81 @@ func TestCloseClientConnectionOnIdleServer(t *testing.T) {
|
||||
t.Errorf("Error expected, but no error returned")
|
||||
}
|
||||
}
|
||||
+
|
||||
+// discardConn wraps a net.Conn but discards all writes, but reports that they happened.
|
||||
+type discardConn struct {
|
||||
+ net.Conn
|
||||
+}
|
||||
+
|
||||
+func (dc *discardConn) Write(data []byte) (int, error) {
|
||||
+ return len(data), nil
|
||||
+}
|
||||
+
|
||||
+// largeRSAKeyCertPEM contains a 8193 bit RSA key
|
||||
+const largeRSAKeyCertPEM = `-----BEGIN CERTIFICATE-----
|
||||
+MIIInjCCBIWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwd0ZXN0
|
||||
+aW5nMB4XDTIzMDYwNzIxMjMzNloXDTIzMDYwNzIzMjMzNlowEjEQMA4GA1UEAxMH
|
||||
+dGVzdGluZzCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAWdHsf6Rh2Ca
|
||||
+n2SQwn4t4OQrOjbLLdGE1pM6TBKKrHUFy62uEL8atNjlcfXIsa4aEu3xNGiqxqur
|
||||
+ZectlkZbm0FkaaQ1Wr9oikDY3KfjuaXdPdO/XC/h8AKNxlDOylyXwUSK/CuYb+1j
|
||||
+gy8yF5QFvVfwW/xwTlHmhUeSkVSQPosfQ6yXNNsmMzkd+ZPWLrfq4R+wiNtwYGu0
|
||||
+WSBcI/M9o8/vrNLnIppoiBJJ13j9CR1ToEAzOFh9wwRWLY10oZhoh1ONN1KQURx4
|
||||
+qedzvvP2DSjZbUccdvl2rBGvZpzfOiFdm1FCnxB0c72Cqx+GTHXBFf8bsa7KHky9
|
||||
+sNO1GUanbq17WoDNgwbY6H51bfShqv0CErxatwWox3we4EcAmFHPVTCYL1oWVMGo
|
||||
+a3Eth91NZj+b/nGhF9lhHKGzXSv9brmLLkfvM1jA6XhNhA7BQ5Vz67lj2j3XfXdh
|
||||
+t/BU5pBXbL4Ut4mIhT1YnKXAjX2/LF5RHQTE8Vwkx5JAEKZyUEGOReD/B+7GOrLp
|
||||
+HduMT9vZAc5aR2k9I8qq1zBAzsL69lyQNAPaDYd1BIAjUety9gAYaSQffCgAgpRO
|
||||
+Gt+DYvxS+7AT/yEd5h74MU2AH7KrAkbXOtlwupiGwhMVTstncDJWXMJqbBhyHPF8
|
||||
+3UmZH0hbL4PYmzSj9LDWQQXI2tv6vrCpfts3Cqhqxz9vRpgY7t1Wu6l/r+KxYYz3
|
||||
+1pcGpPvRmPh0DJm7cPTiXqPnZcPt+ulSaSdlxmd19OnvG5awp0fXhxryZVwuiT8G
|
||||
+VDkhyARrxYrdjlINsZJZbQjO0t8ketXAELJOnbFXXzeCOosyOHkLwsqOO96AVJA8
|
||||
+45ZVL5m95ClGy0RSrjVIkXsxTAMVG6SPAqKwk6vmTdRGuSPS4rhgckPVDHmccmuq
|
||||
+dfnT2YkX+wB2/M3oCgU+s30fAHGkbGZ0pCdNbFYFZLiH0iiMbTDl/0L/z7IdK0nH
|
||||
+GLHVE7apPraKC6xl6rPWsD2iSfrmtIPQa0+rqbIVvKP5JdfJ8J4alI+OxFw/znQe
|
||||
+V0/Rez0j22Fe119LZFFSXhRv+ZSvcq20xDwh00mzcumPWpYuCVPozA18yIhC9tNn
|
||||
+ALHndz0tDseIdy9vC71jQWy9iwri3ueN0DekMMF8JGzI1Z6BAFzgyAx3DkHtwHg7
|
||||
+B7qD0jPG5hJ5+yt323fYgJsuEAYoZ8/jzZ01pkX8bt+UsVN0DGnSGsI2ktnIIk3J
|
||||
+l+8krjmUy6EaW79nITwoOqaeHOIp8m3UkjEcoKOYrzHRKqRy+A09rY+m/cAQaafW
|
||||
+4xp0Zv7qZPLwnu0jsqB4jD8Ll9yPB02ndsoV6U5PeHzTkVhPml19jKUAwFfs7TJg
|
||||
+kXy+/xFhYVUCAwEAATANBgkqhkiG9w0BAQsFAAOCBAIAAQnZY77pMNeypfpba2WK
|
||||
+aDasT7dk2JqP0eukJCVPTN24Zca+xJNPdzuBATm/8SdZK9lddIbjSnWRsKvTnO2r
|
||||
+/rYdlPf3jM5uuJtb8+Uwwe1s+gszelGS9G/lzzq+ehWicRIq2PFcs8o3iQMfENiv
|
||||
+qILJ+xjcrvms5ZPDNahWkfRx3KCg8Q+/at2n5p7XYjMPYiLKHnDC+RE2b1qT20IZ
|
||||
+FhuK/fTWLmKbfYFNNga6GC4qcaZJ7x0pbm4SDTYp0tkhzcHzwKhidfNB5J2vNz6l
|
||||
+Ur6wiYwamFTLqcOwWo7rdvI+sSn05WQBv0QZlzFX+OAu0l7WQ7yU+noOxBhjvHds
|
||||
+14+r9qcQZg2q9kG+evopYZqYXRUNNlZKo9MRBXhfrISulFAc5lRFQIXMXnglvAu+
|
||||
+Ipz2gomEAOcOPNNVldhKAU94GAMJd/KfN0ZP7gX3YvPzuYU6XDhag5RTohXLm18w
|
||||
+5AF+ES3DOQ6ixu3DTf0D+6qrDuK+prdX8ivcdTQVNOQ+MIZeGSc6NWWOTaMGJ3lg
|
||||
+aZIxJUGdo6E7GBGiC1YTjgFKFbHzek1LRTh/LX3vbSudxwaG0HQxwsU9T4DWiMqa
|
||||
+Fkf2KteLEUA6HrR+0XlAZrhwoqAmrJ+8lCFX3V0gE9lpENfVHlFXDGyx10DpTB28
|
||||
+DdjnY3F7EPWNzwf9P3oNT69CKW3Bk6VVr3ROOJtDxVu1ioWo3TaXltQ0VOnap2Pu
|
||||
+sa5wfrpfwBDuAS9JCDg4ttNp2nW3F7tgXC6xPqw5pvGwUppEw9XNrqV8TZrxduuv
|
||||
+rQ3NyZ7KSzIpmFlD3UwV/fGfz3UQmHS6Ng1evrUID9DjfYNfRqSGIGjDfxGtYD+j
|
||||
+Z1gLJZuhjJpNtwBkKRtlNtrCWCJK2hidK/foxwD7kwAPo2I9FjpltxCRywZUs07X
|
||||
+KwXTfBR9v6ij1LV6K58hFS+8ezZyZ05CeVBFkMQdclTOSfuPxlMkQOtjp8QWDj+F
|
||||
+j/MYziT5KBkHvcbrjdRtUJIAi4N7zCsPZtjik918AK1WBNRVqPbrgq/XSEXMfuvs
|
||||
+6JbfK0B76vdBDRtJFC1JsvnIrGbUztxXzyQwFLaR/AjVJqpVlysLWzPKWVX6/+SJ
|
||||
+u1NQOl2E8P6ycyBsuGnO89p0S4F8cMRcI2X1XQsZ7/q0NBrOMaEp5T3SrWo9GiQ3
|
||||
+o2SBdbs3Y6MBPBtTu977Z/0RO63J3M5i2tjUiDfrFy7+VRLKr7qQ7JibohyB8QaR
|
||||
+9tedgjn2f+of7PnP/PEl1cCphUZeHM7QKUMPT8dbqwmKtlYY43EHXcvNOT5IBk3X
|
||||
+9lwJoZk/B2i+ZMRNSP34ztAwtxmasPt6RAWGQpWCn9qmttAHAnMfDqe7F7jVR6rS
|
||||
+u58=
|
||||
+-----END CERTIFICATE-----`
|
||||
+
|
||||
+func TestHandshakeRSATooBig(t *testing.T) {
|
||||
+ testCert, _ := pem.Decode([]byte(largeRSAKeyCertPEM))
|
||||
+
|
||||
+ c := &Conn{conn: &discardConn{}, config: testConfig.Clone()}
|
||||
+
|
||||
+ expectedErr := "tls: server sent certificate containing RSA key larger than 8192 bits"
|
||||
+ err := c.verifyServerCertificate([][]byte{testCert.Bytes})
|
||||
+ if err == nil || err.Error() != expectedErr {
|
||||
+ t.Errorf("Conn.verifyServerCertificate unexpected error: want %q, got %q", expectedErr, err)
|
||||
+ }
|
||||
+
|
||||
+ expectedErr = "tls: client sent certificate containing RSA key larger than 8192 bits"
|
||||
+ err = c.processCertsFromClient(Certificate{Certificate: [][]byte{testCert.Bytes}})
|
||||
+ if err == nil || err.Error() != expectedErr {
|
||||
+ t.Errorf("Conn.processCertsFromClient unexpected error: want %q, got %q", expectedErr, err)
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
|
||||
index b16415a..2e36840 100644
|
||||
--- a/src/crypto/tls/handshake_server.go
|
||||
+++ b/src/crypto/tls/handshake_server.go
|
||||
@@ -738,6 +738,10 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
|
||||
c.sendAlert(alertBadCertificate)
|
||||
return errors.New("tls: failed to parse client certificate: " + err.Error())
|
||||
}
|
||||
+ if certs[i].PublicKeyAlgorithm == x509.RSA && certs[i].PublicKey.(*rsa.PublicKey).N.BitLen() > maxRSAKeySize {
|
||||
+ c.sendAlert(alertBadCertificate)
|
||||
+ return fmt.Errorf("tls: client sent certificate containing RSA key larger than %d bits", maxRSAKeySize)
|
||||
+ }
|
||||
}
|
||||
|
||||
if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -29,3 +29,6 @@ do_install() {
|
||||
}
|
||||
|
||||
BBCLASSEXTEND = "native nativesdk"
|
||||
|
||||
# This is a different Ninja
|
||||
CVE_CHECK_WHITELIST += "CVE-2021-4336"
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
From 064ec20bf7a181ba5fa961aaa12973812aa6ca5d Mon Sep 17 00:00:00 2001
|
||||
From: "Miss Islington (bot)"
|
||||
<31488909+miss-islington@users.noreply.github.com>
|
||||
Date: Mon, 7 Nov 2022 18:57:10 -0800
|
||||
Subject: [PATCH] [3.11] gh-98433: Fix quadratic time idna decoding. (GH-99092)
|
||||
(GH-99222)
|
||||
|
||||
There was an unnecessary quadratic loop in idna decoding. This restores
|
||||
the behavior to linear.
|
||||
|
||||
(cherry picked from commit d315722564927c7202dd6e111dc79eaf14240b0d)
|
||||
|
||||
(cherry picked from commit a6f6c3a3d6f2b580f2d87885c9b8a9350ad7bf15)
|
||||
|
||||
Co-authored-by: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
|
||||
Co-authored-by: Gregory P. Smith <greg@krypto.org>
|
||||
|
||||
CVE: CVE-2022-45061
|
||||
Upstream-Status: Backport [https://github.com/python/cpython/pull/99231/commits/064ec20bf7a181ba5fa961aaa12973812aa6ca5d]
|
||||
Signed-off-by: Omkar Patil <Omkar.Patil@kpit.com>
|
||||
|
||||
---
|
||||
Lib/encodings/idna.py | 32 +++++++++----------
|
||||
Lib/test/test_codecs.py | 6 ++++
|
||||
...2-11-04-09-29-36.gh-issue-98433.l76c5G.rst | 6 ++++
|
||||
3 files changed, 27 insertions(+), 17 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Security/2022-11-04-09-29-36.gh-issue-98433.l76c5G.rst
|
||||
|
||||
diff --git a/Lib/encodings/idna.py b/Lib/encodings/idna.py
|
||||
index ea4058512fe3..bf98f513366b 100644
|
||||
--- a/Lib/encodings/idna.py
|
||||
+++ b/Lib/encodings/idna.py
|
||||
@@ -39,23 +39,21 @@ def nameprep(label):
|
||||
|
||||
# Check bidi
|
||||
RandAL = [stringprep.in_table_d1(x) for x in label]
|
||||
- for c in RandAL:
|
||||
- if c:
|
||||
- # There is a RandAL char in the string. Must perform further
|
||||
- # tests:
|
||||
- # 1) The characters in section 5.8 MUST be prohibited.
|
||||
- # This is table C.8, which was already checked
|
||||
- # 2) If a string contains any RandALCat character, the string
|
||||
- # MUST NOT contain any LCat character.
|
||||
- if any(stringprep.in_table_d2(x) for x in label):
|
||||
- raise UnicodeError("Violation of BIDI requirement 2")
|
||||
-
|
||||
- # 3) If a string contains any RandALCat character, a
|
||||
- # RandALCat character MUST be the first character of the
|
||||
- # string, and a RandALCat character MUST be the last
|
||||
- # character of the string.
|
||||
- if not RandAL[0] or not RandAL[-1]:
|
||||
- raise UnicodeError("Violation of BIDI requirement 3")
|
||||
+ if any(RandAL):
|
||||
+ # There is a RandAL char in the string. Must perform further
|
||||
+ # tests:
|
||||
+ # 1) The characters in section 5.8 MUST be prohibited.
|
||||
+ # This is table C.8, which was already checked
|
||||
+ # 2) If a string contains any RandALCat character, the string
|
||||
+ # MUST NOT contain any LCat character.
|
||||
+ if any(stringprep.in_table_d2(x) for x in label):
|
||||
+ raise UnicodeError("Violation of BIDI requirement 2")
|
||||
+ # 3) If a string contains any RandALCat character, a
|
||||
+ # RandALCat character MUST be the first character of the
|
||||
+ # string, and a RandALCat character MUST be the last
|
||||
+ # character of the string.
|
||||
+ if not RandAL[0] or not RandAL[-1]:
|
||||
+ raise UnicodeError("Violation of BIDI requirement 3")
|
||||
|
||||
return label
|
||||
|
||||
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
|
||||
index d1faf0126c1e..37ade7d80d02 100644
|
||||
--- a/Lib/test/test_codecs.py
|
||||
+++ b/Lib/test/test_codecs.py
|
||||
@@ -1532,6 +1532,12 @@ def test_builtin_encode(self):
|
||||
self.assertEqual("pyth\xf6n.org".encode("idna"), b"xn--pythn-mua.org")
|
||||
self.assertEqual("pyth\xf6n.org.".encode("idna"), b"xn--pythn-mua.org.")
|
||||
|
||||
+ def test_builtin_decode_length_limit(self):
|
||||
+ with self.assertRaisesRegex(UnicodeError, "too long"):
|
||||
+ (b"xn--016c"+b"a"*1100).decode("idna")
|
||||
+ with self.assertRaisesRegex(UnicodeError, "too long"):
|
||||
+ (b"xn--016c"+b"a"*70).decode("idna")
|
||||
+
|
||||
def test_stream(self):
|
||||
r = codecs.getreader("idna")(io.BytesIO(b"abc"))
|
||||
r.read(3)
|
||||
diff --git a/Misc/NEWS.d/next/Security/2022-11-04-09-29-36.gh-issue-98433.l76c5G.rst b/Misc/NEWS.d/next/Security/2022-11-04-09-29-36.gh-issue-98433.l76c5G.rst
|
||||
new file mode 100644
|
||||
index 000000000000..5185fac2e29d
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Security/2022-11-04-09-29-36.gh-issue-98433.l76c5G.rst
|
||||
@@ -0,0 +1,6 @@
|
||||
+The IDNA codec decoder used on DNS hostnames by :mod:`socket` or :mod:`asyncio`
|
||||
+related name resolution functions no longer involves a quadratic algorithm.
|
||||
+This prevents a potential CPU denial of service if an out-of-spec excessive
|
||||
+length hostname involving bidirectional characters were decoded. Some protocols
|
||||
+such as :mod:`urllib` http ``3xx`` redirects potentially allow for an attacker
|
||||
+to supply such a name.
|
||||
@@ -1,105 +0,0 @@
|
||||
From 948c6794711458fd148a3fa62296cadeeb2ed631 Mon Sep 17 00:00:00 2001
|
||||
From: "Miss Islington (bot)"
|
||||
<31488909+miss-islington@users.noreply.github.com>
|
||||
Date: Fri, 28 Oct 2022 03:07:50 -0700
|
||||
Subject: [PATCH] [3.8] gh-98517: Fix buffer overflows in _sha3 module
|
||||
(GH-98519) (#98527)
|
||||
|
||||
This is a port of the applicable part of XKCP's fix [1] for
|
||||
CVE-2022-37454 and avoids the segmentation fault and the infinite
|
||||
loop in the test cases published in [2].
|
||||
|
||||
[1]: https://github.com/XKCP/XKCP/commit/fdc6fef075f4e81d6b1bc38364248975e08e340a
|
||||
[2]: https://mouha.be/sha-3-buffer-overflow/
|
||||
|
||||
Regression test added by: Gregory P. Smith [Google LLC] <greg@krypto.org>
|
||||
(cherry picked from commit 0e4e058602d93b88256ff90bbef501ba20be9dd3)
|
||||
|
||||
Co-authored-by: Theo Buehler <botovq@users.noreply.github.com>
|
||||
|
||||
CVE: CVE-2022-37454
|
||||
Upstream-Status: Backport [https://github.com/python/cpython/commit/948c6794711458fd148a3fa62296cadeeb2ed631]
|
||||
Signed-off-by: Pawan Badganchi <Pawan.Badganchi@kpit.com>
|
||||
---
|
||||
Lib/test/test_hashlib.py | 9 +++++++++
|
||||
.../2022-10-21-13-31-47.gh-issue-98517.SXXGfV.rst | 1 +
|
||||
Modules/_sha3/kcp/KeccakSponge.inc | 15 ++++++++-------
|
||||
3 files changed, 18 insertions(+), 7 deletions(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Security/2022-10-21-13-31-47.gh-issue-98517.SXXGfV.rst
|
||||
|
||||
diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py
|
||||
index 8b53d23ef525..e6cec4e306e5 100644
|
||||
--- a/Lib/test/test_hashlib.py
|
||||
+++ b/Lib/test/test_hashlib.py
|
||||
@@ -434,6 +434,15 @@ def test_case_md5_huge(self, size):
|
||||
def test_case_md5_uintmax(self, size):
|
||||
self.check('md5', b'A'*size, '28138d306ff1b8281f1a9067e1a1a2b3')
|
||||
|
||||
+ @unittest.skipIf(sys.maxsize < _4G - 1, 'test cannot run on 32-bit systems')
|
||||
+ @bigmemtest(size=_4G - 1, memuse=1, dry_run=False)
|
||||
+ def test_sha3_update_overflow(self, size):
|
||||
+ """Regression test for gh-98517 CVE-2022-37454."""
|
||||
+ h = hashlib.sha3_224()
|
||||
+ h.update(b'\x01')
|
||||
+ h.update(b'\x01'*0xffff_ffff)
|
||||
+ self.assertEqual(h.hexdigest(), '80762e8ce6700f114fec0f621fd97c4b9c00147fa052215294cceeed')
|
||||
+
|
||||
# use the three examples from Federal Information Processing Standards
|
||||
# Publication 180-1, Secure Hash Standard, 1995 April 17
|
||||
# http://www.itl.nist.gov/div897/pubs/fip180-1.htm
|
||||
diff --git a/Misc/NEWS.d/next/Security/2022-10-21-13-31-47.gh-issue-98517.SXXGfV.rst b/Misc/NEWS.d/next/Security/2022-10-21-13-31-47.gh-issue-98517.SXXGfV.rst
|
||||
new file mode 100644
|
||||
index 000000000000..2d23a6ad93c7
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Security/2022-10-21-13-31-47.gh-issue-98517.SXXGfV.rst
|
||||
@@ -0,0 +1 @@
|
||||
+Port XKCP's fix for the buffer overflows in SHA-3 (CVE-2022-37454).
|
||||
diff --git a/Modules/_sha3/kcp/KeccakSponge.inc b/Modules/_sha3/kcp/KeccakSponge.inc
|
||||
index e10739deafa8..cf92e4db4d36 100644
|
||||
--- a/Modules/_sha3/kcp/KeccakSponge.inc
|
||||
+++ b/Modules/_sha3/kcp/KeccakSponge.inc
|
||||
@@ -171,7 +171,7 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat
|
||||
i = 0;
|
||||
curData = data;
|
||||
while(i < dataByteLen) {
|
||||
- if ((instance->byteIOIndex == 0) && (dataByteLen >= (i + rateInBytes))) {
|
||||
+ if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) {
|
||||
#ifdef SnP_FastLoop_Absorb
|
||||
/* processing full blocks first */
|
||||
|
||||
@@ -199,10 +199,10 @@ int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dat
|
||||
}
|
||||
else {
|
||||
/* normal lane: using the message queue */
|
||||
-
|
||||
- partialBlock = (unsigned int)(dataByteLen - i);
|
||||
- if (partialBlock+instance->byteIOIndex > rateInBytes)
|
||||
+ if (dataByteLen-i > rateInBytes-instance->byteIOIndex)
|
||||
partialBlock = rateInBytes-instance->byteIOIndex;
|
||||
+ else
|
||||
+ partialBlock = (unsigned int)(dataByteLen - i);
|
||||
#ifdef KeccakReference
|
||||
displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
|
||||
#endif
|
||||
@@ -281,7 +281,7 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte
|
||||
i = 0;
|
||||
curData = data;
|
||||
while(i < dataByteLen) {
|
||||
- if ((instance->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
|
||||
+ if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) {
|
||||
for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
|
||||
SnP_Permute(instance->state);
|
||||
SnP_ExtractBytes(instance->state, curData, 0, rateInBytes);
|
||||
@@ -299,9 +299,10 @@ int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByte
|
||||
SnP_Permute(instance->state);
|
||||
instance->byteIOIndex = 0;
|
||||
}
|
||||
- partialBlock = (unsigned int)(dataByteLen - i);
|
||||
- if (partialBlock+instance->byteIOIndex > rateInBytes)
|
||||
+ if (dataByteLen-i > rateInBytes-instance->byteIOIndex)
|
||||
partialBlock = rateInBytes-instance->byteIOIndex;
|
||||
+ else
|
||||
+ partialBlock = (unsigned int)(dataByteLen - i);
|
||||
i += partialBlock;
|
||||
|
||||
SnP_ExtractBytes(instance->state, curData, instance->byteIOIndex, partialBlock);
|
||||
80
meta/recipes-devtools/python/python3/CVE-2023-24329.patch
Normal file
80
meta/recipes-devtools/python/python3/CVE-2023-24329.patch
Normal file
@@ -0,0 +1,80 @@
|
||||
From 72d356e3584ebfb8e813a8e9f2cd3dccf233c0d9 Mon Sep 17 00:00:00 2001
|
||||
From: "Miss Islington (bot)"
|
||||
<31488909+miss-islington@users.noreply.github.com>
|
||||
Date: Sun, 13 Nov 2022 11:00:25 -0800
|
||||
Subject: [PATCH] gh-99418: Make urllib.parse.urlparse enforce that a scheme
|
||||
must begin with an alphabetical ASCII character. (GH-99421)
|
||||
|
||||
Prevent urllib.parse.urlparse from accepting schemes that don't begin with an alphabetical ASCII character.
|
||||
|
||||
RFC 3986 defines a scheme like this: `scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )`
|
||||
RFC 2234 defines an ALPHA like this: `ALPHA = %x41-5A / %x61-7A`
|
||||
|
||||
The WHATWG URL spec defines a scheme like this:
|
||||
`"A URL-scheme string must be one ASCII alpha, followed by zero or more of ASCII alphanumeric, U+002B (+), U+002D (-), and U+002E (.)."`
|
||||
(cherry picked from commit 439b9cfaf43080e91c4ad69f312f21fa098befc7)
|
||||
|
||||
Co-authored-by: Ben Kallus <49924171+kenballus@users.noreply.github.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/python/cpython/commit/72d356e3584ebfb8e813a8e9f2cd3dccf233c0d9]
|
||||
CVE: CVE-2023-24329
|
||||
Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
|
||||
---
|
||||
Lib/test/test_urlparse.py | 18 ++++++++++++++++++
|
||||
Lib/urllib/parse.py | 2 +-
|
||||
...22-11-12-15-45-51.gh-issue-99418.FxfAXS.rst | 2 ++
|
||||
3 files changed, 21 insertions(+), 1 deletion(-)
|
||||
create mode 100644 Misc/NEWS.d/next/Library/2022-11-12-15-45-51.gh-issue-99418.FxfAXS.rst
|
||||
|
||||
diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py
|
||||
index 0ad3bf1..e1aa913 100644
|
||||
--- a/Lib/test/test_urlparse.py
|
||||
+++ b/Lib/test/test_urlparse.py
|
||||
@@ -735,6 +735,24 @@ class UrlParseTestCase(unittest.TestCase):
|
||||
with self.assertRaises(ValueError):
|
||||
p.port
|
||||
|
||||
+ def test_attributes_bad_scheme(self):
|
||||
+ """Check handling of invalid schemes."""
|
||||
+ for bytes in (False, True):
|
||||
+ for parse in (urllib.parse.urlsplit, urllib.parse.urlparse):
|
||||
+ for scheme in (".", "+", "-", "0", "http&", "६http"):
|
||||
+ with self.subTest(bytes=bytes, parse=parse, scheme=scheme):
|
||||
+ url = scheme + "://www.example.net"
|
||||
+ if bytes:
|
||||
+ if url.isascii():
|
||||
+ url = url.encode("ascii")
|
||||
+ else:
|
||||
+ continue
|
||||
+ p = parse(url)
|
||||
+ if bytes:
|
||||
+ self.assertEqual(p.scheme, b"")
|
||||
+ else:
|
||||
+ self.assertEqual(p.scheme, "")
|
||||
+
|
||||
def test_attributes_without_netloc(self):
|
||||
# This example is straight from RFC 3261. It looks like it
|
||||
# should allow the username, hostname, and port to be filled
|
||||
diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
|
||||
index 979e6d2..2e7a3e2 100644
|
||||
--- a/Lib/urllib/parse.py
|
||||
+++ b/Lib/urllib/parse.py
|
||||
@@ -452,7 +452,7 @@ def urlsplit(url, scheme='', allow_fragments=True):
|
||||
clear_cache()
|
||||
netloc = query = fragment = ''
|
||||
i = url.find(':')
|
||||
- if i > 0:
|
||||
+ if i > 0 and url[0].isascii() and url[0].isalpha():
|
||||
if url[:i] == 'http': # optimize the common case
|
||||
url = url[i+1:]
|
||||
if url[:2] == '//':
|
||||
diff --git a/Misc/NEWS.d/next/Library/2022-11-12-15-45-51.gh-issue-99418.FxfAXS.rst b/Misc/NEWS.d/next/Library/2022-11-12-15-45-51.gh-issue-99418.FxfAXS.rst
|
||||
new file mode 100644
|
||||
index 0000000..0a06e7c
|
||||
--- /dev/null
|
||||
+++ b/Misc/NEWS.d/next/Library/2022-11-12-15-45-51.gh-issue-99418.FxfAXS.rst
|
||||
@@ -0,0 +1,2 @@
|
||||
+Fix bug in :func:`urllib.parse.urlparse` that causes URL schemes that begin
|
||||
+with a digit, a plus sign, or a minus sign to be parsed incorrectly.
|
||||
--
|
||||
2.25.1
|
||||
@@ -4,7 +4,7 @@ DESCRIPTION = "Python is a programming language that lets you work more quickly
|
||||
LICENSE = "PSF-2.0 & BSD-0-Clause"
|
||||
SECTION = "devel/python"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://LICENSE;md5=c84eccf626bb6fde43e6ea5e28d8feb5"
|
||||
LIC_FILES_CHKSUM = "file://LICENSE;md5=07fc4b9a9c0c0e48050ed38a5e72552b"
|
||||
|
||||
SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
|
||||
file://run-ptest \
|
||||
@@ -34,8 +34,7 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
|
||||
file://0001-python3-Do-not-hardcode-lib-for-distutils.patch \
|
||||
file://0020-configure.ac-setup.py-do-not-add-a-curses-include-pa.patch \
|
||||
file://makerace.patch \
|
||||
file://CVE-2022-45061.patch \
|
||||
file://CVE-2022-37454.patch \
|
||||
file://CVE-2023-24329.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_class-native = " \
|
||||
@@ -44,8 +43,8 @@ SRC_URI_append_class-native = " \
|
||||
file://0001-Don-t-search-system-for-headers-libraries.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "78710eed185b71f4198d354502ff62c9"
|
||||
SRC_URI[sha256sum] = "5d77e278271ba803e9909a41a4f3baca006181c93ada682a5e5fe8dc4a24c5f3"
|
||||
SRC_URI[md5sum] = "70223497e664524303ca2364208647e1"
|
||||
SRC_URI[sha256sum] = "2e54b0c68191f16552f6de2e97a2396540572a219f6bbb28591a137cecc490a9"
|
||||
|
||||
# exclude pre-releases for both python 2.x and 3.x
|
||||
UPSTREAM_CHECK_REGEX = "[Pp]ython-(?P<pver>\d+(\.\d+)+).tar"
|
||||
@@ -62,6 +61,8 @@ CVE_CHECK_WHITELIST += "CVE-2020-15523 CVE-2022-26488"
|
||||
# The mailcap module is insecure by design, so this can't be fixed in a meaningful way.
|
||||
# The module will be removed in the future and flaws documented.
|
||||
CVE_CHECK_WHITELIST += "CVE-2015-20107"
|
||||
# Not an issue, in fact expected behaviour
|
||||
CVE_CHECK_WHITELIST += "CVE-2023-36632"
|
||||
|
||||
PYTHON_MAJMIN = "3.8"
|
||||
|
||||
@@ -137,6 +137,10 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
|
||||
file://CVE-2021-3409-4.patch \
|
||||
file://CVE-2021-3409-5.patch \
|
||||
file://hw-display-qxl-Pass-requested-buffer-size-to-qxl_phy.patch \
|
||||
file://CVE-2023-0330_1.patch \
|
||||
file://CVE-2023-0330_2.patch \
|
||||
file://CVE-2023-3354.patch \
|
||||
file://CVE-2023-3180.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
|
||||
|
||||
|
||||
@@ -20,16 +20,19 @@ Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
Tested-by: Alexander Bulekov <alxndr@bu.edu>
|
||||
Message-Id: <20210407195801.685-7-mark.cave-ayland@ilande.co.uk>
|
||||
|
||||
CVE: CVE-2020-35504
|
||||
CVE: CVE-2020-35505
|
||||
Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/qemu/tree/debian/patches/CVE-2020-35505.patch?h=ubuntu/focal-security Upstream commit https://github.com/qemu/qemu/commit/99545751734035b76bd372c4e7215bb337428d89 ]
|
||||
Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
|
||||
Signed-off-by: Emily Vekariya <emily.vekariya@einfochips.com>
|
||||
---
|
||||
hw/scsi/esp.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
hw/scsi/esp.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
|
||||
index c7d701bf..c2a67bc8 100644
|
||||
--- a/hw/scsi/esp.c
|
||||
+++ b/hw/scsi/esp.c
|
||||
@@ -193,6 +193,10 @@ static void do_busid_cmd(ESPState *s, ui
|
||||
@@ -193,6 +193,10 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
|
||||
|
||||
trace_esp_do_busid_cmd(busid);
|
||||
lun = busid & 7;
|
||||
|
||||
77
meta/recipes-devtools/qemu/qemu/CVE-2023-0330_1.patch
Normal file
77
meta/recipes-devtools/qemu/qemu/CVE-2023-0330_1.patch
Normal file
@@ -0,0 +1,77 @@
|
||||
[Ubuntu note: remove fuzz-lsi53c895a-test.c changes since the file does not
|
||||
exist for this release]
|
||||
From b987718bbb1d0eabf95499b976212dd5f0120d75 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Huth <thuth@redhat.com>
|
||||
Date: Mon, 22 May 2023 11:10:11 +0200
|
||||
Subject: [PATCH] hw/scsi/lsi53c895a: Fix reentrancy issues in the LSI
|
||||
controller (CVE-2023-0330)
|
||||
|
||||
We cannot use the generic reentrancy guard in the LSI code, so
|
||||
we have to manually prevent endless reentrancy here. The problematic
|
||||
lsi_execute_script() function has already a way to detect whether
|
||||
too many instructions have been executed - we just have to slightly
|
||||
change the logic here that it also takes into account if the function
|
||||
has been called too often in a reentrant way.
|
||||
|
||||
The code in fuzz-lsi53c895a-test.c has been taken from an earlier
|
||||
patch by Mauro Matteo Cascella.
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1563
|
||||
Message-Id: <20230522091011.1082574-1-thuth@redhat.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Reference: https://launchpad.net/ubuntu/+source/qemu/1:4.2-3ubuntu6.27
|
||||
|
||||
Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/qemu/tree/debian/patches/CVE-2023-0330.patch?h=ubuntu/focal-security
|
||||
Upstream commit https://gitlab.com/qemu-project/qemu/-/commit/b987718bbb1d0eabf95499b976212dd5f0120d75]
|
||||
CVE: CVE-2023-0330
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
hw/scsi/lsi53c895a.c | 23 +++++++++++++++------
|
||||
tests/qtest/fuzz-lsi53c895a-test.c | 33 ++++++++++++++++++++++++++++++
|
||||
2 files changed, 50 insertions(+), 6 deletions(-)
|
||||
|
||||
--- qemu-4.2.orig/hw/scsi/lsi53c895a.c
|
||||
+++ qemu-4.2/hw/scsi/lsi53c895a.c
|
||||
@@ -1135,15 +1135,24 @@ static void lsi_execute_script(LSIState
|
||||
uint32_t addr, addr_high;
|
||||
int opcode;
|
||||
int insn_processed = 0;
|
||||
+ static int reentrancy_level;
|
||||
+
|
||||
+ reentrancy_level++;
|
||||
|
||||
s->istat1 |= LSI_ISTAT1_SRUN;
|
||||
again:
|
||||
- if (++insn_processed > LSI_MAX_INSN) {
|
||||
- /* Some windows drivers make the device spin waiting for a memory
|
||||
- location to change. If we have been executed a lot of code then
|
||||
- assume this is the case and force an unexpected device disconnect.
|
||||
- This is apparently sufficient to beat the drivers into submission.
|
||||
- */
|
||||
+ /*
|
||||
+ * Some windows drivers make the device spin waiting for a memory location
|
||||
+ * to change. If we have executed more than LSI_MAX_INSN instructions then
|
||||
+ * assume this is the case and force an unexpected device disconnect. This
|
||||
+ * is apparently sufficient to beat the drivers into submission.
|
||||
+ *
|
||||
+ * Another issue (CVE-2023-0330) can occur if the script is programmed to
|
||||
+ * trigger itself again and again. Avoid this problem by stopping after
|
||||
+ * being called multiple times in a reentrant way (8 is an arbitrary value
|
||||
+ * which should be enough for all valid use cases).
|
||||
+ */
|
||||
+ if (++insn_processed > LSI_MAX_INSN || reentrancy_level > 8) {
|
||||
if (!(s->sien0 & LSI_SIST0_UDC)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"lsi_scsi: inf. loop with UDC masked");
|
||||
@@ -1597,6 +1606,8 @@ again:
|
||||
}
|
||||
}
|
||||
trace_lsi_execute_script_stop();
|
||||
+
|
||||
+ reentrancy_level--;
|
||||
}
|
||||
|
||||
static uint8_t lsi_reg_readb(LSIState *s, int offset)
|
||||
135
meta/recipes-devtools/qemu/qemu/CVE-2023-0330_2.patch
Normal file
135
meta/recipes-devtools/qemu/qemu/CVE-2023-0330_2.patch
Normal file
@@ -0,0 +1,135 @@
|
||||
From a2e1753b8054344f32cf94f31c6399a58794a380 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Bulekov <alxndr@bu.edu>
|
||||
Date: Thu, 27 Apr 2023 17:10:06 -0400
|
||||
Subject: [PATCH] memory: prevent dma-reentracy issues
|
||||
|
||||
Add a flag to the DeviceState, when a device is engaged in PIO/MMIO/DMA.
|
||||
This flag is set/checked prior to calling a device's MemoryRegion
|
||||
handlers, and set when device code initiates DMA. The purpose of this
|
||||
flag is to prevent two types of DMA-based reentrancy issues:
|
||||
|
||||
1.) mmio -> dma -> mmio case
|
||||
2.) bh -> dma write -> mmio case
|
||||
|
||||
These issues have led to problems such as stack-exhaustion and
|
||||
use-after-frees.
|
||||
|
||||
Summary of the problem from Peter Maydell:
|
||||
https://lore.kernel.org/qemu-devel/CAFEAcA_23vc7hE3iaM-JVA6W38LK4hJoWae5KcknhPRD5fPBZA@mail.gmail.com
|
||||
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/62
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/540
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/541
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/556
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/557
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/827
|
||||
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1282
|
||||
Resolves: CVE-2023-0330
|
||||
|
||||
Signed-off-by: Alexander Bulekov <alxndr@bu.edu>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-Id: <20230427211013.2994127-2-alxndr@bu.edu>
|
||||
[thuth: Replace warn_report() with warn_report_once()]
|
||||
Signed-off-by: Thomas Huth <thuth@redhat.com>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/a2e1753b8054344f32cf94f31c6399a58794a380]
|
||||
CVE: CVE-2023-0330
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
include/exec/memory.h | 5 +++++
|
||||
include/hw/qdev-core.h | 7 +++++++
|
||||
memory.c | 16 ++++++++++++++++
|
||||
3 files changed, 28 insertions(+)
|
||||
|
||||
diff --git a/include/exec/memory.h b/include/exec/memory.h
|
||||
index 2b8bccdd..0c8cdb8e 100644
|
||||
--- a/include/exec/memory.h
|
||||
+++ b/include/exec/memory.h
|
||||
@@ -378,6 +378,8 @@ struct MemoryRegion {
|
||||
bool is_iommu;
|
||||
RAMBlock *ram_block;
|
||||
Object *owner;
|
||||
+ /* owner as TYPE_DEVICE. Used for re-entrancy checks in MR access hotpath */
|
||||
+ DeviceState *dev;
|
||||
|
||||
const MemoryRegionOps *ops;
|
||||
void *opaque;
|
||||
@@ -400,6 +402,9 @@ struct MemoryRegion {
|
||||
const char *name;
|
||||
unsigned ioeventfd_nb;
|
||||
MemoryRegionIoeventfd *ioeventfds;
|
||||
+
|
||||
+ /* For devices designed to perform re-entrant IO into their own IO MRs */
|
||||
+ bool disable_reentrancy_guard;
|
||||
};
|
||||
|
||||
struct IOMMUMemoryRegion {
|
||||
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
|
||||
index 1518495b..206f0a70 100644
|
||||
--- a/include/hw/qdev-core.h
|
||||
+++ b/include/hw/qdev-core.h
|
||||
@@ -138,6 +138,10 @@ struct NamedGPIOList {
|
||||
QLIST_ENTRY(NamedGPIOList) node;
|
||||
};
|
||||
|
||||
+typedef struct {
|
||||
+ bool engaged_in_io;
|
||||
+} MemReentrancyGuard;
|
||||
+
|
||||
/**
|
||||
* DeviceState:
|
||||
* @realized: Indicates whether the device has been fully constructed.
|
||||
@@ -163,6 +167,9 @@ struct DeviceState {
|
||||
int num_child_bus;
|
||||
int instance_id_alias;
|
||||
int alias_required_for_version;
|
||||
+
|
||||
+ /* Is the device currently in mmio/pio/dma? Used to prevent re-entrancy */
|
||||
+ MemReentrancyGuard mem_reentrancy_guard;
|
||||
};
|
||||
|
||||
struct DeviceListener {
|
||||
diff --git a/memory.c b/memory.c
|
||||
index 8cafb86a..94ebcaf9 100644
|
||||
--- a/memory.c
|
||||
+++ b/memory.c
|
||||
@@ -531,6 +531,18 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
|
||||
access_size_max = 4;
|
||||
}
|
||||
|
||||
+ /* Do not allow more than one simultaneous access to a device's IO Regions */
|
||||
+ if (mr->dev && !mr->disable_reentrancy_guard &&
|
||||
+ !mr->ram_device && !mr->ram && !mr->rom_device && !mr->readonly) {
|
||||
+ if (mr->dev->mem_reentrancy_guard.engaged_in_io) {
|
||||
+ warn_report_once("Blocked re-entrant IO on MemoryRegion: "
|
||||
+ "%s at addr: 0x%" HWADDR_PRIX,
|
||||
+ memory_region_name(mr), addr);
|
||||
+ return MEMTX_ACCESS_ERROR;
|
||||
+ }
|
||||
+ mr->dev->mem_reentrancy_guard.engaged_in_io = true;
|
||||
+ }
|
||||
+
|
||||
/* FIXME: support unaligned access? */
|
||||
access_size = MAX(MIN(size, access_size_max), access_size_min);
|
||||
access_mask = MAKE_64BIT_MASK(0, access_size * 8);
|
||||
@@ -545,6 +557,9 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
|
||||
access_mask, attrs);
|
||||
}
|
||||
}
|
||||
+ if (mr->dev) {
|
||||
+ mr->dev->mem_reentrancy_guard.engaged_in_io = false;
|
||||
+ }
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -1132,6 +1147,7 @@ static void memory_region_do_init(MemoryRegion *mr,
|
||||
}
|
||||
mr->name = g_strdup(name);
|
||||
mr->owner = owner;
|
||||
+ mr->dev = (DeviceState *) object_dynamic_cast(mr->owner, TYPE_DEVICE);
|
||||
mr->ram_block = NULL;
|
||||
|
||||
if (name) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
49
meta/recipes-devtools/qemu/qemu/CVE-2023-3180.patch
Normal file
49
meta/recipes-devtools/qemu/qemu/CVE-2023-3180.patch
Normal file
@@ -0,0 +1,49 @@
|
||||
From 9d38a8434721a6479fe03fb5afb150ca793d3980 Mon Sep 17 00:00:00 2001
|
||||
From: zhenwei pi <pizhenwei@bytedance.com>
|
||||
Date: Thu, 3 Aug 2023 10:43:13 +0800
|
||||
Subject: [PATCH] virtio-crypto: verify src&dst buffer length for sym request
|
||||
|
||||
For symmetric algorithms, the length of ciphertext must be as same
|
||||
as the plaintext.
|
||||
The missing verification of the src_len and the dst_len in
|
||||
virtio_crypto_sym_op_helper() may lead buffer overflow/divulged.
|
||||
|
||||
This patch is originally written by Yiming Tao for QEMU-SECURITY,
|
||||
resend it(a few changes of error message) in qemu-devel.
|
||||
|
||||
Fixes: CVE-2023-3180
|
||||
Fixes: 04b9b37edda("virtio-crypto: add data queue processing handler")
|
||||
Cc: Gonglei <arei.gonglei@huawei.com>
|
||||
Cc: Mauro Matteo Cascella <mcascell@redhat.com>
|
||||
Cc: Yiming Tao <taoym@zju.edu.cn>
|
||||
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
|
||||
Message-Id: <20230803024314.29962-2-pizhenwei@bytedance.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
|
||||
Upstream-Status: Backport from [https://gitlab.com/qemu-project/qemu/-/commit/9d38a8434721a6479fe03fb5afb150ca793d3980]
|
||||
CVE: CVE-2023-3180
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
|
||||
hw/virtio/virtio-crypto.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
|
||||
index 44faf5a522b..13aec771e11 100644
|
||||
--- a/hw/virtio/virtio-crypto.c
|
||||
+++ b/hw/virtio/virtio-crypto.c
|
||||
@@ -634,6 +634,11 @@ virtio_crypto_sym_op_helper(VirtIODevice *vdev,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ if (unlikely(src_len != dst_len)) {
|
||||
+ virtio_error(vdev, "sym request src len is different from dst len");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
max_len = (uint64_t)iv_len + aad_len + src_len + dst_len + hash_result_len;
|
||||
if (unlikely(max_len > vcrypto->conf.max_size)) {
|
||||
virtio_error(vdev, "virtio-crypto too big length");
|
||||
--
|
||||
GitLab
|
||||
|
||||
87
meta/recipes-devtools/qemu/qemu/CVE-2023-3354.patch
Normal file
87
meta/recipes-devtools/qemu/qemu/CVE-2023-3354.patch
Normal file
@@ -0,0 +1,87 @@
|
||||
From 10be627d2b5ec2d6b3dce045144aa739eef678b4 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Tue, 20 Jun 2023 09:45:34 +0100
|
||||
Subject: [PATCH] io: remove io watch if TLS channel is closed during handshake
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The TLS handshake make take some time to complete, during which time an
|
||||
I/O watch might be registered with the main loop. If the owner of the
|
||||
I/O channel invokes qio_channel_close() while the handshake is waiting
|
||||
to continue the I/O watch must be removed. Failing to remove it will
|
||||
later trigger the completion callback which the owner is not expecting
|
||||
to receive. In the case of the VNC server, this results in a SEGV as
|
||||
vnc_disconnect_start() tries to shutdown a client connection that is
|
||||
already gone / NULL.
|
||||
|
||||
CVE-2023-3354
|
||||
Reported-by: jiangyegen <jiangyegen@huawei.com>
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/10be627d2b5ec2d6b3dce045144aa739eef678b4]
|
||||
CVE: CVE-2023-3354
|
||||
Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
|
||||
---
|
||||
include/io/channel-tls.h | 1 +
|
||||
io/channel-tls.c | 18 ++++++++++++------
|
||||
2 files changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/include/io/channel-tls.h b/include/io/channel-tls.h
|
||||
index fdbdf12f..e49e2831 100644
|
||||
--- a/include/io/channel-tls.h
|
||||
+++ b/include/io/channel-tls.h
|
||||
@@ -49,6 +49,7 @@ struct QIOChannelTLS {
|
||||
QIOChannel *master;
|
||||
QCryptoTLSSession *session;
|
||||
QIOChannelShutdown shutdown;
|
||||
+ guint hs_ioc_tag;
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/io/channel-tls.c b/io/channel-tls.c
|
||||
index 7ec8ceff..8b32fbde 100644
|
||||
--- a/io/channel-tls.c
|
||||
+++ b/io/channel-tls.c
|
||||
@@ -194,12 +194,13 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
|
||||
}
|
||||
|
||||
trace_qio_channel_tls_handshake_pending(ioc, status);
|
||||
- qio_channel_add_watch_full(ioc->master,
|
||||
- condition,
|
||||
- qio_channel_tls_handshake_io,
|
||||
- data,
|
||||
- NULL,
|
||||
- context);
|
||||
+ ioc->hs_ioc_tag =
|
||||
+ qio_channel_add_watch_full(ioc->master,
|
||||
+ condition,
|
||||
+ qio_channel_tls_handshake_io,
|
||||
+ data,
|
||||
+ NULL,
|
||||
+ context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +215,7 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
|
||||
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(
|
||||
qio_task_get_source(task));
|
||||
|
||||
+ tioc->hs_ioc_tag = 0;
|
||||
g_free(data);
|
||||
qio_channel_tls_handshake_task(tioc, task, context);
|
||||
|
||||
@@ -371,6 +373,10 @@ static int qio_channel_tls_close(QIOChannel *ioc,
|
||||
{
|
||||
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
|
||||
|
||||
+ if (tioc->hs_ioc_tag) {
|
||||
+ g_clear_handle_id(&tioc->hs_ioc_tag, g_source_remove);
|
||||
+ }
|
||||
+
|
||||
return qio_channel_close(tioc->master, errp);
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
139
meta/recipes-devtools/ruby/ruby/CVE-2021-33621.patch
Normal file
139
meta/recipes-devtools/ruby/ruby/CVE-2021-33621.patch
Normal file
@@ -0,0 +1,139 @@
|
||||
From 64c5045c0a6b84fdb938a8465a0890e5f7162708 Mon Sep 17 00:00:00 2001
|
||||
From: Yusuke Endoh <mame@ruby-lang.org>
|
||||
Date: Tue, 22 Nov 2022 10:49:27 +0900
|
||||
Subject: [PATCH] Prevent CRLF injection
|
||||
|
||||
Throw a RuntimeError if the HTTP response header contains CR or LF to
|
||||
prevent HTTP response splitting.
|
||||
|
||||
https://hackerone.com/reports/1204695
|
||||
|
||||
Upstream-Status: Backport [https://github.com/ruby/cgi/commit/64c5045c0a6b84fdb938a8465a0890e5f7162708]
|
||||
CVE: CVE-2021-33621
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
lib/cgi/core.rb | 45 +++++++++++++++++++++++--------------
|
||||
test/cgi/test_cgi_header.rb | 8 +++++++
|
||||
2 files changed, 36 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
|
||||
index bec76e0..62e6068 100644
|
||||
--- a/lib/cgi/core.rb
|
||||
+++ b/lib/cgi/core.rb
|
||||
@@ -188,17 +188,28 @@ class CGI
|
||||
# Using #header with the HTML5 tag maker will create a <header> element.
|
||||
alias :header :http_header
|
||||
|
||||
+ def _no_crlf_check(str)
|
||||
+ if str
|
||||
+ str = str.to_s
|
||||
+ raise "A HTTP status or header field must not include CR and LF" if str =~ /[\r\n]/
|
||||
+ str
|
||||
+ else
|
||||
+ nil
|
||||
+ end
|
||||
+ end
|
||||
+ private :_no_crlf_check
|
||||
+
|
||||
def _header_for_string(content_type) #:nodoc:
|
||||
buf = ''.dup
|
||||
if nph?()
|
||||
- buf << "#{$CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'} 200 OK#{EOL}"
|
||||
+ buf << "#{_no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'} 200 OK#{EOL}"
|
||||
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||
- buf << "Server: #{$CGI_ENV['SERVER_SOFTWARE']}#{EOL}"
|
||||
+ buf << "Server: #{_no_crlf_check($CGI_ENV['SERVER_SOFTWARE'])}#{EOL}"
|
||||
buf << "Connection: close#{EOL}"
|
||||
end
|
||||
- buf << "Content-Type: #{content_type}#{EOL}"
|
||||
+ buf << "Content-Type: #{_no_crlf_check(content_type)}#{EOL}"
|
||||
if @output_cookies
|
||||
- @output_cookies.each {|cookie| buf << "Set-Cookie: #{cookie}#{EOL}" }
|
||||
+ @output_cookies.each {|cookie| buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}" }
|
||||
end
|
||||
return buf
|
||||
end # _header_for_string
|
||||
@@ -213,9 +224,9 @@ class CGI
|
||||
## NPH
|
||||
options.delete('nph') if defined?(MOD_RUBY)
|
||||
if options.delete('nph') || nph?()
|
||||
- protocol = $CGI_ENV['SERVER_PROTOCOL'] || 'HTTP/1.0'
|
||||
+ protocol = _no_crlf_check($CGI_ENV['SERVER_PROTOCOL']) || 'HTTP/1.0'
|
||||
status = options.delete('status')
|
||||
- status = HTTP_STATUS[status] || status || '200 OK'
|
||||
+ status = HTTP_STATUS[status] || _no_crlf_check(status) || '200 OK'
|
||||
buf << "#{protocol} #{status}#{EOL}"
|
||||
buf << "Date: #{CGI.rfc1123_date(Time.now)}#{EOL}"
|
||||
options['server'] ||= $CGI_ENV['SERVER_SOFTWARE'] || ''
|
||||
@@ -223,38 +234,38 @@ class CGI
|
||||
end
|
||||
## common headers
|
||||
status = options.delete('status')
|
||||
- buf << "Status: #{HTTP_STATUS[status] || status}#{EOL}" if status
|
||||
+ buf << "Status: #{HTTP_STATUS[status] || _no_crlf_check(status)}#{EOL}" if status
|
||||
server = options.delete('server')
|
||||
- buf << "Server: #{server}#{EOL}" if server
|
||||
+ buf << "Server: #{_no_crlf_check(server)}#{EOL}" if server
|
||||
connection = options.delete('connection')
|
||||
- buf << "Connection: #{connection}#{EOL}" if connection
|
||||
+ buf << "Connection: #{_no_crlf_check(connection)}#{EOL}" if connection
|
||||
type = options.delete('type')
|
||||
- buf << "Content-Type: #{type}#{EOL}" #if type
|
||||
+ buf << "Content-Type: #{_no_crlf_check(type)}#{EOL}" #if type
|
||||
length = options.delete('length')
|
||||
- buf << "Content-Length: #{length}#{EOL}" if length
|
||||
+ buf << "Content-Length: #{_no_crlf_check(length)}#{EOL}" if length
|
||||
language = options.delete('language')
|
||||
- buf << "Content-Language: #{language}#{EOL}" if language
|
||||
+ buf << "Content-Language: #{_no_crlf_check(language)}#{EOL}" if language
|
||||
expires = options.delete('expires')
|
||||
buf << "Expires: #{CGI.rfc1123_date(expires)}#{EOL}" if expires
|
||||
## cookie
|
||||
if cookie = options.delete('cookie')
|
||||
case cookie
|
||||
when String, Cookie
|
||||
- buf << "Set-Cookie: #{cookie}#{EOL}"
|
||||
+ buf << "Set-Cookie: #{_no_crlf_check(cookie)}#{EOL}"
|
||||
when Array
|
||||
arr = cookie
|
||||
- arr.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ arr.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
when Hash
|
||||
hash = cookie
|
||||
- hash.each_value {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ hash.each_value {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
end
|
||||
end
|
||||
if @output_cookies
|
||||
- @output_cookies.each {|c| buf << "Set-Cookie: #{c}#{EOL}" }
|
||||
+ @output_cookies.each {|c| buf << "Set-Cookie: #{_no_crlf_check(c)}#{EOL}" }
|
||||
end
|
||||
## other headers
|
||||
options.each do |key, value|
|
||||
- buf << "#{key}: #{value}#{EOL}"
|
||||
+ buf << "#{_no_crlf_check(key)}: #{_no_crlf_check(value)}#{EOL}"
|
||||
end
|
||||
return buf
|
||||
end # _header_for_hash
|
||||
diff --git a/test/cgi/test_cgi_header.rb b/test/cgi/test_cgi_header.rb
|
||||
index bab2d03..ec2f4de 100644
|
||||
--- a/test/cgi/test_cgi_header.rb
|
||||
+++ b/test/cgi/test_cgi_header.rb
|
||||
@@ -176,6 +176,14 @@ class CGIHeaderTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
|
||||
+ def test_cgi_http_header_crlf_injection
|
||||
+ cgi = CGI.new
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("text/xhtml\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("type" => "text/xhtml\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("status" => "200 OK\r\nBOO") }
|
||||
+ assert_raise(RuntimeError) { cgi.http_header("location" => "text/xhtml\r\nBOO") }
|
||||
+ end
|
||||
+
|
||||
|
||||
instance_methods.each do |method|
|
||||
private method if method =~ /^test_(.*)/ && $1 != ENV['TEST']
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -8,6 +8,7 @@ SRC_URI += " \
|
||||
file://0001-Modify-shebang-of-libexec-y2racc-and-libexec-racc2y.patch \
|
||||
file://0001-template-Makefile.in-do-not-write-host-cross-cc-item.patch \
|
||||
file://CVE-2023-28756.patch \
|
||||
file://CVE-2021-33621.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "f972fb0cce662966bec10d5c5f32d042"
|
||||
|
||||
@@ -14,6 +14,8 @@ SRC_URI = "https://github.com/apple/cups/releases/download/v${PV}/${BP}-source.t
|
||||
file://0003-cups_1.4.6.bb-Fix-build-on-ppc64.patch \
|
||||
file://0004-cups-fix-multilib-install-file-conflicts.patch\
|
||||
file://CVE-2022-26691.patch \
|
||||
file://CVE-2023-32324.patch \
|
||||
file://CVE-2023-34241.patch \
|
||||
"
|
||||
|
||||
UPSTREAM_CHECK_URI = "https://github.com/apple/cups/releases"
|
||||
|
||||
36
meta/recipes-extended/cups/cups/CVE-2023-32324.patch
Normal file
36
meta/recipes-extended/cups/cups/CVE-2023-32324.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 07cbffd11107eed3aaf1c64e35552aec20f792da Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Dohnal <zdohnal@redhat.com>
|
||||
Date: Thu, 1 Jun 2023 12:04:00 +0200
|
||||
Subject: [PATCH] cups/string.c: Return if `size` is 0 (fixes CVE-2023-32324)
|
||||
|
||||
CVE: CVE-2023-32324
|
||||
Upstream-Status: Backport [https://github.com/OpenPrinting/cups/commit/fd8bc2d32589]
|
||||
|
||||
(cherry picked from commit fd8bc2d32589d1fd91fe1c0521be2a7c0462109e)
|
||||
Signed-off-by: Sanjay Chitroda <schitrod@cisco.com>
|
||||
---
|
||||
cups/string.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/cups/string.c b/cups/string.c
|
||||
index 93cdad19..6ef58515 100644
|
||||
--- a/cups/string.c
|
||||
+++ b/cups/string.c
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* String functions for CUPS.
|
||||
*
|
||||
+ * Copyright © 2023 by OpenPrinting.
|
||||
* Copyright © 2007-2019 by Apple Inc.
|
||||
* Copyright © 1997-2007 by Easy Software Products.
|
||||
*
|
||||
@@ -730,6 +731,9 @@ _cups_strlcpy(char *dst, /* O - Destination string */
|
||||
size_t srclen; /* Length of source string */
|
||||
|
||||
|
||||
+ if (size == 0)
|
||||
+ return (0);
|
||||
+
|
||||
/*
|
||||
* Figure out how much room is needed...
|
||||
*/
|
||||
65
meta/recipes-extended/cups/cups/CVE-2023-34241.patch
Normal file
65
meta/recipes-extended/cups/cups/CVE-2023-34241.patch
Normal file
@@ -0,0 +1,65 @@
|
||||
From ffd290b4ab247f82722927ba9b21358daa16dbf1 Mon Sep 17 00:00:00 2001
|
||||
From: Rose <83477269+AtariDreams@users.noreply.github.com>
|
||||
Date: Thu, 1 Jun 2023 11:33:39 -0400
|
||||
Subject: [PATCH] Log result of httpGetHostname BEFORE closing the connection
|
||||
|
||||
httpClose frees the memory of con->http. This is problematic because httpGetHostname then tries to access the memory it points to.
|
||||
|
||||
We have to log the hostname first.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/OpenPrinting/cups/commit/9809947a959e18409dcf562a3466ef246cb90cb2]
|
||||
CVE: CVE-2023-34241
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
scheduler/client.c | 16 +++++++---------
|
||||
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/scheduler/client.c b/scheduler/client.c
|
||||
index 91e441188c..327473a4d1 100644
|
||||
--- a/scheduler/client.c
|
||||
+++ b/scheduler/client.c
|
||||
@@ -193,13 +193,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
|
||||
/*
|
||||
* Can't have an unresolved IP address with double-lookups enabled...
|
||||
*/
|
||||
-
|
||||
- httpClose(con->http);
|
||||
-
|
||||
cupsdLogClient(con, CUPSD_LOG_WARN,
|
||||
- "Name lookup failed - connection from %s closed!",
|
||||
+ "Name lookup failed - closing connection from %s!",
|
||||
httpGetHostname(con->http, NULL, 0));
|
||||
|
||||
+ httpClose(con->http);
|
||||
free(con);
|
||||
return;
|
||||
}
|
||||
@@ -235,11 +233,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
|
||||
* with double-lookups enabled...
|
||||
*/
|
||||
|
||||
- httpClose(con->http);
|
||||
-
|
||||
cupsdLogClient(con, CUPSD_LOG_WARN,
|
||||
- "IP lookup failed - connection from %s closed!",
|
||||
+ "IP lookup failed - closing connection from %s!",
|
||||
httpGetHostname(con->http, NULL, 0));
|
||||
+
|
||||
+ httpClose(con->http);
|
||||
free(con);
|
||||
return;
|
||||
}
|
||||
@@ -256,11 +254,11 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */
|
||||
|
||||
if (!hosts_access(&wrap_req))
|
||||
{
|
||||
- httpClose(con->http);
|
||||
-
|
||||
cupsdLogClient(con, CUPSD_LOG_WARN,
|
||||
"Connection from %s refused by /etc/hosts.allow and "
|
||||
"/etc/hosts.deny rules.", httpGetHostname(con->http, NULL, 0));
|
||||
+
|
||||
+ httpClose(con->http);
|
||||
free(con);
|
||||
return;
|
||||
}
|
||||
24
meta/recipes-extended/gawk/gawk/remove-sensitive-tests.patch
Normal file
24
meta/recipes-extended/gawk/gawk/remove-sensitive-tests.patch
Normal file
@@ -0,0 +1,24 @@
|
||||
These tests require an unloaded host as otherwise timing sensitive tests can fail
|
||||
https://bugzilla.yoctoproject.org/show_bug.cgi?id=14371
|
||||
|
||||
Upstream-Status: Inappropriate
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
--- a/test/Maketests~
|
||||
+++ b/test/Maketests
|
||||
@@ -2069,7 +2069,2 @@
|
||||
|
||||
-timeout:
|
||||
- @echo $@ $(ZOS_FAIL)
|
||||
- @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
|
||||
- @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
|
||||
-
|
||||
typedregex1:
|
||||
@@ -2297,7 +2292,2 @@
|
||||
@-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
|
||||
-
|
||||
-time:
|
||||
- @echo $@
|
||||
- @AWKPATH="$(srcdir)" $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
|
||||
- @-$(CMP) "$(srcdir)"/$@.ok _$@ && rm -f _$@
|
||||
|
||||
@@ -16,6 +16,7 @@ PACKAGECONFIG[readline] = "--with-readline,--without-readline,readline"
|
||||
PACKAGECONFIG[mpfr] = "--with-mpfr,--without-mpfr, mpfr"
|
||||
|
||||
SRC_URI = "${GNU_MIRROR}/gawk/gawk-${PV}.tar.gz \
|
||||
file://remove-sensitive-tests.patch \
|
||||
file://run-ptest \
|
||||
"
|
||||
|
||||
@@ -41,13 +42,20 @@ inherit ptest
|
||||
do_install_ptest() {
|
||||
mkdir ${D}${PTEST_PATH}/test
|
||||
ln -s ${bindir}/gawk ${D}${PTEST_PATH}/gawk
|
||||
for i in `grep -vE "@|^$|#|Gt-dummy" ${S}/test/Maketests |awk -F: '{print $1}'` Maketests inclib.awk; \
|
||||
do cp ${S}/test/$i* ${D}${PTEST_PATH}/test; \
|
||||
# The list of tests is all targets in Maketests, apart from the dummy Gt-dummy
|
||||
TESTS=$(awk -F: '$1 == "Gt-dummy" { next } /[[:alnum:]]+:$/ { print $1 }' ${S}/test/Maketests)
|
||||
for i in $TESTS Maketests inclib.awk; do
|
||||
cp ${S}/test/$i* ${D}${PTEST_PATH}/test
|
||||
done
|
||||
sed -i -e 's|/usr/local/bin|${bindir}|g' \
|
||||
-e 's|#!${base_bindir}/awk|#!${bindir}/awk|g' ${D}${PTEST_PATH}/test/*.awk
|
||||
|
||||
sed -i -e "s|GAWKLOCALE|LANG|g" ${D}${PTEST_PATH}/test/Maketests
|
||||
sed -i -e "s|GAWKLOCALE|LANG|g" ${D}${PTEST_PATH}/test/Maketests
|
||||
|
||||
# These tests require an unloaded host as otherwise timing sensitive tests can fail
|
||||
# https://bugzilla.yoctoproject.org/show_bug.cgi?id=14371
|
||||
rm -f ${D}${PTEST_PATH}/test/time.*
|
||||
rm -f ${D}${PTEST_PATH}/test/timeout.*
|
||||
}
|
||||
|
||||
RDEPENDS_${PN}-ptest += "make"
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From d81b82c70bc1fb9991bb95f1201abb5dea55f57f Mon Sep 17 00:00:00 2001
|
||||
From: Chris Liddell <chris.liddell@artifex.com>
|
||||
Date: Mon, 17 Jul 2023 14:06:37 +0100
|
||||
Subject: [PATCH] Bug 706897: Copy pcx buffer overrun fix from
|
||||
devices/gdevpcx.c
|
||||
|
||||
Bounds check the buffer, before dereferencing the pointer.
|
||||
|
||||
Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=d81b82c70bc1fb9991bb95f1201abb5dea55f57f]
|
||||
CVE: CVE-2023-38559
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
base/gdevdevn.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/base/gdevdevn.c b/base/gdevdevn.c
|
||||
index 3b019d6..2888776 100644
|
||||
--- a/base/gdevdevn.c
|
||||
+++ b/base/gdevdevn.c
|
||||
@@ -1980,7 +1980,7 @@ devn_pcx_write_rle(const byte * from, const byte * end, int step, gp_file * file
|
||||
byte data = *from;
|
||||
|
||||
from += step;
|
||||
- if (data != *from || from == end) {
|
||||
+ if (from >= end || data != *from) {
|
||||
if (data >= 0xc0)
|
||||
gp_fputc(0xc1, file);
|
||||
} else {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -40,6 +40,7 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d
|
||||
file://CVE-2021-3781_2.patch \
|
||||
file://CVE-2021-3781_3.patch \
|
||||
file://CVE-2023-28879.patch \
|
||||
file://0001-Bug-706897-Copy-pcx-buffer-overrun-fix-from-devices-.patch \
|
||||
"
|
||||
|
||||
SRC_URI = "${SRC_URI_BASE} \
|
||||
|
||||
@@ -46,6 +46,9 @@ SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \
|
||||
SRC_URI[md5sum] = "d953ed6b47694dadf0e6042f8f9ff451"
|
||||
SRC_URI[sha256sum] = "b60d58d12632ecf1e8fad7316dc82c6b9738a35625746b47ecdcaf4aed176176"
|
||||
|
||||
# upstream-wontfix: upstream has documented that reported function is not thread-safe
|
||||
CVE_CHECK_WHITELIST += "CVE-2023-30571"
|
||||
|
||||
inherit autotools update-alternatives pkgconfig
|
||||
|
||||
CPPFLAGS += "-I${WORKDIR}/extra-includes"
|
||||
|
||||
@@ -13,9 +13,9 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=4fbd65380cdd255951079008b364516c"
|
||||
SECTION = "libs"
|
||||
DEPENDS += "libtirpc libnsl2"
|
||||
|
||||
PV = "3.1+git${SRCPV}"
|
||||
PV = "3.2"
|
||||
|
||||
SRCREV = "062f31999b35393abf7595cb89dfc9590d5a42ad"
|
||||
SRCREV = "cd0d391af9535b56e612ed227c1b89be269f3d59"
|
||||
|
||||
SRC_URI = "git://github.com/thkukuk/libnss_nis;branch=master;protocol=https \
|
||||
"
|
||||
|
||||
85
meta/recipes-extended/procps/procps/CVE-2023-4016.patch
Normal file
85
meta/recipes-extended/procps/procps/CVE-2023-4016.patch
Normal file
@@ -0,0 +1,85 @@
|
||||
From 2c933ecba3bb1d3041a5a7a53a7b4078a6003413 Mon Sep 17 00:00:00 2001
|
||||
From: Craig Small <csmall@dropbear.xyz>
|
||||
Date: Thu, 10 Aug 2023 21:18:38 +1000
|
||||
Subject: [PATCH] ps: Fix possible buffer overflow in -C option
|
||||
|
||||
ps allocates memory using malloc(length of arg * len of struct).
|
||||
In certain strange circumstances, the arg length could be very large
|
||||
and the multiplecation will overflow, allocating a small amount of
|
||||
memory.
|
||||
|
||||
Subsequent strncpy() will then write into unallocated memory.
|
||||
The fix is to use calloc. It's slower but this is a one-time
|
||||
allocation. Other malloc(x * y) calls have also been replaced
|
||||
by calloc(x, y)
|
||||
|
||||
References:
|
||||
https://www.freelists.org/post/procps/ps-buffer-overflow-CVE-20234016
|
||||
https://nvd.nist.gov/vuln/detail/CVE-2023-4016
|
||||
https://gitlab.com/procps-ng/procps/-/issues/297
|
||||
https://bugs.debian.org/1042887
|
||||
|
||||
Signed-off-by: Craig Small <csmall@dropbear.xyz>
|
||||
|
||||
CVE: CVE-2023-4016
|
||||
Upstream-Status: Backport [https://gitlab.com/procps-ng/procps/-/commit/2c933ecba3bb1d3041a5a7a53a7b4078a6003413]
|
||||
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
|
||||
---
|
||||
NEWS | 1 +
|
||||
ps/parser.c | 8 ++++----
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/NEWS b/NEWS
|
||||
index b9509734..64fa3da8 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -1,3 +1,5 @@
|
||||
+ * ps: Fix buffer overflow in -C option CVE-2023-4016 Debian #1042887, issue #297
|
||||
+
|
||||
procps-ng-3.3.16
|
||||
----------------
|
||||
* library: Increment to 8:2:0
|
||||
diff --git a/ps/parser.c b/ps/parser.c
|
||||
index 248aa741..15873dfa 100644
|
||||
--- a/ps/parser.c
|
||||
+++ b/ps/parser.c
|
||||
@@ -184,7 +184,6 @@ static const char *parse_list(const char *arg, const char *(*parse_fn)(char *, s
|
||||
const char *err; /* error code that could or did happen */
|
||||
/*** prepare to operate ***/
|
||||
node = malloc(sizeof(selection_node));
|
||||
- node->u = malloc(strlen(arg)*sizeof(sel_union)); /* waste is insignificant */
|
||||
node->n = 0;
|
||||
buf = strdup(arg);
|
||||
/*** sanity check and count items ***/
|
||||
@@ -205,6 +204,7 @@ static const char *parse_list(const char *arg, const char *(*parse_fn)(char *, s
|
||||
} while (*++walk);
|
||||
if(need_item) goto parse_error;
|
||||
node->n = items;
|
||||
+ node->u = calloc(items, sizeof(sel_union));
|
||||
/*** actually parse the list ***/
|
||||
walk = buf;
|
||||
while(items--){
|
||||
@@ -1031,15 +1031,15 @@ static const char *parse_trailing_pids(void){
|
||||
thisarg = ps_argc - 1; /* we must be at the end now */
|
||||
|
||||
pidnode = malloc(sizeof(selection_node));
|
||||
- pidnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
+ pidnode->u = calloc(i, sizeof(sel_union)); /* waste is insignificant */
|
||||
pidnode->n = 0;
|
||||
|
||||
grpnode = malloc(sizeof(selection_node));
|
||||
- grpnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
+ grpnode->u = calloc(i,sizeof(sel_union)); /* waste is insignificant */
|
||||
grpnode->n = 0;
|
||||
|
||||
sidnode = malloc(sizeof(selection_node));
|
||||
- sidnode->u = malloc(i*sizeof(sel_union)); /* waste is insignificant */
|
||||
+ sidnode->u = calloc(i, sizeof(sel_union)); /* waste is insignificant */
|
||||
sidnode->n = 0;
|
||||
|
||||
while(i--){
|
||||
--
|
||||
GitLab
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user