mirror of
https://git.yoctoproject.org/poky
synced 2026-02-21 17:09:42 +01:00
Compare commits
72 Commits
yocto-3.1.
...
yocto-3.1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b8a307b78 | ||
|
|
f1292a552f | ||
|
|
2e0077aeb8 | ||
|
|
a9f1e9d277 | ||
|
|
2dbbcdb7a6 | ||
|
|
dc9ccb5071 | ||
|
|
dbe88ee83e | ||
|
|
286af7e044 | ||
|
|
95649c2878 | ||
|
|
fcaac4852d | ||
|
|
49175a7478 | ||
|
|
fb6d32853f | ||
|
|
99d085ecc3 | ||
|
|
4c5d832fe9 | ||
|
|
785e988a3d | ||
|
|
2ef094198e | ||
|
|
c778df8884 | ||
|
|
227c428eb1 | ||
|
|
493d3217dd | ||
|
|
6af184a678 | ||
|
|
2c43a87e79 | ||
|
|
ea69dd1bf5 | ||
|
|
6e97ceb858 | ||
|
|
2f3d5da3b0 | ||
|
|
d3a522d857 | ||
|
|
f5b71296f7 | ||
|
|
0a61076d20 | ||
|
|
da2f8dd755 | ||
|
|
16b4b0bd4b | ||
|
|
d0a8cd82f6 | ||
|
|
e0919b7a16 | ||
|
|
df2f9f09d7 | ||
|
|
8b710efc2a | ||
|
|
eae8d7d3a2 | ||
|
|
15d8a11b99 | ||
|
|
893481f07a | ||
|
|
9b1d9ad3b4 | ||
|
|
0ca0313980 | ||
|
|
3ff484966d | ||
|
|
b4fc8a65f5 | ||
|
|
80e00ba9b9 | ||
|
|
cc26cf0eb4 | ||
|
|
eb5651b443 | ||
|
|
3155eb565f | ||
|
|
fb5a8ed05e | ||
|
|
f7ecae8d15 | ||
|
|
8e544b6e34 | ||
|
|
5e17b15094 | ||
|
|
d4836ffd14 | ||
|
|
5a4433a52b | ||
|
|
44c4df6fba | ||
|
|
a1323a9e67 | ||
|
|
4caa67f395 | ||
|
|
417fef99f2 | ||
|
|
f86814103a | ||
|
|
4104d39151 | ||
|
|
d6dd3b49bd | ||
|
|
d9cfb16b8b | ||
|
|
122b22b366 | ||
|
|
e4a273eb58 | ||
|
|
cf0e66cf7a | ||
|
|
40df9e039a | ||
|
|
fdca6ac5fa | ||
|
|
b574cdd1e0 | ||
|
|
9bb56c4550 | ||
|
|
a4683ad5a1 | ||
|
|
9bd10b1548 | ||
|
|
471e3cee02 | ||
|
|
1ab1a5821e | ||
|
|
124e5c8391 | ||
|
|
4341dc9953 | ||
|
|
4978b9a24f |
@@ -3854,7 +3854,7 @@ Setting Up and Running a Multiple Configuration Build
|
||||
|
||||
To accomplish a multiple configuration build, you must define each
|
||||
target's configuration separately using a parallel configuration file in
|
||||
the :term:`Build Directory`, and you
|
||||
the :term:`Build Directory` or configuration directory within a layer, and you
|
||||
must follow a required file hierarchy. Additionally, you must enable the
|
||||
multiple configuration builds in your ``local.conf`` file.
|
||||
|
||||
@@ -3862,47 +3862,47 @@ Follow these steps to set up and execute multiple configuration builds:
|
||||
|
||||
- *Create Separate Configuration Files*: You need to create a single
|
||||
configuration file for each build target (each multiconfig).
|
||||
Minimally, each configuration file must define the machine and the
|
||||
temporary directory BitBake uses for the build. Suggested practice
|
||||
dictates that you do not overlap the temporary directories used
|
||||
during the builds. However, it is possible that you can share the
|
||||
temporary directory
|
||||
(:term:`TMPDIR`). For example,
|
||||
consider a scenario with two different multiconfigs for the same
|
||||
The configuration definitions are implementation dependent but often
|
||||
each configuration file will define the machine and the
|
||||
temporary directory BitBake uses for the build. Whether the same
|
||||
temporary directory (:term:`TMPDIR`) can be shared will depend on what is
|
||||
similar and what is different between the configurations. Multiple MACHINE
|
||||
targets can share the same (:term:`TMPDIR`) as long as the rest of the
|
||||
configuration is the same, multiple DISTRO settings would need separate
|
||||
(:term:`TMPDIR`) directories.
|
||||
|
||||
For example, consider a scenario with two different multiconfigs for the same
|
||||
:term:`MACHINE`: "qemux86" built
|
||||
for two distributions such as "poky" and "poky-lsb". In this case,
|
||||
you might want to use the same ``TMPDIR``.
|
||||
you would need to use the different :term:`TMPDIR`.
|
||||
|
||||
Here is an example showing the minimal statements needed in a
|
||||
configuration file for a "qemux86" target whose temporary build
|
||||
directory is ``tmpmultix86``:
|
||||
::
|
||||
directory is ``tmpmultix86``::
|
||||
|
||||
MACHINE = "qemux86"
|
||||
TMPDIR = "${TOPDIR}/tmpmultix86"
|
||||
|
||||
The location for these multiconfig configuration files is specific.
|
||||
They must reside in the current build directory in a sub-directory of
|
||||
``conf`` named ``multiconfig``. Following is an example that defines
|
||||
They must reside in the current :term:`Build Directory` in a sub-directory of
|
||||
``conf`` named ``multiconfig`` or within a layer's ``conf`` directory
|
||||
under a directory named ``multiconfig``. Following is an example that defines
|
||||
two configuration files for the "x86" and "arm" multiconfigs:
|
||||
|
||||
.. image:: figures/multiconfig_files.png
|
||||
:align: center
|
||||
:width: 50%
|
||||
|
||||
The reason for this required file hierarchy is because the ``BBPATH``
|
||||
variable is not constructed until the layers are parsed.
|
||||
Consequently, using the configuration file as a pre-configuration
|
||||
file is not possible unless it is located in the current working
|
||||
directory.
|
||||
The usual :term:`BBPATH` search path is used to locate multiconfig files in
|
||||
a similar way to other conf files.
|
||||
|
||||
- *Add the BitBake Multi-configuration Variable to the Local
|
||||
Configuration File*: Use the
|
||||
:term:`BBMULTICONFIG`
|
||||
variable in your ``conf/local.conf`` configuration file to specify
|
||||
each multiconfig. Continuing with the example from the previous
|
||||
figure, the ``BBMULTICONFIG`` variable needs to enable two
|
||||
multiconfigs: "x86" and "arm" by specifying each configuration file:
|
||||
::
|
||||
figure, the :term:`BBMULTICONFIG` variable needs to enable two
|
||||
multiconfigs: "x86" and "arm" by specifying each configuration file::
|
||||
|
||||
BBMULTICONFIG = "x86 arm"
|
||||
|
||||
@@ -3916,13 +3916,11 @@ Follow these steps to set up and execute multiple configuration builds:
|
||||
with "".
|
||||
|
||||
- *Launch BitBake*: Use the following BitBake command form to launch
|
||||
the multiple configuration build:
|
||||
::
|
||||
the multiple configuration build::
|
||||
|
||||
$ bitbake [mc:multiconfigname:]target [[[mc:multiconfigname:]target] ... ]
|
||||
|
||||
For the example in this section, the following command applies:
|
||||
::
|
||||
For the example in this section, the following command applies::
|
||||
|
||||
$ bitbake mc:x86:core-image-minimal mc:arm:core-image-sato mc::core-image-base
|
||||
|
||||
@@ -3937,7 +3935,7 @@ Follow these steps to set up and execute multiple configuration builds:
|
||||
Support for multiple configuration builds in the Yocto Project &DISTRO;
|
||||
(&DISTRO_NAME;) Release does not include Shared State (sstate)
|
||||
optimizations. Consequently, if a build uses the same object twice
|
||||
in, for example, two different ``TMPDIR``
|
||||
in, for example, two different :term:`TMPDIR`
|
||||
directories, the build either loads from an existing sstate cache for
|
||||
that build at the start or builds the object fresh.
|
||||
|
||||
@@ -3958,38 +3956,34 @@ essentially that the
|
||||
|
||||
To enable dependencies in a multiple configuration build, you must
|
||||
declare the dependencies in the recipe using the following statement
|
||||
form:
|
||||
::
|
||||
form::
|
||||
|
||||
task_or_package[mcdepends] = "mc:from_multiconfig:to_multiconfig:recipe_name:task_on_which_to_depend"
|
||||
|
||||
To better show how to use this statement, consider the example scenario
|
||||
from the first paragraph of this section. The following statement needs
|
||||
to be added to the recipe that builds the ``core-image-sato`` image:
|
||||
::
|
||||
to be added to the recipe that builds the ``core-image-sato`` image::
|
||||
|
||||
do_image[mcdepends] = "mc:x86:arm:core-image-minimal:do_rootfs"
|
||||
|
||||
In this example, the `from_multiconfig` is "x86". The `to_multiconfig` is "arm". The
|
||||
task on which the ``do_image`` task in the recipe depends is the
|
||||
``do_rootfs`` task from the ``core-image-minimal`` recipe associated
|
||||
task on which the :ref:`ref-tasks-image` task in the recipe depends is the
|
||||
:ref:`ref-tasks-rootfs` task from the ``core-image-minimal`` recipe associated
|
||||
with the "arm" multiconfig.
|
||||
|
||||
Once you set up this dependency, you can build the "x86" multiconfig
|
||||
using a BitBake command as follows:
|
||||
::
|
||||
using a BitBake command as follows::
|
||||
|
||||
$ bitbake mc:x86:core-image-sato
|
||||
|
||||
This command executes all the tasks needed to create the
|
||||
``core-image-sato`` image for the "x86" multiconfig. Because of the
|
||||
dependency, BitBake also executes through the ``do_rootfs`` task for the
|
||||
dependency, BitBake also executes through the :ref:`ref-tasks-rootfs` task for the
|
||||
"arm" multiconfig build.
|
||||
|
||||
Having a recipe depend on the root filesystem of another build might not
|
||||
seem that useful. Consider this change to the statement in the
|
||||
``core-image-sato`` recipe:
|
||||
::
|
||||
``core-image-sato`` recipe::
|
||||
|
||||
do_image[mcdepends] = "mc:x86:arm:core-image-minimal:do_image"
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
DISTRO : "3.1.21"
|
||||
DISTRO : "3.1.22"
|
||||
DISTRO_NAME_NO_CAP : "dunfell"
|
||||
DISTRO_NAME : "Dunfell"
|
||||
DISTRO_NAME_NO_CAP_MINUS_ONE : "zeus"
|
||||
YOCTO_DOC_VERSION : "3.1.21"
|
||||
YOCTO_DOC_VERSION : "3.1.22"
|
||||
YOCTO_DOC_VERSION_MINUS_ONE : "3.0.4"
|
||||
DISTRO_REL_TAG : "yocto-3.1.21"
|
||||
DOCCONF_VERSION : "3.1.21"
|
||||
DISTRO_REL_TAG : "yocto-3.1.22"
|
||||
DOCCONF_VERSION : "3.1.22"
|
||||
BITBAKE_SERIES : "1.46"
|
||||
POKYVERSION : "23.0.21"
|
||||
POKYVERSION : "23.0.22"
|
||||
YOCTO_POKY : "poky-&DISTRO_NAME_NO_CAP;-&POKYVERSION;"
|
||||
YOCTO_DL_URL : "https://downloads.yoctoproject.org"
|
||||
YOCTO_AB_URL : "https://autobuilder.yoctoproject.org"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
DISTRO = "poky"
|
||||
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
|
||||
DISTRO_VERSION = "3.1.21"
|
||||
DISTRO_VERSION = "3.1.22"
|
||||
DISTRO_CODENAME = "dunfell"
|
||||
SDK_VENDOR = "-pokysdk"
|
||||
SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${DATE}', 'snapshot')}"
|
||||
|
||||
@@ -7,8 +7,8 @@ KMACHINE_genericx86 ?= "common-pc"
|
||||
KMACHINE_genericx86-64 ?= "common-pc-64"
|
||||
KMACHINE_beaglebone-yocto ?= "beaglebone"
|
||||
|
||||
SRCREV_machine_genericx86 ?= "8a59dfded81659402005acfb06fbb00b71c8ce86"
|
||||
SRCREV_machine_genericx86-64 ?= "8a59dfded81659402005acfb06fbb00b71c8ce86"
|
||||
SRCREV_machine_genericx86 ?= "35826e154ee014b64ccfa0d1f12d36b8f8a75939"
|
||||
SRCREV_machine_genericx86-64 ?= "35826e154ee014b64ccfa0d1f12d36b8f8a75939"
|
||||
SRCREV_machine_edgerouter ?= "706efec4c1e270ec5dda92275898cd465dfdc7dd"
|
||||
SRCREV_machine_beaglebone-yocto ?= "706efec4c1e270ec5dda92275898cd465dfdc7dd"
|
||||
|
||||
@@ -17,7 +17,7 @@ COMPATIBLE_MACHINE_genericx86-64 = "genericx86-64"
|
||||
COMPATIBLE_MACHINE_edgerouter = "edgerouter"
|
||||
COMPATIBLE_MACHINE_beaglebone-yocto = "beaglebone-yocto"
|
||||
|
||||
LINUX_VERSION_genericx86 = "5.4.205"
|
||||
LINUX_VERSION_genericx86-64 = "5.4.205"
|
||||
LINUX_VERSION_genericx86 = "5.4.219"
|
||||
LINUX_VERSION_genericx86-64 = "5.4.219"
|
||||
LINUX_VERSION_edgerouter = "5.4.58"
|
||||
LINUX_VERSION_beaglebone-yocto = "5.4.58"
|
||||
|
||||
@@ -139,7 +139,7 @@ def setup_hosttools_dir(dest, toolsvar, d, fatal=True):
|
||||
# /usr/local/bin/ccache/gcc -> /usr/bin/ccache, then which(gcc)
|
||||
# would return /usr/local/bin/ccache/gcc, but what we need is
|
||||
# /usr/bin/gcc, this code can check and fix that.
|
||||
if "ccache" in srctool:
|
||||
if os.path.islink(srctool) and os.path.basename(os.readlink(srctool)) == 'ccache':
|
||||
srctool = bb.utils.which(path, tool, executable=True, direction=1)
|
||||
if srctool:
|
||||
os.symlink(srctool, desttool)
|
||||
|
||||
@@ -225,7 +225,7 @@ def srctree_hash_files(d, srcdir=None):
|
||||
env['GIT_INDEX_FILE'] = tmp_index.name
|
||||
subprocess.check_output(['git', 'add', '-A', '.'], cwd=s_dir, env=env)
|
||||
git_sha1 = subprocess.check_output(['git', 'write-tree'], cwd=s_dir, env=env).decode("utf-8")
|
||||
if os.path.exists(".gitmodules"):
|
||||
if os.path.exists(os.path.join(s_dir, ".gitmodules")):
|
||||
submodule_helper = subprocess.check_output(["git", "config", "--file", ".gitmodules", "--get-regexp", "path"], cwd=s_dir, env=env).decode("utf-8")
|
||||
for line in submodule_helper.splitlines():
|
||||
module_dir = os.path.join(s_dir, line.rsplit(maxsplit=1)[1])
|
||||
|
||||
@@ -64,5 +64,5 @@ HOST_AR_KERNEL_ARCH ?= "${TARGET_AR_KERNEL_ARCH}"
|
||||
KERNEL_CC = "${CCACHE}${HOST_PREFIX}gcc ${HOST_CC_KERNEL_ARCH} -fuse-ld=bfd ${DEBUG_PREFIX_MAP} -fdebug-prefix-map=${STAGING_KERNEL_DIR}=${KERNEL_SRC_PATH} -fdebug-prefix-map=${STAGING_KERNEL_BUILDDIR}=${KERNEL_SRC_PATH}"
|
||||
KERNEL_LD = "${CCACHE}${HOST_PREFIX}ld.bfd ${HOST_LD_KERNEL_ARCH}"
|
||||
KERNEL_AR = "${CCACHE}${HOST_PREFIX}ar ${HOST_AR_KERNEL_ARCH}"
|
||||
TOOLCHAIN = "gcc"
|
||||
TOOLCHAIN ?= "gcc"
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ python __anonymous () {
|
||||
# KERNEL_IMAGETYPES may contain a mixture of image types supported directly
|
||||
# by the kernel build system and types which are created by post-processing
|
||||
# the output of the kernel build system (e.g. compressing vmlinux ->
|
||||
# vmlinux.gz in kernel_do_compile()).
|
||||
# vmlinux.gz in kernel_do_transform_kernel()).
|
||||
# KERNEL_IMAGETYPE_FOR_MAKE should contain only image types supported
|
||||
# directly by the kernel build system.
|
||||
if not d.getVar('KERNEL_IMAGETYPE_FOR_MAKE'):
|
||||
@@ -106,6 +106,8 @@ python __anonymous () {
|
||||
# standalone for use by wic and other tools.
|
||||
if image:
|
||||
d.appendVarFlag('do_bundle_initramfs', 'depends', ' ${INITRAMFS_IMAGE}:do_image_complete')
|
||||
if image and bb.utils.to_boolean(d.getVar('INITRAMFS_IMAGE_BUNDLE')):
|
||||
bb.build.addtask('do_transform_bundled_initramfs', 'do_deploy', 'do_bundle_initramfs', d)
|
||||
|
||||
# NOTE: setting INITRAMFS_TASK is for backward compatibility
|
||||
# The preferred method is to set INITRAMFS_IMAGE, because
|
||||
@@ -280,6 +282,14 @@ do_bundle_initramfs () {
|
||||
}
|
||||
do_bundle_initramfs[dirs] = "${B}"
|
||||
|
||||
kernel_do_transform_bundled_initramfs() {
|
||||
# vmlinux.gz is not built by kernel
|
||||
if (echo "${KERNEL_IMAGETYPES}" | grep -wq "vmlinux\.gz"); then
|
||||
gzip -9cn < ${KERNEL_OUTPUT_DIR}/vmlinux.initramfs > ${KERNEL_OUTPUT_DIR}/vmlinux.gz.initramfs
|
||||
fi
|
||||
}
|
||||
do_transform_bundled_initramfs[dirs] = "${B}"
|
||||
|
||||
python do_devshell_prepend () {
|
||||
os.environ["LDFLAGS"] = ''
|
||||
}
|
||||
@@ -311,6 +321,10 @@ kernel_do_compile() {
|
||||
export KBUILD_BUILD_TIMESTAMP="$ts"
|
||||
export KCONFIG_NOTIMESTAMP=1
|
||||
bbnote "KBUILD_BUILD_TIMESTAMP: $ts"
|
||||
else
|
||||
ts=`LC_ALL=C date`
|
||||
export KBUILD_BUILD_TIMESTAMP="$ts"
|
||||
bbnote "KBUILD_BUILD_TIMESTAMP: $ts"
|
||||
fi
|
||||
# The $use_alternate_initrd is only set from
|
||||
# do_bundle_initramfs() This variable is specifically for the
|
||||
@@ -329,12 +343,17 @@ kernel_do_compile() {
|
||||
for typeformake in ${KERNEL_IMAGETYPE_FOR_MAKE} ; do
|
||||
oe_runmake ${typeformake} CC="${KERNEL_CC} $cc_extra " LD="${KERNEL_LD}" ${KERNEL_EXTRA_ARGS} $use_alternate_initrd
|
||||
done
|
||||
}
|
||||
|
||||
kernel_do_transform_kernel() {
|
||||
# vmlinux.gz is not built by kernel
|
||||
if (echo "${KERNEL_IMAGETYPES}" | grep -wq "vmlinux\.gz"); then
|
||||
mkdir -p "${KERNEL_OUTPUT_DIR}"
|
||||
gzip -9cn < ${B}/vmlinux > "${KERNEL_OUTPUT_DIR}/vmlinux.gz"
|
||||
fi
|
||||
}
|
||||
do_transform_kernel[dirs] = "${B}"
|
||||
addtask transform_kernel after do_compile before do_install
|
||||
|
||||
do_compile_kernelmodules() {
|
||||
unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE
|
||||
@@ -352,6 +371,10 @@ do_compile_kernelmodules() {
|
||||
export KBUILD_BUILD_TIMESTAMP="$ts"
|
||||
export KCONFIG_NOTIMESTAMP=1
|
||||
bbnote "KBUILD_BUILD_TIMESTAMP: $ts"
|
||||
else
|
||||
ts=`LC_ALL=C date`
|
||||
export KBUILD_BUILD_TIMESTAMP="$ts"
|
||||
bbnote "KBUILD_BUILD_TIMESTAMP: $ts"
|
||||
fi
|
||||
if (grep -q -i -e '^CONFIG_MODULES=y$' ${B}/.config); then
|
||||
cc_extra=$(get_cc_option)
|
||||
@@ -576,7 +599,7 @@ inherit cml1
|
||||
|
||||
KCONFIG_CONFIG_COMMAND_append = " LD='${KERNEL_LD}' HOSTLDFLAGS='${BUILD_LDFLAGS}'"
|
||||
|
||||
EXPORT_FUNCTIONS do_compile do_install do_configure
|
||||
EXPORT_FUNCTIONS do_compile do_transform_kernel do_transform_bundled_initramfs do_install do_configure
|
||||
|
||||
# kernel-base becomes kernel-${KERNEL_VERSION}
|
||||
# kernel-image becomes kernel-image-${KERNEL_VERSION}
|
||||
@@ -721,7 +744,7 @@ kernel_do_deploy() {
|
||||
fi
|
||||
|
||||
if [ ! -z "${INITRAMFS_IMAGE}" -a x"${INITRAMFS_IMAGE_BUNDLE}" = x1 ]; then
|
||||
for imageType in ${KERNEL_IMAGETYPE_FOR_MAKE} ; do
|
||||
for imageType in ${KERNEL_IMAGETYPES} ; do
|
||||
if [ "$imageType" = "fitImage" ] ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# QB_OPT_APPEND: options to append to qemu, e.g., "-show-cursor"
|
||||
#
|
||||
# QB_DEFAULT_KERNEL: default kernel to boot, e.g., "bzImage"
|
||||
# e.g., "bzImage-initramfs-qemux86-64.bin" if INITRAMFS_IMAGE_BUNDLE is set to 1.
|
||||
#
|
||||
# QB_DEFAULT_FSTYPE: default FSTYPE to boot, e.g., "ext4"
|
||||
#
|
||||
@@ -75,7 +76,7 @@
|
||||
|
||||
QB_MEM ?= "-m 256"
|
||||
QB_SERIAL_OPT ?= "-serial mon:stdio -serial null"
|
||||
QB_DEFAULT_KERNEL ?= "${KERNEL_IMAGETYPE}"
|
||||
QB_DEFAULT_KERNEL ?= "${@bb.utils.contains("INITRAMFS_IMAGE_BUNDLE", "1", "${KERNEL_IMAGETYPE}-${INITRAMFS_LINK_NAME}.bin", "${KERNEL_IMAGETYPE}", d)}"
|
||||
QB_DEFAULT_FSTYPE ?= "ext4"
|
||||
QB_OPT_APPEND ?= "-show-cursor"
|
||||
QB_NETWORK_DEVICE ?= "-device virtio-net-pci,netdev=net0,mac=@MAC@"
|
||||
|
||||
@@ -27,6 +27,13 @@ BB_SCHEDULER ?= "completion"
|
||||
BB_TASK_IONICE_LEVEL_task-rm_work = "3.0"
|
||||
|
||||
do_rm_work () {
|
||||
# Force using the HOSTTOOLS 'rm' - otherwise the SYSROOT_NATIVE 'rm' can be selected depending on PATH
|
||||
# Avoids race-condition accessing 'rm' when deleting WORKDIR folders at the end of this function
|
||||
RM_BIN="$(PATH=${HOSTTOOLS_DIR} command -v rm)"
|
||||
if [ -z "${RM_BIN}" ]; then
|
||||
bbfatal "Binary 'rm' not found in HOSTTOOLS_DIR, cannot remove WORKDIR data."
|
||||
fi
|
||||
|
||||
# If the recipe name is in the RM_WORK_EXCLUDE, skip the recipe.
|
||||
for p in ${RM_WORK_EXCLUDE}; do
|
||||
if [ "$p" = "${PN}" ]; then
|
||||
@@ -73,7 +80,7 @@ do_rm_work () {
|
||||
# sstate version since otherwise we'd need to leave 'plaindirs' around
|
||||
# such as 'packages' and 'packages-split' and these can be large. No end
|
||||
# of chain tasks depend directly on do_package anymore.
|
||||
rm -f -- $i;
|
||||
"${RM_BIN}" -f -- $i;
|
||||
;;
|
||||
*_setscene*)
|
||||
# Skip stamps which are already setscene versions
|
||||
@@ -90,7 +97,7 @@ do_rm_work () {
|
||||
;;
|
||||
esac
|
||||
done
|
||||
rm -f -- $i
|
||||
"${RM_BIN}" -f -- $i
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -100,9 +107,9 @@ do_rm_work () {
|
||||
# Retain only logs and other files in temp, safely ignore
|
||||
# failures of removing pseudo folers on NFS2/3 server.
|
||||
if [ $dir = 'pseudo' ]; then
|
||||
rm -rf -- $dir 2> /dev/null || true
|
||||
"${RM_BIN}" -rf -- $dir 2> /dev/null || true
|
||||
elif ! echo "$excludes" | grep -q -w "$dir"; then
|
||||
rm -rf -- $dir
|
||||
"${RM_BIN}" -rf -- $dir
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ def generate_sstatefn(spec, hash, taskname, siginfo, d):
|
||||
components = spec.split(":")
|
||||
# Fields 0,5,6 are mandatory, 1 is most useful, 2,3,4 are just for information
|
||||
# 7 is for the separators
|
||||
avail = (254 - len(hash + "_" + taskname + extension) - len(components[0]) - len(components[1]) - len(components[5]) - len(components[6]) - 7) // 3
|
||||
avail = (limit - len(hash + "_" + taskname + extension) - len(components[0]) - len(components[1]) - len(components[5]) - len(components[6]) - 7) // 3
|
||||
components[2] = components[2][:avail]
|
||||
components[3] = components[3][:avail]
|
||||
components[4] = components[4][:avail]
|
||||
|
||||
@@ -194,7 +194,7 @@ RECIPE_MAINTAINER_pn-gcc-cross-canadian-${TRANSLATED_TARGET_ARCH} = "Khem Raj <r
|
||||
RECIPE_MAINTAINER_pn-gcc-crosssdk-${SDK_SYS} = "Khem Raj <raj.khem@gmail.com>"
|
||||
RECIPE_MAINTAINER_pn-gcc-runtime = "Khem Raj <raj.khem@gmail.com>"
|
||||
RECIPE_MAINTAINER_pn-gcc-sanitizers = "Khem Raj <raj.khem@gmail.com>"
|
||||
RECIPE_MAINTAINER_pn-gcc-source-9.3.0 = "Khem Raj <raj.khem@gmail.com>"
|
||||
RECIPE_MAINTAINER_pn-gcc-source-9.5.0 = "Khem Raj <raj.khem@gmail.com>"
|
||||
RECIPE_MAINTAINER_pn-gconf = "Ross Burton <ross.burton@arm.com>"
|
||||
RECIPE_MAINTAINER_pn-gcr = "Alexander Kanavin <alex.kanavin@gmail.com>"
|
||||
RECIPE_MAINTAINER_pn-gdb = "Khem Raj <raj.khem@gmail.com>"
|
||||
|
||||
@@ -49,21 +49,20 @@ class RpmBasicTest(OERuntimeTestCase):
|
||||
msg = 'status: %s. Cannot run rpm -qa: %s' % (status, output)
|
||||
self.assertEqual(status, 0, msg=msg)
|
||||
|
||||
def check_no_process_for_user(u):
|
||||
_, output = self.target.run(self.tc.target_cmds['ps'])
|
||||
if u + ' ' in output:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
def wait_for_no_process_for_user(u, timeout = 120):
|
||||
timeout_at = time.time() + timeout
|
||||
while time.time() < timeout_at:
|
||||
_, output = self.target.run(self.tc.target_cmds['ps'])
|
||||
if u + ' ' not in output:
|
||||
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)
|
||||
|
||||
def unset_up_test_user(u):
|
||||
# ensure no test1 process in running
|
||||
timeout = time.time() + 30
|
||||
while time.time() < timeout:
|
||||
if check_no_process_for_user(u):
|
||||
break
|
||||
else:
|
||||
time.sleep(1)
|
||||
wait_for_no_process_for_user(u)
|
||||
status, output = self.target.run('userdel -r %s' % u)
|
||||
msg = 'Failed to erase user: %s' % output
|
||||
self.assertTrue(status == 0, msg=msg)
|
||||
|
||||
@@ -65,6 +65,20 @@ class TinfoilTests(OESelftestTestCase):
|
||||
localdata.setVar('PN', 'hello')
|
||||
self.assertEqual('hello', localdata.getVar('BPN'))
|
||||
|
||||
# The config_data API tp parse_recipe_file is used by:
|
||||
# layerindex-web layerindex/update_layer.py
|
||||
def test_parse_recipe_custom_data(self):
|
||||
with bb.tinfoil.Tinfoil() as tinfoil:
|
||||
tinfoil.prepare(config_only=False, quiet=2)
|
||||
localdata = bb.data.createCopy(tinfoil.config_data)
|
||||
localdata.setVar("TESTVAR", "testval")
|
||||
testrecipe = 'mdadm'
|
||||
best = tinfoil.find_best_provider(testrecipe)
|
||||
if not best:
|
||||
self.fail('Unable to find recipe providing %s' % testrecipe)
|
||||
rd = tinfoil.parse_recipe_file(best[3], config_data=localdata)
|
||||
self.assertEqual("testval", rd.getVar('TESTVAR'))
|
||||
|
||||
def test_list_recipes(self):
|
||||
with bb.tinfoil.Tinfoil() as tinfoil:
|
||||
tinfoil.prepare(config_only=False, quiet=2)
|
||||
|
||||
87
meta/recipes-bsp/grub/files/CVE-2022-2601.patch
Normal file
87
meta/recipes-bsp/grub/files/CVE-2022-2601.patch
Normal file
@@ -0,0 +1,87 @@
|
||||
From e8060722acf0bcca037982d7fb29472363ccdfd4 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Fri, 5 Aug 2022 01:58:27 +0800
|
||||
Subject: [PATCH] font: Fix several integer overflows in
|
||||
grub_font_construct_glyph()
|
||||
|
||||
This patch fixes several integer overflows in grub_font_construct_glyph().
|
||||
Glyphs of invalid size, zero or leading to an overflow, are rejected.
|
||||
The inconsistency between "glyph" and "max_glyph_size" when grub_malloc()
|
||||
returns NULL is fixed too.
|
||||
|
||||
Fixes: CVE-2022-2601
|
||||
|
||||
Reported-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
|
||||
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?id=768e1ef2fc159f6e14e7246e4be09363708ac39e]
|
||||
CVE: CVE-2022-2601
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
grub-core/font/font.c | 29 +++++++++++++++++------------
|
||||
1 file changed, 17 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index df17dba..f110db9 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -1509,6 +1509,7 @@ grub_font_construct_glyph (grub_font_t hinted_font,
|
||||
struct grub_video_signed_rect bounds;
|
||||
static struct grub_font_glyph *glyph = 0;
|
||||
static grub_size_t max_glyph_size = 0;
|
||||
+ grub_size_t cur_glyph_size;
|
||||
|
||||
ensure_comb_space (glyph_id);
|
||||
|
||||
@@ -1525,29 +1526,33 @@ grub_font_construct_glyph (grub_font_t hinted_font,
|
||||
if (!glyph_id->ncomb && !glyph_id->attributes)
|
||||
return main_glyph;
|
||||
|
||||
- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT)
|
||||
+ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) ||
|
||||
+ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size))
|
||||
+ return main_glyph;
|
||||
+
|
||||
+ if (max_glyph_size < cur_glyph_size)
|
||||
{
|
||||
grub_free (glyph);
|
||||
- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2;
|
||||
- if (max_glyph_size < 8)
|
||||
- max_glyph_size = 8;
|
||||
- glyph = grub_malloc (max_glyph_size);
|
||||
+ if (grub_mul (cur_glyph_size, 2, &max_glyph_size))
|
||||
+ max_glyph_size = 0;
|
||||
+ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL;
|
||||
}
|
||||
if (!glyph)
|
||||
{
|
||||
+ max_glyph_size = 0;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return main_glyph;
|
||||
}
|
||||
|
||||
- grub_memset (glyph, 0, sizeof (*glyph)
|
||||
- + (bounds.width * bounds.height
|
||||
- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT);
|
||||
+ grub_memset (glyph, 0, cur_glyph_size);
|
||||
|
||||
glyph->font = main_glyph->font;
|
||||
- glyph->width = bounds.width;
|
||||
- glyph->height = bounds.height;
|
||||
- glyph->offset_x = bounds.x;
|
||||
- glyph->offset_y = bounds.y;
|
||||
+ if (bounds.width == 0 || bounds.height == 0 ||
|
||||
+ grub_cast (bounds.width, &glyph->width) ||
|
||||
+ grub_cast (bounds.height, &glyph->height) ||
|
||||
+ grub_cast (bounds.x, &glyph->offset_x) ||
|
||||
+ grub_cast (bounds.y, &glyph->offset_y))
|
||||
+ return main_glyph;
|
||||
|
||||
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
|
||||
grub_font_blit_glyph_mirror (glyph, main_glyph,
|
||||
--
|
||||
2.25.1
|
||||
|
||||
271
meta/recipes-bsp/grub/files/CVE-2022-28735.patch
Normal file
271
meta/recipes-bsp/grub/files/CVE-2022-28735.patch
Normal file
@@ -0,0 +1,271 @@
|
||||
From 6fe755c5c07bb386fda58306bfd19e4a1c974c53 Mon Sep 17 00:00:00 2001
|
||||
From: Julian Andres Klode <julian.klode@canonical.com>
|
||||
Date: Thu, 2 Dec 2021 15:03:53 +0100
|
||||
Subject: kern/efi/sb: Reject non-kernel files in the shim_lock verifier
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6fe755c5c07bb386fda58306bfd19e4a1c974c53]
|
||||
CVE: CVE-2022-28735
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
|
||||
We must not allow other verifiers to pass things like the GRUB modules.
|
||||
Instead of maintaining a blocklist, maintain an allowlist of things
|
||||
that we do not care about.
|
||||
|
||||
This allowlist really should be made reusable, and shared by the
|
||||
lockdown verifier, but this is the minimal patch addressing
|
||||
security concerns where the TPM verifier was able to mark modules
|
||||
as verified (or the OpenPGP verifier for that matter), when it
|
||||
should not do so on shim-powered secure boot systems.
|
||||
|
||||
Fixes: CVE-2022-28735
|
||||
|
||||
Signed-off-by: Julian Andres Klode <julian.klode@canonical.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/efi/sb.c | 221 ++++++++++++++++++++++++++++++++++++++++
|
||||
include/grub/verify.h | 1 +
|
||||
2 files changed, 222 insertions(+)
|
||||
create mode 100644 grub-core/kern/efi/sb.c
|
||||
|
||||
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
new file mode 100644
|
||||
index 0000000..89c4bb3
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -0,0 +1,221 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2020 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/>.
|
||||
+ *
|
||||
+ * UEFI Secure Boot related checkings.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+#include <grub/efi/sb.h>
|
||||
+#include <grub/env.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/file.h>
|
||||
+#include <grub/i386/linux.h>
|
||||
+#include <grub/kernel.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/verify.h>
|
||||
+
|
||||
+static grub_efi_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
+
|
||||
+/*
|
||||
+ * Determine whether we're in secure boot mode.
|
||||
+ *
|
||||
+ * Please keep the logic in sync with the Linux kernel,
|
||||
+ * drivers/firmware/efi/libstub/secureboot.c:efi_get_secureboot().
|
||||
+ */
|
||||
+grub_uint8_t
|
||||
+grub_efi_get_secureboot (void)
|
||||
+{
|
||||
+ static grub_efi_guid_t efi_variable_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_efi_uint32_t attr = 0;
|
||||
+ grub_size_t size = 0;
|
||||
+ grub_uint8_t *secboot = NULL;
|
||||
+ grub_uint8_t *setupmode = NULL;
|
||||
+ grub_uint8_t *moksbstate = NULL;
|
||||
+ grub_uint8_t secureboot = GRUB_EFI_SECUREBOOT_MODE_UNKNOWN;
|
||||
+ const char *secureboot_str = "UNKNOWN";
|
||||
+
|
||||
+ status = grub_efi_get_variable ("SecureBoot", &efi_variable_guid,
|
||||
+ &size, (void **) &secboot);
|
||||
+
|
||||
+ if (status == GRUB_EFI_NOT_FOUND)
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ goto out;
|
||||
+
|
||||
+ status = grub_efi_get_variable ("SetupMode", &efi_variable_guid,
|
||||
+ &size, (void **) &setupmode);
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ goto out;
|
||||
+
|
||||
+ if ((*secboot == 0) || (*setupmode == 1))
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * See if a user has put the shim into insecure mode. If so, and if the
|
||||
+ * variable doesn't have the runtime attribute set, we might as well
|
||||
+ * honor that.
|
||||
+ */
|
||||
+ status = grub_efi_get_variable_with_attributes ("MokSBState", &shim_lock_guid,
|
||||
+ &size, (void **) &moksbstate, &attr);
|
||||
+
|
||||
+ /* If it fails, we don't care why. Default to secure. */
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_ENABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!(attr & GRUB_EFI_VARIABLE_RUNTIME_ACCESS) && *moksbstate == 1)
|
||||
+ {
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_DISABLED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ secureboot = GRUB_EFI_SECUREBOOT_MODE_ENABLED;
|
||||
+
|
||||
+ out:
|
||||
+ grub_free (moksbstate);
|
||||
+ grub_free (setupmode);
|
||||
+ grub_free (secboot);
|
||||
+
|
||||
+ if (secureboot == GRUB_EFI_SECUREBOOT_MODE_DISABLED)
|
||||
+ secureboot_str = "Disabled";
|
||||
+ else if (secureboot == GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
+ secureboot_str = "Enabled";
|
||||
+
|
||||
+ grub_dprintf ("efi", "UEFI Secure Boot state: %s\n", secureboot_str);
|
||||
+
|
||||
+ return secureboot;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)),
|
||||
+ enum grub_file_type type,
|
||||
+ void **context __attribute__ ((unused)),
|
||||
+ enum grub_verify_flags *flags)
|
||||
+{
|
||||
+ *flags = GRUB_VERIFY_FLAGS_NONE;
|
||||
+
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ /* Files we check. */
|
||||
+ case GRUB_FILE_TYPE_LINUX_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_MULTIBOOT_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_BSD_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_XNU_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_PLAN9_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE:
|
||||
+ *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ /* Files that do not affect secureboot state. */
|
||||
+ case GRUB_FILE_TYPE_NONE:
|
||||
+ case GRUB_FILE_TYPE_LOOPBACK:
|
||||
+ case GRUB_FILE_TYPE_LINUX_INITRD:
|
||||
+ case GRUB_FILE_TYPE_OPENBSD_RAMDISK:
|
||||
+ case GRUB_FILE_TYPE_XNU_RAMDISK:
|
||||
+ case GRUB_FILE_TYPE_SIGNATURE:
|
||||
+ case GRUB_FILE_TYPE_PUBLIC_KEY:
|
||||
+ case GRUB_FILE_TYPE_PUBLIC_KEY_TRUST:
|
||||
+ case GRUB_FILE_TYPE_PRINT_BLOCKLIST:
|
||||
+ case GRUB_FILE_TYPE_TESTLOAD:
|
||||
+ case GRUB_FILE_TYPE_GET_SIZE:
|
||||
+ case GRUB_FILE_TYPE_FONT:
|
||||
+ case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY:
|
||||
+ case GRUB_FILE_TYPE_CAT:
|
||||
+ case GRUB_FILE_TYPE_HEXCAT:
|
||||
+ case GRUB_FILE_TYPE_CMP:
|
||||
+ case GRUB_FILE_TYPE_HASHLIST:
|
||||
+ case GRUB_FILE_TYPE_TO_HASH:
|
||||
+ case GRUB_FILE_TYPE_KEYBOARD_LAYOUT:
|
||||
+ case GRUB_FILE_TYPE_PIXMAP:
|
||||
+ case GRUB_FILE_TYPE_GRUB_MODULE_LIST:
|
||||
+ case GRUB_FILE_TYPE_CONFIG:
|
||||
+ case GRUB_FILE_TYPE_THEME:
|
||||
+ case GRUB_FILE_TYPE_GETTEXT_CATALOG:
|
||||
+ case GRUB_FILE_TYPE_FS_SEARCH:
|
||||
+ case GRUB_FILE_TYPE_LOADENV:
|
||||
+ case GRUB_FILE_TYPE_SAVEENV:
|
||||
+ case GRUB_FILE_TYPE_VERIFY_SIGNATURE:
|
||||
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ /* Other files. */
|
||||
+ default:
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by secure boot policy"));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+shim_lock_verifier_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size)
|
||||
+{
|
||||
+ grub_efi_shim_lock_protocol_t *sl = grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
+
|
||||
+ if (!sl)
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("shim_lock protocol not found"));
|
||||
+
|
||||
+ if (sl->verify (buf, size) != GRUB_EFI_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad shim signature"));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+struct grub_file_verifier shim_lock_verifier =
|
||||
+ {
|
||||
+ .name = "shim_lock_verifier",
|
||||
+ .init = shim_lock_verifier_init,
|
||||
+ .write = shim_lock_verifier_write
|
||||
+ };
|
||||
+
|
||||
+void
|
||||
+grub_shim_lock_verifier_setup (void)
|
||||
+{
|
||||
+ struct grub_module_header *header;
|
||||
+ grub_efi_shim_lock_protocol_t *sl =
|
||||
+ grub_efi_locate_protocol (&shim_lock_guid, 0);
|
||||
+
|
||||
+ /* shim_lock is missing, check if GRUB image is built with --disable-shim-lock. */
|
||||
+ if (!sl)
|
||||
+ {
|
||||
+ FOR_MODULES (header)
|
||||
+ {
|
||||
+ if (header->type == OBJ_TYPE_DISABLE_SHIM_LOCK)
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Secure Boot is off. Do not load shim_lock. */
|
||||
+ if (grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED)
|
||||
+ return;
|
||||
+
|
||||
+ /* Enforce shim_lock_verifier. */
|
||||
+ grub_verifier_register (&shim_lock_verifier);
|
||||
+
|
||||
+ grub_env_set ("shim_lock", "y");
|
||||
+ grub_env_export ("shim_lock");
|
||||
+}
|
||||
diff --git a/include/grub/verify.h b/include/grub/verify.h
|
||||
index cd129c3..672ae16 100644
|
||||
--- a/include/grub/verify.h
|
||||
+++ b/include/grub/verify.h
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
enum grub_verify_flags
|
||||
{
|
||||
+ GRUB_VERIFY_FLAGS_NONE = 0,
|
||||
GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1,
|
||||
GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2,
|
||||
/* Defer verification to another authority. */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
97
meta/recipes-bsp/grub/files/CVE-2022-3775.patch
Normal file
97
meta/recipes-bsp/grub/files/CVE-2022-3775.patch
Normal file
@@ -0,0 +1,97 @@
|
||||
From fdbe7209152ad6f09a1166f64f162017f2145ba3 Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Mon, 24 Oct 2022 08:05:35 +0800
|
||||
Subject: [PATCH] font: Fix an integer underflow in blit_comb()
|
||||
|
||||
The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may
|
||||
evaluate to a very big invalid value even if both ctx.bounds.height and
|
||||
combining_glyphs[i]->height are small integers. For example, if
|
||||
ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this
|
||||
expression evaluates to 2147483647 (expected -1). This is because
|
||||
coordinates are allowed to be negative but ctx.bounds.height is an
|
||||
unsigned int. So, the subtraction operates on unsigned ints and
|
||||
underflows to a very big value. The division makes things even worse.
|
||||
The quotient is still an invalid value even if converted back to int.
|
||||
|
||||
This patch fixes the problem by casting ctx.bounds.height to int. As
|
||||
a result the subtraction will operate on int and grub_uint16_t which
|
||||
will be promoted to an int. So, the underflow will no longer happen. Other
|
||||
uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int,
|
||||
to ensure coordinates are always calculated on signed integers.
|
||||
|
||||
Fixes: CVE-2022-3775
|
||||
|
||||
Reported-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
|
||||
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?id=992c06191babc1e109caf40d6a07ec6fdef427af]
|
||||
CVE: CVE-2022-3775
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
grub-core/font/font.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index f110db9..3b76b22 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -1200,12 +1200,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
||||
ctx.bounds.height = main_glyph->height;
|
||||
|
||||
above_rightx = main_glyph->offset_x + main_glyph->width;
|
||||
- above_righty = ctx.bounds.y + ctx.bounds.height;
|
||||
+ above_righty = ctx.bounds.y + (int) ctx.bounds.height;
|
||||
|
||||
above_leftx = main_glyph->offset_x;
|
||||
- above_lefty = ctx.bounds.y + ctx.bounds.height;
|
||||
+ above_lefty = ctx.bounds.y + (int) ctx.bounds.height;
|
||||
|
||||
- below_rightx = ctx.bounds.x + ctx.bounds.width;
|
||||
+ below_rightx = ctx.bounds.x + (int) ctx.bounds.width;
|
||||
below_righty = ctx.bounds.y;
|
||||
|
||||
comb = grub_unicode_get_comb (glyph_id);
|
||||
@@ -1218,7 +1218,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
||||
|
||||
if (!combining_glyphs[i])
|
||||
continue;
|
||||
- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
|
||||
+ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
|
||||
/* CGJ is to avoid diacritics reordering. */
|
||||
if (comb[i].code
|
||||
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
|
||||
@@ -1228,8 +1228,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
||||
case GRUB_UNICODE_COMB_OVERLAY:
|
||||
do_blit (combining_glyphs[i],
|
||||
targetx,
|
||||
- (ctx.bounds.height - combining_glyphs[i]->height) / 2
|
||||
- - (ctx.bounds.height + ctx.bounds.y), &ctx);
|
||||
+ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2
|
||||
+ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx);
|
||||
if (min_devwidth < combining_glyphs[i]->width)
|
||||
min_devwidth = combining_glyphs[i]->width;
|
||||
break;
|
||||
@@ -1302,7 +1302,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
||||
/* Fallthrough. */
|
||||
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
|
||||
do_blit (combining_glyphs[i], targetx,
|
||||
- -(ctx.bounds.height + ctx.bounds.y + space
|
||||
+ -((int) ctx.bounds.height + ctx.bounds.y + space
|
||||
+ combining_glyphs[i]->height), &ctx);
|
||||
if (min_devwidth < combining_glyphs[i]->width)
|
||||
min_devwidth = combining_glyphs[i]->width;
|
||||
@@ -1310,7 +1310,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
|
||||
|
||||
case GRUB_UNICODE_COMB_HEBREW_DAGESH:
|
||||
do_blit (combining_glyphs[i], targetx,
|
||||
- -(ctx.bounds.height / 2 + ctx.bounds.y
|
||||
+ -((int) ctx.bounds.height / 2 + ctx.bounds.y
|
||||
+ combining_glyphs[i]->height / 2), &ctx);
|
||||
if (min_devwidth < combining_glyphs[i]->width)
|
||||
min_devwidth = combining_glyphs[i]->width;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
From 1f511ae054fe42dce7aedfbfe0f234fa1e0a7a3e Mon Sep 17 00:00:00 2001
|
||||
From: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Date: Fri, 5 Aug 2022 00:51:20 +0800
|
||||
Subject: [PATCH] font: Fix size overflow in grub_font_get_glyph_internal()
|
||||
|
||||
The length of memory allocation and file read may overflow. This patch
|
||||
fixes the problem by using safemath macros.
|
||||
|
||||
There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe
|
||||
if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz().
|
||||
It is safe replacement for such code. It has safemath-like prototype.
|
||||
|
||||
This patch also introduces grub_cast(value, pointer), it casts value to
|
||||
typeof(*pointer) then store the value to *pointer. It returns true when
|
||||
overflow occurs or false if there is no overflow. The semantics of arguments
|
||||
and return value are designed to be consistent with other safemath macros.
|
||||
|
||||
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/grub.git/commit/?id=9c76ec09ae08155df27cd237eaea150b4f02f532]
|
||||
|
||||
Signed-off-by: Xiangyu Chen <xiangyu.chen@windriver.com>
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
grub-core/font/font.c | 17 +++++++++++++----
|
||||
include/grub/bitmap.h | 18 ++++++++++++++++++
|
||||
include/grub/safemath.h | 2 ++
|
||||
3 files changed, 33 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index 5edb477..df17dba 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -733,7 +733,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|
||||
grub_int16_t xoff;
|
||||
grub_int16_t yoff;
|
||||
grub_int16_t dwidth;
|
||||
- int len;
|
||||
+ grub_ssize_t len;
|
||||
+ grub_size_t sz;
|
||||
|
||||
if (index_entry->glyph)
|
||||
/* Return cached glyph. */
|
||||
@@ -760,9 +761,17 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- len = (width * height + 7) / 8;
|
||||
- glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
|
||||
- if (!glyph)
|
||||
+ /* Calculate real struct size of current glyph. */
|
||||
+ if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) ||
|
||||
+ grub_add (sizeof (struct grub_font_glyph), len, &sz))
|
||||
+ {
|
||||
+ remove_font (font);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Allocate and initialize the glyph struct. */
|
||||
+ glyph = grub_malloc (sz);
|
||||
+ if (glyph == NULL)
|
||||
{
|
||||
remove_font (font);
|
||||
return 0;
|
||||
diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h
|
||||
index 5728f8c..0d9603f 100644
|
||||
--- a/include/grub/bitmap.h
|
||||
+++ b/include/grub/bitmap.h
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <grub/symbol.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/video.h>
|
||||
+#include <grub/safemath.h>
|
||||
|
||||
struct grub_video_bitmap
|
||||
{
|
||||
@@ -79,6 +80,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap)
|
||||
return bitmap->mode_info.height;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Calculate and store the size of data buffer of 1bit bitmap in result.
|
||||
+ * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs.
|
||||
+ * Return true when overflow occurs or false if there is no overflow.
|
||||
+ * This function is intentionally implemented as a macro instead of
|
||||
+ * an inline function. Although a bit awkward, it preserves data types for
|
||||
+ * safemath macros and reduces macro side effects as much as possible.
|
||||
+ *
|
||||
+ * XXX: Will report false overflow if width * height > UINT64_MAX.
|
||||
+ */
|
||||
+#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \
|
||||
+({ \
|
||||
+ grub_uint64_t _bitmap_pixels; \
|
||||
+ grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \
|
||||
+ grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \
|
||||
+})
|
||||
+
|
||||
void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap,
|
||||
struct grub_video_mode_info *mode_info);
|
||||
|
||||
diff --git a/include/grub/safemath.h b/include/grub/safemath.h
|
||||
index c17b89b..bb0f826 100644
|
||||
--- a/include/grub/safemath.h
|
||||
+++ b/include/grub/safemath.h
|
||||
@@ -30,6 +30,8 @@
|
||||
#define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res)
|
||||
#define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res)
|
||||
|
||||
+#define grub_cast(a, res) grub_add ((a), 0, (res))
|
||||
+
|
||||
#else
|
||||
#error gcc 5.1 or newer or clang 3.8 or newer is required
|
||||
#endif
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -102,6 +102,10 @@ SRC_URI = "${GNU_MIRROR}/grub/grub-${PV}.tar.gz \
|
||||
file://CVE-2022-28733.patch \
|
||||
file://CVE-2022-28734.patch \
|
||||
file://CVE-2022-28736.patch \
|
||||
file://CVE-2022-28735.patch \
|
||||
file://font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch \
|
||||
file://CVE-2022-2601.patch \
|
||||
file://CVE-2022-3775.patch \
|
||||
"
|
||||
SRC_URI[md5sum] = "5ce674ca6b2612d8939b9e6abed32934"
|
||||
SRC_URI[sha256sum] = "f10c85ae3e204dbaec39ae22fa3c5e99f0665417e91c2cb49b7e5031658ba6ea"
|
||||
|
||||
@@ -5,8 +5,8 @@ SECTION = "network"
|
||||
LICENSE = "PD"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=87964579b2a8ece4bc6744d2dc9a8b04"
|
||||
|
||||
SRCREV = "fe19892a8168bf19d81e3bc4ee319bf7f9f058f5"
|
||||
PV = "20220725"
|
||||
SRCREV = "22a5de3ef637990ce03141f786fbdb327e9c5a3f"
|
||||
PV = "20221107"
|
||||
PE = "1"
|
||||
|
||||
SRC_URI = "git://gitlab.gnome.org/GNOME/mobile-broadband-provider-info.git;protocol=https;branch=main"
|
||||
|
||||
50
meta/recipes-connectivity/ppp/ppp/CVE-2022-4603.patch
Normal file
50
meta/recipes-connectivity/ppp/ppp/CVE-2022-4603.patch
Normal file
@@ -0,0 +1,50 @@
|
||||
From 2aeb41a9a3a43b11b1e46628d0bf98197ff9f141 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Mackerras <paulus@ozlabs.org>
|
||||
Date: Thu, 29 Dec 2022 18:00:20 +0100
|
||||
Subject: [PATCH] pppdump: Avoid out-of-range access to packet buffer
|
||||
|
||||
This fixes a potential vulnerability where data is written to spkt.buf
|
||||
and rpkt.buf without a check on the array index. To fix this, we
|
||||
check the array index (pkt->cnt) before storing the byte or
|
||||
incrementing the count. This also means we no longer have a potential
|
||||
signed integer overflow on the increment of pkt->cnt.
|
||||
|
||||
Fortunately, pppdump is not used in the normal process of setting up a
|
||||
PPP connection, is not installed setuid-root, and is not invoked
|
||||
automatically in any scenario that I am aware of.
|
||||
|
||||
Ustream-Status: Backport [https://github.com/ppp-project/ppp/commit/a75fb7b198eed50d769c80c36629f38346882cbf]
|
||||
CVE: CVE-2022-4603
|
||||
Signed-off-by:Minjae Kim <flowergom@gmail.com>
|
||||
---
|
||||
pppdump/pppdump.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pppdump/pppdump.c b/pppdump/pppdump.c
|
||||
index 87c2e8f..dec4def 100644
|
||||
--- a/pppdump/pppdump.c
|
||||
+++ b/pppdump/pppdump.c
|
||||
@@ -296,6 +296,10 @@ dumpppp(f)
|
||||
printf("%s aborted packet:\n ", dir);
|
||||
q = " ";
|
||||
}
|
||||
+ if (pkt->cnt >= sizeof(pkt->buf)) {
|
||||
+ printf("%s over-long packet truncated:\n ", dir);
|
||||
+ q = " ";
|
||||
+ }
|
||||
nb = pkt->cnt;
|
||||
p = pkt->buf;
|
||||
pkt->cnt = 0;
|
||||
@@ -399,7 +403,8 @@ dumpppp(f)
|
||||
c ^= 0x20;
|
||||
pkt->esc = 0;
|
||||
}
|
||||
- pkt->buf[pkt->cnt++] = c;
|
||||
+ if (pkt->cnt < sizeof(pkt->buf))
|
||||
+ pkt->buf[pkt->cnt++] = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -34,6 +34,7 @@ SRC_URI = "https://download.samba.org/pub/${BPN}/${BP}.tar.gz \
|
||||
file://0001-ppp-Remove-unneeded-include.patch \
|
||||
file://ppp-2.4.7-DES-openssl.patch \
|
||||
file://0001-pppd-Fix-bounds-check-in-EAP-code.patch \
|
||||
file://CVE-2022-4603.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_libc-musl = "\
|
||||
|
||||
@@ -29,6 +29,7 @@ SRC_URI = "http://matt.ucc.asn.au/dropbear/releases/dropbear-${PV}.tar.bz2 \
|
||||
${@bb.utils.contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \
|
||||
${@bb.utils.contains('PACKAGECONFIG', 'disable-weak-ciphers', 'file://dropbear-disable-weak-ciphers.patch', '', d)} \
|
||||
file://CVE-2020-36254.patch \
|
||||
file://CVE-2021-36369.patch \
|
||||
"
|
||||
|
||||
PAM_SRC_URI = "file://0005-dropbear-enable-pam.patch \
|
||||
|
||||
145
meta/recipes-core/dropbear/dropbear/CVE-2021-36369.patch
Normal file
145
meta/recipes-core/dropbear/dropbear/CVE-2021-36369.patch
Normal file
@@ -0,0 +1,145 @@
|
||||
From e10dec82930863e487b22978d3df107274f366b2 Mon Sep 17 00:00:00 2001
|
||||
From: Manfred Kaiser <37737811+manfred-kaiser@users.noreply.github.com>
|
||||
Date: Thu, 19 Aug 2021 17:37:14 +0200
|
||||
Subject: [PATCH] added option to disable trivial auth methods (#128)
|
||||
|
||||
* added option to disable trivial auth methods
|
||||
|
||||
* rename argument to match with other ssh clients
|
||||
|
||||
* fixed trivial auth detection for pubkeys
|
||||
|
||||
[https://github.com/mkj/dropbear/pull/128]
|
||||
Upstream-Status: Backport
|
||||
CVE: CVE-2021-36369
|
||||
Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
|
||||
|
||||
---
|
||||
cli-auth.c | 3 +++
|
||||
cli-authinteract.c | 1 +
|
||||
cli-authpasswd.c | 2 +-
|
||||
cli-authpubkey.c | 1 +
|
||||
cli-runopts.c | 7 +++++++
|
||||
cli-session.c | 1 +
|
||||
runopts.h | 1 +
|
||||
session.h | 1 +
|
||||
8 files changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cli-auth.c b/cli-auth.c
|
||||
index 2e509e5..6f04495 100644
|
||||
--- a/cli-auth.c
|
||||
+++ b/cli-auth.c
|
||||
@@ -267,6 +267,9 @@ void recv_msg_userauth_success() {
|
||||
if DROPBEAR_CLI_IMMEDIATE_AUTH is set */
|
||||
|
||||
TRACE(("received msg_userauth_success"))
|
||||
+ if (cli_opts.disable_trivial_auth && cli_ses.is_trivial_auth) {
|
||||
+ dropbear_exit("trivial authentication not allowed");
|
||||
+ }
|
||||
/* Note: in delayed-zlib mode, setting authdone here
|
||||
* will enable compression in the transport layer */
|
||||
ses.authstate.authdone = 1;
|
||||
diff --git a/cli-authinteract.c b/cli-authinteract.c
|
||||
index e1cc9a1..f7128ee 100644
|
||||
--- a/cli-authinteract.c
|
||||
+++ b/cli-authinteract.c
|
||||
@@ -114,6 +114,7 @@ void recv_msg_userauth_info_request() {
|
||||
m_free(instruction);
|
||||
|
||||
for (i = 0; i < num_prompts; i++) {
|
||||
+ cli_ses.is_trivial_auth = 0;
|
||||
unsigned int response_len = 0;
|
||||
prompt = buf_getstring(ses.payload, NULL);
|
||||
cleantext(prompt);
|
||||
diff --git a/cli-authpasswd.c b/cli-authpasswd.c
|
||||
index 00fdd8b..a24d43e 100644
|
||||
--- a/cli-authpasswd.c
|
||||
+++ b/cli-authpasswd.c
|
||||
@@ -155,7 +155,7 @@ void cli_auth_password() {
|
||||
|
||||
encrypt_packet();
|
||||
m_burn(password, strlen(password));
|
||||
-
|
||||
+ cli_ses.is_trivial_auth = 0;
|
||||
TRACE(("leave cli_auth_password"))
|
||||
}
|
||||
#endif /* DROPBEAR_CLI_PASSWORD_AUTH */
|
||||
diff --git a/cli-authpubkey.c b/cli-authpubkey.c
|
||||
index 7cee164..7da1a04 100644
|
||||
--- a/cli-authpubkey.c
|
||||
+++ b/cli-authpubkey.c
|
||||
@@ -174,6 +174,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
|
||||
buf_putbytes(sigbuf, ses.writepayload->data, ses.writepayload->len);
|
||||
cli_buf_put_sign(ses.writepayload, key, type, sigbuf);
|
||||
buf_free(sigbuf); /* Nothing confidential in the buffer */
|
||||
+ cli_ses.is_trivial_auth = 0;
|
||||
}
|
||||
|
||||
encrypt_packet();
|
||||
diff --git a/cli-runopts.c b/cli-runopts.c
|
||||
index 7d1fffe..6bf8b8e 100644
|
||||
--- a/cli-runopts.c
|
||||
+++ b/cli-runopts.c
|
||||
@@ -152,6 +152,7 @@ void cli_getopts(int argc, char ** argv) {
|
||||
#if DROPBEAR_CLI_ANYTCPFWD
|
||||
cli_opts.exit_on_fwd_failure = 0;
|
||||
#endif
|
||||
+ cli_opts.disable_trivial_auth = 0;
|
||||
#if DROPBEAR_CLI_LOCALTCPFWD
|
||||
cli_opts.localfwds = list_new();
|
||||
opts.listen_fwd_all = 0;
|
||||
@@ -888,6 +889,7 @@ static void add_extendedopt(const char* origstr) {
|
||||
#if DROPBEAR_CLI_ANYTCPFWD
|
||||
"\tExitOnForwardFailure\n"
|
||||
#endif
|
||||
+ "\tDisableTrivialAuth\n"
|
||||
#ifndef DISABLE_SYSLOG
|
||||
"\tUseSyslog\n"
|
||||
#endif
|
||||
@@ -915,5 +917,10 @@ static void add_extendedopt(const char* origstr) {
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (match_extendedopt(&optstr, "DisableTrivialAuth") == DROPBEAR_SUCCESS) {
|
||||
+ cli_opts.disable_trivial_auth = parse_flag_value(optstr);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
dropbear_log(LOG_WARNING, "Ignoring unknown configuration option '%s'", origstr);
|
||||
}
|
||||
diff --git a/cli-session.c b/cli-session.c
|
||||
index 56dd4af..73ef0db 100644
|
||||
--- a/cli-session.c
|
||||
+++ b/cli-session.c
|
||||
@@ -164,6 +164,7 @@ static void cli_session_init(pid_t proxy_cmd_pid) {
|
||||
/* Auth */
|
||||
cli_ses.lastprivkey = NULL;
|
||||
cli_ses.lastauthtype = 0;
|
||||
+ cli_ses.is_trivial_auth = 1;
|
||||
|
||||
/* For printing "remote host closed" for the user */
|
||||
ses.remoteclosed = cli_remoteclosed;
|
||||
diff --git a/runopts.h b/runopts.h
|
||||
index 31eae1f..8519626 100644
|
||||
--- a/runopts.h
|
||||
+++ b/runopts.h
|
||||
@@ -154,6 +154,7 @@ typedef struct cli_runopts {
|
||||
#if DROPBEAR_CLI_ANYTCPFWD
|
||||
int exit_on_fwd_failure;
|
||||
#endif
|
||||
+ int disable_trivial_auth;
|
||||
#if DROPBEAR_CLI_REMOTETCPFWD
|
||||
m_list * remotefwds;
|
||||
#endif
|
||||
diff --git a/session.h b/session.h
|
||||
index 0f77055..8676054 100644
|
||||
--- a/session.h
|
||||
+++ b/session.h
|
||||
@@ -287,6 +287,7 @@ struct clientsession {
|
||||
|
||||
int lastauthtype; /* either AUTH_TYPE_PUBKEY or AUTH_TYPE_PASSWORD,
|
||||
for the last type of auth we tried */
|
||||
+ int is_trivial_auth;
|
||||
int ignore_next_auth_response;
|
||||
#if DROPBEAR_CLI_INTERACT_AUTH
|
||||
int auth_interact_failed; /* flag whether interactive auth can still
|
||||
@@ -24,7 +24,7 @@ IMAGE_FSTYPES = "wic.vmdk"
|
||||
|
||||
inherit core-image setuptools3
|
||||
|
||||
SRCREV ?= "2b7d97af746e4713036050e730d28b9b13a3c4a2"
|
||||
SRCREV ?= "f1292a552f33a329ff27bbdea4c90250908d6301"
|
||||
SRC_URI = "git://git.yoctoproject.org/poky;branch=dunfell \
|
||||
file://Yocto_Build_Appliance.vmx \
|
||||
file://Yocto_Build_Appliance.vmxf \
|
||||
|
||||
623
meta/recipes-core/libxml/libxml2/CVE-2022-40303.patch
Normal file
623
meta/recipes-core/libxml/libxml2/CVE-2022-40303.patch
Normal file
@@ -0,0 +1,623 @@
|
||||
From c846986356fc149915a74972bf198abc266bc2c0 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 Aug 2022 17:43:08 +0200
|
||||
Subject: [PATCH] [CVE-2022-40303] Fix integer overflows with XML_PARSE_HUGE
|
||||
|
||||
Also impose size limits when XML_PARSE_HUGE is set. Limit size of names
|
||||
to XML_MAX_TEXT_LENGTH (10 million bytes) and other content to
|
||||
XML_MAX_HUGE_LENGTH (1 billion bytes).
|
||||
|
||||
Move some the length checks to the end of the respective loop to make
|
||||
them strict.
|
||||
|
||||
xmlParseEntityValue didn't have a length limitation at all. But without
|
||||
XML_PARSE_HUGE, this should eventually trigger an error in xmlGROW.
|
||||
|
||||
Thanks to Maddie Stone working with Google Project Zero for the report!
|
||||
|
||||
CVE: CVE-2022-40303
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/c846986356fc149915a74972bf198abc266bc2c0]
|
||||
Comments: Refreshed hunk
|
||||
|
||||
Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
|
||||
---
|
||||
parser.c | 233 +++++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 121 insertions(+), 112 deletions(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 93f031be..79479979 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -102,6 +102,8 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt);
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
+#define XML_MAX_HUGE_LENGTH 1000000000
|
||||
+
|
||||
#define XML_PARSER_BIG_ENTITY 1000
|
||||
#define XML_PARSER_LOT_ENTITY 5000
|
||||
|
||||
@@ -552,7 +554,7 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
|
||||
errmsg = "Malformed declaration expecting version";
|
||||
break;
|
||||
case XML_ERR_NAME_TOO_LONG:
|
||||
- errmsg = "Name too long use XML_PARSE_HUGE option";
|
||||
+ errmsg = "Name too long";
|
||||
break;
|
||||
#if 0
|
||||
case:
|
||||
@@ -3202,6 +3204,9 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0, l;
|
||||
int c;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseNameComplex++;
|
||||
@@ -3267,7 +3272,8 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
return(NULL);
|
||||
}
|
||||
- len += l;
|
||||
+ if (len <= INT_MAX - l)
|
||||
+ len += l;
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
@@ -3293,13 +3299,13 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
return(NULL);
|
||||
}
|
||||
- len += l;
|
||||
+ if (len <= INT_MAX - l)
|
||||
+ len += l;
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3338,7 +3344,10 @@ const xmlChar *
|
||||
xmlParseName(xmlParserCtxtPtr ctxt) {
|
||||
const xmlChar *in;
|
||||
const xmlChar *ret;
|
||||
- int count = 0;
|
||||
+ size_t count = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
GROW;
|
||||
|
||||
@@ -3362,8 +3371,7 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
|
||||
in++;
|
||||
if ((*in > 0) && (*in < 0x80)) {
|
||||
count = in - ctxt->input->cur;
|
||||
- if ((count > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (count > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3384,6 +3392,9 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0, l;
|
||||
int c;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
size_t startPosition = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -3404,17 +3415,13 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
|
||||
(xmlIsNameChar(ctxt, c) && (c != ':'))) {
|
||||
if (count++ > XML_PARSER_CHUNK_SIZE) {
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
- return(NULL);
|
||||
- }
|
||||
count = 0;
|
||||
GROW;
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
return(NULL);
|
||||
}
|
||||
- len += l;
|
||||
+ if (len <= INT_MAX - l)
|
||||
+ len += l;
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
if (c == 0) {
|
||||
@@ -3432,8 +3439,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3459,7 +3465,10 @@ static const xmlChar *
|
||||
xmlParseNCName(xmlParserCtxtPtr ctxt) {
|
||||
const xmlChar *in, *e;
|
||||
const xmlChar *ret;
|
||||
- int count = 0;
|
||||
+ size_t count = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseNCName++;
|
||||
@@ -3484,8 +3493,7 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
|
||||
goto complex;
|
||||
if ((*in > 0) && (*in < 0x80)) {
|
||||
count = in - ctxt->input->cur;
|
||||
- if ((count > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (count > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3567,6 +3575,9 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
|
||||
const xmlChar *cur = *str;
|
||||
int len = 0, l;
|
||||
int c;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseStringName++;
|
||||
@@ -3602,12 +3613,6 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
|
||||
if (len + 10 > max) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
- xmlFree(buffer);
|
||||
- return(NULL);
|
||||
- }
|
||||
max *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buffer,
|
||||
max * sizeof(xmlChar));
|
||||
@@ -3621,14 +3626,18 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
|
||||
COPY_BUF(l,buffer,len,c);
|
||||
cur += l;
|
||||
c = CUR_SCHAR(cur, l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
+ xmlFree(buffer);
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buffer[len] = 0;
|
||||
*str = cur;
|
||||
return(buffer);
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3655,6 +3664,9 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0, l;
|
||||
int c;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseNmToken++;
|
||||
@@ -3706,12 +3718,6 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 10 > max) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((max > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
|
||||
- xmlFree(buffer);
|
||||
- return(NULL);
|
||||
- }
|
||||
max *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buffer,
|
||||
max * sizeof(xmlChar));
|
||||
@@ -3725,6 +3731,11 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
COPY_BUF(l,buffer,len,c);
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
|
||||
+ xmlFree(buffer);
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buffer[len] = 0;
|
||||
return(buffer);
|
||||
@@ -3732,8 +3743,7 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
}
|
||||
if (len == 0)
|
||||
return(NULL);
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3759,6 +3769,9 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
|
||||
int len = 0;
|
||||
int size = XML_PARSER_BUFFER_SIZE;
|
||||
int c, l;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
xmlChar stop;
|
||||
xmlChar *ret = NULL;
|
||||
const xmlChar *cur = NULL;
|
||||
@@ -3818,6 +3831,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
|
||||
GROW;
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
+
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
|
||||
+ "entity value too long\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
@@ -3905,6 +3924,9 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
xmlChar *rep = NULL;
|
||||
size_t len = 0;
|
||||
size_t buf_size = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
int c, l, in_space = 0;
|
||||
xmlChar *current = NULL;
|
||||
xmlEntityPtr ent;
|
||||
@@ -3925,16 +3925,6 @@
|
||||
while (((NXT(0) != limit) && /* checked */
|
||||
(IS_CHAR(c)) && (c != '<')) &&
|
||||
(ctxt->instate != XML_PARSER_EOF)) {
|
||||
- /*
|
||||
- * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
|
||||
- * special option is given
|
||||
- */
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
- "AttValue length too long\n");
|
||||
- goto mem_error;
|
||||
- }
|
||||
if (c == 0) break;
|
||||
if (c == '&') {
|
||||
in_space = 0;
|
||||
@@ -4093,6 +4105,11 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
}
|
||||
GROW;
|
||||
c = CUR_CHAR(l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
+ "AttValue length too long\n");
|
||||
+ goto mem_error;
|
||||
+ }
|
||||
}
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
goto error;
|
||||
@@ -4114,16 +4131,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
} else
|
||||
NEXT;
|
||||
|
||||
- /*
|
||||
- * There we potentially risk an overflow, don't allow attribute value of
|
||||
- * length more than INT_MAX it is a very reasonable assumption !
|
||||
- */
|
||||
- if (len >= INT_MAX) {
|
||||
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
- "AttValue length too long\n");
|
||||
- goto mem_error;
|
||||
- }
|
||||
-
|
||||
if (attlen != NULL) *attlen = (int) len;
|
||||
return(buf);
|
||||
|
||||
@@ -4194,6 +4201,9 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0;
|
||||
int size = XML_PARSER_BUFFER_SIZE;
|
||||
int cur, l;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
xmlChar stop;
|
||||
int state = ctxt->instate;
|
||||
int count = 0;
|
||||
@@ -4221,13 +4231,6 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 5 >= size) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((size > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
|
||||
- xmlFree(buf);
|
||||
- ctxt->instate = (xmlParserInputState) state;
|
||||
- return(NULL);
|
||||
- }
|
||||
size *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
|
||||
if (tmp == NULL) {
|
||||
@@ -4256,6 +4259,12 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
|
||||
SHRINK;
|
||||
cur = CUR_CHAR(l);
|
||||
}
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
|
||||
+ xmlFree(buf);
|
||||
+ ctxt->instate = (xmlParserInputState) state;
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
ctxt->instate = (xmlParserInputState) state;
|
||||
@@ -4283,6 +4292,9 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar *buf = NULL;
|
||||
int len = 0;
|
||||
int size = XML_PARSER_BUFFER_SIZE;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
xmlChar cur;
|
||||
xmlChar stop;
|
||||
int count = 0;
|
||||
@@ -4310,12 +4322,6 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 1 >= size) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((size > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
|
||||
- xmlFree(buf);
|
||||
- return(NULL);
|
||||
- }
|
||||
size *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
|
||||
if (tmp == NULL) {
|
||||
@@ -4343,6 +4349,11 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
|
||||
SHRINK;
|
||||
cur = CUR;
|
||||
}
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
|
||||
+ xmlFree(buf);
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
if (cur != stop) {
|
||||
@@ -4742,6 +4753,9 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
|
||||
int r, rl;
|
||||
int cur, l;
|
||||
size_t count = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
int inputid;
|
||||
|
||||
inputid = ctxt->input->id;
|
||||
@@ -4787,13 +4801,6 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
|
||||
if ((r == '-') && (q == '-')) {
|
||||
xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
|
||||
}
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
|
||||
- "Comment too big found", NULL);
|
||||
- xmlFree (buf);
|
||||
- return;
|
||||
- }
|
||||
if (len + 5 >= size) {
|
||||
xmlChar *new_buf;
|
||||
size_t new_size;
|
||||
@@ -4831,6 +4838,13 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
|
||||
GROW;
|
||||
cur = CUR_CHAR(l);
|
||||
}
|
||||
+
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
|
||||
+ "Comment too big found", NULL);
|
||||
+ xmlFree (buf);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
if (cur == 0) {
|
||||
@@ -4875,6 +4889,9 @@ xmlParseComment(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar *buf = NULL;
|
||||
size_t size = XML_PARSER_BUFFER_SIZE;
|
||||
size_t len = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
xmlParserInputState state;
|
||||
const xmlChar *in;
|
||||
size_t nbchar = 0;
|
||||
@@ -4958,8 +4975,7 @@ get_more:
|
||||
buf[len] = 0;
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
|
||||
"Comment too big found", NULL);
|
||||
xmlFree (buf);
|
||||
@@ -5159,6 +5175,9 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar *buf = NULL;
|
||||
size_t len = 0;
|
||||
size_t size = XML_PARSER_BUFFER_SIZE;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
int cur, l;
|
||||
const xmlChar *target;
|
||||
xmlParserInputState state;
|
||||
@@ -5234,14 +5253,6 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
|
||||
return;
|
||||
}
|
||||
count = 0;
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
- "PI %s too big found", target);
|
||||
- xmlFree(buf);
|
||||
- ctxt->instate = state;
|
||||
- return;
|
||||
- }
|
||||
}
|
||||
COPY_BUF(l,buf,len,cur);
|
||||
NEXTL(l);
|
||||
@@ -5251,15 +5262,14 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
|
||||
GROW;
|
||||
cur = CUR_CHAR(l);
|
||||
}
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
+ "PI %s too big found", target);
|
||||
+ xmlFree(buf);
|
||||
+ ctxt->instate = state;
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
- "PI %s too big found", target);
|
||||
- xmlFree(buf);
|
||||
- ctxt->instate = state;
|
||||
- return;
|
||||
- }
|
||||
buf[len] = 0;
|
||||
if (cur != '?') {
|
||||
xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
@@ -8954,6 +8964,9 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
const xmlChar *in = NULL, *start, *end, *last;
|
||||
xmlChar *ret = NULL;
|
||||
int line, col;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
|
||||
GROW;
|
||||
in = (xmlChar *) CUR_PTR;
|
||||
@@ -8993,8 +9006,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
start = in;
|
||||
if (in >= end) {
|
||||
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9007,8 +9019,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
if ((*in++ == 0x20) && (*in == 0x20)) break;
|
||||
if (in >= end) {
|
||||
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9041,16 +9052,14 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
last = last + delta;
|
||||
}
|
||||
end = ctxt->input->end;
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9063,8 +9072,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
col++;
|
||||
if (in >= end) {
|
||||
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9072,8 +9080,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
}
|
||||
}
|
||||
last = in;
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9763,6 +9770,9 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
||||
int s, sl;
|
||||
int cur, l;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
|
||||
/* Check 2.6.0 was NXT(0) not RAW */
|
||||
if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
|
||||
@@ -9796,13 +9806,6 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 5 >= size) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((size > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
|
||||
- "CData section too big found", NULL);
|
||||
- xmlFree (buf);
|
||||
- return;
|
||||
- }
|
||||
tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
|
||||
if (tmp == NULL) {
|
||||
xmlFree(buf);
|
||||
@@ -9829,6 +9832,12 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
||||
}
|
||||
NEXTL(l);
|
||||
cur = CUR_CHAR(l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_CDATA_NOT_FINISHED,
|
||||
+ "CData section too big found\n");
|
||||
+ xmlFree(buf);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
ctxt->instate = XML_PARSER_CONTENT;
|
||||
--
|
||||
GitLab
|
||||
104
meta/recipes-core/libxml/libxml2/CVE-2022-40304.patch
Normal file
104
meta/recipes-core/libxml/libxml2/CVE-2022-40304.patch
Normal file
@@ -0,0 +1,104 @@
|
||||
From 1b41ec4e9433b05bb0376be4725804c54ef1d80b Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 31 Aug 2022 22:11:25 +0200
|
||||
Subject: [PATCH] [CVE-2022-40304] Fix dict corruption caused by entity
|
||||
reference cycles
|
||||
|
||||
When an entity reference cycle is detected, the entity content is
|
||||
cleared by setting its first byte to zero. But the entity content might
|
||||
be allocated from a dict. In this case, the dict entry becomes corrupted
|
||||
leading to all kinds of logic errors, including memory errors like
|
||||
double-frees.
|
||||
|
||||
Stop storing entity content, orig, ExternalID and SystemID in a dict.
|
||||
These values are unlikely to occur multiple times in a document, so they
|
||||
shouldn't have been stored in a dict in the first place.
|
||||
|
||||
Thanks to Ned Williamson and Nathan Wachholz working with Google Project
|
||||
Zero for the report!
|
||||
|
||||
CVE: CVE-2022-40304
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/1b41ec4e9433b05bb0376be4725804c54ef1d80b]
|
||||
Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
|
||||
---
|
||||
entities.c | 55 ++++++++++++++++--------------------------------------
|
||||
1 file changed, 16 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/entities.c b/entities.c
|
||||
index 84435515..d4e5412e 100644
|
||||
--- a/entities.c
|
||||
+++ b/entities.c
|
||||
@@ -128,36 +128,19 @@ xmlFreeEntity(xmlEntityPtr entity)
|
||||
if ((entity->children) && (entity->owner == 1) &&
|
||||
(entity == (xmlEntityPtr) entity->children->parent))
|
||||
xmlFreeNodeList(entity->children);
|
||||
- if (dict != NULL) {
|
||||
- if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name)))
|
||||
- xmlFree((char *) entity->name);
|
||||
- if ((entity->ExternalID != NULL) &&
|
||||
- (!xmlDictOwns(dict, entity->ExternalID)))
|
||||
- xmlFree((char *) entity->ExternalID);
|
||||
- if ((entity->SystemID != NULL) &&
|
||||
- (!xmlDictOwns(dict, entity->SystemID)))
|
||||
- xmlFree((char *) entity->SystemID);
|
||||
- if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI)))
|
||||
- xmlFree((char *) entity->URI);
|
||||
- if ((entity->content != NULL)
|
||||
- && (!xmlDictOwns(dict, entity->content)))
|
||||
- xmlFree((char *) entity->content);
|
||||
- if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig)))
|
||||
- xmlFree((char *) entity->orig);
|
||||
- } else {
|
||||
- if (entity->name != NULL)
|
||||
- xmlFree((char *) entity->name);
|
||||
- if (entity->ExternalID != NULL)
|
||||
- xmlFree((char *) entity->ExternalID);
|
||||
- if (entity->SystemID != NULL)
|
||||
- xmlFree((char *) entity->SystemID);
|
||||
- if (entity->URI != NULL)
|
||||
- xmlFree((char *) entity->URI);
|
||||
- if (entity->content != NULL)
|
||||
- xmlFree((char *) entity->content);
|
||||
- if (entity->orig != NULL)
|
||||
- xmlFree((char *) entity->orig);
|
||||
- }
|
||||
+ if ((entity->name != NULL) &&
|
||||
+ ((dict == NULL) || (!xmlDictOwns(dict, entity->name))))
|
||||
+ xmlFree((char *) entity->name);
|
||||
+ if (entity->ExternalID != NULL)
|
||||
+ xmlFree((char *) entity->ExternalID);
|
||||
+ if (entity->SystemID != NULL)
|
||||
+ xmlFree((char *) entity->SystemID);
|
||||
+ if (entity->URI != NULL)
|
||||
+ xmlFree((char *) entity->URI);
|
||||
+ if (entity->content != NULL)
|
||||
+ xmlFree((char *) entity->content);
|
||||
+ if (entity->orig != NULL)
|
||||
+ xmlFree((char *) entity->orig);
|
||||
xmlFree(entity);
|
||||
}
|
||||
|
||||
@@ -193,18 +176,12 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
|
||||
ret->SystemID = xmlStrdup(SystemID);
|
||||
} else {
|
||||
ret->name = xmlDictLookup(dict, name, -1);
|
||||
- if (ExternalID != NULL)
|
||||
- ret->ExternalID = xmlDictLookup(dict, ExternalID, -1);
|
||||
- if (SystemID != NULL)
|
||||
- ret->SystemID = xmlDictLookup(dict, SystemID, -1);
|
||||
+ ret->ExternalID = xmlStrdup(ExternalID);
|
||||
+ ret->SystemID = xmlStrdup(SystemID);
|
||||
}
|
||||
if (content != NULL) {
|
||||
ret->length = xmlStrlen(content);
|
||||
- if ((dict != NULL) && (ret->length < 5))
|
||||
- ret->content = (xmlChar *)
|
||||
- xmlDictLookup(dict, content, ret->length);
|
||||
- else
|
||||
- ret->content = xmlStrndup(content, ret->length);
|
||||
+ ret->content = xmlStrndup(content, ret->length);
|
||||
} else {
|
||||
ret->length = 0;
|
||||
ret->content = NULL;
|
||||
--
|
||||
GitLab
|
||||
@@ -34,6 +34,8 @@ SRC_URI += "http://www.w3.org/XML/Test/xmlts20080827.tar.gz;subdir=${BP};name=te
|
||||
file://CVE-2022-29824.patch \
|
||||
file://0001-Port-gentest.py-to-Python-3.patch \
|
||||
file://CVE-2016-3709.patch \
|
||||
file://CVE-2022-40303.patch \
|
||||
file://CVE-2022-40304.patch \
|
||||
"
|
||||
|
||||
SRC_URI[archive.sha256sum] = "593b7b751dd18c2d6abcd0c4bcb29efc203d0b4373a6df98e3a455ea74ae2813"
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 7b005f344e533cd913c3ca05b266f9872df886d1 Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Thu, 24 Mar 2022 20:04:34 +0800
|
||||
Subject: [PATCH] BaseTools: fix gcc12 warning
|
||||
|
||||
GenFfs.c:545:5: error: pointer ?InFileHandle? used after ?fclose? [-Werror=use-after-free]
|
||||
545 | Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
GenFfs.c:544:5: note: call to ?fclose? here
|
||||
544 | fclose (InFileHandle);
|
||||
| ^~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/7b005f344e533cd913c3ca05b266f9872df886d1]
|
||||
Signed-off-by: Steve Sakoman <steve@sakoman.com>
|
||||
|
||||
---
|
||||
BaseTools/Source/C/GenFfs/GenFfs.c | 2 +-
|
||||
BaseTools/Source/C/GenSec/GenSec.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/BaseTools/Source/C/GenFfs/GenFfs.c b/BaseTools/Source/C/GenFfs/GenFfs.c
|
||||
index 949025c33325..d78d62ab3689 100644
|
||||
--- a/BaseTools/Source/C/GenFfs/GenFfs.c
|
||||
+++ b/BaseTools/Source/C/GenFfs/GenFfs.c
|
||||
@@ -542,7 +542,7 @@ GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
|
||||
PeFileBuffer = (UINT8 *) malloc (PeFileSize);
|
||||
if (PeFileBuffer == NULL) {
|
||||
fclose (InFileHandle);
|
||||
- Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle);
|
||||
+ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
|
||||
diff --git a/BaseTools/Source/C/GenSec/GenSec.c b/BaseTools/Source/C/GenSec/GenSec.c
|
||||
index d54a4f9e0a7d..b1d05367ec0b 100644
|
||||
--- a/BaseTools/Source/C/GenSec/GenSec.c
|
||||
+++ b/BaseTools/Source/C/GenSec/GenSec.c
|
||||
@@ -1062,7 +1062,7 @@ GetAlignmentFromFile(char *InFile, UINT32 *Alignment)
|
||||
PeFileBuffer = (UINT8 *) malloc (PeFileSize);
|
||||
if (PeFileBuffer == NULL) {
|
||||
fclose (InFileHandle);
|
||||
- Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle);
|
||||
+ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated for %s", InFile);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);
|
||||
@@ -0,0 +1,53 @@
|
||||
From 24551a99d1f765c891a4dc21a36f18ccbf56e612 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Sakoman <steve@sakoman.com>
|
||||
Date: Tue, 10 Jan 2023 06:15:00 -1000
|
||||
Subject: [PATCH] BaseTools: fix gcc12 warning
|
||||
|
||||
Sdk/C/LzmaEnc.c: In function ?LzmaEnc_CodeOneMemBlock?:
|
||||
Sdk/C/LzmaEnc.c:2828:19: error: storing the address of local variable ?outStream? in ?*p.rc.outStream? [-Werror=dangling-pointer=]
|
||||
2828 | p->rc.outStream = &outStream.vt;
|
||||
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
|
||||
Sdk/C/LzmaEnc.c:2811:28: note: ?outStream? declared here
|
||||
2811 | CLzmaEnc_SeqOutStreamBuf outStream;
|
||||
| ^~~~~~~~~
|
||||
Sdk/C/LzmaEnc.c:2811:28: note: ?pp? declared here
|
||||
Sdk/C/LzmaEnc.c:2828:19: error: storing the address of local variable ?outStream? in ?*(CLzmaEnc *)pp.rc.outStream? [-Werror=dangling-pointer=]
|
||||
2828 | p->rc.outStream = &outStream.vt;
|
||||
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
|
||||
Sdk/C/LzmaEnc.c:2811:28: note: ?outStream? declared here
|
||||
2811 | CLzmaEnc_SeqOutStreamBuf outStream;
|
||||
| ^~~~~~~~~
|
||||
Sdk/C/LzmaEnc.c:2811:28: note: ?pp? declared here
|
||||
cc1: all warnings being treated as errors
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/85021f8cf22d1bd4114803c6c610dea5ef0059f1]
|
||||
Signed-off-by: Steve Sakoman <steve@sakoman.com>
|
||||
---
|
||||
BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
|
||||
index e281716fee..b575c4f888 100644
|
||||
--- a/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
|
||||
+++ b/BaseTools/Source/C/LzmaCompress/Sdk/C/LzmaEnc.c
|
||||
@@ -2638,12 +2638,13 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
|
||||
|
||||
nowPos64 = p->nowPos64;
|
||||
RangeEnc_Init(&p->rc);
|
||||
- p->rc.outStream = &outStream.vt;
|
||||
|
||||
if (desiredPackSize == 0)
|
||||
return SZ_ERROR_OUTPUT_EOF;
|
||||
|
||||
+ p->rc.outStream = &outStream.vt;
|
||||
res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize);
|
||||
+ p->rc.outStream = NULL;
|
||||
|
||||
*unpackSize = (UInt32)(p->nowPos64 - nowPos64);
|
||||
*destLen -= outStream.rem;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From 22130dcd98b4d4b76ac8d922adb4a2dbc86fa52c Mon Sep 17 00:00:00 2001
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Thu, 24 Mar 2022 20:04:36 +0800
|
||||
Subject: [PATCH] Basetools: turn off gcc12 warning
|
||||
|
||||
In function ?SetDevicePathEndNode?,
|
||||
inlined from ?FileDevicePath? at DevicePathUtilities.c:857:5:
|
||||
DevicePathUtilities.c:321:3: error: writing 4 bytes into a region of size 1 [-Werror=stringop-overflow=]
|
||||
321 | memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
In file included from UefiDevicePathLib.h:22,
|
||||
from DevicePathUtilities.c:16:
|
||||
../Include/Protocol/DevicePath.h: In function ?FileDevicePath?:
|
||||
../Include/Protocol/DevicePath.h:51:9: note: destination object ?Type? of size 1
|
||||
51 | UINT8 Type; ///< 0x01 Hardware Device Path.
|
||||
| ^~~~
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Reviewed-by: Bob Feng <bob.c.feng@intel.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/tianocore/edk2/commit/22130dcd98b4d4b76ac8d922adb4a2dbc86fa52c]
|
||||
Signed-off-by: Steve Sakoman <steve@sakoman.com>
|
||||
|
||||
---
|
||||
BaseTools/Source/C/DevicePath/GNUmakefile | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/BaseTools/Source/C/DevicePath/GNUmakefile b/BaseTools/Source/C/DevicePath/GNUmakefile
|
||||
index 7ca08af9662d..b05d2bddfa68 100644
|
||||
--- a/BaseTools/Source/C/DevicePath/GNUmakefile
|
||||
+++ b/BaseTools/Source/C/DevicePath/GNUmakefile
|
||||
@@ -13,6 +13,9 @@ OBJECTS = DevicePath.o UefiDevicePathLib.o DevicePathFromText.o DevicePathUtili
|
||||
|
||||
include $(MAKEROOT)/Makefiles/app.makefile
|
||||
|
||||
+# gcc 12 trips over device path handling
|
||||
+BUILD_CFLAGS += -Wno-error=stringop-overflow
|
||||
+
|
||||
LIBS = -lCommon
|
||||
ifeq ($(CYGWIN), CYGWIN)
|
||||
LIBS += -L/lib/e2fsprogs -luuid
|
||||
@@ -18,6 +18,9 @@ SRC_URI = "gitsm://github.com/tianocore/edk2.git;branch=master;protocol=https \
|
||||
file://0003-ovmf-enable-long-path-file.patch \
|
||||
file://0004-ovmf-Update-to-latest.patch \
|
||||
file://0001-Fix-VLA-parameter-warning.patch \
|
||||
file://0001-Basetools-genffs-fix-gcc12-warning.patch \
|
||||
file://0001-Basetools-lzmaenc-fix-gcc12-warning.patch \
|
||||
file://0001-Basetools-turn-off-gcc12-warning.patch \
|
||||
"
|
||||
|
||||
PV = "edk2-stable202008"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
Description=Start psplash boot splash screen
|
||||
DefaultDependencies=no
|
||||
RequiresMountsFor=/run
|
||||
ConditionFileIsExecutable=/usr/bin/psplash
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
|
||||
@@ -4,6 +4,7 @@ DefaultDependencies=no
|
||||
After=psplash-start.service
|
||||
Requires=psplash-start.service
|
||||
RequiresMountsFor=/run
|
||||
ConditionFileIsExecutable=/usr/bin/psplash
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/psplash-systemd
|
||||
|
||||
47
meta/recipes-core/systemd/systemd/CVE-2022-3821.patch
Normal file
47
meta/recipes-core/systemd/systemd/CVE-2022-3821.patch
Normal file
@@ -0,0 +1,47 @@
|
||||
From 9102c625a673a3246d7e73d8737f3494446bad4e Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 7 Jul 2022 18:27:02 +0900
|
||||
Subject: [PATCH] time-util: fix buffer-over-run
|
||||
|
||||
Fixes #23928.
|
||||
|
||||
CVE: CVE-2022-3821
|
||||
Upstream-Status: Backport [https://github.com/systemd/systemd/commit/9102c625a673a3246d7e73d8737f3494446bad4e.patch]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
Comment: Both the hunks refreshed to backport
|
||||
|
||||
---
|
||||
src/basic/time-util.c | 2 +-
|
||||
src/test/test-time-util.c | 5 +++++
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||
index abbc4ad5cd70..26d59de12348 100644
|
||||
--- a/src/basic/time-util.c
|
||||
+++ b/src/basic/time-util.c
|
||||
@@ -514,7 +514,7 @@ char *format_timespan(char *buf, size_t
|
||||
t = b;
|
||||
}
|
||||
|
||||
- n = MIN((size_t) k, l);
|
||||
+ n = MIN((size_t) k, l-1);
|
||||
|
||||
l -= n;
|
||||
p += n;
|
||||
diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c
|
||||
index e8e4e2a67bb1..58c5fa9be40c 100644
|
||||
--- a/src/test/test-time-util.c
|
||||
+++ b/src/test/test-time-util.c
|
||||
@@ -501,6 +501,12 @@ int main(int argc, char *argv[]) {
|
||||
test_format_timespan(1);
|
||||
test_format_timespan(USEC_PER_MSEC);
|
||||
test_format_timespan(USEC_PER_SEC);
|
||||
+
|
||||
+ /* See issue #23928. */
|
||||
+ _cleanup_free_ char *buf;
|
||||
+ assert_se(buf = new(char, 5));
|
||||
+ assert_se(buf == format_timespan(buf, 5, 100005, 1000));
|
||||
+
|
||||
test_timezone_is_valid();
|
||||
test_get_timezones();
|
||||
test_usec_add();
|
||||
@@ -33,6 +33,7 @@ SRC_URI += "file://touchscreen.rules \
|
||||
file://CVE-2021-3997-1.patch \
|
||||
file://CVE-2021-3997-2.patch \
|
||||
file://CVE-2021-3997-3.patch \
|
||||
file://CVE-2022-3821.patch \
|
||||
"
|
||||
|
||||
# patches needed by musl
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
Upstream-Status: Backport [https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=97b668f9a8c6ec565c278a60e7d1492a6932e409]
|
||||
Signed-off-by: Jon Mason <jon.mason@arm.com>
|
||||
|
||||
From 97b668f9a8c6ec565c278a60e7d1492a6932e409 Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Klose <doko@ubuntu.com>
|
||||
Date: Tue, 6 Oct 2020 13:41:37 +0200
|
||||
Subject: [PATCH] Backport fix for PR/tree-optimization/97236 - fix bad use of
|
||||
VMAT_CONTIGUOUS
|
||||
|
||||
This avoids using VMAT_CONTIGUOUS with single-element interleaving
|
||||
when using V1mode vectors. Instead keep VMAT_ELEMENTWISE but
|
||||
continue to avoid load-lanes and gathers.
|
||||
|
||||
2020-10-01 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/97236
|
||||
* tree-vect-stmts.c (get_group_load_store_type): Keep
|
||||
VMAT_ELEMENTWISE for single-element vectors.
|
||||
|
||||
* gcc.dg/vect/pr97236.c: New testcase.
|
||||
|
||||
(cherry picked from commit 1ab88985631dd2c5a5e3b5c0dce47cf8b6ed2f82)
|
||||
---
|
||||
gcc/testsuite/gcc.dg/vect/pr97236.c | 43 +++++++++++++++++++++++++++++
|
||||
gcc/tree-vect-stmts.c | 20 ++++++--------
|
||||
2 files changed, 52 insertions(+), 11 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.dg/vect/pr97236.c
|
||||
|
||||
diff --git a/gcc/testsuite/gcc.dg/vect/pr97236.c b/gcc/testsuite/gcc.dg/vect/pr97236.c
|
||||
new file mode 100644
|
||||
index 000000000000..9d3dc20d953d
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.dg/vect/pr97236.c
|
||||
@@ -0,0 +1,43 @@
|
||||
+typedef unsigned char __uint8_t;
|
||||
+typedef __uint8_t uint8_t;
|
||||
+typedef struct plane_t {
|
||||
+ uint8_t *p_pixels;
|
||||
+ int i_lines;
|
||||
+ int i_pitch;
|
||||
+} plane_t;
|
||||
+
|
||||
+typedef struct {
|
||||
+ plane_t p[5];
|
||||
+} picture_t;
|
||||
+
|
||||
+#define N 4
|
||||
+
|
||||
+void __attribute__((noipa))
|
||||
+picture_Clone(picture_t *picture, picture_t *res)
|
||||
+{
|
||||
+ for (int i = 0; i < N; i++) {
|
||||
+ res->p[i].p_pixels = picture->p[i].p_pixels;
|
||||
+ res->p[i].i_lines = picture->p[i].i_lines;
|
||||
+ res->p[i].i_pitch = picture->p[i].i_pitch;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main()
|
||||
+{
|
||||
+ picture_t aaa, bbb;
|
||||
+ uint8_t pixels[10] = {1, 1, 1, 1, 1, 1, 1, 1};
|
||||
+
|
||||
+ for (unsigned i = 0; i < N; i++)
|
||||
+ aaa.p[i].p_pixels = pixels;
|
||||
+
|
||||
+ picture_Clone (&aaa, &bbb);
|
||||
+
|
||||
+ uint8_t c = 0;
|
||||
+ for (unsigned i = 0; i < N; i++)
|
||||
+ c += bbb.p[i].p_pixels[0];
|
||||
+
|
||||
+ if (c != N)
|
||||
+ __builtin_abort ();
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
|
||||
index 507f81b0a0e8..ffbba3441de2 100644
|
||||
--- a/gcc/tree-vect-stmts.c
|
||||
+++ b/gcc/tree-vect-stmts.c
|
||||
@@ -2355,25 +2355,23 @@ get_group_load_store_type (stmt_vec_info stmt_info, tree vectype, bool slp,
|
||||
/* First cope with the degenerate case of a single-element
|
||||
vector. */
|
||||
if (known_eq (TYPE_VECTOR_SUBPARTS (vectype), 1U))
|
||||
- *memory_access_type = VMAT_CONTIGUOUS;
|
||||
+ ;
|
||||
|
||||
/* Otherwise try using LOAD/STORE_LANES. */
|
||||
- if (*memory_access_type == VMAT_ELEMENTWISE
|
||||
- && (vls_type == VLS_LOAD
|
||||
- ? vect_load_lanes_supported (vectype, group_size, masked_p)
|
||||
- : vect_store_lanes_supported (vectype, group_size,
|
||||
- masked_p)))
|
||||
+ else if (vls_type == VLS_LOAD
|
||||
+ ? vect_load_lanes_supported (vectype, group_size, masked_p)
|
||||
+ : vect_store_lanes_supported (vectype, group_size,
|
||||
+ masked_p))
|
||||
{
|
||||
*memory_access_type = VMAT_LOAD_STORE_LANES;
|
||||
overrun_p = would_overrun_p;
|
||||
}
|
||||
|
||||
/* If that fails, try using permuting loads. */
|
||||
- if (*memory_access_type == VMAT_ELEMENTWISE
|
||||
- && (vls_type == VLS_LOAD
|
||||
- ? vect_grouped_load_supported (vectype, single_element_p,
|
||||
- group_size)
|
||||
- : vect_grouped_store_supported (vectype, group_size)))
|
||||
+ else if (vls_type == VLS_LOAD
|
||||
+ ? vect_grouped_load_supported (vectype, single_element_p,
|
||||
+ group_size)
|
||||
+ : vect_grouped_store_supported (vectype, group_size))
|
||||
{
|
||||
*memory_access_type = VMAT_CONTIGUOUS_PERMUTE;
|
||||
overrun_p = would_overrun_p;
|
||||
--
|
||||
2.20.1
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
CVE: CVE-2020-13844
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
From 20da13e395bde597d8337167c712039c8f923c3b Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Malcomson <matthew.malcomson@arm.com>
|
||||
Date: Thu, 9 Jul 2020 09:11:58 +0100
|
||||
Subject: [PATCH 1/3] aarch64: New Straight Line Speculation (SLS) mitigation
|
||||
flags
|
||||
|
||||
Here we introduce the flags that will be used for straight line speculation.
|
||||
|
||||
The new flag introduced is `-mharden-sls=`.
|
||||
This flag can take arguments of `none`, `all`, or a comma seperated list
|
||||
of one or more of `retbr` or `blr`.
|
||||
`none` indicates no special mitigation of the straight line speculation
|
||||
vulnerability.
|
||||
`all` requests all mitigations currently implemented.
|
||||
`retbr` requests that the RET and BR instructions have a speculation
|
||||
barrier inserted after them.
|
||||
`blr` requests that BLR instructions are replaced by a BL to a function
|
||||
stub using a BR with a speculation barrier after it.
|
||||
|
||||
Setting this on a per-function basis using attributes or the like is not
|
||||
enabled, but may be in the future.
|
||||
|
||||
(cherry picked from commit a9ba2a9b77bec7eacaf066801f22d1c366a2bc86)
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
2020-06-02 Matthew Malcomson <matthew.malcomson@arm.com>
|
||||
|
||||
* config/aarch64/aarch64-protos.h (aarch64_harden_sls_retbr_p):
|
||||
New.
|
||||
(aarch64_harden_sls_blr_p): New.
|
||||
* config/aarch64/aarch64.c (enum aarch64_sls_hardening_type):
|
||||
New.
|
||||
(aarch64_harden_sls_retbr_p): New.
|
||||
(aarch64_harden_sls_blr_p): New.
|
||||
(aarch64_validate_sls_mitigation): New.
|
||||
(aarch64_override_options): Parse options for SLS mitigation.
|
||||
* config/aarch64/aarch64.opt (-mharden-sls): New option.
|
||||
* doc/invoke.texi: Document new option.
|
||||
---
|
||||
gcc/config/aarch64/aarch64-protos.h | 3 ++
|
||||
gcc/config/aarch64/aarch64.c | 76 +++++++++++++++++++++++++++++
|
||||
gcc/config/aarch64/aarch64.opt | 4 ++
|
||||
gcc/doc/invoke.texi | 12 +++++
|
||||
4 files changed, 95 insertions(+)
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
|
||||
index c083cad53..31493f412 100644
|
||||
--- a/gcc/config/aarch64/aarch64-protos.h
|
||||
+++ b/gcc/config/aarch64/aarch64-protos.h
|
||||
@@ -644,4 +644,7 @@ poly_uint64 aarch64_regmode_natural_size (machine_mode);
|
||||
|
||||
bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT);
|
||||
|
||||
+extern bool aarch64_harden_sls_retbr_p (void);
|
||||
+extern bool aarch64_harden_sls_blr_p (void);
|
||||
+
|
||||
#endif /* GCC_AARCH64_PROTOS_H */
|
||||
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
|
||||
index b452a53af..269ff6c92 100644
|
||||
--- a/gcc/config/aarch64/aarch64.c
|
||||
+++ b/gcc/config/aarch64/aarch64.c
|
||||
@@ -11734,6 +11734,79 @@ aarch64_validate_mcpu (const char *str, const struct processor **res,
|
||||
return false;
|
||||
}
|
||||
|
||||
+/* Straight line speculation indicators. */
|
||||
+enum aarch64_sls_hardening_type
|
||||
+{
|
||||
+ SLS_NONE = 0,
|
||||
+ SLS_RETBR = 1,
|
||||
+ SLS_BLR = 2,
|
||||
+ SLS_ALL = 3,
|
||||
+};
|
||||
+static enum aarch64_sls_hardening_type aarch64_sls_hardening;
|
||||
+
|
||||
+/* Return whether we should mitigatate Straight Line Speculation for the RET
|
||||
+ and BR instructions. */
|
||||
+bool
|
||||
+aarch64_harden_sls_retbr_p (void)
|
||||
+{
|
||||
+ return aarch64_sls_hardening & SLS_RETBR;
|
||||
+}
|
||||
+
|
||||
+/* Return whether we should mitigatate Straight Line Speculation for the BLR
|
||||
+ instruction. */
|
||||
+bool
|
||||
+aarch64_harden_sls_blr_p (void)
|
||||
+{
|
||||
+ return aarch64_sls_hardening & SLS_BLR;
|
||||
+}
|
||||
+
|
||||
+/* As of yet we only allow setting these options globally, in the future we may
|
||||
+ allow setting them per function. */
|
||||
+static void
|
||||
+aarch64_validate_sls_mitigation (const char *const_str)
|
||||
+{
|
||||
+ char *token_save = NULL;
|
||||
+ char *str = NULL;
|
||||
+
|
||||
+ if (strcmp (const_str, "none") == 0)
|
||||
+ {
|
||||
+ aarch64_sls_hardening = SLS_NONE;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (strcmp (const_str, "all") == 0)
|
||||
+ {
|
||||
+ aarch64_sls_hardening = SLS_ALL;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ char *str_root = xstrdup (const_str);
|
||||
+ str = strtok_r (str_root, ",", &token_save);
|
||||
+ if (!str)
|
||||
+ error ("invalid argument given to %<-mharden-sls=%>");
|
||||
+
|
||||
+ int temp = SLS_NONE;
|
||||
+ while (str)
|
||||
+ {
|
||||
+ if (strcmp (str, "blr") == 0)
|
||||
+ temp |= SLS_BLR;
|
||||
+ else if (strcmp (str, "retbr") == 0)
|
||||
+ temp |= SLS_RETBR;
|
||||
+ else if (strcmp (str, "none") == 0 || strcmp (str, "all") == 0)
|
||||
+ {
|
||||
+ error ("%<%s%> must be by itself for %<-mharden-sls=%>", str);
|
||||
+ break;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ error ("invalid argument %<%s%> for %<-mharden-sls=%>", str);
|
||||
+ break;
|
||||
+ }
|
||||
+ str = strtok_r (NULL, ",", &token_save);
|
||||
+ }
|
||||
+ aarch64_sls_hardening = (aarch64_sls_hardening_type) temp;
|
||||
+ free (str_root);
|
||||
+}
|
||||
+
|
||||
/* Parses CONST_STR for branch protection features specified in
|
||||
aarch64_branch_protect_types, and set any global variables required. Returns
|
||||
the parsing result and assigns LAST_STR to the last processed token from
|
||||
@@ -11972,6 +12045,9 @@ aarch64_override_options (void)
|
||||
selected_arch = NULL;
|
||||
selected_tune = NULL;
|
||||
|
||||
+ if (aarch64_harden_sls_string)
|
||||
+ aarch64_validate_sls_mitigation (aarch64_harden_sls_string);
|
||||
+
|
||||
if (aarch64_branch_protection_string)
|
||||
aarch64_validate_mbranch_protection (aarch64_branch_protection_string);
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
|
||||
index 3c6d1cc90..d27ab6df8 100644
|
||||
--- a/gcc/config/aarch64/aarch64.opt
|
||||
+++ b/gcc/config/aarch64/aarch64.opt
|
||||
@@ -71,6 +71,10 @@ mgeneral-regs-only
|
||||
Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Save
|
||||
Generate code which uses only the general registers.
|
||||
|
||||
+mharden-sls=
|
||||
+Target RejectNegative Joined Var(aarch64_harden_sls_string)
|
||||
+Generate code to mitigate against straight line speculation.
|
||||
+
|
||||
mfix-cortex-a53-835769
|
||||
Target Report Var(aarch64_fix_a53_err835769) Init(2) Save
|
||||
Workaround for ARM Cortex-A53 Erratum number 835769.
|
||||
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
|
||||
index 2f7ffe456..5f04a7d2b 100644
|
||||
--- a/gcc/doc/invoke.texi
|
||||
+++ b/gcc/doc/invoke.texi
|
||||
@@ -638,6 +638,7 @@ Objective-C and Objective-C++ Dialects}.
|
||||
-mpc-relative-literal-loads @gol
|
||||
-msign-return-address=@var{scope} @gol
|
||||
-mbranch-protection=@var{none}|@var{standard}|@var{pac-ret}[+@var{leaf}]|@var{bti} @gol
|
||||
+-mharden-sls=@var{opts} @gol
|
||||
-march=@var{name} -mcpu=@var{name} -mtune=@var{name} @gol
|
||||
-moverride=@var{string} -mverbose-cost-dump @gol
|
||||
-mstack-protector-guard=@var{guard} -mstack-protector-guard-reg=@var{sysreg} @gol
|
||||
@@ -15955,6 +15956,17 @@ argument @samp{leaf} can be used to extend the signing to include leaf
|
||||
functions.
|
||||
@samp{bti} turns on branch target identification mechanism.
|
||||
|
||||
+@item -mharden-sls=@var{opts}
|
||||
+@opindex mharden-sls
|
||||
+Enable compiler hardening against straight line speculation (SLS).
|
||||
+@var{opts} is a comma-separated list of the following options:
|
||||
+@table @samp
|
||||
+@item retbr
|
||||
+@item blr
|
||||
+@end table
|
||||
+In addition, @samp{-mharden-sls=all} enables all SLS hardening while
|
||||
+@samp{-mharden-sls=none} disables all SLS hardening.
|
||||
+
|
||||
@item -msve-vector-bits=@var{bits}
|
||||
@opindex msve-vector-bits
|
||||
Specify the number of bits in an SVE vector register. This option only has
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,600 +0,0 @@
|
||||
CVE: CVE-2020-13844
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
From dc586a749228ecfb71f72ec2ca10e6f7b6874af3 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Malcomson <matthew.malcomson@arm.com>
|
||||
Date: Thu, 9 Jul 2020 09:11:59 +0100
|
||||
Subject: [PATCH 2/3] aarch64: Introduce SLS mitigation for RET and BR
|
||||
instructions
|
||||
|
||||
Instructions following RET or BR are not necessarily executed. In order
|
||||
to avoid speculation past RET and BR we can simply append a speculation
|
||||
barrier.
|
||||
|
||||
Since these speculation barriers will not be architecturally executed,
|
||||
they are not expected to add a high performance penalty.
|
||||
|
||||
The speculation barrier is to be SB when targeting architectures which
|
||||
have this enabled, and DSB SY + ISB otherwise.
|
||||
|
||||
We add tests for each of the cases where such an instruction was seen.
|
||||
|
||||
This is implemented by modifying each machine description pattern that
|
||||
emits either a RET or a BR instruction. We choose not to use something
|
||||
like `TARGET_ASM_FUNCTION_EPILOGUE` since it does not affect the
|
||||
`indirect_jump`, `jump`, `sibcall_insn` and `sibcall_value_insn`
|
||||
patterns and we find it preferable to implement the functionality in the
|
||||
same way for every pattern.
|
||||
|
||||
There is one particular case which is slightly tricky. The
|
||||
implementation of TARGET_ASM_TRAMPOLINE_TEMPLATE uses a BR which needs
|
||||
to be mitigated against. The trampoline template is used *once* per
|
||||
compilation unit, and the TRAMPOLINE_SIZE is exposed to the user via the
|
||||
builtin macro __LIBGCC_TRAMPOLINE_SIZE__.
|
||||
In the future we may implement function specific attributes to turn on
|
||||
and off hardening on a per-function basis.
|
||||
The fixed nature of the trampoline described above implies it will be
|
||||
safer to ensure this speculation barrier is always used.
|
||||
|
||||
Testing:
|
||||
Bootstrap and regtest done on aarch64-none-linux
|
||||
Used a temporary hack(1) to use these options on every test in the
|
||||
testsuite and a script to check that the output never emitted an
|
||||
unmitigated RET or BR.
|
||||
|
||||
1) Temporary hack was a change to the testsuite to always use
|
||||
`-save-temps` and run a script on the assembly output of those
|
||||
compilations which produced one to ensure every RET or BR is immediately
|
||||
followed by a speculation barrier.
|
||||
|
||||
(cherry picked from be178ecd5ac1fe1510d960ff95c66d0ff831afe1)
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* config/aarch64/aarch64-protos.h (aarch64_sls_barrier): New.
|
||||
* config/aarch64/aarch64.c (aarch64_output_casesi): Emit
|
||||
speculation barrier after BR instruction if needs be.
|
||||
(aarch64_trampoline_init): Handle ptr_mode value & adjust size
|
||||
of code copied.
|
||||
(aarch64_sls_barrier): New.
|
||||
(aarch64_asm_trampoline_template): Add needed barriers.
|
||||
* config/aarch64/aarch64.h (AARCH64_ISA_SB): New.
|
||||
(TARGET_SB): New.
|
||||
(TRAMPOLINE_SIZE): Account for barrier.
|
||||
* config/aarch64/aarch64.md (indirect_jump, *casesi_dispatch,
|
||||
simple_return, *do_return, *sibcall_insn, *sibcall_value_insn):
|
||||
Emit barrier if needs be, also account for possible barrier using
|
||||
"sls_length" attribute.
|
||||
(sls_length): New attribute.
|
||||
(length): Determine default using any non-default sls_length
|
||||
value.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c: New test.
|
||||
* gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c:
|
||||
New test.
|
||||
* gcc.target/aarch64/sls-mitigation/sls-mitigation.exp: New file.
|
||||
* lib/target-supports.exp (check_effective_target_aarch64_asm_sb_ok):
|
||||
New proc.
|
||||
---
|
||||
gcc/config/aarch64/aarch64-protos.h | 1 +
|
||||
gcc/config/aarch64/aarch64.c | 41 +++++-
|
||||
gcc/config/aarch64/aarch64.h | 10 +-
|
||||
gcc/config/aarch64/aarch64.md | 75 ++++++++---
|
||||
.../sls-mitigation/sls-miti-retbr-pacret.c | 15 +++
|
||||
.../aarch64/sls-mitigation/sls-miti-retbr.c | 119 ++++++++++++++++++
|
||||
.../aarch64/sls-mitigation/sls-mitigation.exp | 73 +++++++++++
|
||||
gcc/testsuite/lib/target-supports.exp | 3 +-
|
||||
8 files changed, 312 insertions(+), 25 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
|
||||
index 31493f412..885eae893 100644
|
||||
--- a/gcc/config/aarch64/aarch64-protos.h
|
||||
+++ b/gcc/config/aarch64/aarch64-protos.h
|
||||
@@ -644,6 +644,7 @@ poly_uint64 aarch64_regmode_natural_size (machine_mode);
|
||||
|
||||
bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT);
|
||||
|
||||
+const char *aarch64_sls_barrier (int);
|
||||
extern bool aarch64_harden_sls_retbr_p (void);
|
||||
extern bool aarch64_harden_sls_blr_p (void);
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
|
||||
index 269ff6c92..dff61105c 100644
|
||||
--- a/gcc/config/aarch64/aarch64.c
|
||||
+++ b/gcc/config/aarch64/aarch64.c
|
||||
@@ -8412,8 +8412,8 @@ aarch64_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
|
||||
static void
|
||||
aarch64_asm_trampoline_template (FILE *f)
|
||||
{
|
||||
- int offset1 = 16;
|
||||
- int offset2 = 20;
|
||||
+ int offset1 = 24;
|
||||
+ int offset2 = 28;
|
||||
|
||||
if (aarch64_bti_enabled ())
|
||||
{
|
||||
@@ -8436,6 +8436,17 @@ aarch64_asm_trampoline_template (FILE *f)
|
||||
}
|
||||
asm_fprintf (f, "\tbr\t%s\n", reg_names [IP1_REGNUM]);
|
||||
|
||||
+ /* We always emit a speculation barrier.
|
||||
+ This is because the same trampoline template is used for every nested
|
||||
+ function. Since nested functions are not particularly common or
|
||||
+ performant we don't worry too much about the extra instructions to copy
|
||||
+ around.
|
||||
+ This is not yet a problem, since we have not yet implemented function
|
||||
+ specific attributes to choose between hardening against straight line
|
||||
+ speculation or not, but such function specific attributes are likely to
|
||||
+ happen in the future. */
|
||||
+ asm_fprintf (f, "\tdsb\tsy\n\tisb\n");
|
||||
+
|
||||
/* The trampoline needs an extra padding instruction. In case if BTI is
|
||||
enabled the padding instruction is replaced by the BTI instruction at
|
||||
the beginning. */
|
||||
@@ -8450,10 +8461,14 @@ static void
|
||||
aarch64_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
|
||||
{
|
||||
rtx fnaddr, mem, a_tramp;
|
||||
- const int tramp_code_sz = 16;
|
||||
+ const int tramp_code_sz = 24;
|
||||
|
||||
/* Don't need to copy the trailing D-words, we fill those in below. */
|
||||
- emit_block_move (m_tramp, assemble_trampoline_template (),
|
||||
+ /* We create our own memory address in Pmode so that `emit_block_move` can
|
||||
+ use parts of the backend which expect Pmode addresses. */
|
||||
+ rtx temp = convert_memory_address (Pmode, XEXP (m_tramp, 0));
|
||||
+ emit_block_move (gen_rtx_MEM (BLKmode, temp),
|
||||
+ assemble_trampoline_template (),
|
||||
GEN_INT (tramp_code_sz), BLOCK_OP_NORMAL);
|
||||
mem = adjust_address (m_tramp, ptr_mode, tramp_code_sz);
|
||||
fnaddr = XEXP (DECL_RTL (fndecl), 0);
|
||||
@@ -8640,6 +8655,8 @@ aarch64_output_casesi (rtx *operands)
|
||||
output_asm_insn (buf, operands);
|
||||
output_asm_insn (patterns[index][1], operands);
|
||||
output_asm_insn ("br\t%3", operands);
|
||||
+ output_asm_insn (aarch64_sls_barrier (aarch64_harden_sls_retbr_p ()),
|
||||
+ operands);
|
||||
assemble_label (asm_out_file, label);
|
||||
return "";
|
||||
}
|
||||
@@ -18976,6 +18993,22 @@ aarch64_file_end_indicate_exec_stack ()
|
||||
#undef GNU_PROPERTY_AARCH64_FEATURE_1_BTI
|
||||
#undef GNU_PROPERTY_AARCH64_FEATURE_1_AND
|
||||
|
||||
+/* Helper function for straight line speculation.
|
||||
+ Return what barrier should be emitted for straight line speculation
|
||||
+ mitigation.
|
||||
+ When not mitigating against straight line speculation this function returns
|
||||
+ an empty string.
|
||||
+ When mitigating against straight line speculation, use:
|
||||
+ * SB when the v8.5-A SB extension is enabled.
|
||||
+ * DSB+ISB otherwise. */
|
||||
+const char *
|
||||
+aarch64_sls_barrier (int mitigation_required)
|
||||
+{
|
||||
+ return mitigation_required
|
||||
+ ? (TARGET_SB ? "sb" : "dsb\tsy\n\tisb")
|
||||
+ : "";
|
||||
+}
|
||||
+
|
||||
/* Target-specific selftests. */
|
||||
|
||||
#if CHECKING_P
|
||||
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
|
||||
index 772a97296..72ddc6fd9 100644
|
||||
--- a/gcc/config/aarch64/aarch64.h
|
||||
+++ b/gcc/config/aarch64/aarch64.h
|
||||
@@ -235,6 +235,7 @@ extern unsigned aarch64_architecture_version;
|
||||
#define AARCH64_ISA_F16FML (aarch64_isa_flags & AARCH64_FL_F16FML)
|
||||
#define AARCH64_ISA_RCPC8_4 (aarch64_isa_flags & AARCH64_FL_RCPC8_4)
|
||||
#define AARCH64_ISA_V8_5 (aarch64_isa_flags & AARCH64_FL_V8_5)
|
||||
+#define AARCH64_ISA_SB (aarch64_isa_flags & AARCH64_FL_SB)
|
||||
|
||||
/* Crypto is an optional extension to AdvSIMD. */
|
||||
#define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO)
|
||||
@@ -285,6 +286,9 @@ extern unsigned aarch64_architecture_version;
|
||||
#define TARGET_FIX_ERR_A53_835769_DEFAULT 1
|
||||
#endif
|
||||
|
||||
+/* SB instruction is enabled through +sb. */
|
||||
+#define TARGET_SB (AARCH64_ISA_SB)
|
||||
+
|
||||
/* Apply the workaround for Cortex-A53 erratum 835769. */
|
||||
#define TARGET_FIX_ERR_A53_835769 \
|
||||
((aarch64_fix_a53_err835769 == 2) \
|
||||
@@ -931,8 +935,10 @@ typedef struct
|
||||
|
||||
#define RETURN_ADDR_RTX aarch64_return_addr
|
||||
|
||||
-/* BTI c + 3 insns + 2 pointer-sized entries. */
|
||||
-#define TRAMPOLINE_SIZE (TARGET_ILP32 ? 24 : 32)
|
||||
+/* BTI c + 3 insns
|
||||
+ + sls barrier of DSB + ISB.
|
||||
+ + 2 pointer-sized entries. */
|
||||
+#define TRAMPOLINE_SIZE (24 + (TARGET_ILP32 ? 8 : 16))
|
||||
|
||||
/* Trampolines contain dwords, so must be dword aligned. */
|
||||
#define TRAMPOLINE_ALIGNMENT 64
|
||||
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
|
||||
index cc5a887d4..494aee964 100644
|
||||
--- a/gcc/config/aarch64/aarch64.md
|
||||
+++ b/gcc/config/aarch64/aarch64.md
|
||||
@@ -331,10 +331,25 @@
|
||||
;; Attribute that specifies whether the alternative uses MOVPRFX.
|
||||
(define_attr "movprfx" "no,yes" (const_string "no"))
|
||||
|
||||
+;; Attribute to specify that an alternative has the length of a single
|
||||
+;; instruction plus a speculation barrier.
|
||||
+(define_attr "sls_length" "none,retbr,casesi" (const_string "none"))
|
||||
+
|
||||
(define_attr "length" ""
|
||||
(cond [(eq_attr "movprfx" "yes")
|
||||
(const_int 8)
|
||||
- ] (const_int 4)))
|
||||
+
|
||||
+ (eq_attr "sls_length" "retbr")
|
||||
+ (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 4)
|
||||
+ (match_test "TARGET_SB") (const_int 8)]
|
||||
+ (const_int 12))
|
||||
+
|
||||
+ (eq_attr "sls_length" "casesi")
|
||||
+ (cond [(match_test "!aarch64_harden_sls_retbr_p ()") (const_int 16)
|
||||
+ (match_test "TARGET_SB") (const_int 20)]
|
||||
+ (const_int 24))
|
||||
+ ]
|
||||
+ (const_int 4)))
|
||||
|
||||
;; Strictly for compatibility with AArch32 in pipeline models, since AArch64 has
|
||||
;; no predicated insns.
|
||||
@@ -370,8 +385,12 @@
|
||||
(define_insn "indirect_jump"
|
||||
[(set (pc) (match_operand:DI 0 "register_operand" "r"))]
|
||||
""
|
||||
- "br\\t%0"
|
||||
- [(set_attr "type" "branch")]
|
||||
+ {
|
||||
+ output_asm_insn ("br\\t%0", operands);
|
||||
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
||||
+ }
|
||||
+ [(set_attr "type" "branch")
|
||||
+ (set_attr "sls_length" "retbr")]
|
||||
)
|
||||
|
||||
(define_insn "jump"
|
||||
@@ -657,7 +676,7 @@
|
||||
"*
|
||||
return aarch64_output_casesi (operands);
|
||||
"
|
||||
- [(set_attr "length" "16")
|
||||
+ [(set_attr "sls_length" "casesi")
|
||||
(set_attr "type" "branch")]
|
||||
)
|
||||
|
||||
@@ -736,14 +755,18 @@
|
||||
[(return)]
|
||||
""
|
||||
{
|
||||
+ const char *ret = NULL;
|
||||
if (aarch64_return_address_signing_enabled ()
|
||||
&& TARGET_ARMV8_3
|
||||
&& !crtl->calls_eh_return)
|
||||
- return "retaa";
|
||||
-
|
||||
- return "ret";
|
||||
+ ret = "retaa";
|
||||
+ else
|
||||
+ ret = "ret";
|
||||
+ output_asm_insn (ret, operands);
|
||||
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
||||
}
|
||||
- [(set_attr "type" "branch")]
|
||||
+ [(set_attr "type" "branch")
|
||||
+ (set_attr "sls_length" "retbr")]
|
||||
)
|
||||
|
||||
(define_expand "return"
|
||||
@@ -755,8 +778,12 @@
|
||||
(define_insn "simple_return"
|
||||
[(simple_return)]
|
||||
"aarch64_use_simple_return_insn_p ()"
|
||||
- "ret"
|
||||
- [(set_attr "type" "branch")]
|
||||
+ {
|
||||
+ output_asm_insn ("ret", operands);
|
||||
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
||||
+ }
|
||||
+ [(set_attr "type" "branch")
|
||||
+ (set_attr "sls_length" "retbr")]
|
||||
)
|
||||
|
||||
(define_insn "*cb<optab><mode>1"
|
||||
@@ -947,10 +974,16 @@
|
||||
(match_operand 1 "" ""))
|
||||
(return)]
|
||||
"SIBLING_CALL_P (insn)"
|
||||
- "@
|
||||
- br\\t%0
|
||||
- b\\t%c0"
|
||||
- [(set_attr "type" "branch, branch")]
|
||||
+ {
|
||||
+ if (which_alternative == 0)
|
||||
+ {
|
||||
+ output_asm_insn ("br\\t%0", operands);
|
||||
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
||||
+ }
|
||||
+ return "b\\t%c0";
|
||||
+ }
|
||||
+ [(set_attr "type" "branch, branch")
|
||||
+ (set_attr "sls_length" "retbr,none")]
|
||||
)
|
||||
|
||||
(define_insn "*sibcall_value_insn"
|
||||
@@ -960,10 +993,16 @@
|
||||
(match_operand 2 "" "")))
|
||||
(return)]
|
||||
"SIBLING_CALL_P (insn)"
|
||||
- "@
|
||||
- br\\t%1
|
||||
- b\\t%c1"
|
||||
- [(set_attr "type" "branch, branch")]
|
||||
+ {
|
||||
+ if (which_alternative == 0)
|
||||
+ {
|
||||
+ output_asm_insn ("br\\t%1", operands);
|
||||
+ return aarch64_sls_barrier (aarch64_harden_sls_retbr_p ());
|
||||
+ }
|
||||
+ return "b\\t%c1";
|
||||
+ }
|
||||
+ [(set_attr "type" "branch, branch")
|
||||
+ (set_attr "sls_length" "retbr,none")]
|
||||
)
|
||||
|
||||
;; Call subroutine returning any type.
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c
|
||||
new file mode 100644
|
||||
index 000000000..7656123ee
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr-pacret.c
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* Avoid ILP32 since pacret is only available for LP64 */
|
||||
+/* { dg-do compile { target { ! ilp32 } } } */
|
||||
+/* { dg-additional-options "-mharden-sls=retbr -mbranch-protection=pac-ret -march=armv8.3-a" } */
|
||||
+
|
||||
+/* Testing the do_return pattern for retaa. */
|
||||
+long retbr_subcall(void);
|
||||
+long retbr_do_return_retaa(void)
|
||||
+{
|
||||
+ return retbr_subcall()+1;
|
||||
+}
|
||||
+
|
||||
+/* Ensure there are no BR or RET instructions which are not directly followed
|
||||
+ by a speculation barrier. */
|
||||
+/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb)} } } */
|
||||
+/* { dg-final { scan-assembler-not {ret\t} } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c
|
||||
new file mode 100644
|
||||
index 000000000..573b30cdc
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-retbr.c
|
||||
@@ -0,0 +1,119 @@
|
||||
+/* We ensure that -Wpedantic is off since it complains about the trampolines
|
||||
+ we explicitly want to test. */
|
||||
+/* { dg-additional-options "-mharden-sls=retbr -Wno-pedantic " } */
|
||||
+/*
|
||||
+ Ensure that the SLS hardening of RET and BR leaves no unprotected RET/BR
|
||||
+ instructions.
|
||||
+ */
|
||||
+typedef int (foo) (int, int);
|
||||
+typedef void (bar) (int, int);
|
||||
+struct sls_testclass {
|
||||
+ foo *x;
|
||||
+ bar *y;
|
||||
+ int left;
|
||||
+ int right;
|
||||
+};
|
||||
+
|
||||
+int
|
||||
+retbr_sibcall_value_insn (struct sls_testclass x)
|
||||
+{
|
||||
+ return x.x(x.left, x.right);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+retbr_sibcall_insn (struct sls_testclass x)
|
||||
+{
|
||||
+ x.y(x.left, x.right);
|
||||
+}
|
||||
+
|
||||
+/* Aim to test two different returns.
|
||||
+ One that introduces a tail call in the middle of the function, and one that
|
||||
+ has a normal return. */
|
||||
+int
|
||||
+retbr_multiple_returns (struct sls_testclass x)
|
||||
+{
|
||||
+ int temp;
|
||||
+ if (x.left % 10)
|
||||
+ return x.x(x.left, 100);
|
||||
+ else if (x.right % 20)
|
||||
+ {
|
||||
+ return x.x(x.left * x.right, 100);
|
||||
+ }
|
||||
+ temp = x.left % x.right;
|
||||
+ temp *= 100;
|
||||
+ temp /= 2;
|
||||
+ return temp % 3;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+retbr_multiple_returns_void (struct sls_testclass x)
|
||||
+{
|
||||
+ if (x.left % 10)
|
||||
+ {
|
||||
+ x.y(x.left, 100);
|
||||
+ }
|
||||
+ else if (x.right % 20)
|
||||
+ {
|
||||
+ x.y(x.left * x.right, 100);
|
||||
+ }
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+/* Testing the casesi jump via register. */
|
||||
+__attribute__ ((optimize ("Os")))
|
||||
+int
|
||||
+retbr_casesi_dispatch (struct sls_testclass x)
|
||||
+{
|
||||
+ switch (x.left)
|
||||
+ {
|
||||
+ case -5:
|
||||
+ return -2;
|
||||
+ case -3:
|
||||
+ return -1;
|
||||
+ case 0:
|
||||
+ return 0;
|
||||
+ case 3:
|
||||
+ return 1;
|
||||
+ case 5:
|
||||
+ break;
|
||||
+ default:
|
||||
+ __builtin_unreachable ();
|
||||
+ }
|
||||
+ return x.right;
|
||||
+}
|
||||
+
|
||||
+/* Testing the BR in trampolines is mitigated against. */
|
||||
+void f1 (void *);
|
||||
+void f3 (void *, void (*)(void *));
|
||||
+void f2 (void *);
|
||||
+
|
||||
+int
|
||||
+retbr_trampolines (void *a, int b)
|
||||
+{
|
||||
+ if (!b)
|
||||
+ {
|
||||
+ f1 (a);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ if (b)
|
||||
+ {
|
||||
+ void retbr_tramp_internal (void *c)
|
||||
+ {
|
||||
+ if (c == a)
|
||||
+ f2 (c);
|
||||
+ }
|
||||
+ f3 (a, retbr_tramp_internal);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Testing the indirect_jump pattern. */
|
||||
+void
|
||||
+retbr_indirect_jump (int *buf)
|
||||
+{
|
||||
+ __builtin_longjmp(buf, 1);
|
||||
+}
|
||||
+
|
||||
+/* Ensure there are no BR or RET instructions which are not directly followed
|
||||
+ by a speculation barrier. */
|
||||
+/* { dg-final { scan-assembler-not {\t(br|ret|retaa)\tx[0-9][0-9]?\n\t(?!dsb\tsy\n\tisb|sb)} } } */
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp
|
||||
new file mode 100644
|
||||
index 000000000..812250379
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-mitigation.exp
|
||||
@@ -0,0 +1,73 @@
|
||||
+# Regression driver for SLS mitigation on AArch64.
|
||||
+# Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
+# Contributed by ARM Ltd.
|
||||
+#
|
||||
+# This file is part of GCC.
|
||||
+#
|
||||
+# GCC 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, or (at your option)
|
||||
+# any later version.
|
||||
+#
|
||||
+# GCC 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 GCC; see the file COPYING3. If not see
|
||||
+# <http://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+# Exit immediately if this isn't an AArch64 target.
|
||||
+if {![istarget aarch64*-*-*] } then {
|
||||
+ return
|
||||
+}
|
||||
+
|
||||
+# Load support procs.
|
||||
+load_lib gcc-dg.exp
|
||||
+load_lib torture-options.exp
|
||||
+
|
||||
+# If a testcase doesn't have special options, use these.
|
||||
+global DEFAULT_CFLAGS
|
||||
+if ![info exists DEFAULT_CFLAGS] then {
|
||||
+ set DEFAULT_CFLAGS " "
|
||||
+}
|
||||
+
|
||||
+# Initialize `dg'.
|
||||
+dg-init
|
||||
+torture-init
|
||||
+
|
||||
+# Use different architectures as well as the normal optimisation options.
|
||||
+# (i.e. use both SB and DSB+ISB barriers).
|
||||
+
|
||||
+set save-dg-do-what-default ${dg-do-what-default}
|
||||
+# Main loop.
|
||||
+# Run with torture tests (i.e. a bunch of different optimisation levels) just
|
||||
+# to increase test coverage.
|
||||
+set dg-do-what-default assemble
|
||||
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
|
||||
+ "-save-temps" $DEFAULT_CFLAGS
|
||||
+
|
||||
+# Run the same tests but this time with SB extension.
|
||||
+# Since not all supported assemblers will support that extension we decide
|
||||
+# whether to assemble or just compile based on whether the extension is
|
||||
+# supported for the available assembler.
|
||||
+
|
||||
+set templist {}
|
||||
+foreach x $DG_TORTURE_OPTIONS {
|
||||
+ lappend templist "$x -march=armv8.3-a+sb "
|
||||
+ lappend templist "$x -march=armv8-a+sb "
|
||||
+}
|
||||
+set-torture-options $templist
|
||||
+if { [check_effective_target_aarch64_asm_sb_ok] } {
|
||||
+ set dg-do-what-default assemble
|
||||
+} else {
|
||||
+ set dg-do-what-default compile
|
||||
+}
|
||||
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
|
||||
+ "-save-temps" $DEFAULT_CFLAGS
|
||||
+set dg-do-what-default ${save-dg-do-what-default}
|
||||
+
|
||||
+# All done.
|
||||
+torture-finish
|
||||
+dg-finish
|
||||
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
|
||||
index ea9a50ccb..79482f9b6 100644
|
||||
--- a/gcc/testsuite/lib/target-supports.exp
|
||||
+++ b/gcc/testsuite/lib/target-supports.exp
|
||||
@@ -8579,7 +8579,8 @@ proc check_effective_target_aarch64_tiny { } {
|
||||
# Create functions to check that the AArch64 assembler supports the
|
||||
# various architecture extensions via the .arch_extension pseudo-op.
|
||||
|
||||
-foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve"} {
|
||||
+foreach { aarch64_ext } { "fp" "simd" "crypto" "crc" "lse" "dotprod" "sve"
|
||||
+ "sb"} {
|
||||
eval [string map [list FUNC $aarch64_ext] {
|
||||
proc check_effective_target_aarch64_asm_FUNC_ok { } {
|
||||
if { [istarget aarch64*-*-*] } {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,659 +0,0 @@
|
||||
CVE: CVE-2020-13844
|
||||
Upstream-Status: Backport
|
||||
Signed-off-by: Ross Burton <ross.burton@arm.com>
|
||||
|
||||
From 2155170525f93093b90a1a065e7ed71a925566e9 Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Malcomson <matthew.malcomson@arm.com>
|
||||
Date: Thu, 9 Jul 2020 09:11:59 +0100
|
||||
Subject: [PATCH 3/3] aarch64: Mitigate SLS for BLR instruction
|
||||
|
||||
This patch introduces the mitigation for Straight Line Speculation past
|
||||
the BLR instruction.
|
||||
|
||||
This mitigation replaces BLR instructions with a BL to a stub which uses
|
||||
a BR to jump to the original value. These function stubs are then
|
||||
appended with a speculation barrier to ensure no straight line
|
||||
speculation happens after these jumps.
|
||||
|
||||
When optimising for speed we use a set of stubs for each function since
|
||||
this should help the branch predictor make more accurate predictions
|
||||
about where a stub should branch.
|
||||
|
||||
When optimising for size we use one set of stubs for all functions.
|
||||
This set of stubs can have human readable names, and we are using
|
||||
`__call_indirect_x<N>` for register x<N>.
|
||||
|
||||
When BTI branch protection is enabled the BLR instruction can jump to a
|
||||
`BTI c` instruction using any register, while the BR instruction can
|
||||
only jump to a `BTI c` instruction using the x16 or x17 registers.
|
||||
Hence, in order to ensure this transformation is safe we mov the value
|
||||
of the original register into x16 and use x16 for the BR.
|
||||
|
||||
As an example when optimising for size:
|
||||
a
|
||||
BLR x0
|
||||
instruction would get transformed to something like
|
||||
BL __call_indirect_x0
|
||||
where __call_indirect_x0 labels a thunk that contains
|
||||
__call_indirect_x0:
|
||||
MOV X16, X0
|
||||
BR X16
|
||||
<speculation barrier>
|
||||
|
||||
The first version of this patch used local symbols specific to a
|
||||
compilation unit to try and avoid relocations.
|
||||
This was mistaken since functions coming from the same compilation unit
|
||||
can still be in different sections, and the assembler will insert
|
||||
relocations at jumps between sections.
|
||||
|
||||
On any relocation the linker is permitted to emit a veneer to handle
|
||||
jumps between symbols that are very far apart. The registers x16 and
|
||||
x17 may be clobbered by these veneers.
|
||||
Hence the function stubs cannot rely on the values of x16 and x17 being
|
||||
the same as just before the function stub is called.
|
||||
|
||||
Similar can be said for the hot/cold partitioning of single functions,
|
||||
so function-local stubs have the same restriction.
|
||||
|
||||
This updated version of the patch never emits function stubs for x16 and
|
||||
x17, and instead forces other registers to be used.
|
||||
|
||||
Given the above, there is now no benefit to local symbols (since they
|
||||
are not enough to avoid dealing with linker intricacies). This patch
|
||||
now uses global symbols with hidden visibility each stored in their own
|
||||
COMDAT section. This means stubs can be shared between compilation
|
||||
units while still avoiding the PLT indirection.
|
||||
|
||||
This patch also removes the `__call_indirect_x30` stub (and
|
||||
function-local equivalent) which would simply jump back to the original
|
||||
location.
|
||||
|
||||
The function-local stubs are emitted to the assembly output file in one
|
||||
chunk, which means we need not add the speculation barrier directly
|
||||
after each one.
|
||||
This is because we know for certain that the instructions directly after
|
||||
the BR in all but the last function stub will be from another one of
|
||||
these stubs and hence will not contain a speculation gadget.
|
||||
Instead we add a speculation barrier at the end of the sequence of
|
||||
stubs.
|
||||
|
||||
The global stubs are emitted in COMDAT/.linkonce sections by
|
||||
themselves so that the linker can remove duplicates from multiple object
|
||||
files. This means they are not emitted in one chunk, and each one must
|
||||
include the speculation barrier.
|
||||
|
||||
Another difference is that since the global stubs are shared across
|
||||
compilation units we do not know that all functions will be targeting an
|
||||
architecture supporting the SB instruction.
|
||||
Rather than provide multiple stubs for each architecture, we provide a
|
||||
stub that will work for all architectures -- using the DSB+ISB barrier.
|
||||
|
||||
This mitigation does not apply for BLR instructions in the following
|
||||
places:
|
||||
- Some accesses to thread-local variables use a code sequence with a BLR
|
||||
instruction. This code sequence is part of the binary interface between
|
||||
compiler and linker. If this BLR instruction needs to be mitigated, it'd
|
||||
probably be best to do so in the linker. It seems that the code sequence
|
||||
for thread-local variable access is unlikely to lead to a Spectre Revalation
|
||||
Gadget.
|
||||
- PLT stubs are produced by the linker and each contain a BLR instruction.
|
||||
It seems that at most only after the last PLT stub a Spectre Revalation
|
||||
Gadget might appear.
|
||||
|
||||
Testing:
|
||||
Bootstrap and regtest on AArch64
|
||||
(with BOOT_CFLAGS="-mharden-sls=retbr,blr")
|
||||
Used a temporary hack(1) in gcc-dg.exp to use these options on every
|
||||
test in the testsuite, a slight modification to emit the speculation
|
||||
barrier after every function stub, and a script to check that the
|
||||
output never emitted a BLR, or unmitigated BR or RET instruction.
|
||||
Similar on an aarch64-none-elf cross-compiler.
|
||||
|
||||
1) Temporary hack emitted a speculation barrier at the end of every stub
|
||||
function, and used a script to ensure that:
|
||||
a) Every RET or BR is immediately followed by a speculation barrier.
|
||||
b) No BLR instruction is emitted by compiler.
|
||||
|
||||
(cherry picked from 96b7f495f9269d5448822e4fc28882edb35a58d7)
|
||||
|
||||
gcc/ChangeLog:
|
||||
|
||||
* config/aarch64/aarch64-protos.h (aarch64_indirect_call_asm):
|
||||
New declaration.
|
||||
* config/aarch64/aarch64.c (aarch64_regno_regclass): Handle new
|
||||
stub registers class.
|
||||
(aarch64_class_max_nregs): Likewise.
|
||||
(aarch64_register_move_cost): Likewise.
|
||||
(aarch64_sls_shared_thunks): Global array to store stub labels.
|
||||
(aarch64_sls_emit_function_stub): New.
|
||||
(aarch64_create_blr_label): New.
|
||||
(aarch64_sls_emit_blr_function_thunks): New.
|
||||
(aarch64_sls_emit_shared_blr_thunks): New.
|
||||
(aarch64_asm_file_end): New.
|
||||
(aarch64_indirect_call_asm): New.
|
||||
(TARGET_ASM_FILE_END): Use aarch64_asm_file_end.
|
||||
(TARGET_ASM_FUNCTION_EPILOGUE): Use
|
||||
aarch64_sls_emit_blr_function_thunks.
|
||||
* config/aarch64/aarch64.h (STB_REGNUM_P): New.
|
||||
(enum reg_class): Add STUB_REGS class.
|
||||
(machine_function): Introduce `call_via` array for
|
||||
function-local stub labels.
|
||||
* config/aarch64/aarch64.md (*call_insn, *call_value_insn): Use
|
||||
aarch64_indirect_call_asm to emit code when hardening BLR
|
||||
instructions.
|
||||
* config/aarch64/constraints.md (Ucr): New constraint
|
||||
representing registers for indirect calls. Is GENERAL_REGS
|
||||
usually, and STUB_REGS when hardening BLR instruction against
|
||||
SLS.
|
||||
* config/aarch64/predicates.md (aarch64_general_reg): STUB_REGS class
|
||||
is also a general register.
|
||||
|
||||
gcc/testsuite/ChangeLog:
|
||||
|
||||
* gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c: New test.
|
||||
* gcc.target/aarch64/sls-mitigation/sls-miti-blr.c: New test.
|
||||
---
|
||||
gcc/config/aarch64/aarch64-protos.h | 1 +
|
||||
gcc/config/aarch64/aarch64.c | 225 +++++++++++++++++-
|
||||
gcc/config/aarch64/aarch64.h | 15 ++
|
||||
gcc/config/aarch64/aarch64.md | 11 +-
|
||||
gcc/config/aarch64/constraints.md | 9 +
|
||||
gcc/config/aarch64/predicates.md | 3 +-
|
||||
.../aarch64/sls-mitigation/sls-miti-blr-bti.c | 40 ++++
|
||||
.../aarch64/sls-mitigation/sls-miti-blr.c | 33 +++
|
||||
8 files changed, 328 insertions(+), 9 deletions(-)
|
||||
create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c
|
||||
create mode 100644 gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
|
||||
index 885eae893..2676e43ae 100644
|
||||
--- a/gcc/config/aarch64/aarch64-protos.h
|
||||
+++ b/gcc/config/aarch64/aarch64-protos.h
|
||||
@@ -645,6 +645,7 @@ poly_uint64 aarch64_regmode_natural_size (machine_mode);
|
||||
bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT);
|
||||
|
||||
const char *aarch64_sls_barrier (int);
|
||||
+const char *aarch64_indirect_call_asm (rtx);
|
||||
extern bool aarch64_harden_sls_retbr_p (void);
|
||||
extern bool aarch64_harden_sls_blr_p (void);
|
||||
|
||||
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
|
||||
index dff61105c..bc6c02c3a 100644
|
||||
--- a/gcc/config/aarch64/aarch64.c
|
||||
+++ b/gcc/config/aarch64/aarch64.c
|
||||
@@ -8190,6 +8190,9 @@ aarch64_label_mentioned_p (rtx x)
|
||||
enum reg_class
|
||||
aarch64_regno_regclass (unsigned regno)
|
||||
{
|
||||
+ if (STUB_REGNUM_P (regno))
|
||||
+ return STUB_REGS;
|
||||
+
|
||||
if (GP_REGNUM_P (regno))
|
||||
return GENERAL_REGS;
|
||||
|
||||
@@ -8499,6 +8502,7 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode)
|
||||
unsigned int nregs;
|
||||
switch (regclass)
|
||||
{
|
||||
+ case STUB_REGS:
|
||||
case TAILCALL_ADDR_REGS:
|
||||
case POINTER_REGS:
|
||||
case GENERAL_REGS:
|
||||
@@ -10693,10 +10697,12 @@ aarch64_register_move_cost (machine_mode mode,
|
||||
= aarch64_tune_params.regmove_cost;
|
||||
|
||||
/* Caller save and pointer regs are equivalent to GENERAL_REGS. */
|
||||
- if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS)
|
||||
+ if (to == TAILCALL_ADDR_REGS || to == POINTER_REGS
|
||||
+ || to == STUB_REGS)
|
||||
to = GENERAL_REGS;
|
||||
|
||||
- if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS)
|
||||
+ if (from == TAILCALL_ADDR_REGS || from == POINTER_REGS
|
||||
+ || from == STUB_REGS)
|
||||
from = GENERAL_REGS;
|
||||
|
||||
/* Moving between GPR and stack cost is the same as GP2GP. */
|
||||
@@ -19009,6 +19015,215 @@ aarch64_sls_barrier (int mitigation_required)
|
||||
: "";
|
||||
}
|
||||
|
||||
+static GTY (()) tree aarch64_sls_shared_thunks[30];
|
||||
+static GTY (()) bool aarch64_sls_shared_thunks_needed = false;
|
||||
+const char *indirect_symbol_names[30] = {
|
||||
+ "__call_indirect_x0",
|
||||
+ "__call_indirect_x1",
|
||||
+ "__call_indirect_x2",
|
||||
+ "__call_indirect_x3",
|
||||
+ "__call_indirect_x4",
|
||||
+ "__call_indirect_x5",
|
||||
+ "__call_indirect_x6",
|
||||
+ "__call_indirect_x7",
|
||||
+ "__call_indirect_x8",
|
||||
+ "__call_indirect_x9",
|
||||
+ "__call_indirect_x10",
|
||||
+ "__call_indirect_x11",
|
||||
+ "__call_indirect_x12",
|
||||
+ "__call_indirect_x13",
|
||||
+ "__call_indirect_x14",
|
||||
+ "__call_indirect_x15",
|
||||
+ "", /* "__call_indirect_x16", */
|
||||
+ "", /* "__call_indirect_x17", */
|
||||
+ "__call_indirect_x18",
|
||||
+ "__call_indirect_x19",
|
||||
+ "__call_indirect_x20",
|
||||
+ "__call_indirect_x21",
|
||||
+ "__call_indirect_x22",
|
||||
+ "__call_indirect_x23",
|
||||
+ "__call_indirect_x24",
|
||||
+ "__call_indirect_x25",
|
||||
+ "__call_indirect_x26",
|
||||
+ "__call_indirect_x27",
|
||||
+ "__call_indirect_x28",
|
||||
+ "__call_indirect_x29",
|
||||
+};
|
||||
+
|
||||
+/* Function to create a BLR thunk. This thunk is used to mitigate straight
|
||||
+ line speculation. Instead of a simple BLR that can be speculated past,
|
||||
+ we emit a BL to this thunk, and this thunk contains a BR to the relevant
|
||||
+ register. These thunks have the relevant speculation barries put after
|
||||
+ their indirect branch so that speculation is blocked.
|
||||
+
|
||||
+ We use such a thunk so the speculation barriers are kept off the
|
||||
+ architecturally executed path in order to reduce the performance overhead.
|
||||
+
|
||||
+ When optimizing for size we use stubs shared by the linked object.
|
||||
+ When optimizing for performance we emit stubs for each function in the hope
|
||||
+ that the branch predictor can better train on jumps specific for a given
|
||||
+ function. */
|
||||
+rtx
|
||||
+aarch64_sls_create_blr_label (int regnum)
|
||||
+{
|
||||
+ gcc_assert (STUB_REGNUM_P (regnum));
|
||||
+ if (optimize_function_for_size_p (cfun))
|
||||
+ {
|
||||
+ /* For the thunks shared between different functions in this compilation
|
||||
+ unit we use a named symbol -- this is just for users to more easily
|
||||
+ understand the generated assembly. */
|
||||
+ aarch64_sls_shared_thunks_needed = true;
|
||||
+ const char *thunk_name = indirect_symbol_names[regnum];
|
||||
+ if (aarch64_sls_shared_thunks[regnum] == NULL)
|
||||
+ {
|
||||
+ /* Build a decl representing this function stub and record it for
|
||||
+ later. We build a decl here so we can use the GCC machinery for
|
||||
+ handling sections automatically (through `get_named_section` and
|
||||
+ `make_decl_one_only`). That saves us a lot of trouble handling
|
||||
+ the specifics of different output file formats. */
|
||||
+ tree decl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
|
||||
+ get_identifier (thunk_name),
|
||||
+ build_function_type_list (void_type_node,
|
||||
+ NULL_TREE));
|
||||
+ DECL_RESULT (decl) = build_decl (BUILTINS_LOCATION, RESULT_DECL,
|
||||
+ NULL_TREE, void_type_node);
|
||||
+ TREE_PUBLIC (decl) = 1;
|
||||
+ TREE_STATIC (decl) = 1;
|
||||
+ DECL_IGNORED_P (decl) = 1;
|
||||
+ DECL_ARTIFICIAL (decl) = 1;
|
||||
+ make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl));
|
||||
+ resolve_unique_section (decl, 0, false);
|
||||
+ aarch64_sls_shared_thunks[regnum] = decl;
|
||||
+ }
|
||||
+
|
||||
+ return gen_rtx_SYMBOL_REF (Pmode, thunk_name);
|
||||
+ }
|
||||
+
|
||||
+ if (cfun->machine->call_via[regnum] == NULL)
|
||||
+ cfun->machine->call_via[regnum]
|
||||
+ = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
|
||||
+ return cfun->machine->call_via[regnum];
|
||||
+}
|
||||
+
|
||||
+/* Helper function for aarch64_sls_emit_blr_function_thunks and
|
||||
+ aarch64_sls_emit_shared_blr_thunks below. */
|
||||
+static void
|
||||
+aarch64_sls_emit_function_stub (FILE *out_file, int regnum)
|
||||
+{
|
||||
+ /* Save in x16 and branch to that function so this transformation does
|
||||
+ not prevent jumping to `BTI c` instructions. */
|
||||
+ asm_fprintf (out_file, "\tmov\tx16, x%d\n", regnum);
|
||||
+ asm_fprintf (out_file, "\tbr\tx16\n");
|
||||
+}
|
||||
+
|
||||
+/* Emit all BLR stubs for this particular function.
|
||||
+ Here we emit all the BLR stubs needed for the current function. Since we
|
||||
+ emit these stubs in a consecutive block we know there will be no speculation
|
||||
+ gadgets between each stub, and hence we only emit a speculation barrier at
|
||||
+ the end of the stub sequences.
|
||||
+
|
||||
+ This is called in the TARGET_ASM_FUNCTION_EPILOGUE hook. */
|
||||
+void
|
||||
+aarch64_sls_emit_blr_function_thunks (FILE *out_file)
|
||||
+{
|
||||
+ if (! aarch64_harden_sls_blr_p ())
|
||||
+ return;
|
||||
+
|
||||
+ bool any_functions_emitted = false;
|
||||
+ /* We must save and restore the current function section since this assembly
|
||||
+ is emitted at the end of the function. This means it can be emitted *just
|
||||
+ after* the cold section of a function. That cold part would be emitted in
|
||||
+ a different section. That switch would trigger a `.cfi_endproc` directive
|
||||
+ to be emitted in the original section and a `.cfi_startproc` directive to
|
||||
+ be emitted in the new section. Switching to the original section without
|
||||
+ restoring would mean that the `.cfi_endproc` emitted as a function ends
|
||||
+ would happen in a different section -- leaving an unmatched
|
||||
+ `.cfi_startproc` in the cold text section and an unmatched `.cfi_endproc`
|
||||
+ in the standard text section. */
|
||||
+ section *save_text_section = in_section;
|
||||
+ switch_to_section (function_section (current_function_decl));
|
||||
+ for (int regnum = 0; regnum < 30; ++regnum)
|
||||
+ {
|
||||
+ rtx specu_label = cfun->machine->call_via[regnum];
|
||||
+ if (specu_label == NULL)
|
||||
+ continue;
|
||||
+
|
||||
+ targetm.asm_out.print_operand (out_file, specu_label, 0);
|
||||
+ asm_fprintf (out_file, ":\n");
|
||||
+ aarch64_sls_emit_function_stub (out_file, regnum);
|
||||
+ any_functions_emitted = true;
|
||||
+ }
|
||||
+ if (any_functions_emitted)
|
||||
+ /* Can use the SB if needs be here, since this stub will only be used
|
||||
+ by the current function, and hence for the current target. */
|
||||
+ asm_fprintf (out_file, "\t%s\n", aarch64_sls_barrier (true));
|
||||
+ switch_to_section (save_text_section);
|
||||
+}
|
||||
+
|
||||
+/* Emit shared BLR stubs for the current compilation unit.
|
||||
+ Over the course of compiling this unit we may have converted some BLR
|
||||
+ instructions to a BL to a shared stub function. This is where we emit those
|
||||
+ stub functions.
|
||||
+ This function is for the stubs shared between different functions in this
|
||||
+ compilation unit. We share when optimizing for size instead of speed.
|
||||
+
|
||||
+ This function is called through the TARGET_ASM_FILE_END hook. */
|
||||
+void
|
||||
+aarch64_sls_emit_shared_blr_thunks (FILE *out_file)
|
||||
+{
|
||||
+ if (! aarch64_sls_shared_thunks_needed)
|
||||
+ return;
|
||||
+
|
||||
+ for (int regnum = 0; regnum < 30; ++regnum)
|
||||
+ {
|
||||
+ tree decl = aarch64_sls_shared_thunks[regnum];
|
||||
+ if (!decl)
|
||||
+ continue;
|
||||
+
|
||||
+ const char *name = indirect_symbol_names[regnum];
|
||||
+ switch_to_section (get_named_section (decl, NULL, 0));
|
||||
+ ASM_OUTPUT_ALIGN (out_file, 2);
|
||||
+ targetm.asm_out.globalize_label (out_file, name);
|
||||
+ /* Only emits if the compiler is configured for an assembler that can
|
||||
+ handle visibility directives. */
|
||||
+ targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN);
|
||||
+ ASM_OUTPUT_TYPE_DIRECTIVE (out_file, name, "function");
|
||||
+ ASM_OUTPUT_LABEL (out_file, name);
|
||||
+ aarch64_sls_emit_function_stub (out_file, regnum);
|
||||
+ /* Use the most conservative target to ensure it can always be used by any
|
||||
+ function in the translation unit. */
|
||||
+ asm_fprintf (out_file, "\tdsb\tsy\n\tisb\n");
|
||||
+ ASM_DECLARE_FUNCTION_SIZE (out_file, name, decl);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Implement TARGET_ASM_FILE_END. */
|
||||
+void
|
||||
+aarch64_asm_file_end ()
|
||||
+{
|
||||
+ aarch64_sls_emit_shared_blr_thunks (asm_out_file);
|
||||
+ /* Since this function will be called for the ASM_FILE_END hook, we ensure
|
||||
+ that what would be called otherwise (e.g. `file_end_indicate_exec_stack`
|
||||
+ for FreeBSD) still gets called. */
|
||||
+#ifdef TARGET_ASM_FILE_END
|
||||
+ TARGET_ASM_FILE_END ();
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+const char *
|
||||
+aarch64_indirect_call_asm (rtx addr)
|
||||
+{
|
||||
+ gcc_assert (REG_P (addr));
|
||||
+ if (aarch64_harden_sls_blr_p ())
|
||||
+ {
|
||||
+ rtx stub_label = aarch64_sls_create_blr_label (REGNO (addr));
|
||||
+ output_asm_insn ("bl\t%0", &stub_label);
|
||||
+ }
|
||||
+ else
|
||||
+ output_asm_insn ("blr\t%0", &addr);
|
||||
+ return "";
|
||||
+}
|
||||
+
|
||||
/* Target-specific selftests. */
|
||||
|
||||
#if CHECKING_P
|
||||
@@ -19529,6 +19744,12 @@ aarch64_libgcc_floating_mode_supported_p
|
||||
#define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests
|
||||
#endif /* #if CHECKING_P */
|
||||
|
||||
+#undef TARGET_ASM_FILE_END
|
||||
+#define TARGET_ASM_FILE_END aarch64_asm_file_end
|
||||
+
|
||||
+#undef TARGET_ASM_FUNCTION_EPILOGUE
|
||||
+#define TARGET_ASM_FUNCTION_EPILOGUE aarch64_sls_emit_blr_function_thunks
|
||||
+
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
#include "gt-aarch64.h"
|
||||
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
|
||||
index 72ddc6fd9..60682a100 100644
|
||||
--- a/gcc/config/aarch64/aarch64.h
|
||||
+++ b/gcc/config/aarch64/aarch64.h
|
||||
@@ -540,6 +540,16 @@ extern unsigned aarch64_architecture_version;
|
||||
#define GP_REGNUM_P(REGNO) \
|
||||
(((unsigned) (REGNO - R0_REGNUM)) <= (R30_REGNUM - R0_REGNUM))
|
||||
|
||||
+/* Registers known to be preserved over a BL instruction. This consists of the
|
||||
+ GENERAL_REGS without x16, x17, and x30. The x30 register is changed by the
|
||||
+ BL instruction itself, while the x16 and x17 registers may be used by
|
||||
+ veneers which can be inserted by the linker. */
|
||||
+#define STUB_REGNUM_P(REGNO) \
|
||||
+ (GP_REGNUM_P (REGNO) \
|
||||
+ && (REGNO) != R16_REGNUM \
|
||||
+ && (REGNO) != R17_REGNUM \
|
||||
+ && (REGNO) != R30_REGNUM) \
|
||||
+
|
||||
#define FP_REGNUM_P(REGNO) \
|
||||
(((unsigned) (REGNO - V0_REGNUM)) <= (V31_REGNUM - V0_REGNUM))
|
||||
|
||||
@@ -561,6 +571,7 @@ enum reg_class
|
||||
{
|
||||
NO_REGS,
|
||||
TAILCALL_ADDR_REGS,
|
||||
+ STUB_REGS,
|
||||
GENERAL_REGS,
|
||||
STACK_REG,
|
||||
POINTER_REGS,
|
||||
@@ -580,6 +591,7 @@ enum reg_class
|
||||
{ \
|
||||
"NO_REGS", \
|
||||
"TAILCALL_ADDR_REGS", \
|
||||
+ "STUB_REGS", \
|
||||
"GENERAL_REGS", \
|
||||
"STACK_REG", \
|
||||
"POINTER_REGS", \
|
||||
@@ -596,6 +608,7 @@ enum reg_class
|
||||
{ \
|
||||
{ 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
|
||||
{ 0x00030000, 0x00000000, 0x00000000 }, /* TAILCALL_ADDR_REGS */\
|
||||
+ { 0x3ffcffff, 0x00000000, 0x00000000 }, /* STUB_REGS */ \
|
||||
{ 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \
|
||||
{ 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \
|
||||
{ 0xffffffff, 0x00000000, 0x00000003 }, /* POINTER_REGS */ \
|
||||
@@ -735,6 +748,8 @@ typedef struct GTY (()) machine_function
|
||||
struct aarch64_frame frame;
|
||||
/* One entry for each hard register. */
|
||||
bool reg_is_wrapped_separately[LAST_SAVED_REGNUM];
|
||||
+ /* One entry for each general purpose register. */
|
||||
+ rtx call_via[SP_REGNUM];
|
||||
bool label_is_assembled;
|
||||
} machine_function;
|
||||
#endif
|
||||
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
|
||||
index 494aee964..ed8cf8ece 100644
|
||||
--- a/gcc/config/aarch64/aarch64.md
|
||||
+++ b/gcc/config/aarch64/aarch64.md
|
||||
@@ -908,15 +908,14 @@
|
||||
)
|
||||
|
||||
(define_insn "*call_insn"
|
||||
- [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "r, Usf"))
|
||||
+ [(call (mem:DI (match_operand:DI 0 "aarch64_call_insn_operand" "Ucr, Usf"))
|
||||
(match_operand 1 "" ""))
|
||||
(clobber (reg:DI LR_REGNUM))]
|
||||
""
|
||||
"@
|
||||
- blr\\t%0
|
||||
+ * return aarch64_indirect_call_asm (operands[0]);
|
||||
bl\\t%c0"
|
||||
- [(set_attr "type" "call, call")]
|
||||
-)
|
||||
+ [(set_attr "type" "call, call")])
|
||||
|
||||
(define_expand "call_value"
|
||||
[(parallel [(set (match_operand 0 "" "")
|
||||
@@ -934,12 +933,12 @@
|
||||
|
||||
(define_insn "*call_value_insn"
|
||||
[(set (match_operand 0 "" "")
|
||||
- (call (mem:DI (match_operand:DI 1 "aarch64_call_insn_operand" "r, Usf"))
|
||||
+ (call (mem:DI (match_operand:DI 1 "aarch64_call_insn_operand" "Ucr, Usf"))
|
||||
(match_operand 2 "" "")))
|
||||
(clobber (reg:DI LR_REGNUM))]
|
||||
""
|
||||
"@
|
||||
- blr\\t%1
|
||||
+ * return aarch64_indirect_call_asm (operands[1]);
|
||||
bl\\t%c1"
|
||||
[(set_attr "type" "call, call")]
|
||||
)
|
||||
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
|
||||
index 21f9549e6..7756dbe83 100644
|
||||
--- a/gcc/config/aarch64/constraints.md
|
||||
+++ b/gcc/config/aarch64/constraints.md
|
||||
@@ -24,6 +24,15 @@
|
||||
(define_register_constraint "Ucs" "TAILCALL_ADDR_REGS"
|
||||
"@internal Registers suitable for an indirect tail call")
|
||||
|
||||
+(define_register_constraint "Ucr"
|
||||
+ "aarch64_harden_sls_blr_p () ? STUB_REGS : GENERAL_REGS"
|
||||
+ "@internal Registers to be used for an indirect call.
|
||||
+ This is usually the general registers, but when we are hardening against
|
||||
+ Straight Line Speculation we disallow x16, x17, and x30 so we can use
|
||||
+ indirection stubs. These indirection stubs cannot use the above registers
|
||||
+ since they will be reached by a BL that may have to go through a linker
|
||||
+ veneer.")
|
||||
+
|
||||
(define_register_constraint "w" "FP_REGS"
|
||||
"Floating point and SIMD vector registers.")
|
||||
|
||||
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
|
||||
index 8e1b78421..4250aecb3 100644
|
||||
--- a/gcc/config/aarch64/predicates.md
|
||||
+++ b/gcc/config/aarch64/predicates.md
|
||||
@@ -32,7 +32,8 @@
|
||||
|
||||
(define_predicate "aarch64_general_reg"
|
||||
(and (match_operand 0 "register_operand")
|
||||
- (match_test "REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS")))
|
||||
+ (match_test "REGNO_REG_CLASS (REGNO (op)) == STUB_REGS
|
||||
+ || REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS")))
|
||||
|
||||
;; Return true if OP a (const_int 0) operand.
|
||||
(define_predicate "const0_operand"
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c
|
||||
new file mode 100644
|
||||
index 000000000..b1fb754c7
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr-bti.c
|
||||
@@ -0,0 +1,40 @@
|
||||
+/* { dg-do compile } */
|
||||
+/* { dg-additional-options "-mharden-sls=blr -mbranch-protection=bti" } */
|
||||
+/*
|
||||
+ Ensure that the SLS hardening of BLR leaves no BLR instructions.
|
||||
+ Here we also check that there are no BR instructions with anything except an
|
||||
+ x16 or x17 register. This is because a `BTI c` instruction can be branched
|
||||
+ to using a BLR instruction using any register, but can only be branched to
|
||||
+ with a BR using an x16 or x17 register.
|
||||
+ */
|
||||
+typedef int (foo) (int, int);
|
||||
+typedef void (bar) (int, int);
|
||||
+struct sls_testclass {
|
||||
+ foo *x;
|
||||
+ bar *y;
|
||||
+ int left;
|
||||
+ int right;
|
||||
+};
|
||||
+
|
||||
+/* We test both RTL patterns for a call which returns a value and a call which
|
||||
+ does not. */
|
||||
+int blr_call_value (struct sls_testclass x)
|
||||
+{
|
||||
+ int retval = x.x(x.left, x.right);
|
||||
+ if (retval % 10)
|
||||
+ return 100;
|
||||
+ return 9;
|
||||
+}
|
||||
+
|
||||
+int blr_call (struct sls_testclass x)
|
||||
+{
|
||||
+ x.y(x.left, x.right);
|
||||
+ if (x.left % 10)
|
||||
+ return 100;
|
||||
+ return 9;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-not {\tblr\t} } } */
|
||||
+/* { dg-final { scan-assembler-not {\tbr\tx(?!16|17)} } } */
|
||||
+/* { dg-final { scan-assembler {\tbr\tx(16|17)} } } */
|
||||
+
|
||||
diff --git a/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c
|
||||
new file mode 100644
|
||||
index 000000000..88baffffe
|
||||
--- /dev/null
|
||||
+++ b/gcc/testsuite/gcc.target/aarch64/sls-mitigation/sls-miti-blr.c
|
||||
@@ -0,0 +1,33 @@
|
||||
+/* { dg-additional-options "-mharden-sls=blr -save-temps" } */
|
||||
+/* Ensure that the SLS hardening of BLR leaves no BLR instructions.
|
||||
+ We only test that all BLR instructions have been removed, not that the
|
||||
+ resulting code makes sense. */
|
||||
+typedef int (foo) (int, int);
|
||||
+typedef void (bar) (int, int);
|
||||
+struct sls_testclass {
|
||||
+ foo *x;
|
||||
+ bar *y;
|
||||
+ int left;
|
||||
+ int right;
|
||||
+};
|
||||
+
|
||||
+/* We test both RTL patterns for a call which returns a value and a call which
|
||||
+ does not. */
|
||||
+int blr_call_value (struct sls_testclass x)
|
||||
+{
|
||||
+ int retval = x.x(x.left, x.right);
|
||||
+ if (retval % 10)
|
||||
+ return 100;
|
||||
+ return 9;
|
||||
+}
|
||||
+
|
||||
+int blr_call (struct sls_testclass x)
|
||||
+{
|
||||
+ x.y(x.left, x.right);
|
||||
+ if (x.left % 10)
|
||||
+ return 100;
|
||||
+ return 9;
|
||||
+}
|
||||
+
|
||||
+/* { dg-final { scan-assembler-not {\tblr\t} } } */
|
||||
+/* { dg-final { scan-assembler {\tbr\tx[0-9][0-9]?} } } */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
From b19d8aac15649f31a7588b2634411a1922906ea8 Mon Sep 17 00:00:00 2001
|
||||
From: Romain Naour <romain.naour@gmail.com>
|
||||
Date: Wed, 3 Jun 2020 12:30:57 -0600
|
||||
Subject: [PATCH] Fix missing dependencies for selftests which occasionally
|
||||
causes failed builds.
|
||||
|
||||
gcc/
|
||||
|
||||
* Makefile.in (SELFTEST_DEPS): Move before including language makefile
|
||||
fragments.
|
||||
|
||||
Upstream-Status: Backport [https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=b19d8aac15649f31a7588b2634411a1922906ea8]
|
||||
Signed-off-by:Steve Sakoman <steve@sakoman.com>
|
||||
|
||||
---
|
||||
gcc/Makefile.in | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
|
||||
index aab1dbba57b..be11311b60d 100644
|
||||
--- a/gcc/Makefile.in
|
||||
+++ b/gcc/Makefile.in
|
||||
@@ -1735,6 +1735,10 @@ $(FULL_DRIVER_NAME): ./xgcc$(exeext)
|
||||
$(LN_S) $< $@
|
||||
|
||||
#
|
||||
+# SELFTEST_DEPS need to be set before including language makefile fragments.
|
||||
+# Otherwise $(SELFTEST_DEPS) is empty when used from <LANG>/Make-lang.in.
|
||||
+SELFTEST_DEPS = $(GCC_PASSES) stmp-int-hdrs $(srcdir)/testsuite/selftests
|
||||
+
|
||||
# Language makefile fragments.
|
||||
|
||||
# The following targets define the interface between us and the languages.
|
||||
@@ -2010,8 +2014,6 @@ DEVNULL=$(if $(findstring mingw,$(build)),nul,/dev/null)
|
||||
SELFTEST_FLAGS = -nostdinc $(DEVNULL) -S -o $(DEVNULL) \
|
||||
-fself-test=$(srcdir)/testsuite/selftests
|
||||
|
||||
-SELFTEST_DEPS = $(GCC_PASSES) stmp-int-hdrs $(srcdir)/testsuite/selftests
|
||||
-
|
||||
# Run the selftests during the build once we have a driver and the frontend,
|
||||
# so that self-test failures are caught as early as possible.
|
||||
# Use "s-selftest-FE" to ensure that we only run the selftests if the
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@@ -2,13 +2,13 @@ require gcc-common.inc
|
||||
|
||||
# Third digit in PV should be incremented after a minor release
|
||||
|
||||
PV = "9.3.0"
|
||||
PV = "9.5.0"
|
||||
|
||||
# BINV should be incremented to a revision after a minor gcc release
|
||||
|
||||
BINV = "9.3.0"
|
||||
BINV = "9.5.0"
|
||||
|
||||
FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc-9.3:${FILE_DIRNAME}/gcc-9.3/backport:"
|
||||
FILESEXTRAPATHS =. "${FILE_DIRNAME}/gcc-9.5:${FILE_DIRNAME}/gcc-9.5/backport:"
|
||||
|
||||
DEPENDS =+ "mpfr gmp libmpc zlib flex-native"
|
||||
NATIVEDEPS = "mpfr-native gmp-native libmpc-native zlib-native flex-native"
|
||||
@@ -69,14 +69,9 @@ SRC_URI = "\
|
||||
file://0037-CVE-2019-14250-Check-zero-value-in-simple_object_elf.patch \
|
||||
file://0038-gentypes-genmodes-Do-not-use-__LINE__-for-maintainin.patch \
|
||||
file://0039-process_alt_operands-Don-t-match-user-defined-regs-o.patch \
|
||||
file://0040-fix-missing-dependencies-for-selftests.patch \
|
||||
file://0001-aarch64-New-Straight-Line-Speculation-SLS-mitigation.patch \
|
||||
file://0002-aarch64-Introduce-SLS-mitigation-for-RET-and-BR-inst.patch \
|
||||
file://0003-aarch64-Mitigate-SLS-for-BLR-instruction.patch \
|
||||
file://0001-Backport-fix-for-PR-tree-optimization-97236-fix-bad-.patch \
|
||||
"
|
||||
S = "${TMPDIR}/work-shared/gcc-${PV}-${PR}/gcc-${PV}"
|
||||
SRC_URI[sha256sum] = "71e197867611f6054aa1119b13a0c0abac12834765fe2d81f35ac57f84f742d1"
|
||||
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}"
|
||||
@@ -43,6 +43,14 @@ SRC_URI += "\
|
||||
file://0004-CVE-2022-32190.patch \
|
||||
file://CVE-2022-2880.patch \
|
||||
file://CVE-2022-2879.patch \
|
||||
file://CVE-2021-33195.patch \
|
||||
file://CVE-2021-33198.patch \
|
||||
file://CVE-2021-44716.patch \
|
||||
file://CVE-2022-24921.patch \
|
||||
file://CVE-2022-28131.patch \
|
||||
file://CVE-2022-28327.patch \
|
||||
file://CVE-2022-41715.patch \
|
||||
file://CVE-2022-41717.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch"
|
||||
@@ -58,4 +66,15 @@ CVE_CHECK_WHITELIST += "CVE-2021-29923"
|
||||
CVE_CHECK_WHITELIST += "CVE-2022-29526"
|
||||
|
||||
# Issue only on windows
|
||||
CVE_CHECK_WHITELIST += "CVE-2022-29804"
|
||||
CVE_CHECK_WHITELIST += "CVE-2022-30580"
|
||||
CVE_CHECK_WHITELIST += "CVE-2022-30634"
|
||||
|
||||
# Issue is in golang.org/x/net/html/parse.go, not used in go compiler
|
||||
CVE_CHECK_WHITELIST += "CVE-2021-33194"
|
||||
|
||||
# Issue introduced in go1.16, does not exist in 1.14
|
||||
CVE_CHECK_WHITELIST += "CVE-2021-41772"
|
||||
|
||||
# Fixes code that was added in go1.16, does not exist in 1.14
|
||||
CVE_CHECK_WHITELIST += "CVE-2022-30630"
|
||||
|
||||
373
meta/recipes-devtools/go/go-1.14/CVE-2021-33195.patch
Normal file
373
meta/recipes-devtools/go/go-1.14/CVE-2021-33195.patch
Normal file
@@ -0,0 +1,373 @@
|
||||
From 9324d7e53151e9dfa4b25af994a28c2e0b11f729 Mon Sep 17 00:00:00 2001
|
||||
From: Roland Shoemaker <roland@golang.org>
|
||||
Date: Thu, 27 May 2021 10:40:06 -0700
|
||||
Subject: [PATCH] net: verify results from Lookup* are valid domain names
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/31d60cda1f58b7558fc5725d2b9e4531655d980e]
|
||||
CVE: CVE-2021-33195
|
||||
Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
|
||||
|
||||
|
||||
For the methods LookupCNAME, LookupSRV, LookupMX, LookupNS, and
|
||||
LookupAddr check that the returned domain names are in fact valid DNS
|
||||
names using the existing isDomainName function.
|
||||
|
||||
Thanks to Philipp Jeitner and Haya Shulman from Fraunhofer SIT for
|
||||
reporting this issue.
|
||||
|
||||
Updates #46241
|
||||
Fixes #46356
|
||||
Fixes CVE-2021-33195
|
||||
|
||||
Change-Id: I47a4f58c031cb752f732e88bbdae7f819f0af4f3
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/323131
|
||||
Trust: Roland Shoemaker <roland@golang.org>
|
||||
Run-TryBot: Roland Shoemaker <roland@golang.org>
|
||||
TryBot-Result: Go Bot <gobot@golang.org>
|
||||
Reviewed-by: Filippo Valsorda <filippo@golang.org>
|
||||
Reviewed-by: Katie Hockman <katie@golang.org>
|
||||
(cherry picked from commit cdcd02842da7c004efd023881e3719105209c908)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/323269
|
||||
---
|
||||
src/net/dnsclient_unix_test.go | 157 +++++++++++++++++++++++++++++++++
|
||||
src/net/lookup.go | 111 ++++++++++++++++++++---
|
||||
2 files changed, 255 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
|
||||
index 2ad40df..b8617d9 100644
|
||||
--- a/src/net/dnsclient_unix_test.go
|
||||
+++ b/src/net/dnsclient_unix_test.go
|
||||
@@ -1800,3 +1800,160 @@ func TestPTRandNonPTR(t *testing.T) {
|
||||
t.Errorf("names = %q; want %q", names, want)
|
||||
}
|
||||
}
|
||||
+
|
||||
+func TestCVE202133195(t *testing.T) {
|
||||
+ fake := fakeDNSServer{
|
||||
+ rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) {
|
||||
+ r := dnsmessage.Message{
|
||||
+ Header: dnsmessage.Header{
|
||||
+ ID: q.Header.ID,
|
||||
+ Response: true,
|
||||
+ RCode: dnsmessage.RCodeSuccess,
|
||||
+ RecursionAvailable: true,
|
||||
+ },
|
||||
+ Questions: q.Questions,
|
||||
+ }
|
||||
+ switch q.Questions[0].Type {
|
||||
+ case dnsmessage.TypeCNAME:
|
||||
+ r.Answers = []dnsmessage.Resource{}
|
||||
+ case dnsmessage.TypeA: // CNAME lookup uses a A/AAAA as a proxy
|
||||
+ r.Answers = append(r.Answers,
|
||||
+ dnsmessage.Resource{
|
||||
+ Header: dnsmessage.ResourceHeader{
|
||||
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ Type: dnsmessage.TypeA,
|
||||
+ Class: dnsmessage.ClassINET,
|
||||
+ Length: 4,
|
||||
+ },
|
||||
+ Body: &dnsmessage.AResource{
|
||||
+ A: TestAddr,
|
||||
+ },
|
||||
+ },
|
||||
+ )
|
||||
+ case dnsmessage.TypeSRV:
|
||||
+ n := q.Questions[0].Name
|
||||
+ if n.String() == "_hdr._tcp.golang.org." {
|
||||
+ n = dnsmessage.MustNewName("<html>.golang.org.")
|
||||
+ }
|
||||
+ r.Answers = append(r.Answers,
|
||||
+ dnsmessage.Resource{
|
||||
+ Header: dnsmessage.ResourceHeader{
|
||||
+ Name: n,
|
||||
+ Type: dnsmessage.TypeSRV,
|
||||
+ Class: dnsmessage.ClassINET,
|
||||
+ Length: 4,
|
||||
+ },
|
||||
+ Body: &dnsmessage.SRVResource{
|
||||
+ Target: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ },
|
||||
+ },
|
||||
+ )
|
||||
+ case dnsmessage.TypeMX:
|
||||
+ r.Answers = append(r.Answers,
|
||||
+ dnsmessage.Resource{
|
||||
+ Header: dnsmessage.ResourceHeader{
|
||||
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ Type: dnsmessage.TypeMX,
|
||||
+ Class: dnsmessage.ClassINET,
|
||||
+ Length: 4,
|
||||
+ },
|
||||
+ Body: &dnsmessage.MXResource{
|
||||
+ MX: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ },
|
||||
+ },
|
||||
+ )
|
||||
+ case dnsmessage.TypeNS:
|
||||
+ r.Answers = append(r.Answers,
|
||||
+ dnsmessage.Resource{
|
||||
+ Header: dnsmessage.ResourceHeader{
|
||||
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ Type: dnsmessage.TypeNS,
|
||||
+ Class: dnsmessage.ClassINET,
|
||||
+ Length: 4,
|
||||
+ },
|
||||
+ Body: &dnsmessage.NSResource{
|
||||
+ NS: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ },
|
||||
+ },
|
||||
+ )
|
||||
+ case dnsmessage.TypePTR:
|
||||
+ r.Answers = append(r.Answers,
|
||||
+ dnsmessage.Resource{
|
||||
+ Header: dnsmessage.ResourceHeader{
|
||||
+ Name: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ Type: dnsmessage.TypePTR,
|
||||
+ Class: dnsmessage.ClassINET,
|
||||
+ Length: 4,
|
||||
+ },
|
||||
+ Body: &dnsmessage.PTRResource{
|
||||
+ PTR: dnsmessage.MustNewName("<html>.golang.org."),
|
||||
+ },
|
||||
+ },
|
||||
+ )
|
||||
+ }
|
||||
+ return r, nil
|
||||
+ },
|
||||
+ }
|
||||
+
|
||||
+ r := Resolver{PreferGo: true, Dial: fake.DialContext}
|
||||
+ // Change the default resolver to match our manipulated resolver
|
||||
+ originalDefault := DefaultResolver
|
||||
+ DefaultResolver = &r
|
||||
+ defer func() {
|
||||
+ DefaultResolver = originalDefault
|
||||
+ }()
|
||||
+
|
||||
+ _, err := r.LookupCNAME(context.Background(), "golang.org")
|
||||
+ if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+ _, err = LookupCNAME("golang.org")
|
||||
+ if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+
|
||||
+ _, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org")
|
||||
+ if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+ _, _, err = LookupSRV("target", "tcp", "golang.org")
|
||||
+ if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+
|
||||
+ _, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org")
|
||||
+ if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+ _, _, err = LookupSRV("hdr", "tcp", "golang.org")
|
||||
+ if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+
|
||||
+ _, err = r.LookupMX(context.Background(), "golang.org")
|
||||
+ if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+ _, err = LookupMX("golang.org")
|
||||
+ if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("LookupMX returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+
|
||||
+ _, err = r.LookupNS(context.Background(), "golang.org")
|
||||
+ if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+ _, err = LookupNS("golang.org")
|
||||
+ if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("LookupNS returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+
|
||||
+ _, err = r.LookupAddr(context.Background(), "1.2.3.4")
|
||||
+ if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+ _, err = LookupAddr("1.2.3.4")
|
||||
+ if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected {
|
||||
+ t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected)
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/net/lookup.go b/src/net/lookup.go
|
||||
index 9cebd10..05e88e4 100644
|
||||
--- a/src/net/lookup.go
|
||||
+++ b/src/net/lookup.go
|
||||
@@ -364,8 +364,11 @@ func (r *Resolver) LookupPort(ctx context.Context, network, service string) (por
|
||||
// LookupCNAME does not return an error if host does not
|
||||
// contain DNS "CNAME" records, as long as host resolves to
|
||||
// address records.
|
||||
+//
|
||||
+// The returned canonical name is validated to be a properly
|
||||
+// formatted presentation-format domain name.
|
||||
func LookupCNAME(host string) (cname string, err error) {
|
||||
- return DefaultResolver.lookupCNAME(context.Background(), host)
|
||||
+ return DefaultResolver.LookupCNAME(context.Background(), host)
|
||||
}
|
||||
|
||||
// LookupCNAME returns the canonical name for the given host.
|
||||
@@ -378,8 +381,18 @@ func LookupCNAME(host string) (cname string, err error) {
|
||||
// LookupCNAME does not return an error if host does not
|
||||
// contain DNS "CNAME" records, as long as host resolves to
|
||||
// address records.
|
||||
-func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string, err error) {
|
||||
- return r.lookupCNAME(ctx, host)
|
||||
+//
|
||||
+// The returned canonical name is validated to be a properly
|
||||
+// formatted presentation-format domain name.
|
||||
+func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) {
|
||||
+ cname, err := r.lookupCNAME(ctx, host)
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
+ if !isDomainName(cname) {
|
||||
+ return "", &DNSError{Err: "CNAME target is invalid", Name: host}
|
||||
+ }
|
||||
+ return cname, nil
|
||||
}
|
||||
|
||||
// LookupSRV tries to resolve an SRV query of the given service,
|
||||
@@ -391,8 +404,11 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string,
|
||||
// That is, it looks up _service._proto.name. To accommodate services
|
||||
// publishing SRV records under non-standard names, if both service
|
||||
// and proto are empty strings, LookupSRV looks up name directly.
|
||||
+//
|
||||
+// The returned service names are validated to be properly
|
||||
+// formatted presentation-format domain names.
|
||||
func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
|
||||
- return DefaultResolver.lookupSRV(context.Background(), service, proto, name)
|
||||
+ return DefaultResolver.LookupSRV(context.Background(), service, proto, name)
|
||||
}
|
||||
|
||||
// LookupSRV tries to resolve an SRV query of the given service,
|
||||
@@ -404,28 +420,82 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err err
|
||||
// That is, it looks up _service._proto.name. To accommodate services
|
||||
// publishing SRV records under non-standard names, if both service
|
||||
// and proto are empty strings, LookupSRV looks up name directly.
|
||||
-func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*SRV, err error) {
|
||||
- return r.lookupSRV(ctx, service, proto, name)
|
||||
+//
|
||||
+// The returned service names are validated to be properly
|
||||
+// formatted presentation-format domain names.
|
||||
+func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) {
|
||||
+ cname, addrs, err := r.lookupSRV(ctx, service, proto, name)
|
||||
+ if err != nil {
|
||||
+ return "", nil, err
|
||||
+ }
|
||||
+ if cname != "" && !isDomainName(cname) {
|
||||
+ return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name}
|
||||
+ }
|
||||
+ for _, addr := range addrs {
|
||||
+ if addr == nil {
|
||||
+ continue
|
||||
+ }
|
||||
+ if !isDomainName(addr.Target) {
|
||||
+ return "", nil, &DNSError{Err: "SRV target is invalid", Name: name}
|
||||
+ }
|
||||
+ }
|
||||
+ return cname, addrs, nil
|
||||
}
|
||||
|
||||
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
|
||||
+//
|
||||
+// The returned mail server names are validated to be properly
|
||||
+// formatted presentation-format domain names.
|
||||
func LookupMX(name string) ([]*MX, error) {
|
||||
- return DefaultResolver.lookupMX(context.Background(), name)
|
||||
+ return DefaultResolver.LookupMX(context.Background(), name)
|
||||
}
|
||||
|
||||
// LookupMX returns the DNS MX records for the given domain name sorted by preference.
|
||||
+//
|
||||
+// The returned mail server names are validated to be properly
|
||||
+// formatted presentation-format domain names.
|
||||
func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) {
|
||||
- return r.lookupMX(ctx, name)
|
||||
+ records, err := r.lookupMX(ctx, name)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ for _, mx := range records {
|
||||
+ if mx == nil {
|
||||
+ continue
|
||||
+ }
|
||||
+ if !isDomainName(mx.Host) {
|
||||
+ return nil, &DNSError{Err: "MX target is invalid", Name: name}
|
||||
+ }
|
||||
+ }
|
||||
+ return records, nil
|
||||
}
|
||||
|
||||
// LookupNS returns the DNS NS records for the given domain name.
|
||||
+//
|
||||
+// The returned name server names are validated to be properly
|
||||
+// formatted presentation-format domain names.
|
||||
func LookupNS(name string) ([]*NS, error) {
|
||||
- return DefaultResolver.lookupNS(context.Background(), name)
|
||||
+ return DefaultResolver.LookupNS(context.Background(), name)
|
||||
}
|
||||
|
||||
// LookupNS returns the DNS NS records for the given domain name.
|
||||
+//
|
||||
+// The returned name server names are validated to be properly
|
||||
+// formatted presentation-format domain names.
|
||||
func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) {
|
||||
- return r.lookupNS(ctx, name)
|
||||
+ records, err := r.lookupNS(ctx, name)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ for _, ns := range records {
|
||||
+ if ns == nil {
|
||||
+ continue
|
||||
+ }
|
||||
+ if !isDomainName(ns.Host) {
|
||||
+ return nil, &DNSError{Err: "NS target is invalid", Name: name}
|
||||
+ }
|
||||
+ }
|
||||
+ return records, nil
|
||||
}
|
||||
|
||||
// LookupTXT returns the DNS TXT records for the given domain name.
|
||||
@@ -441,14 +511,29 @@ func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error)
|
||||
// LookupAddr performs a reverse lookup for the given address, returning a list
|
||||
// of names mapping to that address.
|
||||
//
|
||||
+// The returned names are validated to be properly formatted presentation-format
|
||||
+// domain names.
|
||||
+//
|
||||
// When using the host C library resolver, at most one result will be
|
||||
// returned. To bypass the host resolver, use a custom Resolver.
|
||||
func LookupAddr(addr string) (names []string, err error) {
|
||||
- return DefaultResolver.lookupAddr(context.Background(), addr)
|
||||
+ return DefaultResolver.LookupAddr(context.Background(), addr)
|
||||
}
|
||||
|
||||
// LookupAddr performs a reverse lookup for the given address, returning a list
|
||||
// of names mapping to that address.
|
||||
-func (r *Resolver) LookupAddr(ctx context.Context, addr string) (names []string, err error) {
|
||||
- return r.lookupAddr(ctx, addr)
|
||||
+//
|
||||
+// The returned names are validated to be properly formatted presentation-format
|
||||
+// domain names.
|
||||
+func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) {
|
||||
+ names, err := r.lookupAddr(ctx, addr)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ for _, name := range names {
|
||||
+ if !isDomainName(name) {
|
||||
+ return nil, &DNSError{Err: "PTR target is invalid", Name: addr}
|
||||
+ }
|
||||
+ }
|
||||
+ return names, nil
|
||||
}
|
||||
113
meta/recipes-devtools/go/go-1.14/CVE-2021-33198.patch
Normal file
113
meta/recipes-devtools/go/go-1.14/CVE-2021-33198.patch
Normal file
@@ -0,0 +1,113 @@
|
||||
From c8866491ac424cdf39aedb325e6dec9e54418cfb Mon Sep 17 00:00:00 2001
|
||||
From: Robert Griesemer <gri@golang.org>
|
||||
Date: Sun, 2 May 2021 11:27:03 -0700
|
||||
Subject: [PATCH] math/big: check for excessive exponents in Rat.SetString
|
||||
|
||||
CVE-2021-33198
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/df9ce19db6df32d94eae8760927bdfbc595433c3]
|
||||
CVE: CVE-2021-33198
|
||||
Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
|
||||
|
||||
|
||||
Found by OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33284
|
||||
|
||||
Thanks to Emmanuel Odeke for reporting this issue.
|
||||
|
||||
Updates #45910
|
||||
Fixes #46305
|
||||
Fixes CVE-2021-33198
|
||||
|
||||
Change-Id: I61e7b04dbd80343420b57eede439e361c0f7b79c
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/316149
|
||||
Trust: Robert Griesemer <gri@golang.org>
|
||||
Trust: Katie Hockman <katie@golang.org>
|
||||
Run-TryBot: Robert Griesemer <gri@golang.org>
|
||||
TryBot-Result: Go Bot <gobot@golang.org>
|
||||
Reviewed-by: Katie Hockman <katie@golang.org>
|
||||
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
|
||||
(cherry picked from commit 6c591f79b0b5327549bd4e94970f7a279efb4ab0)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/321831
|
||||
Run-TryBot: Katie Hockman <katie@golang.org>
|
||||
Reviewed-by: Roland Shoemaker <roland@golang.org>
|
||||
---
|
||||
src/math/big/ratconv.go | 15 ++++++++-------
|
||||
src/math/big/ratconv_test.go | 25 +++++++++++++++++++++++++
|
||||
2 files changed, 33 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go
|
||||
index e8cbdbe..90053a9 100644
|
||||
--- a/src/math/big/ratconv.go
|
||||
+++ b/src/math/big/ratconv.go
|
||||
@@ -51,7 +51,8 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
|
||||
// An optional base-10 ``e'' or base-2 ``p'' (or their upper-case variants)
|
||||
// exponent may be provided as well, except for hexadecimal floats which
|
||||
// only accept an (optional) ``p'' exponent (because an ``e'' or ``E'' cannot
|
||||
-// be distinguished from a mantissa digit).
|
||||
+// be distinguished from a mantissa digit). If the exponent's absolute value
|
||||
+// is too large, the operation may fail.
|
||||
// The entire string, not just a prefix, must be valid for success. If the
|
||||
// operation failed, the value of z is undefined but the returned value is nil.
|
||||
func (z *Rat) SetString(s string) (*Rat, bool) {
|
||||
@@ -174,6 +175,9 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
+ if n > 1e6 {
|
||||
+ return nil, false // avoid excessively large exponents
|
||||
+ }
|
||||
pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs
|
||||
if exp5 > 0 {
|
||||
z.a.abs = z.a.abs.mul(z.a.abs, pow5)
|
||||
@@ -186,15 +190,12 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
|
||||
}
|
||||
|
||||
// apply exp2 contributions
|
||||
+ if exp2 < -1e7 || exp2 > 1e7 {
|
||||
+ return nil, false // avoid excessively large exponents
|
||||
+ }
|
||||
if exp2 > 0 {
|
||||
- if int64(uint(exp2)) != exp2 {
|
||||
- panic("exponent too large")
|
||||
- }
|
||||
z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2))
|
||||
} else if exp2 < 0 {
|
||||
- if int64(uint(-exp2)) != -exp2 {
|
||||
- panic("exponent too large")
|
||||
- }
|
||||
z.b.abs = z.b.abs.shl(z.b.abs, uint(-exp2))
|
||||
}
|
||||
|
||||
diff --git a/src/math/big/ratconv_test.go b/src/math/big/ratconv_test.go
|
||||
index b820df4..e55e655 100644
|
||||
--- a/src/math/big/ratconv_test.go
|
||||
+++ b/src/math/big/ratconv_test.go
|
||||
@@ -590,3 +590,28 @@ func TestIssue31184(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+func TestIssue45910(t *testing.T) {
|
||||
+ var x Rat
|
||||
+ for _, test := range []struct {
|
||||
+ input string
|
||||
+ want bool
|
||||
+ }{
|
||||
+ {"1e-1000001", false},
|
||||
+ {"1e-1000000", true},
|
||||
+ {"1e+1000000", true},
|
||||
+ {"1e+1000001", false},
|
||||
+
|
||||
+ {"0p1000000000000", true},
|
||||
+ {"1p-10000001", false},
|
||||
+ {"1p-10000000", true},
|
||||
+ {"1p+10000000", true},
|
||||
+ {"1p+10000001", false},
|
||||
+ {"1.770p02041010010011001001", false}, // test case from issue
|
||||
+ } {
|
||||
+ _, got := x.SetString(test.input)
|
||||
+ if got != test.want {
|
||||
+ t.Errorf("SetString(%s) got ok = %v; want %v", test.input, got, test.want)
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
93
meta/recipes-devtools/go/go-1.14/CVE-2021-44716.patch
Normal file
93
meta/recipes-devtools/go/go-1.14/CVE-2021-44716.patch
Normal file
@@ -0,0 +1,93 @@
|
||||
From 9f1860075990e7bf908ca7cc329d1d3ef91741c8 Mon Sep 17 00:00:00 2001
|
||||
From: Filippo Valsorda <filippo@golang.org>
|
||||
Date: Thu, 9 Dec 2021 06:13:31 -0500
|
||||
Subject: [PATCH] net/http: update bundled golang.org/x/net/http2
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/d0aebe3e74fe14799f97ddd3f01129697c6a290a]
|
||||
CVE: CVE-2021-44716
|
||||
Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
|
||||
|
||||
|
||||
Pull in security fix
|
||||
|
||||
a5309b3 http2: cap the size of the server's canonical header cache
|
||||
|
||||
Updates #50058
|
||||
Fixes CVE-2021-44716
|
||||
|
||||
Change-Id: Ifdd13f97fce168de5fb4b2e74ef2060d059800b9
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/370575
|
||||
Trust: Filippo Valsorda <filippo@golang.org>
|
||||
Run-TryBot: Filippo Valsorda <filippo@golang.org>
|
||||
Reviewed-by: Alex Rakoczy <alex@golang.org>
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
(cherry picked from commit d0aebe3e74fe14799f97ddd3f01129697c6a290a)
|
||||
---
|
||||
src/go.mod | 2 +-
|
||||
src/go.sum | 4 ++--
|
||||
src/net/http/h2_bundle.go | 10 +++++++++-
|
||||
src/vendor/modules.txt | 2 +-
|
||||
4 files changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/go.mod b/src/go.mod
|
||||
index ec6bd98..56f2fbb 100644
|
||||
--- a/src/go.mod
|
||||
+++ b/src/go.mod
|
||||
@@ -4,7 +4,7 @@ go 1.14
|
||||
|
||||
require (
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
|
||||
- golang.org/x/net v0.0.0-20210129194117-4acb7895a057
|
||||
+ golang.org/x/net v0.0.0-20211209100217-a5309b321dca
|
||||
golang.org/x/sys v0.0.0-20200201011859-915c9c3d4ccf // indirect
|
||||
golang.org/x/text v0.3.3-0.20191031172631-4b67af870c6f // indirect
|
||||
)
|
||||
diff --git a/src/go.sum b/src/go.sum
|
||||
index 171e083..1ceba05 100644
|
||||
--- a/src/go.sum
|
||||
+++ b/src/go.sum
|
||||
@@ -2,8 +2,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
|
||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
-golang.org/x/net v0.0.0-20210129194117-4acb7895a057 h1:HThQeV5c0Ab/Puir+q6mC97b7+3dfZdsLWMLoBrzo68=
|
||||
-golang.org/x/net v0.0.0-20210129194117-4acb7895a057/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
+golang.org/x/net v0.0.0-20211209100217-a5309b321dca h1:UmeWAm8AwB6NA/e4FSaGlK1EKTLXKX3utx4Si+6kfPg=
|
||||
+golang.org/x/net v0.0.0-20211209100217-a5309b321dca/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200201011859-915c9c3d4ccf h1:+4j7oujXP478CVb/AFvHJmVX5+Pczx2NGts5yirA0oY=
|
||||
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
|
||||
index 702fd5a..83f2a72 100644
|
||||
--- a/src/net/http/h2_bundle.go
|
||||
+++ b/src/net/http/h2_bundle.go
|
||||
@@ -4293,7 +4293,15 @@ func (sc *http2serverConn) canonicalHeader(v string) string {
|
||||
sc.canonHeader = make(map[string]string)
|
||||
}
|
||||
cv = CanonicalHeaderKey(v)
|
||||
- sc.canonHeader[v] = cv
|
||||
+ // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of
|
||||
+ // entries in the canonHeader cache. This should be larger than the number
|
||||
+ // of unique, uncommon header keys likely to be sent by the peer, while not
|
||||
+ // so high as to permit unreaasonable memory usage if the peer sends an unbounded
|
||||
+ // number of unique header keys.
|
||||
+ const maxCachedCanonicalHeaders = 32
|
||||
+ if len(sc.canonHeader) < maxCachedCanonicalHeaders {
|
||||
+ sc.canonHeader[v] = cv
|
||||
+ }
|
||||
return cv
|
||||
}
|
||||
|
||||
diff --git a/src/vendor/modules.txt b/src/vendor/modules.txt
|
||||
index 669bd9b..1d67183 100644
|
||||
--- a/src/vendor/modules.txt
|
||||
+++ b/src/vendor/modules.txt
|
||||
@@ -8,7 +8,7 @@ golang.org/x/crypto/curve25519
|
||||
golang.org/x/crypto/hkdf
|
||||
golang.org/x/crypto/internal/subtle
|
||||
golang.org/x/crypto/poly1305
|
||||
-# golang.org/x/net v0.0.0-20210129194117-4acb7895a057
|
||||
+# golang.org/x/net v0.0.0-20211209100217-a5309b321dca
|
||||
## explicit
|
||||
golang.org/x/net/dns/dnsmessage
|
||||
golang.org/x/net/http/httpguts
|
||||
198
meta/recipes-devtools/go/go-1.14/CVE-2022-24921.patch
Normal file
198
meta/recipes-devtools/go/go-1.14/CVE-2022-24921.patch
Normal file
@@ -0,0 +1,198 @@
|
||||
From ba99f699d26483ea1045f47c760e9be30799e311 Mon Sep 17 00:00:00 2001
|
||||
From: Russ Cox <rsc@golang.org>
|
||||
Date: Wed, 2 Feb 2022 16:41:32 -0500
|
||||
Subject: [PATCH] regexp/syntax: reject very deeply nested regexps in Parse
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/2b65cde5868d8245ef8a0b8eba1e361440252d3b]
|
||||
CVE: CVE-2022-24921
|
||||
Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org
|
||||
|
||||
|
||||
The regexp code assumes it can recurse over the structure of
|
||||
a regexp safely. Go's growable stacks make that reasonable
|
||||
for all plausible regexps, but implausible ones can reach the
|
||||
“infinite recursion?” stack limit.
|
||||
|
||||
This CL limits the depth of any parsed regexp to 1000.
|
||||
That is, the depth of the parse tree is required to be ≤ 1000.
|
||||
Regexps that require deeper parse trees will return ErrInternalError.
|
||||
A future CL will change the error to ErrInvalidDepth,
|
||||
but using ErrInternalError for now avoids introducing new API
|
||||
in point releases when this is backported.
|
||||
|
||||
Fixes #51112.
|
||||
Fixes #51117.
|
||||
|
||||
Change-Id: I97d2cd82195946eb43a4ea8561f5b95f91fb14c5
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/384616
|
||||
Trust: Russ Cox <rsc@golang.org>
|
||||
Run-TryBot: Russ Cox <rsc@golang.org>
|
||||
Reviewed-by: Ian Lance Taylor <iant@golang.org>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/384855
|
||||
---
|
||||
src/regexp/syntax/parse.go | 72 ++++++++++++++++++++++++++++++++-
|
||||
src/regexp/syntax/parse_test.go | 7 ++++
|
||||
2 files changed, 77 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/regexp/syntax/parse.go b/src/regexp/syntax/parse.go
|
||||
index 8c6d43a..55bd20d 100644
|
||||
--- a/src/regexp/syntax/parse.go
|
||||
+++ b/src/regexp/syntax/parse.go
|
||||
@@ -76,13 +76,29 @@ const (
|
||||
opVerticalBar
|
||||
)
|
||||
|
||||
+// maxHeight is the maximum height of a regexp parse tree.
|
||||
+// It is somewhat arbitrarily chosen, but the idea is to be large enough
|
||||
+// that no one will actually hit in real use but at the same time small enough
|
||||
+// that recursion on the Regexp tree will not hit the 1GB Go stack limit.
|
||||
+// The maximum amount of stack for a single recursive frame is probably
|
||||
+// closer to 1kB, so this could potentially be raised, but it seems unlikely
|
||||
+// that people have regexps nested even this deeply.
|
||||
+// We ran a test on Google's C++ code base and turned up only
|
||||
+// a single use case with depth > 100; it had depth 128.
|
||||
+// Using depth 1000 should be plenty of margin.
|
||||
+// As an optimization, we don't even bother calculating heights
|
||||
+// until we've allocated at least maxHeight Regexp structures.
|
||||
+const maxHeight = 1000
|
||||
+
|
||||
type parser struct {
|
||||
flags Flags // parse mode flags
|
||||
stack []*Regexp // stack of parsed expressions
|
||||
free *Regexp
|
||||
numCap int // number of capturing groups seen
|
||||
wholeRegexp string
|
||||
- tmpClass []rune // temporary char class work space
|
||||
+ tmpClass []rune // temporary char class work space
|
||||
+ numRegexp int // number of regexps allocated
|
||||
+ height map[*Regexp]int // regexp height for height limit check
|
||||
}
|
||||
|
||||
func (p *parser) newRegexp(op Op) *Regexp {
|
||||
@@ -92,16 +108,52 @@ func (p *parser) newRegexp(op Op) *Regexp {
|
||||
*re = Regexp{}
|
||||
} else {
|
||||
re = new(Regexp)
|
||||
+ p.numRegexp++
|
||||
}
|
||||
re.Op = op
|
||||
return re
|
||||
}
|
||||
|
||||
func (p *parser) reuse(re *Regexp) {
|
||||
+ if p.height != nil {
|
||||
+ delete(p.height, re)
|
||||
+ }
|
||||
re.Sub0[0] = p.free
|
||||
p.free = re
|
||||
}
|
||||
|
||||
+func (p *parser) checkHeight(re *Regexp) {
|
||||
+ if p.numRegexp < maxHeight {
|
||||
+ return
|
||||
+ }
|
||||
+ if p.height == nil {
|
||||
+ p.height = make(map[*Regexp]int)
|
||||
+ for _, re := range p.stack {
|
||||
+ p.checkHeight(re)
|
||||
+ }
|
||||
+ }
|
||||
+ if p.calcHeight(re, true) > maxHeight {
|
||||
+ panic(ErrInternalError)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func (p *parser) calcHeight(re *Regexp, force bool) int {
|
||||
+ if !force {
|
||||
+ if h, ok := p.height[re]; ok {
|
||||
+ return h
|
||||
+ }
|
||||
+ }
|
||||
+ h := 1
|
||||
+ for _, sub := range re.Sub {
|
||||
+ hsub := p.calcHeight(sub, false)
|
||||
+ if h < 1+hsub {
|
||||
+ h = 1 + hsub
|
||||
+ }
|
||||
+ }
|
||||
+ p.height[re] = h
|
||||
+ return h
|
||||
+}
|
||||
+
|
||||
// Parse stack manipulation.
|
||||
|
||||
// push pushes the regexp re onto the parse stack and returns the regexp.
|
||||
@@ -137,6 +189,7 @@ func (p *parser) push(re *Regexp) *Regexp {
|
||||
}
|
||||
|
||||
p.stack = append(p.stack, re)
|
||||
+ p.checkHeight(re)
|
||||
return re
|
||||
}
|
||||
|
||||
@@ -252,6 +305,7 @@ func (p *parser) repeat(op Op, min, max int, before, after, lastRepeat string) (
|
||||
re.Sub = re.Sub0[:1]
|
||||
re.Sub[0] = sub
|
||||
p.stack[n-1] = re
|
||||
+ p.checkHeight(re)
|
||||
|
||||
if op == OpRepeat && (min >= 2 || max >= 2) && !repeatIsValid(re, 1000) {
|
||||
return "", &Error{ErrInvalidRepeatSize, before[:len(before)-len(after)]}
|
||||
@@ -699,6 +753,21 @@ func literalRegexp(s string, flags Flags) *Regexp {
|
||||
// Flags, and returns a regular expression parse tree. The syntax is
|
||||
// described in the top-level comment.
|
||||
func Parse(s string, flags Flags) (*Regexp, error) {
|
||||
+ return parse(s, flags)
|
||||
+}
|
||||
+
|
||||
+func parse(s string, flags Flags) (_ *Regexp, err error) {
|
||||
+ defer func() {
|
||||
+ switch r := recover(); r {
|
||||
+ default:
|
||||
+ panic(r)
|
||||
+ case nil:
|
||||
+ // ok
|
||||
+ case ErrInternalError:
|
||||
+ err = &Error{Code: ErrInternalError, Expr: s}
|
||||
+ }
|
||||
+ }()
|
||||
+
|
||||
if flags&Literal != 0 {
|
||||
// Trivial parser for literal string.
|
||||
if err := checkUTF8(s); err != nil {
|
||||
@@ -710,7 +779,6 @@ func Parse(s string, flags Flags) (*Regexp, error) {
|
||||
// Otherwise, must do real work.
|
||||
var (
|
||||
p parser
|
||||
- err error
|
||||
c rune
|
||||
op Op
|
||||
lastRepeat string
|
||||
diff --git a/src/regexp/syntax/parse_test.go b/src/regexp/syntax/parse_test.go
|
||||
index 5581ba1..1ef6d8a 100644
|
||||
--- a/src/regexp/syntax/parse_test.go
|
||||
+++ b/src/regexp/syntax/parse_test.go
|
||||
@@ -207,6 +207,11 @@ var parseTests = []parseTest{
|
||||
// Valid repetitions.
|
||||
{`((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}))`, ``},
|
||||
{`((((((((((x{1}){2}){2}){2}){2}){2}){2}){2}){2}){2})`, ``},
|
||||
+
|
||||
+ // Valid nesting.
|
||||
+ {strings.Repeat("(", 999) + strings.Repeat(")", 999), ``},
|
||||
+ {strings.Repeat("(?:", 999) + strings.Repeat(")*", 999), ``},
|
||||
+ {"(" + strings.Repeat("|", 12345) + ")", ``}, // not nested at all
|
||||
}
|
||||
|
||||
const testFlags = MatchNL | PerlX | UnicodeGroups
|
||||
@@ -482,6 +487,8 @@ var invalidRegexps = []string{
|
||||
`a{100000}`,
|
||||
`a{100000,}`,
|
||||
"((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}){2})",
|
||||
+ strings.Repeat("(", 1000) + strings.Repeat(")", 1000),
|
||||
+ strings.Repeat("(?:", 1000) + strings.Repeat(")*", 1000),
|
||||
`\Q\E*`,
|
||||
}
|
||||
|
||||
104
meta/recipes-devtools/go/go-1.14/CVE-2022-28131.patch
Normal file
104
meta/recipes-devtools/go/go-1.14/CVE-2022-28131.patch
Normal file
@@ -0,0 +1,104 @@
|
||||
From 8136eb2e5c316a51d0da710fbd0504cbbefee526 Mon Sep 17 00:00:00 2001
|
||||
From: Roland Shoemaker <roland@golang.org>
|
||||
Date: Mon, 28 Mar 2022 18:41:26 -0700
|
||||
Subject: [PATCH] encoding/xml: use iterative Skip, rather than recursive
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/58facfbe7db2fbb9afed794b281a70bdb12a60ae]
|
||||
CVE: CVE-2022-28131
|
||||
Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
|
||||
|
||||
|
||||
Prevents exhausting the stack limit in _incredibly_ deeply nested
|
||||
structures.
|
||||
|
||||
Fixes #53711
|
||||
Updates #53614
|
||||
Fixes CVE-2022-28131
|
||||
|
||||
Change-Id: I47db4595ce10cecc29fbd06afce7b299868599e6
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1419912
|
||||
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
(cherry picked from commit 9278cb78443d2b4deb24cbb5b61c9ba5ac688d49)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/417068
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Reviewed-by: Heschi Kreinick <heschi@google.com>
|
||||
Run-TryBot: Michael Knyszek <mknyszek@google.com>
|
||||
---
|
||||
src/encoding/xml/read.go | 15 ++++++++-------
|
||||
src/encoding/xml/read_test.go | 18 ++++++++++++++++++
|
||||
2 files changed, 26 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/encoding/xml/read.go b/src/encoding/xml/read.go
|
||||
index 4ffed80..3fac859 100644
|
||||
--- a/src/encoding/xml/read.go
|
||||
+++ b/src/encoding/xml/read.go
|
||||
@@ -743,12 +743,12 @@ Loop:
|
||||
}
|
||||
|
||||
// Skip reads tokens until it has consumed the end element
|
||||
-// matching the most recent start element already consumed.
|
||||
-// It recurs if it encounters a start element, so it can be used to
|
||||
-// skip nested structures.
|
||||
+// matching the most recent start element already consumed,
|
||||
+// skipping nested structures.
|
||||
// It returns nil if it finds an end element matching the start
|
||||
// element; otherwise it returns an error describing the problem.
|
||||
func (d *Decoder) Skip() error {
|
||||
+ var depth int64
|
||||
for {
|
||||
tok, err := d.Token()
|
||||
if err != nil {
|
||||
@@ -756,11 +756,12 @@ func (d *Decoder) Skip() error {
|
||||
}
|
||||
switch tok.(type) {
|
||||
case StartElement:
|
||||
- if err := d.Skip(); err != nil {
|
||||
- return err
|
||||
- }
|
||||
+ depth++
|
||||
case EndElement:
|
||||
- return nil
|
||||
+ if depth == 0 {
|
||||
+ return nil
|
||||
+ }
|
||||
+ depth--
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/encoding/xml/read_test.go b/src/encoding/xml/read_test.go
|
||||
index 6a20b1a..7a621a5 100644
|
||||
--- a/src/encoding/xml/read_test.go
|
||||
+++ b/src/encoding/xml/read_test.go
|
||||
@@ -5,9 +5,11 @@
|
||||
package xml
|
||||
|
||||
import (
|
||||
+ "bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"reflect"
|
||||
+ "runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -1093,3 +1095,19 @@ func TestCVE202228131(t *testing.T) {
|
||||
t.Fatalf("Unmarshal unexpected error: got %q, want %q", err, errExeceededMaxUnmarshalDepth)
|
||||
}
|
||||
}
|
||||
+
|
||||
+func TestCVE202230633(t *testing.T) {
|
||||
+ if runtime.GOARCH == "wasm" {
|
||||
+ t.Skip("causes memory exhaustion on js/wasm")
|
||||
+ }
|
||||
+ defer func() {
|
||||
+ p := recover()
|
||||
+ if p != nil {
|
||||
+ t.Fatal("Unmarshal panicked")
|
||||
+ }
|
||||
+ }()
|
||||
+ var example struct {
|
||||
+ Things []string
|
||||
+ }
|
||||
+ Unmarshal(bytes.Repeat([]byte("<a>"), 17_000_000), &example)
|
||||
+}
|
||||
36
meta/recipes-devtools/go/go-1.14/CVE-2022-28327.patch
Normal file
36
meta/recipes-devtools/go/go-1.14/CVE-2022-28327.patch
Normal file
@@ -0,0 +1,36 @@
|
||||
From 34d9ab78568d63d8097911237897b188bdaba9c2 Mon Sep 17 00:00:00 2001
|
||||
From: Filippo Valsorda <filippo@golang.org>
|
||||
Date: Thu, 31 Mar 2022 12:31:58 -0400
|
||||
Subject: [PATCH] crypto/elliptic: tolerate zero-padded scalars in generic
|
||||
P-256
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/7139e8b024604ab168b51b99c6e8168257a5bf58]
|
||||
CVE: CVE-2022-28327
|
||||
Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
|
||||
|
||||
|
||||
Updates #52075
|
||||
Fixes #52076
|
||||
Fixes CVE-2022-28327
|
||||
|
||||
Change-Id: I595a7514c9a0aa1b9c76aedfc2307e1124271f27
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/397136
|
||||
Trust: Filippo Valsorda <filippo@golang.org>
|
||||
Reviewed-by: Julie Qiu <julie@golang.org>
|
||||
---
|
||||
src/crypto/elliptic/p256.go | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/crypto/elliptic/p256.go b/src/crypto/elliptic/p256.go
|
||||
index c23e414..787e3e7 100644
|
||||
--- a/src/crypto/elliptic/p256.go
|
||||
+++ b/src/crypto/elliptic/p256.go
|
||||
@@ -51,7 +51,7 @@ func p256GetScalar(out *[32]byte, in []byte) {
|
||||
n := new(big.Int).SetBytes(in)
|
||||
var scalarBytes []byte
|
||||
|
||||
- if n.Cmp(p256Params.N) >= 0 {
|
||||
+ if n.Cmp(p256Params.N) >= 0 || len(in) > len(out) {
|
||||
n.Mod(n, p256Params.N)
|
||||
scalarBytes = n.Bytes()
|
||||
} else {
|
||||
271
meta/recipes-devtools/go/go-1.14/CVE-2022-41715.patch
Normal file
271
meta/recipes-devtools/go/go-1.14/CVE-2022-41715.patch
Normal file
@@ -0,0 +1,271 @@
|
||||
From e9017c2416ad0ef642f5e0c2eab2dbf3cba4d997 Mon Sep 17 00:00:00 2001
|
||||
From: Russ Cox <rsc@golang.org>
|
||||
Date: Wed, 28 Sep 2022 11:18:51 -0400
|
||||
Subject: [PATCH] [release-branch.go1.18] regexp: limit size of parsed regexps
|
||||
|
||||
Set a 128 MB limit on the amount of space used by []syntax.Inst
|
||||
in the compiled form corresponding to a given regexp.
|
||||
|
||||
Also set a 128 MB limit on the rune storage in the *syntax.Regexp
|
||||
tree itself.
|
||||
|
||||
Thanks to Adam Korczynski (ADA Logics) and OSS-Fuzz for reporting this issue.
|
||||
|
||||
Fixes CVE-2022-41715.
|
||||
Updates #55949.
|
||||
Fixes #55950.
|
||||
|
||||
Change-Id: Ia656baed81564436368cf950e1c5409752f28e1b
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1592136
|
||||
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
||||
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/438501
|
||||
Run-TryBot: Carlos Amedee <carlos@golang.org>
|
||||
Reviewed-by: Carlos Amedee <carlos@golang.org>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/e9017c2416ad0ef642f5e0c2eab2dbf3cba4d997]
|
||||
CVE: CVE-2022-41715
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
|
||||
---
|
||||
src/regexp/syntax/parse.go | 145 ++++++++++++++++++++++++++++++--
|
||||
src/regexp/syntax/parse_test.go | 13 +--
|
||||
2 files changed, 148 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/src/regexp/syntax/parse.go b/src/regexp/syntax/parse.go
|
||||
index 55bd20d..60491d5 100644
|
||||
--- a/src/regexp/syntax/parse.go
|
||||
+++ b/src/regexp/syntax/parse.go
|
||||
@@ -90,15 +90,49 @@ const (
|
||||
// until we've allocated at least maxHeight Regexp structures.
|
||||
const maxHeight = 1000
|
||||
|
||||
+// maxSize is the maximum size of a compiled regexp in Insts.
|
||||
+// It too is somewhat arbitrarily chosen, but the idea is to be large enough
|
||||
+// to allow significant regexps while at the same time small enough that
|
||||
+// the compiled form will not take up too much memory.
|
||||
+// 128 MB is enough for a 3.3 million Inst structures, which roughly
|
||||
+// corresponds to a 3.3 MB regexp.
|
||||
+const (
|
||||
+ maxSize = 128 << 20 / instSize
|
||||
+ instSize = 5 * 8 // byte, 2 uint32, slice is 5 64-bit words
|
||||
+)
|
||||
+
|
||||
+// maxRunes is the maximum number of runes allowed in a regexp tree
|
||||
+// counting the runes in all the nodes.
|
||||
+// Ignoring character classes p.numRunes is always less than the length of the regexp.
|
||||
+// Character classes can make it much larger: each \pL adds 1292 runes.
|
||||
+// 128 MB is enough for 32M runes, which is over 26k \pL instances.
|
||||
+// Note that repetitions do not make copies of the rune slices,
|
||||
+// so \pL{1000} is only one rune slice, not 1000.
|
||||
+// We could keep a cache of character classes we've seen,
|
||||
+// so that all the \pL we see use the same rune list,
|
||||
+// but that doesn't remove the problem entirely:
|
||||
+// consider something like [\pL01234][\pL01235][\pL01236]...[\pL^&*()].
|
||||
+// And because the Rune slice is exposed directly in the Regexp,
|
||||
+// there is not an opportunity to change the representation to allow
|
||||
+// partial sharing between different character classes.
|
||||
+// So the limit is the best we can do.
|
||||
+const (
|
||||
+ maxRunes = 128 << 20 / runeSize
|
||||
+ runeSize = 4 // rune is int32
|
||||
+)
|
||||
+
|
||||
type parser struct {
|
||||
flags Flags // parse mode flags
|
||||
stack []*Regexp // stack of parsed expressions
|
||||
free *Regexp
|
||||
numCap int // number of capturing groups seen
|
||||
wholeRegexp string
|
||||
- tmpClass []rune // temporary char class work space
|
||||
- numRegexp int // number of regexps allocated
|
||||
- height map[*Regexp]int // regexp height for height limit check
|
||||
+ tmpClass []rune // temporary char class work space
|
||||
+ numRegexp int // number of regexps allocated
|
||||
+ numRunes int // number of runes in char classes
|
||||
+ repeats int64 // product of all repetitions seen
|
||||
+ height map[*Regexp]int // regexp height, for height limit check
|
||||
+ size map[*Regexp]int64 // regexp compiled size, for size limit check
|
||||
}
|
||||
|
||||
func (p *parser) newRegexp(op Op) *Regexp {
|
||||
@@ -122,6 +156,104 @@ func (p *parser) reuse(re *Regexp) {
|
||||
p.free = re
|
||||
}
|
||||
|
||||
+func (p *parser) checkLimits(re *Regexp) {
|
||||
+ if p.numRunes > maxRunes {
|
||||
+ panic(ErrInternalError)
|
||||
+ }
|
||||
+ p.checkSize(re)
|
||||
+ p.checkHeight(re)
|
||||
+}
|
||||
+
|
||||
+func (p *parser) checkSize(re *Regexp) {
|
||||
+ if p.size == nil {
|
||||
+ // We haven't started tracking size yet.
|
||||
+ // Do a relatively cheap check to see if we need to start.
|
||||
+ // Maintain the product of all the repeats we've seen
|
||||
+ // and don't track if the total number of regexp nodes
|
||||
+ // we've seen times the repeat product is in budget.
|
||||
+ if p.repeats == 0 {
|
||||
+ p.repeats = 1
|
||||
+ }
|
||||
+ if re.Op == OpRepeat {
|
||||
+ n := re.Max
|
||||
+ if n == -1 {
|
||||
+ n = re.Min
|
||||
+ }
|
||||
+ if n <= 0 {
|
||||
+ n = 1
|
||||
+ }
|
||||
+ if int64(n) > maxSize/p.repeats {
|
||||
+ p.repeats = maxSize
|
||||
+ } else {
|
||||
+ p.repeats *= int64(n)
|
||||
+ }
|
||||
+ }
|
||||
+ if int64(p.numRegexp) < maxSize/p.repeats {
|
||||
+ return
|
||||
+ }
|
||||
+
|
||||
+ // We need to start tracking size.
|
||||
+ // Make the map and belatedly populate it
|
||||
+ // with info about everything we've constructed so far.
|
||||
+ p.size = make(map[*Regexp]int64)
|
||||
+ for _, re := range p.stack {
|
||||
+ p.checkSize(re)
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if p.calcSize(re, true) > maxSize {
|
||||
+ panic(ErrInternalError)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func (p *parser) calcSize(re *Regexp, force bool) int64 {
|
||||
+ if !force {
|
||||
+ if size, ok := p.size[re]; ok {
|
||||
+ return size
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ var size int64
|
||||
+ switch re.Op {
|
||||
+ case OpLiteral:
|
||||
+ size = int64(len(re.Rune))
|
||||
+ case OpCapture, OpStar:
|
||||
+ // star can be 1+ or 2+; assume 2 pessimistically
|
||||
+ size = 2 + p.calcSize(re.Sub[0], false)
|
||||
+ case OpPlus, OpQuest:
|
||||
+ size = 1 + p.calcSize(re.Sub[0], false)
|
||||
+ case OpConcat:
|
||||
+ for _, sub := range re.Sub {
|
||||
+ size += p.calcSize(sub, false)
|
||||
+ }
|
||||
+ case OpAlternate:
|
||||
+ for _, sub := range re.Sub {
|
||||
+ size += p.calcSize(sub, false)
|
||||
+ }
|
||||
+ if len(re.Sub) > 1 {
|
||||
+ size += int64(len(re.Sub)) - 1
|
||||
+ }
|
||||
+ case OpRepeat:
|
||||
+ sub := p.calcSize(re.Sub[0], false)
|
||||
+ if re.Max == -1 {
|
||||
+ if re.Min == 0 {
|
||||
+ size = 2 + sub // x*
|
||||
+ } else {
|
||||
+ size = 1 + int64(re.Min)*sub // xxx+
|
||||
+ }
|
||||
+ break
|
||||
+ }
|
||||
+ // x{2,5} = xx(x(x(x)?)?)?
|
||||
+ size = int64(re.Max)*sub + int64(re.Max-re.Min)
|
||||
+ }
|
||||
+
|
||||
+ if size < 1 {
|
||||
+ size = 1
|
||||
+ }
|
||||
+ p.size[re] = size
|
||||
+ return size
|
||||
+}
|
||||
+
|
||||
func (p *parser) checkHeight(re *Regexp) {
|
||||
if p.numRegexp < maxHeight {
|
||||
return
|
||||
@@ -158,6 +290,7 @@ func (p *parser) calcHeight(re *Regexp, force bool) int {
|
||||
|
||||
// push pushes the regexp re onto the parse stack and returns the regexp.
|
||||
func (p *parser) push(re *Regexp) *Regexp {
|
||||
+ p.numRunes += len(re.Rune)
|
||||
if re.Op == OpCharClass && len(re.Rune) == 2 && re.Rune[0] == re.Rune[1] {
|
||||
// Single rune.
|
||||
if p.maybeConcat(re.Rune[0], p.flags&^FoldCase) {
|
||||
@@ -189,7 +322,7 @@ func (p *parser) push(re *Regexp) *Regexp {
|
||||
}
|
||||
|
||||
p.stack = append(p.stack, re)
|
||||
- p.checkHeight(re)
|
||||
+ p.checkLimits(re)
|
||||
return re
|
||||
}
|
||||
|
||||
@@ -305,7 +438,7 @@ func (p *parser) repeat(op Op, min, max int, before, after, lastRepeat string) (
|
||||
re.Sub = re.Sub0[:1]
|
||||
re.Sub[0] = sub
|
||||
p.stack[n-1] = re
|
||||
- p.checkHeight(re)
|
||||
+ p.checkLimits(re)
|
||||
|
||||
if op == OpRepeat && (min >= 2 || max >= 2) && !repeatIsValid(re, 1000) {
|
||||
return "", &Error{ErrInvalidRepeatSize, before[:len(before)-len(after)]}
|
||||
@@ -509,6 +642,7 @@ func (p *parser) factor(sub []*Regexp) []*Regexp {
|
||||
|
||||
for j := start; j < i; j++ {
|
||||
sub[j] = p.removeLeadingString(sub[j], len(str))
|
||||
+ p.checkLimits(sub[j])
|
||||
}
|
||||
suffix := p.collapse(sub[start:i], OpAlternate) // recurse
|
||||
|
||||
@@ -566,6 +700,7 @@ func (p *parser) factor(sub []*Regexp) []*Regexp {
|
||||
for j := start; j < i; j++ {
|
||||
reuse := j != start // prefix came from sub[start]
|
||||
sub[j] = p.removeLeadingRegexp(sub[j], reuse)
|
||||
+ p.checkLimits(sub[j])
|
||||
}
|
||||
suffix := p.collapse(sub[start:i], OpAlternate) // recurse
|
||||
|
||||
diff --git a/src/regexp/syntax/parse_test.go b/src/regexp/syntax/parse_test.go
|
||||
index 1ef6d8a..67e3c56 100644
|
||||
--- a/src/regexp/syntax/parse_test.go
|
||||
+++ b/src/regexp/syntax/parse_test.go
|
||||
@@ -484,12 +484,15 @@ var invalidRegexps = []string{
|
||||
`(?P<>a)`,
|
||||
`[a-Z]`,
|
||||
`(?i)[a-Z]`,
|
||||
- `a{100000}`,
|
||||
- `a{100000,}`,
|
||||
- "((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}){2})",
|
||||
- strings.Repeat("(", 1000) + strings.Repeat(")", 1000),
|
||||
- strings.Repeat("(?:", 1000) + strings.Repeat(")*", 1000),
|
||||
`\Q\E*`,
|
||||
+ `a{100000}`, // too much repetition
|
||||
+ `a{100000,}`, // too much repetition
|
||||
+ "((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}){2})", // too much repetition
|
||||
+ strings.Repeat("(", 1000) + strings.Repeat(")", 1000), // too deep
|
||||
+ strings.Repeat("(?:", 1000) + strings.Repeat(")*", 1000), // too deep
|
||||
+ "(" + strings.Repeat("(xx?)", 1000) + "){1000}", // too long
|
||||
+ strings.Repeat("(xx?){1000}", 1000), // too long
|
||||
+ strings.Repeat(`\pL`, 27000), // too many runes
|
||||
}
|
||||
|
||||
var onlyPerl = []string{
|
||||
--
|
||||
2.25.1
|
||||
|
||||
75
meta/recipes-devtools/go/go-1.14/CVE-2022-41717.patch
Normal file
75
meta/recipes-devtools/go/go-1.14/CVE-2022-41717.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
From 618120c165669c00a1606505defea6ca755cdc27 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Wed, 30 Nov 2022 16:46:33 -0500
|
||||
Subject: [PATCH] [release-branch.go1.19] net/http: update bundled
|
||||
golang.org/x/net/http2
|
||||
|
||||
Disable cmd/internal/moddeps test, since this update includes PRIVATE
|
||||
track fixes.
|
||||
|
||||
For #56350.
|
||||
For #57009.
|
||||
Fixes CVE-2022-41717.
|
||||
|
||||
Change-Id: I5c6ce546add81f361dcf0d5123fa4eaaf8f0a03b
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1663835
|
||||
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||
Reviewed-by: Julie Qiu <julieqiu@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/455363
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Run-TryBot: Jenny Rakoczy <jenny@golang.org>
|
||||
Reviewed-by: Michael Pratt <mpratt@google.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/618120c165669c00a1606505defea6ca755cdc27]
|
||||
CVE-2022-41717
|
||||
Signed-off-by: Vivek Kumbhar <vkumbhar@mvista.com>
|
||||
---
|
||||
src/net/http/h2_bundle.go | 18 +++++++++++-------
|
||||
1 file changed, 11 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
|
||||
index 83f2a72..cc03a62 100644
|
||||
--- a/src/net/http/h2_bundle.go
|
||||
+++ b/src/net/http/h2_bundle.go
|
||||
@@ -4096,6 +4096,7 @@ type http2serverConn struct {
|
||||
headerTableSize uint32
|
||||
peerMaxHeaderListSize uint32 // zero means unknown (default)
|
||||
canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
|
||||
+ canonHeaderKeysSize int // canonHeader keys size in bytes
|
||||
writingFrame bool // started writing a frame (on serve goroutine or separate)
|
||||
writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
|
||||
needsFrameFlush bool // last frame write wasn't a flush
|
||||
@@ -4278,6 +4279,13 @@ func (sc *http2serverConn) condlogf(err error, format string, args ...interface{
|
||||
}
|
||||
}
|
||||
|
||||
+// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
|
||||
+// of the entries in the canonHeader cache.
|
||||
+// This should be larger than the size of unique, uncommon header keys likely to
|
||||
+// be sent by the peer, while not so high as to permit unreasonable memory usage
|
||||
+// if the peer sends an unbounded number of unique header keys.
|
||||
+const http2maxCachedCanonicalHeadersKeysSize = 2048
|
||||
+
|
||||
func (sc *http2serverConn) canonicalHeader(v string) string {
|
||||
sc.serveG.check()
|
||||
http2buildCommonHeaderMapsOnce()
|
||||
@@ -4293,14 +4301,10 @@ func (sc *http2serverConn) canonicalHeader(v string) string {
|
||||
sc.canonHeader = make(map[string]string)
|
||||
}
|
||||
cv = CanonicalHeaderKey(v)
|
||||
- // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of
|
||||
- // entries in the canonHeader cache. This should be larger than the number
|
||||
- // of unique, uncommon header keys likely to be sent by the peer, while not
|
||||
- // so high as to permit unreaasonable memory usage if the peer sends an unbounded
|
||||
- // number of unique header keys.
|
||||
- const maxCachedCanonicalHeaders = 32
|
||||
- if len(sc.canonHeader) < maxCachedCanonicalHeaders {
|
||||
+ size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
|
||||
+ if sc.canonHeaderKeysSize+size <= http2maxCachedCanonicalHeadersKeysSize {
|
||||
sc.canonHeader[v] = cv
|
||||
+ sc.canonHeaderKeysSize += size
|
||||
}
|
||||
return cv
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user