mirror of
https://git.yoctoproject.org/poky
synced 2026-02-13 20:23:04 +01:00
Compare commits
101 Commits
yocto-3.1.
...
dunfell
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63d05fc061 | ||
|
|
7744221192 | ||
|
|
7d6f83abf0 | ||
|
|
99a2caf71e | ||
|
|
832b812ba8 | ||
|
|
9ab80eeb28 | ||
|
|
8afcb61e9b | ||
|
|
9e53801f46 | ||
|
|
30c2cb6ba4 | ||
|
|
b6f7111caf | ||
|
|
b027cb1af8 | ||
|
|
42694d5ea2 | ||
|
|
2e04c8f59a | ||
|
|
601f38e5cd | ||
|
|
50320bfdc8 | ||
|
|
7dafe710db | ||
|
|
f010cd7f24 | ||
|
|
dbb4e8a5cc | ||
|
|
ea68e06fa2 | ||
|
|
869db167b1 | ||
|
|
e555aefeef | ||
|
|
1c2fbec01f | ||
|
|
ad88f632b4 | ||
|
|
21a90afc6b | ||
|
|
a3e4d31c0c | ||
|
|
8226652389 | ||
|
|
e2ed3bde51 | ||
|
|
8031922706 | ||
|
|
ecc91377c2 | ||
|
|
7c67bd3dbe | ||
|
|
53afd9dc5b | ||
|
|
17634daabd | ||
|
|
8b77dd2bcf | ||
|
|
54d8a1f631 | ||
|
|
593cbdf6c3 | ||
|
|
4fd12fa20e | ||
|
|
b000e8b274 | ||
|
|
5fc659fd02 | ||
|
|
dee3046d2b | ||
|
|
6289654c30 | ||
|
|
9ba6ff6278 | ||
|
|
34ae492934 | ||
|
|
0e4ba103bb | ||
|
|
34a1dcf275 | ||
|
|
faec25f77c | ||
|
|
00aec91f57 | ||
|
|
6fc1eafd3b | ||
|
|
6c31f05df4 | ||
|
|
b110cd3d82 | ||
|
|
aa02dc871f | ||
|
|
c846f0d89c | ||
|
|
fa23359034 | ||
|
|
eb0915c699 | ||
|
|
5c5d9d5bcc | ||
|
|
1c77446c96 | ||
|
|
2c6b82aaf0 | ||
|
|
12fab85ba1 | ||
|
|
b22e4f002d | ||
|
|
a528dc22aa | ||
|
|
4bda99df75 | ||
|
|
70de5ee7d1 | ||
|
|
574b303503 | ||
|
|
bffa4f3051 | ||
|
|
9bf63ee197 | ||
|
|
3adc98348b | ||
|
|
8f7ce1acf7 | ||
|
|
a9e3cc3b9e | ||
|
|
378b447059 | ||
|
|
adfae38944 | ||
|
|
40c106bc61 | ||
|
|
acf1b57188 | ||
|
|
d9d1a730ae | ||
|
|
854aafaea4 | ||
|
|
7e3b27865d | ||
|
|
2f7e1a230e | ||
|
|
0948746aac | ||
|
|
5c5aa47adb | ||
|
|
b418ede994 | ||
|
|
dc5397b0f6 | ||
|
|
60b073d8c3 | ||
|
|
11a511fbc9 | ||
|
|
1a94a64268 | ||
|
|
982ab5d6d9 | ||
|
|
8873e8d033 | ||
|
|
bcf4caec9e | ||
|
|
a2bf2f28c4 | ||
|
|
c0e5370a91 | ||
|
|
e25b0dcc9e | ||
|
|
80cc03ec40 | ||
|
|
1de3816043 | ||
|
|
fc412fa80d | ||
|
|
0aa12e4919 | ||
|
|
3433d043c7 | ||
|
|
39aad83070 | ||
|
|
ef0c19babe | ||
|
|
6b9d89ec0b | ||
|
|
c7fbe91c2a | ||
|
|
3eda06c358 | ||
|
|
8efd61ccb1 | ||
|
|
43fa25ea6f | ||
|
|
f56b099225 |
@@ -15,6 +15,13 @@ import sys
|
||||
if sys.version_info < (3, 5, 0):
|
||||
raise RuntimeError("Sorry, python 3.5.0 or later is required for this version of bitbake")
|
||||
|
||||
if sys.version_info < (3, 10, 0):
|
||||
# With python 3.8 and 3.9, we see errors of "libgcc_s.so.1 must be installed for pthread_cancel to work"
|
||||
# https://stackoverflow.com/questions/64797838/libgcc-s-so-1-must-be-installed-for-pthread-cancel-to-work
|
||||
# https://bugs.ams1.psf.io/issue42888
|
||||
# so ensure libgcc_s is loaded early on
|
||||
import ctypes
|
||||
libgcc_s = ctypes.CDLL('libgcc_s.so.1')
|
||||
|
||||
class BBHandledException(Exception):
|
||||
"""
|
||||
|
||||
@@ -301,6 +301,7 @@ def build_dependencies(key, keys, shelldeps, varflagsexcl, d):
|
||||
value += "\n_remove of %s" % r
|
||||
deps |= r2.references
|
||||
deps = deps | (keys & r2.execs)
|
||||
value = handle_contains(value, r2.contains, d)
|
||||
return value
|
||||
|
||||
if "vardepvalue" in varflags:
|
||||
|
||||
@@ -412,6 +412,32 @@ esac
|
||||
# Check final value
|
||||
self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['anothervalue', 'yetanothervalue', 'lastone'])
|
||||
|
||||
def test_contains_vardeps_override_operators(self):
|
||||
# Check override operators handle dependencies correctly with the contains functionality
|
||||
expr_plain = 'testval'
|
||||
expr_prepend = '${@bb.utils.filter("TESTVAR1", "testval1", d)} '
|
||||
expr_append = ' ${@bb.utils.filter("TESTVAR2", "testval2", d)}'
|
||||
expr_remove = '${@bb.utils.contains("TESTVAR3", "no-testval", "testval", "", d)}'
|
||||
# Check dependencies
|
||||
self.d.setVar('ANOTHERVAR', expr_plain)
|
||||
self.d.prependVar('ANOTHERVAR', expr_prepend)
|
||||
self.d.appendVar('ANOTHERVAR', expr_append)
|
||||
self.d.setVar('ANOTHERVAR:remove', expr_remove)
|
||||
self.d.setVar('TESTVAR1', 'blah')
|
||||
self.d.setVar('TESTVAR2', 'testval2')
|
||||
self.d.setVar('TESTVAR3', 'no-testval')
|
||||
deps, values = bb.data.build_dependencies("ANOTHERVAR", set(self.d.keys()), set(), set(), self.d)
|
||||
self.assertEqual(sorted(values.splitlines()),
|
||||
sorted([
|
||||
expr_prepend + expr_plain + expr_append,
|
||||
'_remove of ' + expr_remove,
|
||||
'TESTVAR1{testval1} = Unset',
|
||||
'TESTVAR2{testval2} = Set',
|
||||
'TESTVAR3{no-testval} = Set',
|
||||
]))
|
||||
# Check final value
|
||||
self.assertEqual(self.d.getVar('ANOTHERVAR').split(), ['testval2'])
|
||||
|
||||
#Currently no wildcard support
|
||||
#def test_vardeps_wildcards(self):
|
||||
# self.d.setVar("oe_libinstall", "echo test")
|
||||
|
||||
@@ -206,6 +206,7 @@ class LayerIndexPlugin(ActionPlugin):
|
||||
"""
|
||||
args.show_only = True
|
||||
args.ignore = []
|
||||
args.shallow = True
|
||||
self.do_layerindex_fetch(args)
|
||||
|
||||
def register_commands(self, sp):
|
||||
|
||||
@@ -11,7 +11,7 @@ import os
|
||||
import re
|
||||
import logging
|
||||
import json
|
||||
import subprocess
|
||||
import glob
|
||||
from collections import Counter
|
||||
|
||||
from orm.models import Project, ProjectTarget, Build, Layer_Version
|
||||
@@ -227,20 +227,18 @@ class XhrSetDefaultImageUrl(View):
|
||||
# same logical name
|
||||
# * Each project that uses a layer will have its own
|
||||
# LayerVersion and Project Layer for it
|
||||
# * During the Paroject delete process, when the last
|
||||
# * During the Project delete process, when the last
|
||||
# LayerVersion for a 'local_source_dir' layer is deleted
|
||||
# then the Layer record is deleted to remove orphans
|
||||
#
|
||||
|
||||
def scan_layer_content(layer,layer_version):
|
||||
# if this is a local layer directory, we can immediately scan its content
|
||||
if layer.local_source_dir:
|
||||
if os.path.isdir(layer.local_source_dir):
|
||||
try:
|
||||
# recipes-*/*/*.bb
|
||||
cmd = '%s %s' % ('ls', os.path.join(layer.local_source_dir,'recipes-*/*/*.bb'))
|
||||
recipes_list = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,stderr=subprocess.STDOUT).stdout.read()
|
||||
recipes_list = recipes_list.decode("utf-8").strip()
|
||||
if recipes_list and 'No such' not in recipes_list:
|
||||
recipes_list = glob.glob(os.path.join(layer.local_source_dir, 'recipes-*/*/*.bb'))
|
||||
for recipe in recipes_list:
|
||||
for recipe in recipes_list.split('\n'):
|
||||
recipe_path = recipe[recipe.rfind('recipes-'):]
|
||||
recipe_name = recipe[recipe.rfind('/')+1:].replace('.bb','')
|
||||
@@ -260,6 +258,9 @@ def scan_layer_content(layer,layer_version):
|
||||
|
||||
except Exception as e:
|
||||
logger.warning("ERROR:scan_layer_content: %s" % e)
|
||||
else:
|
||||
logger.warning("ERROR: wrong path given")
|
||||
raise KeyError("local_source_dir")
|
||||
|
||||
class XhrLayer(View):
|
||||
""" Delete, Get, Add and Update Layer information
|
||||
@@ -456,15 +457,18 @@ class XhrLayer(View):
|
||||
'layerdetailurl':
|
||||
layer_dep.get_detailspage_url(project.pk)})
|
||||
|
||||
# Scan the layer's content and update components
|
||||
scan_layer_content(layer,layer_version)
|
||||
# Only scan_layer_content if layer is local
|
||||
if layer_data.get('local_source_dir', None):
|
||||
# Scan the layer's content and update components
|
||||
scan_layer_content(layer,layer_version)
|
||||
|
||||
except Layer_Version.DoesNotExist:
|
||||
return error_response("layer-dep-not-found")
|
||||
except Project.DoesNotExist:
|
||||
return error_response("project-not-found")
|
||||
except KeyError:
|
||||
return error_response("incorrect-parameters")
|
||||
except KeyError as e:
|
||||
_log("KeyError: %s" % e)
|
||||
return error_response(f"incorrect-parameters")
|
||||
|
||||
return JsonResponse({'error': "ok",
|
||||
'imported_layer': {
|
||||
|
||||
@@ -8652,6 +8652,8 @@ In order to run tests, you need to do the following:
|
||||
- Be sure to use an absolute path when calling this script
|
||||
with sudo.
|
||||
|
||||
- Ensure that your host has the package ``iptables`` installed.
|
||||
|
||||
- The package recipe ``qemu-helper-native`` is required to run
|
||||
this script. Build the package using the following command:
|
||||
::
|
||||
|
||||
@@ -659,7 +659,7 @@ Follow these steps to locate and download a particular tarball:
|
||||
Using the Downloads Page
|
||||
------------------------
|
||||
|
||||
The :yocto_home:`Yocto Project Website <>` uses a "DOWNLOADS" page
|
||||
The :yocto_home:`Yocto Project Website <>` uses a "RELEASES" page
|
||||
from which you can locate and download tarballs of any Yocto Project
|
||||
release. Rather than Git repositories, these files represent snapshot
|
||||
tarballs similar to the tarballs located in the Index of Releases
|
||||
@@ -676,12 +676,13 @@ Releases <#accessing-index-of-releases>`__" section.
|
||||
1. *Go to the Yocto Project Website:* Open The
|
||||
:yocto_home:`Yocto Project Website <>` in your browser.
|
||||
|
||||
2. *Get to the Downloads Area:* Select the "DOWNLOADS" item from the
|
||||
pull-down "SOFTWARE" tab menu near the top of the page.
|
||||
#. *Get to the Downloads Area:* Select the "RELEASES" item from the
|
||||
pull-down "DEVELOPMENT" tab menu near the top of the page.
|
||||
|
||||
3. *Select a Yocto Project Release:* Use the menu next to "RELEASE" to
|
||||
display and choose a recent or past supported Yocto Project release
|
||||
(e.g. &DISTRO_NAME_NO_CAP;, &DISTRO_NAME_NO_CAP_MINUS_ONE;, and so forth).
|
||||
#. *Select a Yocto Project Release:* On the top of the "RELEASE" page currently
|
||||
supported releases are displayed, further down past supported Yocto Project
|
||||
releases are visible. The "Download" links in the rows of the table there
|
||||
will lead to the download tarballs for the release.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -691,9 +692,9 @@ Releases <#accessing-index-of-releases>`__" section.
|
||||
You can use the "RELEASE ARCHIVE" link to reveal a menu of all Yocto
|
||||
Project releases.
|
||||
|
||||
4. *Download Tools or Board Support Packages (BSPs):* From the
|
||||
"DOWNLOADS" page, you can download tools or BSPs as well. Just scroll
|
||||
down the page and look for what you need.
|
||||
#. *Download Tools or Board Support Packages (BSPs):* Next to the tarballs you
|
||||
will find download tools or BSPs as well. Just select a Yocto Project
|
||||
release and look for what you need.
|
||||
|
||||
Accessing Nightly Builds
|
||||
------------------------
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
DISTRO : "3.1.30"
|
||||
DISTRO : "3.1.33"
|
||||
DISTRO_NAME_NO_CAP : "dunfell"
|
||||
DISTRO_NAME : "Dunfell"
|
||||
DISTRO_NAME_NO_CAP_MINUS_ONE : "zeus"
|
||||
YOCTO_DOC_VERSION : "3.1.30"
|
||||
YOCTO_DOC_VERSION : "3.1.33"
|
||||
YOCTO_DOC_VERSION_MINUS_ONE : "3.0.4"
|
||||
DISTRO_REL_TAG : "yocto-3.1.30"
|
||||
DOCCONF_VERSION : "3.1.30"
|
||||
DISTRO_REL_TAG : "yocto-3.1.33"
|
||||
DOCCONF_VERSION : "3.1.33"
|
||||
BITBAKE_SERIES : "1.46"
|
||||
POKYVERSION : "23.0.30"
|
||||
POKYVERSION : "23.0.33"
|
||||
YOCTO_POKY : "poky-&DISTRO_NAME_NO_CAP;-&POKYVERSION;"
|
||||
YOCTO_DL_URL : "https://downloads.yoctoproject.org"
|
||||
YOCTO_AB_URL : "https://autobuilder.yoctoproject.org"
|
||||
|
||||
@@ -1315,16 +1315,6 @@ The following list shows the tests you can list with the ``WARN_QA`` and
|
||||
automatically get these versions. Consequently, you should only need
|
||||
to explicitly add dependencies to binary driver recipes.
|
||||
|
||||
.. _ref-classes-insserv:
|
||||
|
||||
``insserv.bbclass``
|
||||
===================
|
||||
|
||||
The ``insserv`` class uses the ``insserv`` utility to update the order
|
||||
of symbolic links in ``/etc/rc?.d/`` within an image based on
|
||||
dependencies specified by LSB headers in the ``init.d`` scripts
|
||||
themselves.
|
||||
|
||||
.. _ref-classes-kernel:
|
||||
|
||||
``kernel.bbclass``
|
||||
|
||||
@@ -138,7 +138,7 @@ consists of the following pieces:
|
||||
piece of software. The test allows the packages to be be run within a
|
||||
target image.
|
||||
|
||||
- ``oe-selftest``: Tests combination BitBake invocations. These tests
|
||||
- ``oe-selftest``: Tests combinations of BitBake invocations. These tests
|
||||
operate outside the OpenEmbedded build system itself. The
|
||||
``oe-selftest`` can run all tests by default or can run selected
|
||||
tests or test suites.
|
||||
|
||||
@@ -37,25 +37,21 @@ Supported Linux Distributions
|
||||
Currently, the &DISTRO; release ("&DISTRO_NAME;") of the Yocto Project is
|
||||
supported on the following distributions:
|
||||
|
||||
|
||||
- Ubuntu 20.04 (LTS)
|
||||
|
||||
- Ubuntu 22.04 (LTS)
|
||||
|
||||
- Fedora 37
|
||||
- Fedora 38
|
||||
|
||||
- Debian GNU/Linux 11.x (Bullseye)
|
||||
|
||||
- AlmaLinux 8.8
|
||||
- AlmaLinux 8
|
||||
|
||||
The following distribution versions are still tested (being listed
|
||||
in :term:`SANITY_TESTED_DISTROS`), even though the organizations
|
||||
publishing them no longer make updates publicly available:
|
||||
The following distribution versions are still tested even though the
|
||||
organizations publishing them no longer make updates publicly available:
|
||||
|
||||
- Ubuntu 18.04 (LTS)
|
||||
|
||||
- OpenSUSE Leap 15.3
|
||||
|
||||
Finally, here are the distribution versions which were previously
|
||||
tested on former revisions of "&DISTRO_NAME;", but no longer are:
|
||||
|
||||
@@ -81,6 +77,8 @@ tested on former revisions of "&DISTRO_NAME;", but no longer are:
|
||||
|
||||
- Fedora 36
|
||||
|
||||
- Fedora 37
|
||||
|
||||
- CentOS 7.x
|
||||
|
||||
- CentOS 8.x
|
||||
@@ -95,9 +93,7 @@ tested on former revisions of "&DISTRO_NAME;", but no longer are:
|
||||
|
||||
- OpenSUSE Leap 15.2
|
||||
|
||||
- AlmaLinux 8.5
|
||||
|
||||
- AlmaLinux 8.7
|
||||
- OpenSUSE Leap 15.3
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
DISTRO = "poky"
|
||||
DISTRO_NAME = "Poky (Yocto Project Reference Distro)"
|
||||
DISTRO_VERSION = "3.1.30"
|
||||
DISTRO_VERSION = "3.1.33"
|
||||
DISTRO_CODENAME = "dunfell"
|
||||
SDK_VENDOR = "-pokysdk"
|
||||
SDK_VERSION = "${@d.getVar('DISTRO_VERSION').replace('snapshot-${DATE}', 'snapshot')}"
|
||||
|
||||
@@ -99,30 +99,9 @@ TESTIMAGE_DUMP_DIR ?= "${LOG_DIR}/runtime-hostdump/"
|
||||
TESTIMAGE_UPDATE_VARS ?= "DL_DIR WORKDIR DEPLOY_DIR"
|
||||
|
||||
testimage_dump_target () {
|
||||
top -bn1
|
||||
ps
|
||||
free
|
||||
df
|
||||
# The next command will export the default gateway IP
|
||||
export DEFAULT_GATEWAY=$(ip route | awk '/default/ { print $3}')
|
||||
ping -c3 $DEFAULT_GATEWAY
|
||||
dmesg
|
||||
netstat -an
|
||||
ip address
|
||||
# Next command will dump logs from /var/log/
|
||||
find /var/log/ -type f 2>/dev/null -exec echo "====================" \; -exec echo {} \; -exec echo "====================" \; -exec cat {} \; -exec echo "" \;
|
||||
}
|
||||
|
||||
testimage_dump_host () {
|
||||
top -bn1
|
||||
iostat -x -z -N -d -p ALL 20 2
|
||||
ps -ef
|
||||
free
|
||||
df
|
||||
memstat
|
||||
dmesg
|
||||
ip -s link
|
||||
netstat -an
|
||||
}
|
||||
|
||||
python do_testimage() {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
# to the distro running on the build machine.
|
||||
#
|
||||
|
||||
UNINATIVE_MAXGLIBCVERSION = "2.38"
|
||||
UNINATIVE_VERSION = "4.3"
|
||||
UNINATIVE_MAXGLIBCVERSION = "2.39"
|
||||
UNINATIVE_VERSION = "4.4"
|
||||
|
||||
UNINATIVE_URL ?= "http://downloads.yoctoproject.org/releases/uninative/${UNINATIVE_VERSION}/"
|
||||
UNINATIVE_CHECKSUM[aarch64] ?= "8df05f4a41455018b4303b2e0ea4eac5c960b5a13713f6dbb33dfdb3e32753ec"
|
||||
UNINATIVE_CHECKSUM[i686] ?= "bea76b4a97c9ba0077c0dd1295f519cd599dbf71f0ca1c964471c4cdb043addd"
|
||||
UNINATIVE_CHECKSUM[x86_64] ?= "1c35f09a75c4096749bbe1e009df4e3968cde151424062cf4aa3ed89db22b030"
|
||||
UNINATIVE_CHECKSUM[aarch64] ?= "b61876130f494f75092f21086b4a64ea5fb064045769bf1d32e9cb6af17ea8ec"
|
||||
UNINATIVE_CHECKSUM[i686] ?= "9f28627828f0082cc0344eede4d9a861a9a064bfa8f36e072e46212f0fe45fcc"
|
||||
UNINATIVE_CHECKSUM[x86_64] ?= "d81c54284be2bb886931fc87281d58177a2cd381cf99d1981f8923039a72a302"
|
||||
|
||||
@@ -37,6 +37,7 @@ SPDXLICENSEMAP[GPL-3.0-only] = "GPL-3.0"
|
||||
SPDXLICENSEMAP[LGPLv2] = "LGPL-2.0"
|
||||
SPDXLICENSEMAP[LGPLv2+] = "LGPL-2.0+"
|
||||
SPDXLICENSEMAP[LGPLv2.0] = "LGPL-2.0"
|
||||
SPDXLICENSEMAP[LGPLv2.0+] = "LGPL-2.0+"
|
||||
SPDXLICENSEMAP[LGPL-2.0-only] = "LGPL-2.0"
|
||||
SPDXLICENSEMAP[LGPL2.1] = "LGPL-2.1"
|
||||
SPDXLICENSEMAP[LGPLv2.1] = "LGPL-2.1"
|
||||
|
||||
@@ -480,8 +480,10 @@ def OEOuthashBasic(path, sigfile, task, d):
|
||||
if "package_write_" in task or task == "package_qa":
|
||||
include_owners = False
|
||||
include_timestamps = False
|
||||
include_root = True
|
||||
if task == "package":
|
||||
include_timestamps = d.getVar('BUILD_REPRODUCIBLE_BINARIES') == '1'
|
||||
include_root = False
|
||||
extra_content = d.getVar('HASHEQUIV_HASH_VERSION')
|
||||
|
||||
try:
|
||||
@@ -592,7 +594,8 @@ def OEOuthashBasic(path, sigfile, task, d):
|
||||
update_hash("\n")
|
||||
|
||||
# Process this directory and all its child files
|
||||
process(root)
|
||||
if include_root or root != ".":
|
||||
process(root)
|
||||
for f in files:
|
||||
if f == 'fixmepath':
|
||||
continue
|
||||
|
||||
@@ -59,6 +59,7 @@ SRC_URI = "${KERNELORG_MIRROR}/linux/bluetooth/bluez-${PV}.tar.xz \
|
||||
file://CVE-2022-0204.patch \
|
||||
file://CVE-2022-39176.patch \
|
||||
file://CVE-2022-3637.patch \
|
||||
file://CVE-2023-45866.patch \
|
||||
"
|
||||
S = "${WORKDIR}/bluez-${PV}"
|
||||
|
||||
|
||||
54
meta/recipes-connectivity/bluez5/bluez5/CVE-2023-45866.patch
Normal file
54
meta/recipes-connectivity/bluez5/bluez5/CVE-2023-45866.patch
Normal file
@@ -0,0 +1,54 @@
|
||||
From 25a471a83e02e1effb15d5a488b3f0085eaeb675 Mon Sep 17 00:00:00 2001
|
||||
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
|
||||
Date: Tue, 10 Oct 2023 13:03:12 -0700
|
||||
Subject: input.conf: Change default of ClassicBondedOnly
|
||||
|
||||
This changes the default of ClassicBondedOnly since defaulting to false
|
||||
is not inline with HID specification which mandates the of Security Mode
|
||||
4:
|
||||
|
||||
BLUETOOTH SPECIFICATION Page 84 of 123
|
||||
Human Interface Device (HID) Profile:
|
||||
|
||||
5.4.3.4.2 Security Modes
|
||||
Bluetooth HID Hosts shall use Security Mode 4 when interoperating with
|
||||
Bluetooth HID devices that are compliant to the Bluetooth Core
|
||||
Specification v2.1+EDR[6].
|
||||
|
||||
Upstream-Status: Backport [https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=25a471a83e02e1effb15d5a488b3f0085eaeb675]
|
||||
CVE: CVE-2023-45866
|
||||
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
|
||||
---
|
||||
profiles/input/device.c | 2 +-
|
||||
profiles/input/input.conf | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/profiles/input/device.c b/profiles/input/device.c
|
||||
index 375314e..0236488 100644
|
||||
--- a/profiles/input/device.c
|
||||
+++ b/profiles/input/device.c
|
||||
@@ -93,7 +93,7 @@ struct input_device {
|
||||
|
||||
static int idle_timeout = 0;
|
||||
static bool uhid_enabled = false;
|
||||
-static bool classic_bonded_only = false;
|
||||
+static bool classic_bonded_only = true;
|
||||
|
||||
void input_set_idle_timeout(int timeout)
|
||||
{
|
||||
diff --git a/profiles/input/input.conf b/profiles/input/input.conf
|
||||
index 4c70bc5..d8645f3 100644
|
||||
--- a/profiles/input/input.conf
|
||||
+++ b/profiles/input/input.conf
|
||||
@@ -17,7 +17,7 @@
|
||||
# platforms may want to make sure that input connections only come from bonded
|
||||
# device connections. Several older mice have been known for not supporting
|
||||
# pairing/encryption.
|
||||
-# Defaults to false to maximize device compatibility.
|
||||
+# Defaults to true for security.
|
||||
#ClassicBondedOnly=true
|
||||
|
||||
# LE upgrade security
|
||||
--
|
||||
2.25.1
|
||||
|
||||
468
meta/recipes-connectivity/openssh/openssh/CVE-2023-48795.patch
Normal file
468
meta/recipes-connectivity/openssh/openssh/CVE-2023-48795.patch
Normal file
@@ -0,0 +1,468 @@
|
||||
(modified to not remove ssh_packet_read_expect(), to add to
|
||||
KexAlgorithms in sshd.c and sshconnect2.c as this version pre-dates
|
||||
kex_proposal_populate_entries(), replace debug*_f() with debug*(),
|
||||
error*_f() with error*(), and fatal_f() with fatal())
|
||||
|
||||
Backport of:
|
||||
|
||||
From 1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Mon, 18 Dec 2023 14:45:17 +0000
|
||||
Subject: [PATCH] upstream: implement "strict key exchange" in ssh and sshd
|
||||
|
||||
This adds a protocol extension to improve the integrity of the SSH
|
||||
transport protocol, particular in and around the initial key exchange
|
||||
(KEX) phase.
|
||||
|
||||
Full details of the extension are in the PROTOCOL file.
|
||||
|
||||
with markus@
|
||||
|
||||
OpenBSD-Commit-ID: 2a66ac962f0a630d7945fee54004ed9e9c439f14
|
||||
|
||||
Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/openssh/tree/debian/patches/CVE-2023-48795.patch?h=ubuntu/focal-security
|
||||
Upstream commit https://github.com/openssh/openssh-portable/commit/1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5]
|
||||
CVE: CVE-2023-48795
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
PROTOCOL | 26 +++++++++++++++++
|
||||
kex.c | 68 +++++++++++++++++++++++++++++++++-----------
|
||||
kex.h | 1 +
|
||||
packet.c | 78 ++++++++++++++++++++++++++++++++++++++-------------
|
||||
sshconnect2.c | 14 +++------
|
||||
sshd.c | 7 +++--
|
||||
6 files changed, 146 insertions(+), 48 deletions(-)
|
||||
|
||||
diff --git a/PROTOCOL b/PROTOCOL
|
||||
index f75c1c0..89bddfe 100644
|
||||
--- a/PROTOCOL
|
||||
+++ b/PROTOCOL
|
||||
@@ -102,6 +102,32 @@ OpenSSH supports the use of ECDH in Curve25519 for key exchange as
|
||||
described at:
|
||||
http://git.libssh.org/users/aris/libssh.git/plain/doc/curve25519-sha256@libssh.org.txt?h=curve25519
|
||||
|
||||
+1.9 transport: strict key exchange extension
|
||||
+
|
||||
+OpenSSH supports a number of transport-layer hardening measures under
|
||||
+a "strict KEX" feature. This feature is signalled similarly to the
|
||||
+RFC8308 ext-info feature: by including a additional algorithm in the
|
||||
+initiial SSH2_MSG_KEXINIT kex_algorithms field. The client may append
|
||||
+"kex-strict-c-v00@openssh.com" to its kex_algorithms and the server
|
||||
+may append "kex-strict-s-v00@openssh.com". These pseudo-algorithms
|
||||
+are only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored
|
||||
+if they are present in subsequent SSH2_MSG_KEXINIT packets.
|
||||
+
|
||||
+When an endpoint that supports this extension observes this algorithm
|
||||
+name in a peer's KEXINIT packet, it MUST make the following changes to
|
||||
+the the protocol:
|
||||
+
|
||||
+a) During initial KEX, terminate the connection if any unexpected or
|
||||
+ out-of-sequence packet is received. This includes terminating the
|
||||
+ connection if the first packet received is not SSH2_MSG_KEXINIT.
|
||||
+ Unexpected packets for the purpose of strict KEX include messages
|
||||
+ that are otherwise valid at any time during the connection such as
|
||||
+ SSH2_MSG_DEBUG and SSH2_MSG_IGNORE.
|
||||
+b) After sending or receiving a SSH2_MSG_NEWKEYS message, reset the
|
||||
+ packet sequence number to zero. This behaviour persists for the
|
||||
+ duration of the connection (i.e. not just the first
|
||||
+ SSH2_MSG_NEWKEYS).
|
||||
+
|
||||
2. Connection protocol changes
|
||||
|
||||
2.1. connection: Channel write close extension "eow@openssh.com"
|
||||
diff --git a/kex.c b/kex.c
|
||||
index ce85f04..3129a4e 100644
|
||||
--- a/kex.c
|
||||
+++ b/kex.c
|
||||
@@ -63,7 +63,7 @@
|
||||
#include "digest.h"
|
||||
|
||||
/* prototype */
|
||||
-static int kex_choose_conf(struct ssh *);
|
||||
+static int kex_choose_conf(struct ssh *, uint32_t seq);
|
||||
static int kex_input_newkeys(int, u_int32_t, struct ssh *);
|
||||
|
||||
static const char *proposal_names[PROPOSAL_MAX] = {
|
||||
@@ -173,6 +173,18 @@ kex_names_valid(const char *names)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/* returns non-zero if proposal contains any algorithm from algs */
|
||||
+static int
|
||||
+has_any_alg(const char *proposal, const char *algs)
|
||||
+{
|
||||
+ char *cp;
|
||||
+
|
||||
+ if ((cp = match_list(proposal, algs, NULL)) == NULL)
|
||||
+ return 0;
|
||||
+ free(cp);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Concatenate algorithm names, avoiding duplicates in the process.
|
||||
* Caller must free returned string.
|
||||
@@ -180,7 +192,7 @@ kex_names_valid(const char *names)
|
||||
char *
|
||||
kex_names_cat(const char *a, const char *b)
|
||||
{
|
||||
- char *ret = NULL, *tmp = NULL, *cp, *p, *m;
|
||||
+ char *ret = NULL, *tmp = NULL, *cp, *p;
|
||||
size_t len;
|
||||
|
||||
if (a == NULL || *a == '\0')
|
||||
@@ -197,10 +209,8 @@ kex_names_cat(const char *a, const char *b)
|
||||
}
|
||||
strlcpy(ret, a, len);
|
||||
for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) {
|
||||
- if ((m = match_list(ret, p, NULL)) != NULL) {
|
||||
- free(m);
|
||||
+ if (has_any_alg(ret, p))
|
||||
continue; /* Algorithm already present */
|
||||
- }
|
||||
if (strlcat(ret, ",", len) >= len ||
|
||||
strlcat(ret, p, len) >= len) {
|
||||
free(tmp);
|
||||
@@ -409,7 +419,12 @@ kex_protocol_error(int type, u_int32_t seq, struct ssh *ssh)
|
||||
{
|
||||
int r;
|
||||
|
||||
- error("kex protocol error: type %d seq %u", type, seq);
|
||||
+ /* If in strict mode, any unexpected message is an error */
|
||||
+ if ((ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict) {
|
||||
+ ssh_packet_disconnect(ssh, "strict KEX violation: "
|
||||
+ "unexpected packet type %u (seqnr %u)", type, seq);
|
||||
+ }
|
||||
+ error("type %u seq %u", type, seq);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_UNIMPLEMENTED)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, seq)) != 0 ||
|
||||
(r = sshpkt_send(ssh)) != 0)
|
||||
@@ -481,6 +496,11 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error);
|
||||
if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0)
|
||||
return r;
|
||||
+ if (ninfo >= 1024) {
|
||||
+ error("SSH2_MSG_EXT_INFO with too many entries, expected "
|
||||
+ "<=1024, received %u", ninfo);
|
||||
+ return dispatch_protocol_error(type, seq, ssh);
|
||||
+ }
|
||||
for (i = 0; i < ninfo; i++) {
|
||||
if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0)
|
||||
return r;
|
||||
@@ -581,7 +601,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
|
||||
error("%s: no hex", __func__);
|
||||
return SSH_ERR_INTERNAL_ERROR;
|
||||
}
|
||||
- ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, NULL);
|
||||
+ ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_protocol_error);
|
||||
ptr = sshpkt_ptr(ssh, &dlen);
|
||||
if ((r = sshbuf_put(kex->peer, ptr, dlen)) != 0)
|
||||
return r;
|
||||
@@ -617,7 +637,7 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh)
|
||||
if (!(kex->flags & KEX_INIT_SENT))
|
||||
if ((r = kex_send_kexinit(ssh)) != 0)
|
||||
return r;
|
||||
- if ((r = kex_choose_conf(ssh)) != 0)
|
||||
+ if ((r = kex_choose_conf(ssh, seq)) != 0)
|
||||
return r;
|
||||
|
||||
if (kex->kex_type < KEX_MAX && kex->kex[kex->kex_type] != NULL)
|
||||
@@ -880,7 +900,13 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
|
||||
}
|
||||
|
||||
static int
|
||||
-kex_choose_conf(struct ssh *ssh)
|
||||
+kexalgs_contains(char **peer, const char *ext)
|
||||
+{
|
||||
+ return has_any_alg(peer[PROPOSAL_KEX_ALGS], ext);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+kex_choose_conf(struct ssh *ssh, uint32_t seq)
|
||||
{
|
||||
struct kex *kex = ssh->kex;
|
||||
struct newkeys *newkeys;
|
||||
@@ -905,13 +931,23 @@ kex_choose_conf(struct ssh *ssh)
|
||||
sprop=peer;
|
||||
}
|
||||
|
||||
- /* Check whether client supports ext_info_c */
|
||||
- if (kex->server && (kex->flags & KEX_INITIAL)) {
|
||||
- char *ext;
|
||||
-
|
||||
- ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL);
|
||||
- kex->ext_info_c = (ext != NULL);
|
||||
- free(ext);
|
||||
+ /* Check whether peer supports ext_info/kex_strict */
|
||||
+ if ((kex->flags & KEX_INITIAL) != 0) {
|
||||
+ if (kex->server) {
|
||||
+ kex->ext_info_c = kexalgs_contains(peer, "ext-info-c");
|
||||
+ kex->kex_strict = kexalgs_contains(peer,
|
||||
+ "kex-strict-c-v00@openssh.com");
|
||||
+ } else {
|
||||
+ kex->kex_strict = kexalgs_contains(peer,
|
||||
+ "kex-strict-s-v00@openssh.com");
|
||||
+ }
|
||||
+ if (kex->kex_strict) {
|
||||
+ debug3("will use strict KEX ordering");
|
||||
+ if (seq != 0)
|
||||
+ ssh_packet_disconnect(ssh,
|
||||
+ "strict KEX violation: "
|
||||
+ "KEXINIT was not the first packet");
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Algorithm Negotiation */
|
||||
diff --git a/kex.h b/kex.h
|
||||
index a5ae6ac..cae38f7 100644
|
||||
--- a/kex.h
|
||||
+++ b/kex.h
|
||||
@@ -145,6 +145,7 @@ struct kex {
|
||||
u_int kex_type;
|
||||
char *server_sig_algs;
|
||||
int ext_info_c;
|
||||
+ int kex_strict;
|
||||
struct sshbuf *my;
|
||||
struct sshbuf *peer;
|
||||
struct sshbuf *client_version;
|
||||
diff --git a/packet.c b/packet.c
|
||||
index 6d3e917..43139f9 100644
|
||||
--- a/packet.c
|
||||
+++ b/packet.c
|
||||
@@ -1203,8 +1203,13 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
sshbuf_dump(state->output, stderr);
|
||||
#endif
|
||||
/* increment sequence number for outgoing packets */
|
||||
- if (++state->p_send.seqnr == 0)
|
||||
+ if (++state->p_send.seqnr == 0) {
|
||||
+ if ((ssh->kex->flags & KEX_INITIAL) != 0) {
|
||||
+ ssh_packet_disconnect(ssh, "outgoing sequence number "
|
||||
+ "wrapped during initial key exchange");
|
||||
+ }
|
||||
logit("outgoing seqnr wraps around");
|
||||
+ }
|
||||
if (++state->p_send.packets == 0)
|
||||
if (!(ssh->compat & SSH_BUG_NOREKEY))
|
||||
return SSH_ERR_NEED_REKEY;
|
||||
@@ -1212,6 +1217,11 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
||||
state->p_send.bytes += len;
|
||||
sshbuf_reset(state->outgoing_packet);
|
||||
|
||||
+ if (type == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
|
||||
+ debug("resetting send seqnr %u", state->p_send.seqnr);
|
||||
+ state->p_send.seqnr = 0;
|
||||
+ }
|
||||
+
|
||||
if (type == SSH2_MSG_NEWKEYS)
|
||||
r = ssh_set_newkeys(ssh, MODE_OUT);
|
||||
else if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side)
|
||||
@@ -1345,8 +1355,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
/* Stay in the loop until we have received a complete packet. */
|
||||
for (;;) {
|
||||
/* Try to read a packet from the buffer. */
|
||||
- r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);
|
||||
- if (r != 0)
|
||||
+ if ((r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p)) != 0)
|
||||
break;
|
||||
/* If we got a packet, return it. */
|
||||
if (*typep != SSH_MSG_NONE)
|
||||
@@ -1633,10 +1642,16 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0)
|
||||
goto out;
|
||||
}
|
||||
+
|
||||
if (seqnr_p != NULL)
|
||||
*seqnr_p = state->p_read.seqnr;
|
||||
- if (++state->p_read.seqnr == 0)
|
||||
+ if (++state->p_read.seqnr == 0) {
|
||||
+ if ((ssh->kex->flags & KEX_INITIAL) != 0) {
|
||||
+ ssh_packet_disconnect(ssh, "incoming sequence number "
|
||||
+ "wrapped during initial key exchange");
|
||||
+ }
|
||||
logit("incoming seqnr wraps around");
|
||||
+ }
|
||||
if (++state->p_read.packets == 0)
|
||||
if (!(ssh->compat & SSH_BUG_NOREKEY))
|
||||
return SSH_ERR_NEED_REKEY;
|
||||
@@ -1702,6 +1717,10 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
#endif
|
||||
/* reset for next packet */
|
||||
state->packlen = 0;
|
||||
+ if (*typep == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
|
||||
+ debug("resetting read seqnr %u", state->p_read.seqnr);
|
||||
+ state->p_read.seqnr = 0;
|
||||
+ }
|
||||
|
||||
/* do we need to rekey? */
|
||||
if (ssh_packet_need_rekeying(ssh, 0)) {
|
||||
@@ -1726,10 +1745,39 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
|
||||
if (r != 0)
|
||||
return r;
|
||||
- if (*typep) {
|
||||
- state->keep_alive_timeouts = 0;
|
||||
- DBG(debug("received packet type %d", *typep));
|
||||
+ if (*typep == 0) {
|
||||
+ /* no message ready */
|
||||
+ return 0;
|
||||
+ }
|
||||
+ state->keep_alive_timeouts = 0;
|
||||
+ DBG(debug("received packet type %d", *typep));
|
||||
+
|
||||
+ /* Always process disconnect messages */
|
||||
+ if (*typep == SSH2_MSG_DISCONNECT) {
|
||||
+ if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
|
||||
+ (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
|
||||
+ return r;
|
||||
+ /* Ignore normal client exit notifications */
|
||||
+ do_log2(ssh->state->server_side &&
|
||||
+ reason == SSH2_DISCONNECT_BY_APPLICATION ?
|
||||
+ SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
|
||||
+ "Received disconnect from %s port %d:"
|
||||
+ "%u: %.400s", ssh_remote_ipaddr(ssh),
|
||||
+ ssh_remote_port(ssh), reason, msg);
|
||||
+ free(msg);
|
||||
+ return SSH_ERR_DISCONNECTED;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Do not implicitly handle any messages here during initial
|
||||
+ * KEX when in strict mode. They will be need to be allowed
|
||||
+ * explicitly by the KEX dispatch table or they will generate
|
||||
+ * protocol errors.
|
||||
+ */
|
||||
+ if (ssh->kex != NULL &&
|
||||
+ (ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict)
|
||||
+ return 0;
|
||||
+ /* Implicitly handle transport-level messages */
|
||||
switch (*typep) {
|
||||
case SSH2_MSG_IGNORE:
|
||||
debug3("Received SSH2_MSG_IGNORE");
|
||||
@@ -1744,19 +1792,6 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
debug("Remote: %.900s", msg);
|
||||
free(msg);
|
||||
break;
|
||||
- case SSH2_MSG_DISCONNECT:
|
||||
- if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
|
||||
- (r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
|
||||
- return r;
|
||||
- /* Ignore normal client exit notifications */
|
||||
- do_log2(ssh->state->server_side &&
|
||||
- reason == SSH2_DISCONNECT_BY_APPLICATION ?
|
||||
- SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
|
||||
- "Received disconnect from %s port %d:"
|
||||
- "%u: %.400s", ssh_remote_ipaddr(ssh),
|
||||
- ssh_remote_port(ssh), reason, msg);
|
||||
- free(msg);
|
||||
- return SSH_ERR_DISCONNECTED;
|
||||
case SSH2_MSG_UNIMPLEMENTED:
|
||||
if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
|
||||
return r;
|
||||
@@ -2235,6 +2270,7 @@ kex_to_blob(struct sshbuf *m, struct kex *kex)
|
||||
(r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->hostkey_nid)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->kex_type)) != 0 ||
|
||||
+ (r = sshbuf_put_u32(m, kex->kex_strict)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->my)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->peer)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->client_version)) != 0 ||
|
||||
@@ -2397,6 +2433,7 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
|
||||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_nid)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->kex_type)) != 0 ||
|
||||
+ (r = sshbuf_get_u32(m, &kex->kex_strict)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->my)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->peer)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->client_version)) != 0 ||
|
||||
@@ -2724,6 +2761,7 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...)
|
||||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
+ debug2("sending SSH2_MSG_DISCONNECT: %s", buf);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
|
||||
diff --git a/sshconnect2.c b/sshconnect2.c
|
||||
index 5df9477..617ed9f 100644
|
||||
--- a/sshconnect2.c
|
||||
+++ b/sshconnect2.c
|
||||
@@ -218,7 +218,8 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port)
|
||||
fatal("%s: kex_assemble_namelist", __func__);
|
||||
free(all_key);
|
||||
|
||||
- if ((s = kex_names_cat(options.kex_algorithms, "ext-info-c")) == NULL)
|
||||
+ if ((s = kex_names_cat(options.kex_algorithms,
|
||||
+ "ext-info-c,kex-strict-c-v00@openssh.com")) == NULL)
|
||||
fatal("%s: kex_names_cat", __func__);
|
||||
myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s);
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] =
|
||||
@@ -343,7 +344,6 @@ struct cauthmethod {
|
||||
};
|
||||
|
||||
static int input_userauth_service_accept(int, u_int32_t, struct ssh *);
|
||||
-static int input_userauth_ext_info(int, u_int32_t, struct ssh *);
|
||||
static int input_userauth_success(int, u_int32_t, struct ssh *);
|
||||
static int input_userauth_failure(int, u_int32_t, struct ssh *);
|
||||
static int input_userauth_banner(int, u_int32_t, struct ssh *);
|
||||
@@ -460,7 +460,7 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
|
||||
|
||||
ssh->authctxt = &authctxt;
|
||||
ssh_dispatch_init(ssh, &input_userauth_error);
|
||||
- ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &input_userauth_ext_info);
|
||||
+ ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, kex_input_ext_info);
|
||||
ssh_dispatch_set(ssh, SSH2_MSG_SERVICE_ACCEPT, &input_userauth_service_accept);
|
||||
ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &authctxt.success); /* loop until success */
|
||||
pubkey_cleanup(ssh);
|
||||
@@ -505,13 +505,6 @@ input_userauth_service_accept(int type, u_int32_t seq, struct ssh *ssh)
|
||||
return r;
|
||||
}
|
||||
|
||||
-/* ARGSUSED */
|
||||
-static int
|
||||
-input_userauth_ext_info(int type, u_int32_t seqnr, struct ssh *ssh)
|
||||
-{
|
||||
- return kex_input_ext_info(type, seqnr, ssh);
|
||||
-}
|
||||
-
|
||||
void
|
||||
userauth(struct ssh *ssh, char *authlist)
|
||||
{
|
||||
@@ -593,6 +586,7 @@ input_userauth_success(int type, u_int32_t seq, struct ssh *ssh)
|
||||
free(authctxt->methoddata);
|
||||
authctxt->methoddata = NULL;
|
||||
authctxt->success = 1; /* break out */
|
||||
+ ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, dispatch_protocol_error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/sshd.c b/sshd.c
|
||||
index 60b2aaf..ffea38c 100644
|
||||
--- a/sshd.c
|
||||
+++ b/sshd.c
|
||||
@@ -2323,11 +2323,13 @@ static void
|
||||
do_ssh2_kex(struct ssh *ssh)
|
||||
{
|
||||
char *myproposal[PROPOSAL_MAX] = { KEX_SERVER };
|
||||
+ char *s;
|
||||
struct kex *kex;
|
||||
int r;
|
||||
|
||||
- myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(
|
||||
- options.kex_algorithms);
|
||||
+ if ((s = kex_names_cat(options.kex_algorithms, "kex-strict-s-v00@openssh.com")) == NULL)
|
||||
+ fatal("kex_names_cat");
|
||||
+ myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s);
|
||||
myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(
|
||||
options.ciphers);
|
||||
myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(
|
||||
@@ -2382,6 +2384,7 @@ do_ssh2_kex(struct ssh *ssh)
|
||||
packet_send();
|
||||
packet_write_wait();
|
||||
#endif
|
||||
+ free(s);
|
||||
debug("KEX done");
|
||||
}
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
From 7ef3787c84b6b524501211b11a26c742f829af1a Mon Sep 17 00:00:00 2001
|
||||
From: "djm@openbsd.org" <djm@openbsd.org>
|
||||
Date: Mon, 18 Dec 2023 14:47:44 +0000
|
||||
Subject: [PATCH] upstream: ban user/hostnames with most shell metacharacters
|
||||
|
||||
This makes ssh(1) refuse user or host names provided on the
|
||||
commandline that contain most shell metacharacters.
|
||||
|
||||
Some programs that invoke ssh(1) using untrusted data do not filter
|
||||
metacharacters in arguments they supply. This could create
|
||||
interactions with user-specified ProxyCommand and other directives
|
||||
that allow shell injection attacks to occur.
|
||||
|
||||
It's a mistake to invoke ssh(1) with arbitrary untrusted arguments,
|
||||
but getting this stuff right can be tricky, so this should prevent
|
||||
most obvious ways of creating risky situations. It however is not
|
||||
and cannot be perfect: ssh(1) has no practical way of interpreting
|
||||
what shell quoting rules are in use and how they interact with the
|
||||
user's specified ProxyCommand.
|
||||
|
||||
To allow configurations that use strange user or hostnames to
|
||||
continue to work, this strictness is applied only to names coming
|
||||
from the commandline. Names specified using User or Hostname
|
||||
directives in ssh_config(5) are not affected.
|
||||
|
||||
feedback/ok millert@ markus@ dtucker@ deraadt@
|
||||
|
||||
OpenBSD-Commit-ID: 3b487348b5964f3e77b6b4d3da4c3b439e94b2d9
|
||||
|
||||
CVE: CVE-2023-51385
|
||||
Upstream-Status: Backport [https://github.com/openssh/openssh-portable/commit/7ef3787c84b6b524501211b11a26c742f829af1a]
|
||||
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
|
||||
Comment: Hunks refreshed to apply cleanly
|
||||
|
||||
---
|
||||
ssh.c | 41 ++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 40 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/ssh.c b/ssh.c
|
||||
index 35c48e62d18..48d93ddf2a9 100644
|
||||
--- a/ssh.c
|
||||
+++ b/ssh.c
|
||||
@@ -583,6 +583,41 @@ set_addrinfo_port(struct addrinfo *addrs
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+valid_hostname(const char *s)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (*s == '-')
|
||||
+ return 0;
|
||||
+ for (i = 0; s[i] != 0; i++) {
|
||||
+ if (strchr("'`\"$\\;&<>|(){}", s[i]) != NULL ||
|
||||
+ isspace((u_char)s[i]) || iscntrl((u_char)s[i]))
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+valid_ruser(const char *s)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (*s == '-')
|
||||
+ return 0;
|
||||
+ for (i = 0; s[i] != 0; i++) {
|
||||
+ if (strchr("'`\";&<>|(){}", s[i]) != NULL)
|
||||
+ return 0;
|
||||
+ /* Disallow '-' after whitespace */
|
||||
+ if (isspace((u_char)s[i]) && s[i + 1] == '-')
|
||||
+ return 0;
|
||||
+ /* Disallow \ in last position */
|
||||
+ if (s[i] == '\\' && s[i + 1] == '\0')
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Main program for the ssh client.
|
||||
*/
|
||||
@@ -1069,6 +1104,10 @@ main(int ac, char **av)
|
||||
if (!host)
|
||||
usage();
|
||||
|
||||
+ if (!valid_hostname(host))
|
||||
+ fatal("hostname contains invalid characters");
|
||||
+ if (options.user != NULL && !valid_ruser(options.user))
|
||||
+ fatal("remote username contains invalid characters");
|
||||
host_arg = xstrdup(host);
|
||||
|
||||
/* Initialize the command to execute on remote host. */
|
||||
@@ -39,6 +39,8 @@ SRC_URI = "http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-${PV}.tar
|
||||
file://CVE-2023-38408-10.patch \
|
||||
file://CVE-2023-38408-11.patch \
|
||||
file://CVE-2023-38408-12.patch \
|
||||
file://CVE-2023-48795.patch \
|
||||
file://CVE-2023-51385.patch \
|
||||
"
|
||||
SRC_URI[md5sum] = "3076e6413e8dbe56d33848c1054ac091"
|
||||
SRC_URI[sha256sum] = "43925151e6cf6cee1450190c0e9af4dc36b41c12737619edff8bcebdff64e671"
|
||||
|
||||
122
meta/recipes-connectivity/openssl/openssl/CVE-2024-0727.patch
Normal file
122
meta/recipes-connectivity/openssl/openssl/CVE-2024-0727.patch
Normal file
@@ -0,0 +1,122 @@
|
||||
Backport of:
|
||||
|
||||
From 09df4395b5071217b76dc7d3d2e630eb8c5a79c2 Mon Sep 17 00:00:00 2001
|
||||
From: Matt Caswell <matt@openssl.org>
|
||||
Date: Fri, 19 Jan 2024 11:28:58 +0000
|
||||
Subject: [PATCH] Add NULL checks where ContentInfo data can be NULL
|
||||
|
||||
PKCS12 structures contain PKCS7 ContentInfo fields. These fields are
|
||||
optional and can be NULL even if the "type" is a valid value. OpenSSL
|
||||
was not properly accounting for this and a NULL dereference can occur
|
||||
causing a crash.
|
||||
|
||||
CVE-2024-0727
|
||||
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
Reviewed-by: Hugo Landau <hlandau@openssl.org>
|
||||
Reviewed-by: Neil Horman <nhorman@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/23362)
|
||||
|
||||
(cherry picked from commit d135eeab8a5dbf72b3da5240bab9ddb7678dbd2c)
|
||||
|
||||
Upstream-Status: Backport [https://github.com/openssl/openssl/commit/d135eeab8a5dbf72b3da5240bab9ddb7678dbd2c]
|
||||
|
||||
CVE: CVE-2024-0727
|
||||
|
||||
Signed-off-by: virendra thakur <virendrak@kpit.com>
|
||||
---
|
||||
crypto/pkcs12/p12_add.c | 18 ++++++++++++++++++
|
||||
crypto/pkcs12/p12_mutl.c | 5 +++++
|
||||
crypto/pkcs12/p12_npas.c | 5 +++--
|
||||
crypto/pkcs7/pk7_mime.c | 7 +++++--
|
||||
4 files changed, 31 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/crypto/pkcs12/p12_add.c
|
||||
+++ b/crypto/pkcs12/p12_add.c
|
||||
@@ -76,6 +76,13 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_
|
||||
PKCS12_R_CONTENT_TYPE_NOT_DATA);
|
||||
return NULL;
|
||||
}
|
||||
+
|
||||
+ if (p7->d.data == NULL) {
|
||||
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,
|
||||
+ PKCS12_R_DECODE_ERROR);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
|
||||
}
|
||||
|
||||
@@ -132,6 +139,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_
|
||||
{
|
||||
if (!PKCS7_type_is_encrypted(p7))
|
||||
return NULL;
|
||||
+
|
||||
+ if (p7->d.encrypted == NULL) {
|
||||
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, PKCS12_R_DECODE_ERROR);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
|
||||
ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
|
||||
pass, passlen,
|
||||
@@ -159,6 +172,13 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes
|
||||
PKCS12_R_CONTENT_TYPE_NOT_DATA);
|
||||
return NULL;
|
||||
}
|
||||
+
|
||||
+ if (p12->authsafes->d.data == NULL) {
|
||||
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,
|
||||
+ PKCS12_R_DECODE_ERROR);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
return ASN1_item_unpack(p12->authsafes->d.data,
|
||||
ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
|
||||
}
|
||||
--- a/crypto/pkcs12/p12_mutl.c
|
||||
+++ b/crypto/pkcs12/p12_mutl.c
|
||||
@@ -93,6 +93,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ if (p12->authsafes->d.data == NULL) {
|
||||
+ PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_DECODE_ERROR);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
salt = p12->mac->salt->data;
|
||||
saltlen = p12->mac->salt->length;
|
||||
if (!p12->mac->iter)
|
||||
--- a/crypto/pkcs12/p12_npas.c
|
||||
+++ b/crypto/pkcs12/p12_npas.c
|
||||
@@ -78,8 +78,9 @@ static int newpass_p12(PKCS12 *p12, cons
|
||||
bags = PKCS12_unpack_p7data(p7);
|
||||
} else if (bagnid == NID_pkcs7_encrypted) {
|
||||
bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
|
||||
- if (!alg_get(p7->d.encrypted->enc_data->algorithm,
|
||||
- &pbe_nid, &pbe_iter, &pbe_saltlen))
|
||||
+ if (p7->d.encrypted == NULL
|
||||
+ || !alg_get(p7->d.encrypted->enc_data->algorithm,
|
||||
+ &pbe_nid, &pbe_iter, &pbe_saltlen))
|
||||
goto err;
|
||||
} else {
|
||||
continue;
|
||||
--- a/crypto/pkcs7/pk7_mime.c
|
||||
+++ b/crypto/pkcs7/pk7_mime.c
|
||||
@@ -30,10 +30,13 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p
|
||||
{
|
||||
STACK_OF(X509_ALGOR) *mdalgs;
|
||||
int ctype_nid = OBJ_obj2nid(p7->type);
|
||||
- if (ctype_nid == NID_pkcs7_signed)
|
||||
+ if (ctype_nid == NID_pkcs7_signed) {
|
||||
+ if (p7->d.sign == NULL)
|
||||
+ return 0;
|
||||
mdalgs = p7->d.sign->md_algs;
|
||||
- else
|
||||
+ } else {
|
||||
mdalgs = NULL;
|
||||
+ }
|
||||
|
||||
flags ^= SMIME_OLDMIME;
|
||||
|
||||
@@ -20,6 +20,7 @@ SRC_URI = "http://www.openssl.org/source/openssl-${PV}.tar.gz \
|
||||
file://reproducibility.patch \
|
||||
file://0001-Configure-add-2-missing-key-sorts.patch \
|
||||
file://0001-Configure-do-not-tweak-mips-cflags.patch \
|
||||
file://CVE-2024-0727.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_class-nativesdk = " \
|
||||
|
||||
986
meta/recipes-core/glibc/glibc/CVE-2023-4813.patch
Normal file
986
meta/recipes-core/glibc/glibc/CVE-2023-4813.patch
Normal file
@@ -0,0 +1,986 @@
|
||||
From 1c37b8022e8763fedbb3f79c02e05c6acfe5a215 Mon Sep 17 00:00:00 2001
|
||||
From: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Date: Thu, 17 Mar 2022 11:44:34 +0530
|
||||
Subject: [PATCH] Simplify allocations and fix merge and continue actions [BZ
|
||||
#28931]
|
||||
|
||||
Allocations for address tuples is currently a bit confusing because of
|
||||
the pointer chasing through PAT, making it hard to observe the sequence
|
||||
in which allocations have been made. Narrow scope of the pointer
|
||||
chasing through PAT so that it is only used where necessary.
|
||||
|
||||
This also tightens actions behaviour with the hosts database in
|
||||
getaddrinfo to comply with the manual text. The "continue" action
|
||||
discards previous results and the "merge" action results in an immedate
|
||||
lookup failure. Consequently, chaining of allocations across modules is
|
||||
no longer necessary, thus opening up cleanup opportunities.
|
||||
|
||||
A test has been added that checks some combinations to ensure that they
|
||||
work correctly.
|
||||
|
||||
Resolves: BZ #28931
|
||||
|
||||
CVE: CVE-2023-4813
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=1c37b8022e8763fedbb3f79c02e05c6acfe5a215]
|
||||
Comments: Hunks refreshed
|
||||
|
||||
Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
Reviewed-by: DJ Delorie <dj@redhat.com>
|
||||
Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
|
||||
---
|
||||
nss/Makefile | 1 +
|
||||
nss/tst-nss-gai-actions.c | 149 ++++++
|
||||
nss/tst-nss-gai-actions.root/etc/host.conf | 1 +
|
||||
nss/tst-nss-gai-actions.root/etc/hosts | 508 +++++++++++++++++++++
|
||||
sysdeps/posix/getaddrinfo.c | 143 +++---
|
||||
5 files changed, 750 insertions(+), 52 deletions(-)
|
||||
create mode 100644 nss/tst-nss-gai-actions.c
|
||||
create mode 100644 nss/tst-nss-gai-actions.root/etc/host.conf
|
||||
create mode 100644 nss/tst-nss-gai-actions.root/etc/hosts
|
||||
|
||||
diff --git a/nss/Makefile b/nss/Makefile
|
||||
index 42a59535cb..d8b06b44fb 100644
|
||||
--- a/nss/Makefile
|
||||
+++ b/nss/Makefile
|
||||
@@ -61,6 +61,7 @@
|
||||
|
||||
tests-container = \
|
||||
tst-nss-test3 \
|
||||
+ tst-nss-gai-actions \
|
||||
tst-nss-files-hosts-long \
|
||||
tst-nss-db-endpwent \
|
||||
tst-nss-db-endgrent
|
||||
diff --git a/nss/tst-nss-gai-actions.c b/nss/tst-nss-gai-actions.c
|
||||
new file mode 100644
|
||||
index 0000000000..efca6cd183
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-gai-actions.c
|
||||
@@ -0,0 +1,149 @@
|
||||
+/* Test continue and merge NSS actions for getaddrinfo.
|
||||
+ Copyright The GNU Toolchain Authors.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ The GNU C Library is free software; you can redistribute it and/or
|
||||
+ modify it under the terms of the GNU Lesser General Public
|
||||
+ License as published by the Free Software Foundation; either
|
||||
+ version 2.1 of the License, or (at your option) any later version.
|
||||
+
|
||||
+ The GNU C Library 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
|
||||
+ Lesser General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU Lesser General Public
|
||||
+ License along with the GNU C Library; if not, see
|
||||
+ <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#include <dlfcn.h>
|
||||
+#include <gnu/lib-names.h>
|
||||
+#include <nss.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#include <support/check.h>
|
||||
+#include <support/format_nss.h>
|
||||
+#include <support/support.h>
|
||||
+#include <support/xstdio.h>
|
||||
+#include <support/xunistd.h>
|
||||
+
|
||||
+enum
|
||||
+{
|
||||
+ ACTION_MERGE = 0,
|
||||
+ ACTION_CONTINUE,
|
||||
+};
|
||||
+
|
||||
+static const char *
|
||||
+family_str (int family)
|
||||
+{
|
||||
+ switch (family)
|
||||
+ {
|
||||
+ case AF_UNSPEC:
|
||||
+ return "AF_UNSPEC";
|
||||
+ case AF_INET:
|
||||
+ return "AF_INET";
|
||||
+ default:
|
||||
+ __builtin_unreachable ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const char *
|
||||
+action_str (int action)
|
||||
+{
|
||||
+ switch (action)
|
||||
+ {
|
||||
+ case ACTION_MERGE:
|
||||
+ return "merge";
|
||||
+ case ACTION_CONTINUE:
|
||||
+ return "continue";
|
||||
+ default:
|
||||
+ __builtin_unreachable ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_one_test (int action, int family, bool canon)
|
||||
+{
|
||||
+ struct addrinfo hints =
|
||||
+ {
|
||||
+ .ai_family = family,
|
||||
+ };
|
||||
+
|
||||
+ struct addrinfo *ai;
|
||||
+
|
||||
+ if (canon)
|
||||
+ hints.ai_flags = AI_CANONNAME;
|
||||
+
|
||||
+ printf ("***** Testing \"files [SUCCESS=%s] files\" for family %s, %s\n",
|
||||
+ action_str (action), family_str (family),
|
||||
+ canon ? "AI_CANONNAME" : "");
|
||||
+
|
||||
+ int ret = getaddrinfo ("example.org", "80", &hints, &ai);
|
||||
+
|
||||
+ switch (action)
|
||||
+ {
|
||||
+ case ACTION_MERGE:
|
||||
+ if (ret == 0)
|
||||
+ {
|
||||
+ char *formatted = support_format_addrinfo (ai, ret);
|
||||
+
|
||||
+ printf ("merge unexpectedly succeeded:\n %s\n", formatted);
|
||||
+ support_record_failure ();
|
||||
+ free (formatted);
|
||||
+ }
|
||||
+ else
|
||||
+ return;
|
||||
+ case ACTION_CONTINUE:
|
||||
+ {
|
||||
+ char *formatted = support_format_addrinfo (ai, ret);
|
||||
+
|
||||
+ /* Verify that the result appears exactly once. */
|
||||
+ const char *expected = "address: STREAM/TCP 192.0.0.1 80\n"
|
||||
+ "address: DGRAM/UDP 192.0.0.1 80\n"
|
||||
+ "address: RAW/IP 192.0.0.1 80\n";
|
||||
+
|
||||
+ const char *contains = strstr (formatted, expected);
|
||||
+ const char *contains2 = NULL;
|
||||
+
|
||||
+ if (contains != NULL)
|
||||
+ contains2 = strstr (contains + strlen (expected), expected);
|
||||
+
|
||||
+ if (contains == NULL || contains2 != NULL)
|
||||
+ {
|
||||
+ printf ("continue failed:\n%s\n", formatted);
|
||||
+ support_record_failure ();
|
||||
+ }
|
||||
+
|
||||
+ free (formatted);
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ __builtin_unreachable ();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_one_test_set (int action)
|
||||
+{
|
||||
+ char buf[32];
|
||||
+
|
||||
+ snprintf (buf, sizeof (buf), "files [SUCCESS=%s] files",
|
||||
+ action_str (action));
|
||||
+ __nss_configure_lookup ("hosts", buf);
|
||||
+
|
||||
+ do_one_test (action, AF_UNSPEC, false);
|
||||
+ do_one_test (action, AF_INET, false);
|
||||
+ do_one_test (action, AF_INET, true);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ do_one_test_set (ACTION_CONTINUE);
|
||||
+ do_one_test_set (ACTION_MERGE);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
||||
diff --git a/nss/tst-nss-gai-actions.root/etc/host.conf b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||||
new file mode 100644
|
||||
index 0000000000..d1a59f73a9
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-gai-actions.root/etc/host.conf
|
||||
@@ -0,0 +1 @@
|
||||
+multi on
|
||||
diff --git a/nss/tst-nss-gai-actions.root/etc/hosts b/nss/tst-nss-gai-actions.root/etc/hosts
|
||||
new file mode 100644
|
||||
index 0000000000..50ce9774dc
|
||||
--- /dev/null
|
||||
+++ b/nss/tst-nss-gai-actions.root/etc/hosts
|
||||
@@ -0,0 +1,508 @@
|
||||
+192.0.0.1 example.org
|
||||
+192.0.0.2 example.org
|
||||
+192.0.0.3 example.org
|
||||
+192.0.0.4 example.org
|
||||
+192.0.0.5 example.org
|
||||
+192.0.0.6 example.org
|
||||
+192.0.0.7 example.org
|
||||
+192.0.0.8 example.org
|
||||
+192.0.0.9 example.org
|
||||
+192.0.0.10 example.org
|
||||
+192.0.0.11 example.org
|
||||
+192.0.0.12 example.org
|
||||
+192.0.0.13 example.org
|
||||
+192.0.0.14 example.org
|
||||
+192.0.0.15 example.org
|
||||
+192.0.0.16 example.org
|
||||
+192.0.0.17 example.org
|
||||
+192.0.0.18 example.org
|
||||
+192.0.0.19 example.org
|
||||
+192.0.0.20 example.org
|
||||
+192.0.0.21 example.org
|
||||
+192.0.0.22 example.org
|
||||
+192.0.0.23 example.org
|
||||
+192.0.0.24 example.org
|
||||
+192.0.0.25 example.org
|
||||
+192.0.0.26 example.org
|
||||
+192.0.0.27 example.org
|
||||
+192.0.0.28 example.org
|
||||
+192.0.0.29 example.org
|
||||
+192.0.0.30 example.org
|
||||
+192.0.0.31 example.org
|
||||
+192.0.0.32 example.org
|
||||
+192.0.0.33 example.org
|
||||
+192.0.0.34 example.org
|
||||
+192.0.0.35 example.org
|
||||
+192.0.0.36 example.org
|
||||
+192.0.0.37 example.org
|
||||
+192.0.0.38 example.org
|
||||
+192.0.0.39 example.org
|
||||
+192.0.0.40 example.org
|
||||
+192.0.0.41 example.org
|
||||
+192.0.0.42 example.org
|
||||
+192.0.0.43 example.org
|
||||
+192.0.0.44 example.org
|
||||
+192.0.0.45 example.org
|
||||
+192.0.0.46 example.org
|
||||
+192.0.0.47 example.org
|
||||
+192.0.0.48 example.org
|
||||
+192.0.0.49 example.org
|
||||
+192.0.0.50 example.org
|
||||
+192.0.0.51 example.org
|
||||
+192.0.0.52 example.org
|
||||
+192.0.0.53 example.org
|
||||
+192.0.0.54 example.org
|
||||
+192.0.0.55 example.org
|
||||
+192.0.0.56 example.org
|
||||
+192.0.0.57 example.org
|
||||
+192.0.0.58 example.org
|
||||
+192.0.0.59 example.org
|
||||
+192.0.0.60 example.org
|
||||
+192.0.0.61 example.org
|
||||
+192.0.0.62 example.org
|
||||
+192.0.0.63 example.org
|
||||
+192.0.0.64 example.org
|
||||
+192.0.0.65 example.org
|
||||
+192.0.0.66 example.org
|
||||
+192.0.0.67 example.org
|
||||
+192.0.0.68 example.org
|
||||
+192.0.0.69 example.org
|
||||
+192.0.0.70 example.org
|
||||
+192.0.0.71 example.org
|
||||
+192.0.0.72 example.org
|
||||
+192.0.0.73 example.org
|
||||
+192.0.0.74 example.org
|
||||
+192.0.0.75 example.org
|
||||
+192.0.0.76 example.org
|
||||
+192.0.0.77 example.org
|
||||
+192.0.0.78 example.org
|
||||
+192.0.0.79 example.org
|
||||
+192.0.0.80 example.org
|
||||
+192.0.0.81 example.org
|
||||
+192.0.0.82 example.org
|
||||
+192.0.0.83 example.org
|
||||
+192.0.0.84 example.org
|
||||
+192.0.0.85 example.org
|
||||
+192.0.0.86 example.org
|
||||
+192.0.0.87 example.org
|
||||
+192.0.0.88 example.org
|
||||
+192.0.0.89 example.org
|
||||
+192.0.0.90 example.org
|
||||
+192.0.0.91 example.org
|
||||
+192.0.0.92 example.org
|
||||
+192.0.0.93 example.org
|
||||
+192.0.0.94 example.org
|
||||
+192.0.0.95 example.org
|
||||
+192.0.0.96 example.org
|
||||
+192.0.0.97 example.org
|
||||
+192.0.0.98 example.org
|
||||
+192.0.0.99 example.org
|
||||
+192.0.0.100 example.org
|
||||
+192.0.0.101 example.org
|
||||
+192.0.0.102 example.org
|
||||
+192.0.0.103 example.org
|
||||
+192.0.0.104 example.org
|
||||
+192.0.0.105 example.org
|
||||
+192.0.0.106 example.org
|
||||
+192.0.0.107 example.org
|
||||
+192.0.0.108 example.org
|
||||
+192.0.0.109 example.org
|
||||
+192.0.0.110 example.org
|
||||
+192.0.0.111 example.org
|
||||
+192.0.0.112 example.org
|
||||
+192.0.0.113 example.org
|
||||
+192.0.0.114 example.org
|
||||
+192.0.0.115 example.org
|
||||
+192.0.0.116 example.org
|
||||
+192.0.0.117 example.org
|
||||
+192.0.0.118 example.org
|
||||
+192.0.0.119 example.org
|
||||
+192.0.0.120 example.org
|
||||
+192.0.0.121 example.org
|
||||
+192.0.0.122 example.org
|
||||
+192.0.0.123 example.org
|
||||
+192.0.0.124 example.org
|
||||
+192.0.0.125 example.org
|
||||
+192.0.0.126 example.org
|
||||
+192.0.0.127 example.org
|
||||
+192.0.0.128 example.org
|
||||
+192.0.0.129 example.org
|
||||
+192.0.0.130 example.org
|
||||
+192.0.0.131 example.org
|
||||
+192.0.0.132 example.org
|
||||
+192.0.0.133 example.org
|
||||
+192.0.0.134 example.org
|
||||
+192.0.0.135 example.org
|
||||
+192.0.0.136 example.org
|
||||
+192.0.0.137 example.org
|
||||
+192.0.0.138 example.org
|
||||
+192.0.0.139 example.org
|
||||
+192.0.0.140 example.org
|
||||
+192.0.0.141 example.org
|
||||
+192.0.0.142 example.org
|
||||
+192.0.0.143 example.org
|
||||
+192.0.0.144 example.org
|
||||
+192.0.0.145 example.org
|
||||
+192.0.0.146 example.org
|
||||
+192.0.0.147 example.org
|
||||
+192.0.0.148 example.org
|
||||
+192.0.0.149 example.org
|
||||
+192.0.0.150 example.org
|
||||
+192.0.0.151 example.org
|
||||
+192.0.0.152 example.org
|
||||
+192.0.0.153 example.org
|
||||
+192.0.0.154 example.org
|
||||
+192.0.0.155 example.org
|
||||
+192.0.0.156 example.org
|
||||
+192.0.0.157 example.org
|
||||
+192.0.0.158 example.org
|
||||
+192.0.0.159 example.org
|
||||
+192.0.0.160 example.org
|
||||
+192.0.0.161 example.org
|
||||
+192.0.0.162 example.org
|
||||
+192.0.0.163 example.org
|
||||
+192.0.0.164 example.org
|
||||
+192.0.0.165 example.org
|
||||
+192.0.0.166 example.org
|
||||
+192.0.0.167 example.org
|
||||
+192.0.0.168 example.org
|
||||
+192.0.0.169 example.org
|
||||
+192.0.0.170 example.org
|
||||
+192.0.0.171 example.org
|
||||
+192.0.0.172 example.org
|
||||
+192.0.0.173 example.org
|
||||
+192.0.0.174 example.org
|
||||
+192.0.0.175 example.org
|
||||
+192.0.0.176 example.org
|
||||
+192.0.0.177 example.org
|
||||
+192.0.0.178 example.org
|
||||
+192.0.0.179 example.org
|
||||
+192.0.0.180 example.org
|
||||
+192.0.0.181 example.org
|
||||
+192.0.0.182 example.org
|
||||
+192.0.0.183 example.org
|
||||
+192.0.0.184 example.org
|
||||
+192.0.0.185 example.org
|
||||
+192.0.0.186 example.org
|
||||
+192.0.0.187 example.org
|
||||
+192.0.0.188 example.org
|
||||
+192.0.0.189 example.org
|
||||
+192.0.0.190 example.org
|
||||
+192.0.0.191 example.org
|
||||
+192.0.0.192 example.org
|
||||
+192.0.0.193 example.org
|
||||
+192.0.0.194 example.org
|
||||
+192.0.0.195 example.org
|
||||
+192.0.0.196 example.org
|
||||
+192.0.0.197 example.org
|
||||
+192.0.0.198 example.org
|
||||
+192.0.0.199 example.org
|
||||
+192.0.0.200 example.org
|
||||
+192.0.0.201 example.org
|
||||
+192.0.0.202 example.org
|
||||
+192.0.0.203 example.org
|
||||
+192.0.0.204 example.org
|
||||
+192.0.0.205 example.org
|
||||
+192.0.0.206 example.org
|
||||
+192.0.0.207 example.org
|
||||
+192.0.0.208 example.org
|
||||
+192.0.0.209 example.org
|
||||
+192.0.0.210 example.org
|
||||
+192.0.0.211 example.org
|
||||
+192.0.0.212 example.org
|
||||
+192.0.0.213 example.org
|
||||
+192.0.0.214 example.org
|
||||
+192.0.0.215 example.org
|
||||
+192.0.0.216 example.org
|
||||
+192.0.0.217 example.org
|
||||
+192.0.0.218 example.org
|
||||
+192.0.0.219 example.org
|
||||
+192.0.0.220 example.org
|
||||
+192.0.0.221 example.org
|
||||
+192.0.0.222 example.org
|
||||
+192.0.0.223 example.org
|
||||
+192.0.0.224 example.org
|
||||
+192.0.0.225 example.org
|
||||
+192.0.0.226 example.org
|
||||
+192.0.0.227 example.org
|
||||
+192.0.0.228 example.org
|
||||
+192.0.0.229 example.org
|
||||
+192.0.0.230 example.org
|
||||
+192.0.0.231 example.org
|
||||
+192.0.0.232 example.org
|
||||
+192.0.0.233 example.org
|
||||
+192.0.0.234 example.org
|
||||
+192.0.0.235 example.org
|
||||
+192.0.0.236 example.org
|
||||
+192.0.0.237 example.org
|
||||
+192.0.0.238 example.org
|
||||
+192.0.0.239 example.org
|
||||
+192.0.0.240 example.org
|
||||
+192.0.0.241 example.org
|
||||
+192.0.0.242 example.org
|
||||
+192.0.0.243 example.org
|
||||
+192.0.0.244 example.org
|
||||
+192.0.0.245 example.org
|
||||
+192.0.0.246 example.org
|
||||
+192.0.0.247 example.org
|
||||
+192.0.0.248 example.org
|
||||
+192.0.0.249 example.org
|
||||
+192.0.0.250 example.org
|
||||
+192.0.0.251 example.org
|
||||
+192.0.0.252 example.org
|
||||
+192.0.0.253 example.org
|
||||
+192.0.0.254 example.org
|
||||
+192.0.1.1 example.org
|
||||
+192.0.1.2 example.org
|
||||
+192.0.1.3 example.org
|
||||
+192.0.1.4 example.org
|
||||
+192.0.1.5 example.org
|
||||
+192.0.1.6 example.org
|
||||
+192.0.1.7 example.org
|
||||
+192.0.1.8 example.org
|
||||
+192.0.1.9 example.org
|
||||
+192.0.1.10 example.org
|
||||
+192.0.1.11 example.org
|
||||
+192.0.1.12 example.org
|
||||
+192.0.1.13 example.org
|
||||
+192.0.1.14 example.org
|
||||
+192.0.1.15 example.org
|
||||
+192.0.1.16 example.org
|
||||
+192.0.1.17 example.org
|
||||
+192.0.1.18 example.org
|
||||
+192.0.1.19 example.org
|
||||
+192.0.1.20 example.org
|
||||
+192.0.1.21 example.org
|
||||
+192.0.1.22 example.org
|
||||
+192.0.1.23 example.org
|
||||
+192.0.1.24 example.org
|
||||
+192.0.1.25 example.org
|
||||
+192.0.1.26 example.org
|
||||
+192.0.1.27 example.org
|
||||
+192.0.1.28 example.org
|
||||
+192.0.1.29 example.org
|
||||
+192.0.1.30 example.org
|
||||
+192.0.1.31 example.org
|
||||
+192.0.1.32 example.org
|
||||
+192.0.1.33 example.org
|
||||
+192.0.1.34 example.org
|
||||
+192.0.1.35 example.org
|
||||
+192.0.1.36 example.org
|
||||
+192.0.1.37 example.org
|
||||
+192.0.1.38 example.org
|
||||
+192.0.1.39 example.org
|
||||
+192.0.1.40 example.org
|
||||
+192.0.1.41 example.org
|
||||
+192.0.1.42 example.org
|
||||
+192.0.1.43 example.org
|
||||
+192.0.1.44 example.org
|
||||
+192.0.1.45 example.org
|
||||
+192.0.1.46 example.org
|
||||
+192.0.1.47 example.org
|
||||
+192.0.1.48 example.org
|
||||
+192.0.1.49 example.org
|
||||
+192.0.1.50 example.org
|
||||
+192.0.1.51 example.org
|
||||
+192.0.1.52 example.org
|
||||
+192.0.1.53 example.org
|
||||
+192.0.1.54 example.org
|
||||
+192.0.1.55 example.org
|
||||
+192.0.1.56 example.org
|
||||
+192.0.1.57 example.org
|
||||
+192.0.1.58 example.org
|
||||
+192.0.1.59 example.org
|
||||
+192.0.1.60 example.org
|
||||
+192.0.1.61 example.org
|
||||
+192.0.1.62 example.org
|
||||
+192.0.1.63 example.org
|
||||
+192.0.1.64 example.org
|
||||
+192.0.1.65 example.org
|
||||
+192.0.1.66 example.org
|
||||
+192.0.1.67 example.org
|
||||
+192.0.1.68 example.org
|
||||
+192.0.1.69 example.org
|
||||
+192.0.1.70 example.org
|
||||
+192.0.1.71 example.org
|
||||
+192.0.1.72 example.org
|
||||
+192.0.1.73 example.org
|
||||
+192.0.1.74 example.org
|
||||
+192.0.1.75 example.org
|
||||
+192.0.1.76 example.org
|
||||
+192.0.1.77 example.org
|
||||
+192.0.1.78 example.org
|
||||
+192.0.1.79 example.org
|
||||
+192.0.1.80 example.org
|
||||
+192.0.1.81 example.org
|
||||
+192.0.1.82 example.org
|
||||
+192.0.1.83 example.org
|
||||
+192.0.1.84 example.org
|
||||
+192.0.1.85 example.org
|
||||
+192.0.1.86 example.org
|
||||
+192.0.1.87 example.org
|
||||
+192.0.1.88 example.org
|
||||
+192.0.1.89 example.org
|
||||
+192.0.1.90 example.org
|
||||
+192.0.1.91 example.org
|
||||
+192.0.1.92 example.org
|
||||
+192.0.1.93 example.org
|
||||
+192.0.1.94 example.org
|
||||
+192.0.1.95 example.org
|
||||
+192.0.1.96 example.org
|
||||
+192.0.1.97 example.org
|
||||
+192.0.1.98 example.org
|
||||
+192.0.1.99 example.org
|
||||
+192.0.1.100 example.org
|
||||
+192.0.1.101 example.org
|
||||
+192.0.1.102 example.org
|
||||
+192.0.1.103 example.org
|
||||
+192.0.1.104 example.org
|
||||
+192.0.1.105 example.org
|
||||
+192.0.1.106 example.org
|
||||
+192.0.1.107 example.org
|
||||
+192.0.1.108 example.org
|
||||
+192.0.1.109 example.org
|
||||
+192.0.1.110 example.org
|
||||
+192.0.1.111 example.org
|
||||
+192.0.1.112 example.org
|
||||
+192.0.1.113 example.org
|
||||
+192.0.1.114 example.org
|
||||
+192.0.1.115 example.org
|
||||
+192.0.1.116 example.org
|
||||
+192.0.1.117 example.org
|
||||
+192.0.1.118 example.org
|
||||
+192.0.1.119 example.org
|
||||
+192.0.1.120 example.org
|
||||
+192.0.1.121 example.org
|
||||
+192.0.1.122 example.org
|
||||
+192.0.1.123 example.org
|
||||
+192.0.1.124 example.org
|
||||
+192.0.1.125 example.org
|
||||
+192.0.1.126 example.org
|
||||
+192.0.1.127 example.org
|
||||
+192.0.1.128 example.org
|
||||
+192.0.1.129 example.org
|
||||
+192.0.1.130 example.org
|
||||
+192.0.1.131 example.org
|
||||
+192.0.1.132 example.org
|
||||
+192.0.1.133 example.org
|
||||
+192.0.1.134 example.org
|
||||
+192.0.1.135 example.org
|
||||
+192.0.1.136 example.org
|
||||
+192.0.1.137 example.org
|
||||
+192.0.1.138 example.org
|
||||
+192.0.1.139 example.org
|
||||
+192.0.1.140 example.org
|
||||
+192.0.1.141 example.org
|
||||
+192.0.1.142 example.org
|
||||
+192.0.1.143 example.org
|
||||
+192.0.1.144 example.org
|
||||
+192.0.1.145 example.org
|
||||
+192.0.1.146 example.org
|
||||
+192.0.1.147 example.org
|
||||
+192.0.1.148 example.org
|
||||
+192.0.1.149 example.org
|
||||
+192.0.1.150 example.org
|
||||
+192.0.1.151 example.org
|
||||
+192.0.1.152 example.org
|
||||
+192.0.1.153 example.org
|
||||
+192.0.1.154 example.org
|
||||
+192.0.1.155 example.org
|
||||
+192.0.1.156 example.org
|
||||
+192.0.1.157 example.org
|
||||
+192.0.1.158 example.org
|
||||
+192.0.1.159 example.org
|
||||
+192.0.1.160 example.org
|
||||
+192.0.1.161 example.org
|
||||
+192.0.1.162 example.org
|
||||
+192.0.1.163 example.org
|
||||
+192.0.1.164 example.org
|
||||
+192.0.1.165 example.org
|
||||
+192.0.1.166 example.org
|
||||
+192.0.1.167 example.org
|
||||
+192.0.1.168 example.org
|
||||
+192.0.1.169 example.org
|
||||
+192.0.1.170 example.org
|
||||
+192.0.1.171 example.org
|
||||
+192.0.1.172 example.org
|
||||
+192.0.1.173 example.org
|
||||
+192.0.1.174 example.org
|
||||
+192.0.1.175 example.org
|
||||
+192.0.1.176 example.org
|
||||
+192.0.1.177 example.org
|
||||
+192.0.1.178 example.org
|
||||
+192.0.1.179 example.org
|
||||
+192.0.1.180 example.org
|
||||
+192.0.1.181 example.org
|
||||
+192.0.1.182 example.org
|
||||
+192.0.1.183 example.org
|
||||
+192.0.1.184 example.org
|
||||
+192.0.1.185 example.org
|
||||
+192.0.1.186 example.org
|
||||
+192.0.1.187 example.org
|
||||
+192.0.1.188 example.org
|
||||
+192.0.1.189 example.org
|
||||
+192.0.1.190 example.org
|
||||
+192.0.1.191 example.org
|
||||
+192.0.1.192 example.org
|
||||
+192.0.1.193 example.org
|
||||
+192.0.1.194 example.org
|
||||
+192.0.1.195 example.org
|
||||
+192.0.1.196 example.org
|
||||
+192.0.1.197 example.org
|
||||
+192.0.1.198 example.org
|
||||
+192.0.1.199 example.org
|
||||
+192.0.1.200 example.org
|
||||
+192.0.1.201 example.org
|
||||
+192.0.1.202 example.org
|
||||
+192.0.1.203 example.org
|
||||
+192.0.1.204 example.org
|
||||
+192.0.1.205 example.org
|
||||
+192.0.1.206 example.org
|
||||
+192.0.1.207 example.org
|
||||
+192.0.1.208 example.org
|
||||
+192.0.1.209 example.org
|
||||
+192.0.1.210 example.org
|
||||
+192.0.1.211 example.org
|
||||
+192.0.1.212 example.org
|
||||
+192.0.1.213 example.org
|
||||
+192.0.1.214 example.org
|
||||
+192.0.1.215 example.org
|
||||
+192.0.1.216 example.org
|
||||
+192.0.1.217 example.org
|
||||
+192.0.1.218 example.org
|
||||
+192.0.1.219 example.org
|
||||
+192.0.1.220 example.org
|
||||
+192.0.1.221 example.org
|
||||
+192.0.1.222 example.org
|
||||
+192.0.1.223 example.org
|
||||
+192.0.1.224 example.org
|
||||
+192.0.1.225 example.org
|
||||
+192.0.1.226 example.org
|
||||
+192.0.1.227 example.org
|
||||
+192.0.1.228 example.org
|
||||
+192.0.1.229 example.org
|
||||
+192.0.1.230 example.org
|
||||
+192.0.1.231 example.org
|
||||
+192.0.1.232 example.org
|
||||
+192.0.1.233 example.org
|
||||
+192.0.1.234 example.org
|
||||
+192.0.1.235 example.org
|
||||
+192.0.1.236 example.org
|
||||
+192.0.1.237 example.org
|
||||
+192.0.1.238 example.org
|
||||
+192.0.1.239 example.org
|
||||
+192.0.1.240 example.org
|
||||
+192.0.1.241 example.org
|
||||
+192.0.1.242 example.org
|
||||
+192.0.1.243 example.org
|
||||
+192.0.1.244 example.org
|
||||
+192.0.1.245 example.org
|
||||
+192.0.1.246 example.org
|
||||
+192.0.1.247 example.org
|
||||
+192.0.1.248 example.org
|
||||
+192.0.1.249 example.org
|
||||
+192.0.1.250 example.org
|
||||
+192.0.1.251 example.org
|
||||
+192.0.1.252 example.org
|
||||
+192.0.1.253 example.org
|
||||
+192.0.1.254 example.org
|
||||
diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
|
||||
index 18dccd5924..3d9bea60c6 100644
|
||||
--- a/sysdeps/posix/getaddrinfo.c
|
||||
+++ b/sysdeps/posix/getaddrinfo.c
|
||||
@@ -458,11 +458,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
if (name != NULL)
|
||||
{
|
||||
- at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||
- at->family = AF_UNSPEC;
|
||||
- at->scopeid = 0;
|
||||
- at->next = NULL;
|
||||
-
|
||||
if (req->ai_flags & AI_IDN)
|
||||
{
|
||||
char *out;
|
||||
@@ -473,13 +468,21 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
malloc_name = true;
|
||||
}
|
||||
|
||||
- if (__inet_aton_exact (name, (struct in_addr *) at->addr) != 0)
|
||||
+ uint32_t addr[4];
|
||||
+ if (__inet_aton_exact (name, (struct in_addr *) addr) != 0)
|
||||
{
|
||||
+ at = alloca_account (sizeof (struct gaih_addrtuple), alloca_used);
|
||||
+ at->scopeid = 0;
|
||||
+ at->next = NULL;
|
||||
+
|
||||
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
|
||||
- at->family = AF_INET;
|
||||
+ {
|
||||
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||||
+ at->family = AF_INET;
|
||||
+ }
|
||||
else if (req->ai_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED))
|
||||
{
|
||||
- at->addr[3] = at->addr[0];
|
||||
+ at->addr[3] = addr[0];
|
||||
at->addr[2] = htonl (0xffff);
|
||||
at->addr[1] = 0;
|
||||
at->addr[0] = 0;
|
||||
@@ -505,49 +505,62 @@
|
||||
|
||||
if (req->ai_flags & AI_CANONNAME)
|
||||
canon = name;
|
||||
+
|
||||
+ goto process_list;
|
||||
}
|
||||
- else if (at->family == AF_UNSPEC)
|
||||
+
|
||||
+ char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||||
+ int e;
|
||||
+
|
||||
+ if (scope_delim == NULL)
|
||||
+ e = inet_pton (AF_INET6, name, addr);
|
||||
+ else
|
||||
+ e = __inet_pton_length (AF_INET6, name, scope_delim - name, addr);
|
||||
+
|
||||
+ if (e > 0)
|
||||
{
|
||||
- char *scope_delim = strchr (name, SCOPE_DELIMITER);
|
||||
- int e;
|
||||
- if (scope_delim == NULL)
|
||||
- e = inet_pton (AF_INET6, name, at->addr);
|
||||
+ at = alloca_account (sizeof (struct gaih_addrtuple),
|
||||
+ alloca_used);
|
||||
+ at->scopeid = 0;
|
||||
+ at->next = NULL;
|
||||
+
|
||||
+ if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||
+ {
|
||||
+ memcpy (at->addr, addr, sizeof (at->addr));
|
||||
+ at->family = AF_INET6;
|
||||
+ }
|
||||
+ else if (req->ai_family == AF_INET
|
||||
+ && IN6_IS_ADDR_V4MAPPED (addr))
|
||||
+ {
|
||||
+ at->addr[0] = addr[3];
|
||||
+ at->addr[1] = addr[1];
|
||||
+ at->addr[2] = addr[2];
|
||||
+ at->addr[3] = addr[3];
|
||||
+ at->family = AF_INET;
|
||||
+ }
|
||||
else
|
||||
- e = __inet_pton_length (AF_INET6, name, scope_delim - name,
|
||||
- at->addr);
|
||||
- if (e > 0)
|
||||
{
|
||||
- if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
|
||||
- at->family = AF_INET6;
|
||||
- else if (req->ai_family == AF_INET
|
||||
- && IN6_IS_ADDR_V4MAPPED (at->addr))
|
||||
- {
|
||||
- at->addr[0] = at->addr[3];
|
||||
- at->family = AF_INET;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- result = -EAI_ADDRFAMILY;
|
||||
- goto free_and_return;
|
||||
- }
|
||||
-
|
||||
- if (scope_delim != NULL
|
||||
- && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||||
- scope_delim + 1,
|
||||
- &at->scopeid) != 0)
|
||||
- {
|
||||
- result = -EAI_NONAME;
|
||||
- goto free_and_return;
|
||||
- }
|
||||
+ result = -EAI_ADDRFAMILY;
|
||||
+ goto free_and_return;
|
||||
+ }
|
||||
|
||||
- if (req->ai_flags & AI_CANONNAME)
|
||||
- canon = name;
|
||||
+ if (scope_delim != NULL
|
||||
+ && __inet6_scopeid_pton ((struct in6_addr *) at->addr,
|
||||
+ scope_delim + 1,
|
||||
+ &at->scopeid) != 0)
|
||||
+ {
|
||||
+ result = -EAI_NONAME;
|
||||
+ goto free_and_return;
|
||||
}
|
||||
+
|
||||
+ if (req->ai_flags & AI_CANONNAME)
|
||||
+ canon = name;
|
||||
+
|
||||
+ goto process_list;
|
||||
}
|
||||
|
||||
- if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
|
||||
+ if ((req->ai_flags & AI_NUMERICHOST) == 0)
|
||||
{
|
||||
- struct gaih_addrtuple **pat = &at;
|
||||
int no_data = 0;
|
||||
int no_inet6_data = 0;
|
||||
service_user *nip;
|
||||
@@ -543,6 +559,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
enum nss_status status = NSS_STATUS_UNAVAIL;
|
||||
int no_more;
|
||||
struct resolv_context *res_ctx = NULL;
|
||||
+ bool do_merge = false;
|
||||
|
||||
/* If we do not have to look for IPv6 addresses or the canonical
|
||||
name, use the simple, old functions, which do not support
|
||||
@@ -579,7 +596,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
result = -EAI_MEMORY;
|
||||
goto free_and_return;
|
||||
}
|
||||
- *pat = addrmem;
|
||||
+ at = addrmem;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -632,6 +649,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
}
|
||||
|
||||
struct gaih_addrtuple *addrfree = addrmem;
|
||||
+ struct gaih_addrtuple **pat = &at;
|
||||
+
|
||||
for (int i = 0; i < air->naddrs; ++i)
|
||||
{
|
||||
socklen_t size = (air->family[i] == AF_INET
|
||||
@@ -695,12 +714,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
free (air);
|
||||
|
||||
- if (at->family == AF_UNSPEC)
|
||||
- {
|
||||
- result = -EAI_NONAME;
|
||||
- goto free_and_return;
|
||||
- }
|
||||
-
|
||||
goto process_list;
|
||||
}
|
||||
else if (err == 0)
|
||||
@@ -750,6 +763,22 @@
|
||||
|
||||
while (!no_more)
|
||||
{
|
||||
+ /* Always start afresh; continue should discard previous results
|
||||
+ and the hosts database does not support merge. */
|
||||
+ at = NULL;
|
||||
+ free (canonbuf);
|
||||
+ free (addrmem);
|
||||
+ canon = canonbuf = NULL;
|
||||
+ addrmem = NULL;
|
||||
+ got_ipv6 = false;
|
||||
+
|
||||
+ if (do_merge)
|
||||
+ {
|
||||
+ __set_h_errno (NETDB_INTERNAL);
|
||||
+ __set_errno (EBUSY);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
no_data = 0;
|
||||
nss_gethostbyname4_r fct4 = NULL;
|
||||
|
||||
@@ -744,12 +773,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
- status = DL_CALL_FCT (fct4, (name, pat,
|
||||
+ status = DL_CALL_FCT (fct4, (name, &at,
|
||||
tmpbuf->data, tmpbuf->length,
|
||||
&errno, &h_errno,
|
||||
NULL));
|
||||
if (status == NSS_STATUS_SUCCESS)
|
||||
break;
|
||||
+ /* gethostbyname4_r may write into AT, so reset it. */
|
||||
+ at = NULL;
|
||||
if (status != NSS_STATUS_TRYAGAIN
|
||||
|| errno != ERANGE || h_errno != NETDB_INTERNAL)
|
||||
{
|
||||
@@ -774,7 +805,9 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
no_data = 1;
|
||||
|
||||
if ((req->ai_flags & AI_CANONNAME) != 0 && canon == NULL)
|
||||
- canon = (*pat)->name;
|
||||
+ canon = at->name;
|
||||
+
|
||||
+ struct gaih_addrtuple **pat = &at;
|
||||
|
||||
while (*pat != NULL)
|
||||
{
|
||||
@@ -826,6 +859,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
|
||||
if (fct != NULL)
|
||||
{
|
||||
+ struct gaih_addrtuple **pat = &at;
|
||||
+
|
||||
if (req->ai_family == AF_INET6
|
||||
|| req->ai_family == AF_UNSPEC)
|
||||
{
|
||||
@@ -917,6 +946,10 @@
|
||||
if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
|
||||
break;
|
||||
|
||||
+ /* The hosts database does not support MERGE. */
|
||||
+ if (nss_next_action (nip, status) == NSS_ACTION_MERGE)
|
||||
+ do_merge = true;
|
||||
+
|
||||
if (nip->next == NULL)
|
||||
no_more = -1;
|
||||
else
|
||||
@@ -930,7 +969,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
|
||||
}
|
||||
|
||||
process_list:
|
||||
- if (at->family == AF_UNSPEC)
|
||||
+ if (at == NULL)
|
||||
{
|
||||
result = -EAI_NONAME;
|
||||
goto free_and_return;
|
||||
--
|
||||
2.39.3
|
||||
@@ -88,6 +88,7 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
|
||||
file://0037-Avoid-deadlock-between-pthread_create-and-ctors.patch \
|
||||
file://CVE-2023-0687.patch \
|
||||
file://CVE-2023-4911.patch \
|
||||
file://CVE-2023-4813.patch \
|
||||
"
|
||||
S = "${WORKDIR}/git"
|
||||
B = "${WORKDIR}/build-${TARGET_SYS}"
|
||||
|
||||
@@ -24,7 +24,7 @@ IMAGE_FSTYPES = "wic.vmdk"
|
||||
|
||||
inherit core-image setuptools3
|
||||
|
||||
SRCREV ?= "b86bf0103c5d5ee04012473b80353e3da1f9e67f"
|
||||
SRCREV ?= "77442211926cbe93d60108f6df4abda3bc06b735"
|
||||
SRC_URI = "git://git.yoctoproject.org/poky;branch=dunfell \
|
||||
file://Yocto_Build_Appliance.vmx \
|
||||
file://Yocto_Build_Appliance.vmxf \
|
||||
|
||||
35
meta/recipes-core/libxml/libxml2/CVE-2021-3516.patch
Normal file
35
meta/recipes-core/libxml/libxml2/CVE-2021-3516.patch
Normal file
@@ -0,0 +1,35 @@
|
||||
From 1358d157d0bd83be1dfe356a69213df9fac0b539 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 21 Apr 2021 13:23:27 +0200
|
||||
Subject: [PATCH] Fix use-after-free with `xmllint --html --push`
|
||||
|
||||
Call htmlCtxtUseOptions to make sure that names aren't stored in
|
||||
dictionaries.
|
||||
|
||||
Note that this issue only affects xmllint using the HTML push parser.
|
||||
|
||||
Fixes #230.
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/1358d157d0bd83be1dfe356a69213df9fac0b539]
|
||||
CVE: CVE-2021-3516
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
xmllint.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xmllint.c b/xmllint.c
|
||||
index 6ca1bf54d..dbef273a8 100644
|
||||
--- a/xmllint.c
|
||||
+++ b/xmllint.c
|
||||
@@ -2213,7 +2213,7 @@ static void parseAndPrintFile(char *filename, xmlParserCtxtPtr rectxt) {
|
||||
if (res > 0) {
|
||||
ctxt = htmlCreatePushParserCtxt(NULL, NULL,
|
||||
chars, res, filename, XML_CHAR_ENCODING_NONE);
|
||||
- xmlCtxtUseOptions(ctxt, options);
|
||||
+ htmlCtxtUseOptions(ctxt, options);
|
||||
while ((res = fread(chars, 1, pushsize, f)) > 0) {
|
||||
htmlParseChunk(ctxt, chars, res, 0);
|
||||
}
|
||||
--
|
||||
GitLab
|
||||
|
||||
50
meta/recipes-core/libxml/libxml2/CVE-2023-45322-1.patch
Normal file
50
meta/recipes-core/libxml/libxml2/CVE-2023-45322-1.patch
Normal file
@@ -0,0 +1,50 @@
|
||||
From a22bd982bf10291deea8ba0c61bf75b898c604ce Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 2 Nov 2022 15:44:42 +0100
|
||||
Subject: [PATCH] malloc-fail: Fix memory leak in xmlStaticCopyNodeList
|
||||
|
||||
Found with libFuzzer, see #344.
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/a22bd982bf10291deea8ba0c61bf75b898c604ce]
|
||||
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
tree.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tree.c b/tree.c
|
||||
index 507869efe..647288ce3 100644
|
||||
--- a/tree.c
|
||||
+++ b/tree.c
|
||||
@@ -4461,7 +4461,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
||||
}
|
||||
if (doc->intSubset == NULL) {
|
||||
q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
|
||||
- if (q == NULL) return(NULL);
|
||||
+ if (q == NULL) goto error;
|
||||
q->doc = doc;
|
||||
q->parent = parent;
|
||||
doc->intSubset = (xmlDtdPtr) q;
|
||||
@@ -4473,7 +4473,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
||||
} else
|
||||
#endif /* LIBXML_TREE_ENABLED */
|
||||
q = xmlStaticCopyNode(node, doc, parent, 1);
|
||||
- if (q == NULL) return(NULL);
|
||||
+ if (q == NULL) goto error;
|
||||
if (ret == NULL) {
|
||||
q->prev = NULL;
|
||||
ret = p = q;
|
||||
@@ -4486,6 +4486,9 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
||||
node = node->next;
|
||||
}
|
||||
return(ret);
|
||||
+error:
|
||||
+ xmlFreeNodeList(ret);
|
||||
+ return(NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
GitLab
|
||||
|
||||
80
meta/recipes-core/libxml/libxml2/CVE-2023-45322-2.patch
Normal file
80
meta/recipes-core/libxml/libxml2/CVE-2023-45322-2.patch
Normal file
@@ -0,0 +1,80 @@
|
||||
From d39f78069dff496ec865c73aa44d7110e429bce9 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 23 Aug 2023 20:24:24 +0200
|
||||
Subject: [PATCH] tree: Fix copying of DTDs
|
||||
|
||||
- Don't create multiple DTD nodes.
|
||||
- Fix UAF if malloc fails.
|
||||
- Skip DTD nodes if tree module is disabled.
|
||||
|
||||
Fixes #583.
|
||||
|
||||
CVE: CVE-2023-45322
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/d39f78069dff496ec865c73aa44d7110e429bce9]
|
||||
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
tree.c | 31 ++++++++++++++++---------------
|
||||
1 file changed, 16 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/tree.c b/tree.c
|
||||
index 6c8a875b9..02c1b5791 100644
|
||||
--- a/tree.c
|
||||
+++ b/tree.c
|
||||
@@ -4471,29 +4471,28 @@ xmlNodePtr
|
||||
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
||||
xmlNodePtr ret = NULL;
|
||||
xmlNodePtr p = NULL,q;
|
||||
+ xmlDtdPtr newSubset = NULL;
|
||||
|
||||
while (node != NULL) {
|
||||
-#ifdef LIBXML_TREE_ENABLED
|
||||
if (node->type == XML_DTD_NODE ) {
|
||||
- if (doc == NULL) {
|
||||
+#ifdef LIBXML_TREE_ENABLED
|
||||
+ if ((doc == NULL) || (doc->intSubset != NULL)) {
|
||||
node = node->next;
|
||||
continue;
|
||||
}
|
||||
- if (doc->intSubset == NULL) {
|
||||
- q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
|
||||
- if (q == NULL) goto error;
|
||||
- q->doc = doc;
|
||||
- q->parent = parent;
|
||||
- doc->intSubset = (xmlDtdPtr) q;
|
||||
- xmlAddChild(parent, q);
|
||||
- } else {
|
||||
- q = (xmlNodePtr) doc->intSubset;
|
||||
- xmlAddChild(parent, q);
|
||||
- }
|
||||
- } else
|
||||
+ q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
|
||||
+ if (q == NULL) goto error;
|
||||
+ q->doc = doc;
|
||||
+ q->parent = parent;
|
||||
+ newSubset = (xmlDtdPtr) q;
|
||||
+#else
|
||||
+ node = node->next;
|
||||
+ continue;
|
||||
#endif /* LIBXML_TREE_ENABLED */
|
||||
+ } else {
|
||||
q = xmlStaticCopyNode(node, doc, parent, 1);
|
||||
- if (q == NULL) goto error;
|
||||
+ if (q == NULL) goto error;
|
||||
+ }
|
||||
if (ret == NULL) {
|
||||
q->prev = NULL;
|
||||
ret = p = q;
|
||||
@@ -4505,6 +4504,8 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
+ if (newSubset != NULL)
|
||||
+ doc->intSubset = newSubset;
|
||||
return(ret);
|
||||
error:
|
||||
xmlFreeNodeList(ret);
|
||||
--
|
||||
GitLab
|
||||
|
||||
38
meta/recipes-core/libxml/libxml2/CVE-2024-25062-pre1.patch
Normal file
38
meta/recipes-core/libxml/libxml2/CVE-2024-25062-pre1.patch
Normal file
@@ -0,0 +1,38 @@
|
||||
From 31c6ce3b63f8a494ad9e31ca65187a73d8ad3508 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 9 Nov 2020 17:55:44 +0100
|
||||
Subject: [PATCH] Avoid call stack overflow with XML reader and recursive
|
||||
XIncludes
|
||||
|
||||
Don't process XIncludes in the result of another inclusion to avoid
|
||||
infinite recursion resulting in a call stack overflow.
|
||||
|
||||
This is something the XInclude engine shouldn't allow but correct
|
||||
handling of intra-document includes would require major changes.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/31c6ce3b63f8a494ad9e31ca65187a73d8ad3508]
|
||||
CVE: CVE-2024-25062 #Dependency Patch
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
xmlreader.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 01adf74f4..72e40b032 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -1585,7 +1585,8 @@ node_found:
|
||||
/*
|
||||
* Handle XInclude if asked for
|
||||
*/
|
||||
- if ((reader->xinclude) && (reader->node != NULL) &&
|
||||
+ if ((reader->xinclude) && (reader->in_xinclude == 0) &&
|
||||
+ (reader->node != NULL) &&
|
||||
(reader->node->type == XML_ELEMENT_NODE) &&
|
||||
(reader->node->ns != NULL) &&
|
||||
((xmlStrEqual(reader->node->ns->href, XINCLUDE_NS)) ||
|
||||
--
|
||||
GitLab
|
||||
|
||||
33
meta/recipes-core/libxml/libxml2/CVE-2024-25062.patch
Normal file
33
meta/recipes-core/libxml/libxml2/CVE-2024-25062.patch
Normal file
@@ -0,0 +1,33 @@
|
||||
From 2b0aac140d739905c7848a42efc60bfe783a39b7 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sat, 14 Oct 2023 22:45:54 +0200
|
||||
Subject: [PATCH] [CVE-2024-25062] xmlreader: Don't expand XIncludes when
|
||||
backtracking
|
||||
|
||||
Fixes a use-after-free if XML Reader if used with DTD validation and
|
||||
XInclude expansion.
|
||||
|
||||
Fixes #604.
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/2b0aac140d739905c7848a42efc60bfe783a39b7]
|
||||
CVE: CVE-2024-25062
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
xmlreader.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 979385a13..fefd68e0b 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -1443,6 +1443,7 @@ node_found:
|
||||
* Handle XInclude if asked for
|
||||
*/
|
||||
if ((reader->xinclude) && (reader->in_xinclude == 0) &&
|
||||
+ (reader->state != XML_TEXTREADER_BACKTRACK) &&
|
||||
(reader->node != NULL) &&
|
||||
(reader->node->type == XML_ELEMENT_NODE) &&
|
||||
(reader->node->ns != NULL) &&
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -41,6 +41,11 @@ SRC_URI += "http://www.w3.org/XML/Test/xmlts20080827.tar.gz;subdir=${BP};name=te
|
||||
file://CVE-2023-39615-pre.patch \
|
||||
file://CVE-2023-39615-0001.patch \
|
||||
file://CVE-2023-39615-0002.patch \
|
||||
file://CVE-2021-3516.patch \
|
||||
file://CVE-2023-45322-1.patch \
|
||||
file://CVE-2023-45322-2.patch \
|
||||
file://CVE-2024-25062-pre1.patch \
|
||||
file://CVE-2024-25062.patch \
|
||||
"
|
||||
|
||||
SRC_URI[archive.sha256sum] = "593b7b751dd18c2d6abcd0c4bcb29efc203d0b4373a6df98e3a455ea74ae2813"
|
||||
|
||||
@@ -26,13 +26,17 @@ NVDCVE_API_KEY ?= ""
|
||||
# Use a negative value to skip the update
|
||||
CVE_DB_UPDATE_INTERVAL ?= "86400"
|
||||
|
||||
# Timeout for blocking socket operations, such as the connection attempt.
|
||||
CVE_SOCKET_TIMEOUT ?= "60"
|
||||
# CVE database incremental update age threshold, in seconds. If the database is
|
||||
# older than this threshold, do a full re-download, else, do an incremental
|
||||
# update. By default: the maximum allowed value from NVD: 120 days (120*24*60*60)
|
||||
# Use 0 to force a full download.
|
||||
CVE_DB_INCR_UPDATE_AGE_THRES ?= "10368000"
|
||||
|
||||
# Number of attempts for each http query to nvd server before giving up
|
||||
CVE_DB_UPDATE_ATTEMPTS ?= "5"
|
||||
|
||||
CVE_DB_TEMP_FILE ?= "${CVE_CHECK_DB_DIR}/temp_nvdcve_2.db"
|
||||
|
||||
CVE_CHECK_DB_FILE ?= "${CVE_CHECK_DB_DIR}/nvdcve_2.db"
|
||||
|
||||
python () {
|
||||
if not bb.data.inherits_class("cve-check", d):
|
||||
raise bb.parse.SkipRecipe("Skip recipe when cve-check class is not loaded.")
|
||||
@@ -114,9 +118,13 @@ def cleanup_db_download(db_file, db_tmp_file):
|
||||
if os.path.exists(db_tmp_file):
|
||||
os.remove(db_tmp_file)
|
||||
|
||||
def nvd_request_next(url, api_key, args):
|
||||
def nvd_request_wait(attempt, min_wait):
|
||||
return min ( ( (2 * attempt) + min_wait ) , 30)
|
||||
|
||||
def nvd_request_next(url, attempts, api_key, args, min_wait):
|
||||
"""
|
||||
Request next part of the NVD dabase
|
||||
Request next part of the NVD database
|
||||
NVD API documentation: https://nvd.nist.gov/developers/vulnerabilities
|
||||
"""
|
||||
|
||||
import urllib.request
|
||||
@@ -130,7 +138,7 @@ def nvd_request_next(url, api_key, args):
|
||||
request.add_header("apiKey", api_key)
|
||||
bb.note("Requesting %s" % request.full_url)
|
||||
|
||||
for attempt in range(5):
|
||||
for attempt in range(attempts):
|
||||
try:
|
||||
r = urllib.request.urlopen(request)
|
||||
|
||||
@@ -143,8 +151,10 @@ def nvd_request_next(url, api_key, args):
|
||||
r.close()
|
||||
|
||||
except Exception as e:
|
||||
bb.note("CVE database: received error (%s), retrying" % (e))
|
||||
time.sleep(6)
|
||||
wait_time = nvd_request_wait(attempt, min_wait)
|
||||
bb.note("CVE database: received error (%s)" % (e))
|
||||
bb.note("CVE database: retrying download after %d seconds. attempted (%d/%d)" % (wait_time, attempt+1, attempts))
|
||||
time.sleep(wait_time)
|
||||
pass
|
||||
else:
|
||||
return raw_data
|
||||
@@ -167,18 +177,24 @@ def update_db_file(db_tmp_file, d, database_time):
|
||||
|
||||
req_args = {'startIndex' : 0}
|
||||
|
||||
# The maximum range for time is 120 days
|
||||
# Force a complete update if our range is longer
|
||||
if (database_time != 0):
|
||||
incr_update_threshold = int(d.getVar("CVE_DB_INCR_UPDATE_AGE_THRES"))
|
||||
if database_time != 0:
|
||||
database_date = datetime.datetime.fromtimestamp(database_time, tz=datetime.timezone.utc)
|
||||
today_date = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
delta = today_date - database_date
|
||||
if delta.days < 120:
|
||||
if incr_update_threshold == 0:
|
||||
bb.note("CVE database: forced full update")
|
||||
elif delta < datetime.timedelta(seconds=incr_update_threshold):
|
||||
bb.note("CVE database: performing partial update")
|
||||
# The maximum range for time is 120 days
|
||||
if delta > datetime.timedelta(days=120):
|
||||
bb.error("CVE database: Trying to do an incremental update on a larger than supported range")
|
||||
req_args['lastModStartDate'] = database_date.isoformat()
|
||||
req_args['lastModEndDate'] = today_date.isoformat()
|
||||
else:
|
||||
bb.note("CVE database: file too old, forcing a full update")
|
||||
else:
|
||||
bb.note("CVE database: no preexisting database, do a full download")
|
||||
|
||||
with bb.progress.ProgressHandler(d) as ph, open(os.path.join(d.getVar("TMPDIR"), 'cve_check'), 'a') as cve_f:
|
||||
|
||||
@@ -186,10 +202,16 @@ def update_db_file(db_tmp_file, d, database_time):
|
||||
index = 0
|
||||
url = d.getVar("NVDCVE_URL")
|
||||
api_key = d.getVar("NVDCVE_API_KEY") or None
|
||||
attempts = int(d.getVar("CVE_DB_UPDATE_ATTEMPTS"))
|
||||
|
||||
# Recommended by NVD
|
||||
wait_time = 6
|
||||
if api_key:
|
||||
wait_time = 2
|
||||
|
||||
while True:
|
||||
req_args['startIndex'] = index
|
||||
raw_data = nvd_request_next(url, api_key, req_args)
|
||||
raw_data = nvd_request_next(url, attempts, api_key, req_args, wait_time)
|
||||
if raw_data is None:
|
||||
# We haven't managed to download data
|
||||
return False
|
||||
@@ -209,7 +231,7 @@ def update_db_file(db_tmp_file, d, database_time):
|
||||
break
|
||||
|
||||
# Recommended by NVD
|
||||
time.sleep(6)
|
||||
time.sleep(wait_time)
|
||||
|
||||
# Update success, set the date to cve_check file.
|
||||
cve_f.write('CVE database update : %s\n\n' % datetime.date.today())
|
||||
@@ -301,6 +323,10 @@ def update_db(conn, elt):
|
||||
accessVector = None
|
||||
cveId = elt['cve']['id']
|
||||
if elt['cve']['vulnStatus'] == "Rejected":
|
||||
c = conn.cursor()
|
||||
c.execute("delete from PRODUCTS where ID = ?;", [cveId])
|
||||
c.execute("delete from NVD where ID = ?;", [cveId])
|
||||
c.close()
|
||||
return
|
||||
cveDesc = ""
|
||||
for desc in elt['cve']['descriptions']:
|
||||
@@ -330,6 +356,10 @@ def update_db(conn, elt):
|
||||
[cveId, cveDesc, cvssv2, cvssv3, date, accessVector]).close()
|
||||
|
||||
try:
|
||||
# Remove any pre-existing CVE configuration. Even for partial database
|
||||
# update, those will be repopulated. This ensures that old
|
||||
# configuration is not kept for an updated CVE.
|
||||
conn.execute("delete from PRODUCTS where ID = ?", [cveId]).close()
|
||||
for config in elt['cve']['configurations']:
|
||||
# This is suboptimal as it doesn't handle AND/OR and negate, but is better than nothing
|
||||
for node in config["nodes"]:
|
||||
|
||||
45
meta/recipes-core/ncurses/files/CVE-2023-29491.patch
Normal file
45
meta/recipes-core/ncurses/files/CVE-2023-29491.patch
Normal file
@@ -0,0 +1,45 @@
|
||||
Backport of:
|
||||
|
||||
Author: Sven Joachim <svenjoac@gmx.de>
|
||||
Description: Change the --disable-root-environ configure option behavior
|
||||
By default, the --disable-root-environ option forbids program run by
|
||||
the superuser to load custom terminfo entries. This patch changes
|
||||
that to only restrict programs running with elevated privileges,
|
||||
matching the behavior of the --disable-setuid-environ option
|
||||
introduced in the 20230423 upstream patchlevel.
|
||||
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1034372#29
|
||||
Bug: https://lists.gnu.org/archive/html/bug-ncurses/2023-04/msg00018.html
|
||||
Forwarded: not-needed
|
||||
Last-Update: 2023-05-01
|
||||
|
||||
Upstream-Status: Backport [https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/ncurses/6.2-0ubuntu2.1/ncurses_6.2-0ubuntu2.1.debian.tar.xz]
|
||||
CVE: CVE-2023-29491
|
||||
Signed-off-by: Virendra Thakur <virendrak@kpit.com>
|
||||
|
||||
---
|
||||
ncurses/tinfo/access.c | 2 --
|
||||
1 file changed, 2 deletions(-)
|
||||
|
||||
--- a/ncurses/tinfo/access.c
|
||||
+++ b/ncurses/tinfo/access.c
|
||||
@@ -178,15 +178,16 @@ _nc_is_file_path(const char *path)
|
||||
NCURSES_EXPORT(int)
|
||||
_nc_env_access(void)
|
||||
{
|
||||
+ int result = TRUE;
|
||||
+
|
||||
#if HAVE_ISSETUGID
|
||||
if (issetugid())
|
||||
- return FALSE;
|
||||
+ result = FALSE;
|
||||
#elif HAVE_GETEUID && HAVE_GETEGID
|
||||
if (getuid() != geteuid()
|
||||
|| getgid() != getegid())
|
||||
- return FALSE;
|
||||
+ result = FALSE;
|
||||
#endif
|
||||
- /* ...finally, disallow root */
|
||||
- return (getuid() != ROOT_UID) && (geteuid() != ROOT_UID);
|
||||
+ return result;
|
||||
}
|
||||
#endif
|
||||
79
meta/recipes-core/ncurses/files/CVE-2023-50495.patch
Normal file
79
meta/recipes-core/ncurses/files/CVE-2023-50495.patch
Normal file
@@ -0,0 +1,79 @@
|
||||
Fix for CVE-2023-50495 from upstream:
|
||||
https://github.com/ThomasDickey/ncurses-snapshots/commit/efe9674ee14b14b788f9618941f97d31742f0adc
|
||||
|
||||
Reference:
|
||||
https://invisible-island.net/archives/ncurses/6.4/ncurses-6.4-20230424.patch.gz
|
||||
|
||||
Upstream-Status: Backport [import from suse ftp.pbone.net/mirror/ftp.opensuse.org/update/leap-micro/5.3/sle/src/ncurses-6.1-150000.5.20.1.src.rpm
|
||||
Upstream commit https://github.com/ThomasDickey/ncurses-snapshots/commit/efe9674ee14b14b788f9618941f97d31742f0adc]
|
||||
CVE: CVE-2023-50495
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
ncurses/tinfo/parse_entry.c | 23 ++++++++++++++++-------
|
||||
1 file changed, 16 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/ncurses/tinfo/parse_entry.c b/ncurses/tinfo/parse_entry.c
|
||||
index 23574b66..56ba9ae6 100644
|
||||
--- a/ncurses/tinfo/parse_entry.c
|
||||
+++ b/ncurses/tinfo/parse_entry.c
|
||||
@@ -110,7 +110,7 @@ _nc_extend_names(ENTRY * entryp, const char *name, int token_type)
|
||||
/* Well, we are given a cancel for a name that we don't recognize */
|
||||
return _nc_extend_names(entryp, name, STRING);
|
||||
default:
|
||||
- return 0;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/* Adjust the 'offset' (insertion-point) to keep the lists of extended
|
||||
@@ -142,6 +142,11 @@ _nc_extend_names(ENTRY * entryp, const char *name, int token_type)
|
||||
for (last = (unsigned) (max - 1); last > tindex; last--)
|
||||
|
||||
if (!found) {
|
||||
+ char *saved;
|
||||
+
|
||||
+ if ((saved = _nc_save_str(name)) == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
switch (token_type) {
|
||||
case BOOLEAN:
|
||||
tp->ext_Booleans++;
|
||||
@@ -169,7 +174,7 @@ _nc_extend_names(ENTRY * entryp, const char *name, int token_type)
|
||||
TYPE_REALLOC(char *, actual, tp->ext_Names);
|
||||
while (--actual > offset)
|
||||
tp->ext_Names[actual] = tp->ext_Names[actual - 1];
|
||||
- tp->ext_Names[offset] = _nc_save_str(name);
|
||||
+ tp->ext_Names[offset] = saved;
|
||||
}
|
||||
|
||||
temp.nte_name = tp->ext_Names[offset];
|
||||
@@ -337,6 +342,8 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent)
|
||||
bool is_use = (strcmp(_nc_curr_token.tk_name, "use") == 0);
|
||||
bool is_tc = !is_use && (strcmp(_nc_curr_token.tk_name, "tc") == 0);
|
||||
if (is_use || is_tc) {
|
||||
+ char *saved;
|
||||
+
|
||||
if (!VALID_STRING(_nc_curr_token.tk_valstring)
|
||||
|| _nc_curr_token.tk_valstring[0] == '\0') {
|
||||
_nc_warning("missing name for use-clause");
|
||||
@@ -350,11 +357,13 @@ _nc_parse_entry(ENTRY * entryp, int literal, bool silent)
|
||||
_nc_curr_token.tk_valstring);
|
||||
continue;
|
||||
}
|
||||
- entryp->uses[entryp->nuses].name = _nc_save_str(_nc_curr_token.tk_valstring);
|
||||
- entryp->uses[entryp->nuses].line = _nc_curr_line;
|
||||
- entryp->nuses++;
|
||||
- if (entryp->nuses > 1 && is_tc) {
|
||||
- BAD_TC_USAGE
|
||||
+ if ((saved = _nc_save_str(_nc_curr_token.tk_valstring)) != NULL) {
|
||||
+ entryp->uses[entryp->nuses].name = saved;
|
||||
+ entryp->uses[entryp->nuses].line = _nc_curr_line;
|
||||
+ entryp->nuses++;
|
||||
+ if (entryp->nuses > 1 && is_tc) {
|
||||
+ BAD_TC_USAGE
|
||||
+ }
|
||||
}
|
||||
} else {
|
||||
/* normal token lookup */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -5,11 +5,13 @@ SRC_URI += "file://0001-tic-hang.patch \
|
||||
file://0003-gen-pkgconfig.in-Do-not-include-LDFLAGS-in-generated.patch \
|
||||
file://CVE-2021-39537.patch \
|
||||
file://CVE-2022-29458.patch \
|
||||
file://CVE-2023-29491.patch \
|
||||
file://CVE-2023-50495.patch \
|
||||
"
|
||||
# commit id corresponds to the revision in package version
|
||||
SRCREV = "a669013cd5e9d6434e5301348ea51baf306c93c4"
|
||||
S = "${WORKDIR}/git"
|
||||
EXTRA_OECONF += "--with-abi-version=5"
|
||||
EXTRA_OECONF += "--with-abi-version=5 --disable-root-environ"
|
||||
UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+(\.\d+)+(\+\d+)*)"
|
||||
|
||||
# This is needed when using patchlevel versions like 6.1+20181013
|
||||
|
||||
@@ -53,3 +53,6 @@ do_install_append_class-target() {
|
||||
}
|
||||
|
||||
BBCLASSEXTEND = "native nativesdk"
|
||||
|
||||
# this CVE is for cloudflare zlib
|
||||
CVE_CHECK_WHITELIST += "CVE-2023-6992"
|
||||
|
||||
@@ -55,5 +55,12 @@ SRC_URI = "\
|
||||
file://CVE-2022-38533.patch \
|
||||
file://CVE-2023-25588.patch \
|
||||
file://CVE-2021-46174.patch \
|
||||
file://CVE-2023-25584.patch \
|
||||
file://CVE-2022-47007.patch \
|
||||
file://CVE-2022-47008.patch \
|
||||
file://CVE-2022-47010.patch \
|
||||
file://CVE-2022-47011.patch \
|
||||
file://CVE-2022-48063.patch \
|
||||
file://CVE-2022-47695.patch \
|
||||
"
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
32
meta/recipes-devtools/binutils/binutils/CVE-2022-47007.patch
Normal file
32
meta/recipes-devtools/binutils/binutils/CVE-2022-47007.patch
Normal file
@@ -0,0 +1,32 @@
|
||||
From 0ebc886149c22aceaf8ed74267821a59ca9d03eb Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Fri, 17 Jun 2022 09:00:41 +0930
|
||||
Subject: [PATCH] PR29254, memory leak in stab_demangle_v3_arg
|
||||
|
||||
PR 29254
|
||||
* stabs.c (stab_demangle_v3_arg): Free dt on failure path.
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff_plain;h=0ebc886149c22aceaf8ed74267821a59ca9d03eb]
|
||||
CVE: CVE-2022-47007
|
||||
Signed-off-by: Virendra Thakur <virendrak@kpit.com>
|
||||
Comment: Patch refreshed based on codebase.
|
||||
---
|
||||
binutils/stabs.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/binutils/stabs.c b/binutils/stabs.c
|
||||
index 2b5241637c1..796ff85b86a 100644
|
||||
--- a/binutils/stabs.c
|
||||
+++ b/binutils/stabs.c
|
||||
@@ -5476,7 +5476,10 @@
|
||||
dc->u.s_binary.right,
|
||||
&varargs);
|
||||
if (pargs == NULL)
|
||||
- return NULL;
|
||||
+ {
|
||||
+ free (dt);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
return debug_make_function_type (dhandle, dt, pargs, varargs);
|
||||
}
|
||||
|
||||
64
meta/recipes-devtools/binutils/binutils/CVE-2022-47008.patch
Normal file
64
meta/recipes-devtools/binutils/binutils/CVE-2022-47008.patch
Normal file
@@ -0,0 +1,64 @@
|
||||
From d6e1d48c83b165c129cb0aa78905f7ca80a1f682 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Fri, 17 Jun 2022 09:13:38 +0930
|
||||
Subject: [PATCH] PR29255, memory leak in make_tempdir
|
||||
|
||||
PR 29255
|
||||
* bucomm.c (make_tempdir, make_tempname): Free template on all
|
||||
failure paths.
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff_plain;h=d6e1d48c83b165c129cb0aa78905f7ca80a1f682]
|
||||
CVE: CVE-2022-47008
|
||||
Signed-off-by: Virendra Thakur <virendrak@kpit.com>
|
||||
Comment: Patch refreshed based on codebase.
|
||||
---
|
||||
binutils/bucomm.c | 20 +++++++++++---------
|
||||
1 file changed, 11 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/binutils/bucomm.c b/binutils/bucomm.c
|
||||
index fdc2209df9c..4395cb9f7f5 100644
|
||||
--- a/binutils/bucomm.c
|
||||
+++ b/binutils/bucomm.c
|
||||
@@ -542,8 +542,9 @@
|
||||
#else
|
||||
tmpname = mktemp (tmpname);
|
||||
if (tmpname == NULL)
|
||||
- return NULL;
|
||||
- fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
+ fd = -1;
|
||||
+ else
|
||||
+ fd = open (tmpname, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||
#endif
|
||||
if (fd == -1)
|
||||
{
|
||||
@@ -561,22 +562,23 @@
|
||||
make_tempdir (const char *filename)
|
||||
{
|
||||
char *tmpname = template_in_dir (filename);
|
||||
+ char *ret;
|
||||
|
||||
#ifdef HAVE_MKDTEMP
|
||||
- return mkdtemp (tmpname);
|
||||
+ ret = mkdtemp (tmpname);
|
||||
#else
|
||||
- tmpname = mktemp (tmpname);
|
||||
- if (tmpname == NULL)
|
||||
- return NULL;
|
||||
+ ret = mktemp (tmpname);
|
||||
#if defined (_WIN32) && !defined (__CYGWIN32__)
|
||||
if (mkdir (tmpname) != 0)
|
||||
- return NULL;
|
||||
+ ret = NULL;
|
||||
#else
|
||||
if (mkdir (tmpname, 0700) != 0)
|
||||
- return NULL;
|
||||
+ ret = NULL;
|
||||
#endif
|
||||
- return tmpname;
|
||||
#endif
|
||||
+ if (ret == NULL)
|
||||
+ free (tmpname);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/* Parse a string into a VMA, with a fatal error if it can't be
|
||||
|
||||
34
meta/recipes-devtools/binutils/binutils/CVE-2022-47010.patch
Normal file
34
meta/recipes-devtools/binutils/binutils/CVE-2022-47010.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
From 0d02e70b197c786f26175b9a73f94e01d14abdab Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Mon, 20 Jun 2022 10:39:31 +0930
|
||||
Subject: [PATCH] PR29262, memory leak in pr_function_type
|
||||
|
||||
PR 29262
|
||||
* prdbg.c (pr_function_type): Free "s" on failure path.
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff_plain;h=0d02e70b197c786f26175b9a73f94e01d14abdab]
|
||||
CVE: CVE-2022-47010
|
||||
Signed-off-by: Virendra Thakur <virendrak@kpit.com>
|
||||
Comment: Patch refreshed based on codebase.
|
||||
---
|
||||
binutils/prdbg.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/binutils/prdbg.c b/binutils/prdbg.c
|
||||
index c1e41628d26..bb42a5b6c2d 100644
|
||||
--- a/binutils/prdbg.c
|
||||
+++ b/binutils/prdbg.c
|
||||
@@ -778,12 +778,9 @@
|
||||
|
||||
strcat (s, ")");
|
||||
|
||||
- if (! substitute_type (info, s))
|
||||
- return FALSE;
|
||||
-
|
||||
+ bfd_boolean ret = substitute_type (info, s);
|
||||
free (s);
|
||||
-
|
||||
- return TRUE;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/* Turn the top type on the stack into a reference to that type. */
|
||||
31
meta/recipes-devtools/binutils/binutils/CVE-2022-47011.patch
Normal file
31
meta/recipes-devtools/binutils/binutils/CVE-2022-47011.patch
Normal file
@@ -0,0 +1,31 @@
|
||||
From 8a24927bc8dbf6beac2000593b21235c3796dc35 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Mon, 20 Jun 2022 10:39:13 +0930
|
||||
Subject: [PATCH] PR29261, memory leak in parse_stab_struct_fields
|
||||
|
||||
PR 29261
|
||||
* stabs.c (parse_stab_struct_fields): Free "fields" on failure path.
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff_plain;h=8a24927bc8dbf6beac2000593b21235c3796dc35]
|
||||
CVE: CVE-2022-47011
|
||||
Signed-off-by: Virendra Thakur <virendrak@kpit.com>
|
||||
Comment: Patch refreshed based on codebase.
|
||||
---
|
||||
binutils/stabs.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/binutils/stabs.c b/binutils/stabs.c
|
||||
index 796ff85b86a..bf3f578cbcc 100644
|
||||
--- a/binutils/stabs.c
|
||||
+++ b/binutils/stabs.c
|
||||
@@ -2368,7 +2368,10 @@
|
||||
|
||||
if (! parse_stab_one_struct_field (dhandle, info, pp, p, fields + c,
|
||||
staticsp, p_end))
|
||||
- return FALSE;
|
||||
+ {
|
||||
+ free (fields);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
|
||||
++c;
|
||||
}
|
||||
57
meta/recipes-devtools/binutils/binutils/CVE-2022-47695.patch
Normal file
57
meta/recipes-devtools/binutils/binutils/CVE-2022-47695.patch
Normal file
@@ -0,0 +1,57 @@
|
||||
From 3d3af4ba39e892b1c544d667ca241846bc3df386 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Sun, 4 Dec 2022 22:15:40 +1030
|
||||
Subject: [PATCH] PR29846, segmentation fault in objdump.c compare_symbols
|
||||
|
||||
Fixes a fuzzed object file problem where plt relocs were manipulated
|
||||
in such a way that two synthetic symbols were generated at the same
|
||||
plt location. Won't occur in real object files.
|
||||
|
||||
PR 29846
|
||||
PR 20337
|
||||
* objdump.c (compare_symbols): Test symbol flags to exclude
|
||||
section and synthetic symbols before attempting to check flavour.
|
||||
Upstream-Status: Backport [https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=3d3af4ba39e892b1c544d667ca241846bc3df386]
|
||||
CVE: CVE-2022-47695
|
||||
Signed-off-by: Virendra Thakur <virendrak@kpit.com>
|
||||
Comment: Patch refreshed based on codebase.
|
||||
---
|
||||
binutils/objdump.c | 23 ++++++++++-------------
|
||||
1 file changed, 10 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/binutils/objdump.c b/binutils/objdump.c
|
||||
index e8481b2d928..d95c8b68bf0 100644
|
||||
--- a/binutils/objdump.c
|
||||
+++ b/binutils/objdump.c
|
||||
@@ -935,20 +935,17 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (bfd_get_flavour (bfd_asymbol_bfd (a)) == bfd_target_elf_flavour
|
||||
+ /* Sort larger size ELF symbols before smaller. See PR20337. */
|
||||
+ bfd_vma asz = 0;
|
||||
+ if ((a->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
|
||||
+ && bfd_get_flavour (bfd_asymbol_bfd (a)) == bfd_target_elf_flavour)
|
||||
+ asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
|
||||
+ bfd_vma bsz = 0;
|
||||
+ if ((b->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0
|
||||
&& bfd_get_flavour (bfd_asymbol_bfd (b)) == bfd_target_elf_flavour)
|
||||
- {
|
||||
- bfd_vma asz, bsz;
|
||||
-
|
||||
- asz = 0;
|
||||
- if ((a->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
|
||||
- asz = ((elf_symbol_type *) a)->internal_elf_sym.st_size;
|
||||
- bsz = 0;
|
||||
- if ((b->flags & (BSF_SECTION_SYM | BSF_SYNTHETIC)) == 0)
|
||||
- bsz = ((elf_symbol_type *) b)->internal_elf_sym.st_size;
|
||||
- if (asz != bsz)
|
||||
- return asz > bsz ? -1 : 1;
|
||||
- }
|
||||
+ bsz = ((elf_symbol_type *) b)->internal_elf_sym.st_size;
|
||||
+ if (asz != bsz)
|
||||
+ return asz > bsz ? -1 : 1;
|
||||
|
||||
/* Symbols that start with '.' might be section names, so sort them
|
||||
after symbols that don't start with '.'. */
|
||||
|
||||
49
meta/recipes-devtools/binutils/binutils/CVE-2022-48063.patch
Normal file
49
meta/recipes-devtools/binutils/binutils/CVE-2022-48063.patch
Normal file
@@ -0,0 +1,49 @@
|
||||
From 75393a2d54bcc40053e5262a3de9d70c5ebfbbfd Mon Sep 17 00:00:00 2001
|
||||
From: Nick Clifton <nickc@redhat.com>
|
||||
Date: Wed, 21 Dec 2022 11:51:23 +0000
|
||||
Subject: [PATCH] Fix an attempt to allocate an unreasonably large amount of
|
||||
memory when parsing a corrupt ELF file.
|
||||
|
||||
PR 29924
|
||||
* objdump.c (load_specific_debug_section): Check for excessively
|
||||
large sections.
|
||||
Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=75393a2d54bcc40053e5262a3de9d70c5ebfbbfd]
|
||||
CVE: CVE-2022-48063
|
||||
Signed-off-by: Virendra Thakur <virendrak@kpit.com>
|
||||
Comment: Patch refreshed based on codebase.
|
||||
---
|
||||
binutils/ChangeLog | 6 ++++++
|
||||
binutils/objdump.c | 4 +++-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
|
||||
index e7f918d3f65..020e09f3700 100644
|
||||
--- a/binutils/ChangeLog
|
||||
+++ b/binutils/ChangeLog
|
||||
@@ -1,3 +1,9 @@
|
||||
+2022-12-21 Nick Clifton <nickc@redhat.com>
|
||||
+
|
||||
+ PR 29924
|
||||
+ * objdump.c (load_specific_debug_section): Check for excessively
|
||||
+ large sections.
|
||||
+
|
||||
2021-02-11 Alan Modra <amodra@gmail.com>
|
||||
|
||||
PR 27290
|
||||
|
||||
diff --git a/binutils/objdump.c b/binutils/objdump.c
|
||||
index d51abbe3858..2eb02de0e76 100644
|
||||
--- a/binutils/objdump.c
|
||||
+++ b/binutils/objdump.c
|
||||
@@ -3479,7 +3479,9 @@
|
||||
section->size = bfd_section_size (sec);
|
||||
/* PR 24360: On 32-bit hosts sizeof (size_t) < sizeof (bfd_size_type). */
|
||||
alloced = amt = section->size + 1;
|
||||
- if (alloced != amt || alloced == 0)
|
||||
+ if (alloced != amt
|
||||
+ || alloced == 0
|
||||
+ || (bfd_get_size (abfd) != 0 && alloced >= bfd_get_size (abfd)))
|
||||
{
|
||||
section->start = NULL;
|
||||
free_debug_section (debug);
|
||||
|
||||
530
meta/recipes-devtools/binutils/binutils/CVE-2023-25584.patch
Normal file
530
meta/recipes-devtools/binutils/binutils/CVE-2023-25584.patch
Normal file
@@ -0,0 +1,530 @@
|
||||
CVE: CVE-2023-25584
|
||||
Upstream-Status: Backport [ import from ubuntu http://archive.ubuntu.com/ubuntu/pool/main/b/binutils/binutils_2.34-6ubuntu1.7.debian.tar.xz upstream https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=77c225bdeb410cf60da804879ad41622f5f1aa44 ]
|
||||
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
|
||||
|
||||
[Ubuntu note: this is backport of the original patch, no major changes just
|
||||
fix this patch for this release]
|
||||
From 77c225bdeb410cf60da804879ad41622f5f1aa44 Mon Sep 17 00:00:00 2001
|
||||
From: Alan Modra <amodra@gmail.com>
|
||||
Date: Mon, 12 Dec 2022 18:28:49 +1030
|
||||
Subject: [PATCH] Lack of bounds checking in vms-alpha.c parse_module
|
||||
|
||||
PR 29873
|
||||
PR 29874
|
||||
PR 29875
|
||||
PR 29876
|
||||
PR 29877
|
||||
PR 29878
|
||||
PR 29879
|
||||
PR 29880
|
||||
PR 29881
|
||||
PR 29882
|
||||
PR 29883
|
||||
PR 29884
|
||||
PR 29885
|
||||
PR 29886
|
||||
PR 29887
|
||||
PR 29888
|
||||
PR 29889
|
||||
PR 29890
|
||||
PR 29891
|
||||
* vms-alpha.c (parse_module): Make length param bfd_size_type.
|
||||
Delete length == -1 checks. Sanity check record_length.
|
||||
Sanity check DST__K_MODBEG, DST__K_RTNBEG, DST__K_RTNEND lengths.
|
||||
Sanity check DST__K_SOURCE and DST__K_LINE_NUM elements
|
||||
before accessing.
|
||||
(build_module_list): Pass dst_section size to parse_module.
|
||||
---
|
||||
bfd/vms-alpha.c | 213 ++++++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 168 insertions(+), 45 deletions(-)
|
||||
|
||||
--- binutils-2.34.orig/bfd/vms-alpha.c
|
||||
+++ binutils-2.34/bfd/vms-alpha.c
|
||||
@@ -4267,7 +4267,7 @@ new_module (bfd *abfd)
|
||||
|
||||
static void
|
||||
parse_module (bfd *abfd, struct module *module, unsigned char *ptr,
|
||||
- int length)
|
||||
+ bfd_size_type length)
|
||||
{
|
||||
unsigned char *maxptr = ptr + length;
|
||||
unsigned char *src_ptr, *pcl_ptr;
|
||||
@@ -4284,7 +4284,7 @@ parse_module (bfd *abfd, struct module *
|
||||
curr_line = (struct lineinfo *) bfd_zalloc (abfd, sizeof (struct lineinfo));
|
||||
module->line_table = curr_line;
|
||||
|
||||
- while (length == -1 || ptr < maxptr)
|
||||
+ while (ptr < maxptr)
|
||||
{
|
||||
/* The first byte is not counted in the recorded length. */
|
||||
int rec_length = bfd_getl16 (ptr) + 1;
|
||||
@@ -4292,15 +4292,19 @@ parse_module (bfd *abfd, struct module *
|
||||
|
||||
vms_debug2 ((2, "DST record: leng %d, type %d\n", rec_length, rec_type));
|
||||
|
||||
- if (length == -1 && rec_type == DST__K_MODEND)
|
||||
+ if (rec_length > maxptr - ptr)
|
||||
+ break;
|
||||
+ if (rec_type == DST__K_MODEND)
|
||||
break;
|
||||
|
||||
switch (rec_type)
|
||||
{
|
||||
case DST__K_MODBEG:
|
||||
+ if (rec_length <= DST_S_B_MODBEG_NAME)
|
||||
+ break;
|
||||
module->name
|
||||
= _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_MODBEG_NAME,
|
||||
- maxptr - (ptr + DST_S_B_MODBEG_NAME));
|
||||
+ rec_length - DST_S_B_MODBEG_NAME);
|
||||
|
||||
curr_pc = 0;
|
||||
prev_pc = 0;
|
||||
@@ -4314,11 +4318,13 @@ parse_module (bfd *abfd, struct module *
|
||||
break;
|
||||
|
||||
case DST__K_RTNBEG:
|
||||
+ if (rec_length <= DST_S_B_RTNBEG_NAME)
|
||||
+ break;
|
||||
funcinfo = (struct funcinfo *)
|
||||
bfd_zalloc (abfd, sizeof (struct funcinfo));
|
||||
funcinfo->name
|
||||
= _bfd_vms_save_counted_string (abfd, ptr + DST_S_B_RTNBEG_NAME,
|
||||
- maxptr - (ptr + DST_S_B_RTNBEG_NAME));
|
||||
+ rec_length - DST_S_B_RTNBEG_NAME);
|
||||
funcinfo->low = bfd_getl32 (ptr + DST_S_L_RTNBEG_ADDRESS);
|
||||
funcinfo->next = module->func_table;
|
||||
module->func_table = funcinfo;
|
||||
@@ -4328,6 +4334,8 @@ parse_module (bfd *abfd, struct module *
|
||||
break;
|
||||
|
||||
case DST__K_RTNEND:
|
||||
+ if (rec_length < DST_S_L_RTNEND_SIZE + 4)
|
||||
+ break;
|
||||
module->func_table->high = module->func_table->low
|
||||
+ bfd_getl32 (ptr + DST_S_L_RTNEND_SIZE) - 1;
|
||||
|
||||
@@ -4358,13 +4366,66 @@ parse_module (bfd *abfd, struct module *
|
||||
|
||||
vms_debug2 ((3, "source info\n"));
|
||||
|
||||
- while (src_ptr < ptr + rec_length)
|
||||
+ while (src_ptr - ptr < rec_length)
|
||||
{
|
||||
int cmd = src_ptr[0], cmd_length, data;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case DST__K_SRC_DECLFILE:
|
||||
+ if (src_ptr - ptr + DST_S_B_SRC_DF_LENGTH >= rec_length)
|
||||
+ cmd_length = 0x10000;
|
||||
+ else
|
||||
+ cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_DEFLINES_B:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_DEFLINES_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_INCRLNUM_B:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_SETFILE:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_SETLNUM_L:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_SETLNUM_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_SETREC_L:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_SETREC_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SRC_FORMFEED:
|
||||
+ cmd_length = 1;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (src_ptr - ptr + cmd_length > rec_length)
|
||||
+ break;
|
||||
+
|
||||
+ switch (cmd)
|
||||
+ {
|
||||
+ case DST__K_SRC_DECLFILE:
|
||||
{
|
||||
unsigned int fileid
|
||||
= bfd_getl16 (src_ptr + DST_S_W_SRC_DF_FILEID);
|
||||
@@ -4384,7 +4445,6 @@ parse_module (bfd *abfd, struct module *
|
||||
|
||||
module->file_table [fileid].name = filename;
|
||||
module->file_table [fileid].srec = 1;
|
||||
- cmd_length = src_ptr[DST_S_B_SRC_DF_LENGTH] + 2;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_DECLFILE: %d, %s\n",
|
||||
fileid, module->file_table [fileid].name));
|
||||
}
|
||||
@@ -4401,7 +4461,6 @@ parse_module (bfd *abfd, struct module *
|
||||
srec->sfile = curr_srec->sfile;
|
||||
curr_srec->next = srec;
|
||||
curr_srec = srec;
|
||||
- cmd_length = 2;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_B: %d\n", data));
|
||||
break;
|
||||
|
||||
@@ -4416,14 +4475,12 @@ parse_module (bfd *abfd, struct module *
|
||||
srec->sfile = curr_srec->sfile;
|
||||
curr_srec->next = srec;
|
||||
curr_srec = srec;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_DEFLINES_W: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SRC_INCRLNUM_B:
|
||||
data = src_ptr[DST_S_B_SRC_UNSBYTE];
|
||||
curr_srec->line += data;
|
||||
- cmd_length = 2;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_INCRLNUM_B: %d\n", data));
|
||||
break;
|
||||
|
||||
@@ -4431,21 +4488,18 @@ parse_module (bfd *abfd, struct module *
|
||||
data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
|
||||
curr_srec->sfile = data;
|
||||
curr_srec->srec = module->file_table[data].srec;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_SETFILE: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SRC_SETLNUM_L:
|
||||
data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
|
||||
curr_srec->line = data;
|
||||
- cmd_length = 5;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_L: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SRC_SETLNUM_W:
|
||||
data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
|
||||
curr_srec->line = data;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_SETLNUM_W: %d\n", data));
|
||||
break;
|
||||
|
||||
@@ -4453,7 +4507,6 @@ parse_module (bfd *abfd, struct module *
|
||||
data = bfd_getl32 (src_ptr + DST_S_L_SRC_UNSLONG);
|
||||
curr_srec->srec = data;
|
||||
module->file_table[curr_srec->sfile].srec = data;
|
||||
- cmd_length = 5;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_SETREC_L: %d\n", data));
|
||||
break;
|
||||
|
||||
@@ -4461,19 +4514,16 @@ parse_module (bfd *abfd, struct module *
|
||||
data = bfd_getl16 (src_ptr + DST_S_W_SRC_UNSWORD);
|
||||
curr_srec->srec = data;
|
||||
module->file_table[curr_srec->sfile].srec = data;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_SETREC_W: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SRC_FORMFEED:
|
||||
- cmd_length = 1;
|
||||
vms_debug2 ((4, "DST_S_C_SRC_FORMFEED\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
_bfd_error_handler (_("unknown source command %d"),
|
||||
cmd);
|
||||
- cmd_length = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4486,7 +4536,7 @@ parse_module (bfd *abfd, struct module *
|
||||
|
||||
vms_debug2 ((3, "line info\n"));
|
||||
|
||||
- while (pcl_ptr < ptr + rec_length)
|
||||
+ while (pcl_ptr - ptr < rec_length)
|
||||
{
|
||||
/* The command byte is signed so we must sign-extend it. */
|
||||
int cmd = ((signed char *)pcl_ptr)[0], cmd_length, data;
|
||||
@@ -4494,10 +4544,106 @@ parse_module (bfd *abfd, struct module *
|
||||
switch (cmd)
|
||||
{
|
||||
case DST__K_DELTA_PC_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_DELTA_PC_L:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_INCR_LINUM:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_INCR_LINUM_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_INCR_LINUM_L:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_LINUM_INCR:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_LINUM_INCR_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_RESET_LINUM_INCR:
|
||||
+ cmd_length = 1;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_BEG_STMT_MODE:
|
||||
+ cmd_length = 1;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_END_STMT_MODE:
|
||||
+ cmd_length = 1;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_LINUM_B:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_LINUM:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_LINUM_L:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_PC:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_PC_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_PC_L:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_STMTNUM:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_TERM:
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_TERM_W:
|
||||
+ cmd_length = 3;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_TERM_L:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ case DST__K_SET_ABS_PC:
|
||||
+ cmd_length = 5;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ if (cmd <= 0)
|
||||
+ cmd_length = 1;
|
||||
+ else
|
||||
+ cmd_length = 2;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (pcl_ptr - ptr + cmd_length > rec_length)
|
||||
+ break;
|
||||
+
|
||||
+ switch (cmd)
|
||||
+ {
|
||||
+ case DST__K_DELTA_PC_W:
|
||||
data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
|
||||
curr_pc += data;
|
||||
curr_linenum += 1;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST__K_DELTA_PC_W: %d\n", data));
|
||||
break;
|
||||
|
||||
@@ -4505,131 +4651,111 @@ parse_module (bfd *abfd, struct module *
|
||||
data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
|
||||
curr_pc += data;
|
||||
curr_linenum += 1;
|
||||
- cmd_length = 5;
|
||||
vms_debug2 ((4, "DST__K_DELTA_PC_L: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_INCR_LINUM:
|
||||
data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
|
||||
curr_linenum += data;
|
||||
- cmd_length = 2;
|
||||
vms_debug2 ((4, "DST__K_INCR_LINUM: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_INCR_LINUM_W:
|
||||
data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
|
||||
curr_linenum += data;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST__K_INCR_LINUM_W: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_INCR_LINUM_L:
|
||||
data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
|
||||
curr_linenum += data;
|
||||
- cmd_length = 5;
|
||||
vms_debug2 ((4, "DST__K_INCR_LINUM_L: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SET_LINUM_INCR:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_SET_LINUM_INCR");
|
||||
- cmd_length = 2;
|
||||
break;
|
||||
|
||||
case DST__K_SET_LINUM_INCR_W:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_SET_LINUM_INCR_W");
|
||||
- cmd_length = 3;
|
||||
break;
|
||||
|
||||
case DST__K_RESET_LINUM_INCR:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_RESET_LINUM_INCR");
|
||||
- cmd_length = 1;
|
||||
break;
|
||||
|
||||
case DST__K_BEG_STMT_MODE:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_BEG_STMT_MODE");
|
||||
- cmd_length = 1;
|
||||
break;
|
||||
|
||||
case DST__K_END_STMT_MODE:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_END_STMT_MODE");
|
||||
- cmd_length = 1;
|
||||
break;
|
||||
|
||||
case DST__K_SET_LINUM_B:
|
||||
data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
|
||||
curr_linenum = data;
|
||||
- cmd_length = 2;
|
||||
vms_debug2 ((4, "DST__K_SET_LINUM_B: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SET_LINUM:
|
||||
data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
|
||||
curr_linenum = data;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST__K_SET_LINE_NUM: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SET_LINUM_L:
|
||||
data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
|
||||
curr_linenum = data;
|
||||
- cmd_length = 5;
|
||||
vms_debug2 ((4, "DST__K_SET_LINUM_L: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SET_PC:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_SET_PC");
|
||||
- cmd_length = 2;
|
||||
break;
|
||||
|
||||
case DST__K_SET_PC_W:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_SET_PC_W");
|
||||
- cmd_length = 3;
|
||||
break;
|
||||
|
||||
case DST__K_SET_PC_L:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_SET_PC_L");
|
||||
- cmd_length = 5;
|
||||
break;
|
||||
|
||||
case DST__K_SET_STMTNUM:
|
||||
_bfd_error_handler
|
||||
(_("%s not implemented"), "DST__K_SET_STMTNUM");
|
||||
- cmd_length = 2;
|
||||
break;
|
||||
|
||||
case DST__K_TERM:
|
||||
data = pcl_ptr[DST_S_B_PCLINE_UNSBYTE];
|
||||
curr_pc += data;
|
||||
- cmd_length = 2;
|
||||
vms_debug2 ((4, "DST__K_TERM: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_TERM_W:
|
||||
data = bfd_getl16 (pcl_ptr + DST_S_W_PCLINE_UNSWORD);
|
||||
curr_pc += data;
|
||||
- cmd_length = 3;
|
||||
vms_debug2 ((4, "DST__K_TERM_W: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_TERM_L:
|
||||
data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
|
||||
curr_pc += data;
|
||||
- cmd_length = 5;
|
||||
vms_debug2 ((4, "DST__K_TERM_L: %d\n", data));
|
||||
break;
|
||||
|
||||
case DST__K_SET_ABS_PC:
|
||||
data = bfd_getl32 (pcl_ptr + DST_S_L_PCLINE_UNSLONG);
|
||||
curr_pc = data;
|
||||
- cmd_length = 5;
|
||||
vms_debug2 ((4, "DST__K_SET_ABS_PC: 0x%x\n", data));
|
||||
break;
|
||||
|
||||
@@ -4638,15 +4764,11 @@ parse_module (bfd *abfd, struct module *
|
||||
{
|
||||
curr_pc -= cmd;
|
||||
curr_linenum += 1;
|
||||
- cmd_length = 1;
|
||||
vms_debug2 ((4, "bump pc to 0x%lx and line to %d\n",
|
||||
(unsigned long)curr_pc, curr_linenum));
|
||||
}
|
||||
else
|
||||
- {
|
||||
- _bfd_error_handler (_("unknown line command %d"), cmd);
|
||||
- cmd_length = 2;
|
||||
- }
|
||||
+ _bfd_error_handler (_("unknown line command %d"), cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4778,7 +4900,7 @@ build_module_list (bfd *abfd)
|
||||
return NULL;
|
||||
|
||||
module = new_module (abfd);
|
||||
- parse_module (abfd, module, PRIV (dst_section)->contents, -1);
|
||||
+ parse_module (abfd, module, PRIV (dst_section)->contents, PRIV (dst_section)->size);
|
||||
list = module;
|
||||
}
|
||||
|
||||
@@ -19,3 +19,6 @@ file( GLOB toolchain_config_files "${CMAKE_TOOLCHAIN_FILE}.d/*.cmake" )
|
||||
foreach(config ${toolchain_config_files})
|
||||
include(${config})
|
||||
endforeach()
|
||||
|
||||
unset(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES)
|
||||
unset(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES)
|
||||
|
||||
@@ -9,3 +9,6 @@ SRC_URI = ""
|
||||
|
||||
do_configure[depends] += "gcc-source-${PV}:do_preconfigure"
|
||||
do_populate_lic[depends] += "gcc-source-${PV}:do_unpack"
|
||||
|
||||
# patch is available via gcc-source recipe
|
||||
CVE_CHECK_WHITELIST += "CVE-2023-4039"
|
||||
|
||||
@@ -71,7 +71,8 @@ SRC_URI += "\
|
||||
file://CVE-2023-29402.patch \
|
||||
file://CVE-2023-29404.patch \
|
||||
file://CVE-2023-29400.patch \
|
||||
file://CVE-2023-29406.patch \
|
||||
file://CVE-2023-29406-1.patch \
|
||||
file://CVE-2023-29406-2.patch \
|
||||
file://CVE-2023-29409.patch \
|
||||
file://CVE-2022-41725-pre1.patch \
|
||||
file://CVE-2022-41725-pre2.patch \
|
||||
@@ -82,6 +83,15 @@ SRC_URI += "\
|
||||
file://CVE-2023-24536_3.patch \
|
||||
file://CVE-2023-39318.patch \
|
||||
file://CVE-2023-39319.patch \
|
||||
file://CVE-2023-39326.patch \
|
||||
file://CVE-2023-45287-pre1.patch \
|
||||
file://CVE-2023-45287-pre2.patch \
|
||||
file://CVE-2023-45287-pre3.patch \
|
||||
file://CVE-2023-45287.patch \
|
||||
file://CVE-2023-45289.patch \
|
||||
file://CVE-2023-45290.patch \
|
||||
file://CVE-2024-24785.patch \
|
||||
file://CVE-2024-24784.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch"
|
||||
|
||||
114
meta/recipes-devtools/go/go-1.14/CVE-2023-29406-2.patch
Normal file
114
meta/recipes-devtools/go/go-1.14/CVE-2023-29406-2.patch
Normal file
@@ -0,0 +1,114 @@
|
||||
From c08a5fa413a34111c9a37fd9e545de27ab0978b1 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Wed, 19 Jul 2023 10:30:46 -0700
|
||||
Subject: [PATCH] [release-branch.go1.19] net/http: permit requests with
|
||||
invalid Host headers
|
||||
|
||||
Historically, the Transport has silently truncated invalid
|
||||
Host headers at the first '/' or ' ' character. CL 506996 changed
|
||||
this behavior to reject invalid Host headers entirely.
|
||||
Unfortunately, Docker appears to rely on the previous behavior.
|
||||
|
||||
When sending a HTTP/1 request with an invalid Host, send an empty
|
||||
Host header. This is safer than truncation: If you care about the
|
||||
Host, then you should get the one you set; if you don't care,
|
||||
then an empty Host should be fine.
|
||||
|
||||
Continue to fully validate Host headers sent to a proxy,
|
||||
since proxies generally can't productively forward requests
|
||||
without a Host.
|
||||
|
||||
For #60374
|
||||
Fixes #61431
|
||||
Fixes #61825
|
||||
|
||||
Change-Id: If170c7dd860aa20eb58fe32990fc93af832742b6
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/511155
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
Reviewed-by: Roland Shoemaker <roland@golang.org>
|
||||
Run-TryBot: Damien Neil <dneil@google.com>
|
||||
(cherry picked from commit b9153f6ef338baee5fe02a867c8fbc83a8b29dd1)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/518855
|
||||
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
|
||||
Run-TryBot: Roland Shoemaker <roland@golang.org>
|
||||
Reviewed-by: Russ Cox <rsc@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/c08a5fa413a34111c9a37fd9e545de27ab0978b1]
|
||||
CVE: CVE-2023-29406
|
||||
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
|
||||
---
|
||||
src/net/http/request.go | 23 ++++++++++++++++++++++-
|
||||
src/net/http/request_test.go | 17 ++++++++++++-----
|
||||
2 files changed, 34 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/net/http/request.go b/src/net/http/request.go
|
||||
index 3100037386..91cb8a66b9 100644
|
||||
--- a/src/net/http/request.go
|
||||
+++ b/src/net/http/request.go
|
||||
@@ -582,8 +582,29 @@ func (r *Request) write(w io.Writer, usingProxy bool, extraHeaders Header, waitF
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
+ // Validate that the Host header is a valid header in general,
|
||||
+ // but don't validate the host itself. This is sufficient to avoid
|
||||
+ // header or request smuggling via the Host field.
|
||||
+ // The server can (and will, if it's a net/http server) reject
|
||||
+ // the request if it doesn't consider the host valid.
|
||||
if !httpguts.ValidHostHeader(host) {
|
||||
- return errors.New("http: invalid Host header")
|
||||
+ // Historically, we would truncate the Host header after '/' or ' '.
|
||||
+ // Some users have relied on this truncation to convert a network
|
||||
+ // address such as Unix domain socket path into a valid, ignored
|
||||
+ // Host header (see https://go.dev/issue/61431).
|
||||
+ //
|
||||
+ // We don't preserve the truncation, because sending an altered
|
||||
+ // header field opens a smuggling vector. Instead, zero out the
|
||||
+ // Host header entirely if it isn't valid. (An empty Host is valid;
|
||||
+ // see RFC 9112 Section 3.2.)
|
||||
+ //
|
||||
+ // Return an error if we're sending to a proxy, since the proxy
|
||||
+ // probably can't do anything useful with an empty Host header.
|
||||
+ if !usingProxy {
|
||||
+ host = ""
|
||||
+ } else {
|
||||
+ return errors.New("http: invalid Host header")
|
||||
+ }
|
||||
}
|
||||
|
||||
// According to RFC 6874, an HTTP client, proxy, or other
|
||||
diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go
|
||||
index fddc85d6a9..dd1e2dc2a1 100644
|
||||
--- a/src/net/http/request_test.go
|
||||
+++ b/src/net/http/request_test.go
|
||||
@@ -770,16 +770,23 @@ func TestRequestWriteBufferedWriter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
-func TestRequestBadHost(t *testing.T) {
|
||||
+func TestRequestBadHostHeader(t *testing.T) {
|
||||
got := []string{}
|
||||
req, err := NewRequest("GET", "http://foo/after", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
- req.Host = "foo.com with spaces"
|
||||
- req.URL.Host = "foo.com with spaces"
|
||||
- if err := req.Write(logWrites{t, &got}); err == nil {
|
||||
- t.Errorf("Writing request with invalid Host: succeded, want error")
|
||||
+ req.Host = "foo.com\nnewline"
|
||||
+ req.URL.Host = "foo.com\nnewline"
|
||||
+ req.Write(logWrites{t, &got})
|
||||
+ want := []string{
|
||||
+ "GET /after HTTP/1.1\r\n",
|
||||
+ "Host: \r\n",
|
||||
+ "User-Agent: " + DefaultUserAgent + "\r\n",
|
||||
+ "\r\n",
|
||||
+ }
|
||||
+ if !reflect.DeepEqual(got, want) {
|
||||
+ t.Errorf("Writes = %q\n Want = %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
181
meta/recipes-devtools/go/go-1.14/CVE-2023-39326.patch
Normal file
181
meta/recipes-devtools/go/go-1.14/CVE-2023-39326.patch
Normal file
@@ -0,0 +1,181 @@
|
||||
From 6446af942e2e2b161c4ec1b60d9703a2b55dc4dd Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Tue, 7 Nov 2023 10:47:56 -0800
|
||||
Subject: [PATCH] [release-branch.go1.20] net/http: limit chunked data overhead
|
||||
|
||||
The chunked transfer encoding adds some overhead to
|
||||
the content transferred. When writing one byte per
|
||||
chunk, for example, there are five bytes of overhead
|
||||
per byte of data transferred: "1\r\nX\r\n" to send "X".
|
||||
|
||||
Chunks may include "chunk extensions",
|
||||
which we skip over and do not use.
|
||||
For example: "1;chunk extension here\r\nX\r\n".
|
||||
|
||||
A malicious sender can use chunk extensions to add
|
||||
about 4k of overhead per byte of data.
|
||||
(The maximum chunk header line size we will accept.)
|
||||
|
||||
Track the amount of overhead read in chunked data,
|
||||
and produce an error if it seems excessive.
|
||||
|
||||
Updates #64433
|
||||
Fixes #64434
|
||||
Fixes CVE-2023-39326
|
||||
|
||||
Change-Id: I40f8d70eb6f9575fb43f506eb19132ccedafcf39
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2076135
|
||||
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||
(cherry picked from commit 3473ae72ee66c60744665a24b2fde143e8964d4f)
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2095407
|
||||
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
||||
TryBot-Result: Security TryBots <security-trybots@go-security-trybots.iam.gserviceaccount.com>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/547355
|
||||
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/6446af942e2e2b161c4ec1b60d9703a2b55dc4dd]
|
||||
CVE: CVE-2023-39326
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/net/http/internal/chunked.go | 36 +++++++++++++---
|
||||
src/net/http/internal/chunked_test.go | 59 +++++++++++++++++++++++++++
|
||||
2 files changed, 89 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/net/http/internal/chunked.go b/src/net/http/internal/chunked.go
|
||||
index f06e572..ddbaacb 100644
|
||||
--- a/src/net/http/internal/chunked.go
|
||||
+++ b/src/net/http/internal/chunked.go
|
||||
@@ -39,7 +39,8 @@ type chunkedReader struct {
|
||||
n uint64 // unread bytes in chunk
|
||||
err error
|
||||
buf [2]byte
|
||||
- checkEnd bool // whether need to check for \r\n chunk footer
|
||||
+ checkEnd bool // whether need to check for \r\n chunk footer
|
||||
+ excess int64 // "excessive" chunk overhead, for malicious sender detection
|
||||
}
|
||||
|
||||
func (cr *chunkedReader) beginChunk() {
|
||||
@@ -49,10 +50,38 @@ func (cr *chunkedReader) beginChunk() {
|
||||
if cr.err != nil {
|
||||
return
|
||||
}
|
||||
+ cr.excess += int64(len(line)) + 2 // header, plus \r\n after the chunk data
|
||||
+ line = trimTrailingWhitespace(line)
|
||||
+ line, cr.err = removeChunkExtension(line)
|
||||
+ if cr.err != nil {
|
||||
+ return
|
||||
+ }
|
||||
cr.n, cr.err = parseHexUint(line)
|
||||
if cr.err != nil {
|
||||
return
|
||||
}
|
||||
+ // A sender who sends one byte per chunk will send 5 bytes of overhead
|
||||
+ // for every byte of data. ("1\r\nX\r\n" to send "X".)
|
||||
+ // We want to allow this, since streaming a byte at a time can be legitimate.
|
||||
+ //
|
||||
+ // A sender can use chunk extensions to add arbitrary amounts of additional
|
||||
+ // data per byte read. ("1;very long extension\r\nX\r\n" to send "X".)
|
||||
+ // We don't want to disallow extensions (although we discard them),
|
||||
+ // but we also don't want to allow a sender to reduce the signal/noise ratio
|
||||
+ // arbitrarily.
|
||||
+ //
|
||||
+ // We track the amount of excess overhead read,
|
||||
+ // and produce an error if it grows too large.
|
||||
+ //
|
||||
+ // Currently, we say that we're willing to accept 16 bytes of overhead per chunk,
|
||||
+ // plus twice the amount of real data in the chunk.
|
||||
+ cr.excess -= 16 + (2 * int64(cr.n))
|
||||
+ if cr.excess < 0 {
|
||||
+ cr.excess = 0
|
||||
+ }
|
||||
+ if cr.excess > 16*1024 {
|
||||
+ cr.err = errors.New("chunked encoding contains too much non-data")
|
||||
+ }
|
||||
if cr.n == 0 {
|
||||
cr.err = io.EOF
|
||||
}
|
||||
@@ -133,11 +162,6 @@ func readChunkLine(b *bufio.Reader) ([]byte, error) {
|
||||
if len(p) >= maxLineLength {
|
||||
return nil, ErrLineTooLong
|
||||
}
|
||||
- p = trimTrailingWhitespace(p)
|
||||
- p, err = removeChunkExtension(p)
|
||||
- if err != nil {
|
||||
- return nil, err
|
||||
- }
|
||||
return p, nil
|
||||
}
|
||||
|
||||
diff --git a/src/net/http/internal/chunked_test.go b/src/net/http/internal/chunked_test.go
|
||||
index d067165..b20747d 100644
|
||||
--- a/src/net/http/internal/chunked_test.go
|
||||
+++ b/src/net/http/internal/chunked_test.go
|
||||
@@ -212,3 +212,62 @@ func TestChunkReadPartial(t *testing.T) {
|
||||
}
|
||||
|
||||
}
|
||||
+
|
||||
+func TestChunkReaderTooMuchOverhead(t *testing.T) {
|
||||
+ // If the sender is sending 100x as many chunk header bytes as chunk data,
|
||||
+ // we should reject the stream at some point.
|
||||
+ chunk := []byte("1;")
|
||||
+ for i := 0; i < 100; i++ {
|
||||
+ chunk = append(chunk, 'a') // chunk extension
|
||||
+ }
|
||||
+ chunk = append(chunk, "\r\nX\r\n"...)
|
||||
+ const bodylen = 1 << 20
|
||||
+ r := NewChunkedReader(&funcReader{f: func(i int) ([]byte, error) {
|
||||
+ if i < bodylen {
|
||||
+ return chunk, nil
|
||||
+ }
|
||||
+ return []byte("0\r\n"), nil
|
||||
+ }})
|
||||
+ _, err := io.ReadAll(r)
|
||||
+ if err == nil {
|
||||
+ t.Fatalf("successfully read body with excessive overhead; want error")
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func TestChunkReaderByteAtATime(t *testing.T) {
|
||||
+ // Sending one byte per chunk should not trip the excess-overhead detection.
|
||||
+ const bodylen = 1 << 20
|
||||
+ r := NewChunkedReader(&funcReader{f: func(i int) ([]byte, error) {
|
||||
+ if i < bodylen {
|
||||
+ return []byte("1\r\nX\r\n"), nil
|
||||
+ }
|
||||
+ return []byte("0\r\n"), nil
|
||||
+ }})
|
||||
+ got, err := io.ReadAll(r)
|
||||
+ if err != nil {
|
||||
+ t.Errorf("unexpected error: %v", err)
|
||||
+ }
|
||||
+ if len(got) != bodylen {
|
||||
+ t.Errorf("read %v bytes, want %v", len(got), bodylen)
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+type funcReader struct {
|
||||
+ f func(iteration int) ([]byte, error)
|
||||
+ i int
|
||||
+ b []byte
|
||||
+ err error
|
||||
+}
|
||||
+
|
||||
+func (r *funcReader) Read(p []byte) (n int, err error) {
|
||||
+ if len(r.b) == 0 && r.err == nil {
|
||||
+ r.b, r.err = r.f(r.i)
|
||||
+ r.i++
|
||||
+ }
|
||||
+ n = copy(p, r.b)
|
||||
+ r.b = r.b[n:]
|
||||
+ if len(r.b) > 0 {
|
||||
+ return n, nil
|
||||
+ }
|
||||
+ return n, r.err
|
||||
+}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
393
meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre1.patch
Normal file
393
meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre1.patch
Normal file
@@ -0,0 +1,393 @@
|
||||
From 9baafabac9a84813a336f068862207d2bb06d255 Mon Sep 17 00:00:00 2001
|
||||
From: Filippo Valsorda <filippo@golang.org>
|
||||
Date: Wed, 1 Apr 2020 17:25:40 -0400
|
||||
Subject: [PATCH] crypto/rsa: refactor RSA-PSS signing and verification
|
||||
|
||||
Cleaned up for readability and consistency.
|
||||
|
||||
There is one tiny behavioral change: when PSSSaltLengthEqualsHash is
|
||||
used and both hash and opts.Hash were set, hash.Size() was used for the
|
||||
salt length instead of opts.Hash.Size(). That's clearly wrong because
|
||||
opts.Hash is documented to override hash.
|
||||
|
||||
Change-Id: I3e25dad933961eac827c6d2e3bbfe45fc5a6fb0e
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/226937
|
||||
Run-TryBot: Filippo Valsorda <filippo@golang.org>
|
||||
TryBot-Result: Gobot Gobot <gobot@golang.org>
|
||||
Reviewed-by: Katie Hockman <katie@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/9baafabac9a84813a336f068862207d2bb06d255]
|
||||
CVE: CVE-2023-45287 #Dependency Patch1
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/crypto/rsa/pss.go | 173 ++++++++++++++++++++++--------------------
|
||||
src/crypto/rsa/rsa.go | 9 ++-
|
||||
2 files changed, 96 insertions(+), 86 deletions(-)
|
||||
|
||||
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
|
||||
index 3ff0c2f4d0076..f9844d87329a8 100644
|
||||
--- a/src/crypto/rsa/pss.go
|
||||
+++ b/src/crypto/rsa/pss.go
|
||||
@@ -4,9 +4,7 @@
|
||||
|
||||
package rsa
|
||||
|
||||
-// This file implements the PSS signature scheme [1].
|
||||
-//
|
||||
-// [1] https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf
|
||||
+// This file implements the RSASSA-PSS signature scheme according to RFC 8017.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -17,8 +15,22 @@ import (
|
||||
"math/big"
|
||||
)
|
||||
|
||||
+// Per RFC 8017, Section 9.1
|
||||
+//
|
||||
+// EM = MGF1 xor DB || H( 8*0x00 || mHash || salt ) || 0xbc
|
||||
+//
|
||||
+// where
|
||||
+//
|
||||
+// DB = PS || 0x01 || salt
|
||||
+//
|
||||
+// and PS can be empty so
|
||||
+//
|
||||
+// emLen = dbLen + hLen + 1 = psLen + sLen + hLen + 2
|
||||
+//
|
||||
+
|
||||
func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
|
||||
- // See [1], section 9.1.1
|
||||
+ // See RFC 8017, Section 9.1.1.
|
||||
+
|
||||
hLen := hash.Size()
|
||||
sLen := len(salt)
|
||||
emLen := (emBits + 7) / 8
|
||||
@@ -30,7 +42,7 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt
|
||||
// 2. Let mHash = Hash(M), an octet string of length hLen.
|
||||
|
||||
if len(mHash) != hLen {
|
||||
- return nil, errors.New("crypto/rsa: input must be hashed message")
|
||||
+ return nil, errors.New("crypto/rsa: input must be hashed with given hash")
|
||||
}
|
||||
|
||||
// 3. If emLen < hLen + sLen + 2, output "encoding error" and stop.
|
||||
@@ -40,8 +52,9 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt
|
||||
}
|
||||
|
||||
em := make([]byte, emLen)
|
||||
- db := em[:emLen-sLen-hLen-2+1+sLen]
|
||||
- h := em[emLen-sLen-hLen-2+1+sLen : emLen-1]
|
||||
+ psLen := emLen - sLen - hLen - 2
|
||||
+ db := em[:psLen+1+sLen]
|
||||
+ h := em[psLen+1+sLen : emLen-1]
|
||||
|
||||
// 4. Generate a random octet string salt of length sLen; if sLen = 0,
|
||||
// then salt is the empty string.
|
||||
@@ -69,8 +82,8 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt
|
||||
// 8. Let DB = PS || 0x01 || salt; DB is an octet string of length
|
||||
// emLen - hLen - 1.
|
||||
|
||||
- db[emLen-sLen-hLen-2] = 0x01
|
||||
- copy(db[emLen-sLen-hLen-1:], salt)
|
||||
+ db[psLen] = 0x01
|
||||
+ copy(db[psLen+1:], salt)
|
||||
|
||||
// 9. Let dbMask = MGF(H, emLen - hLen - 1).
|
||||
//
|
||||
@@ -81,47 +94,57 @@ func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byt
|
||||
// 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
|
||||
// maskedDB to zero.
|
||||
|
||||
- db[0] &= (0xFF >> uint(8*emLen-emBits))
|
||||
+ db[0] &= 0xff >> (8*emLen - emBits)
|
||||
|
||||
// 12. Let EM = maskedDB || H || 0xbc.
|
||||
- em[emLen-1] = 0xBC
|
||||
+ em[emLen-1] = 0xbc
|
||||
|
||||
// 13. Output EM.
|
||||
return em, nil
|
||||
}
|
||||
|
||||
func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
|
||||
+ // See RFC 8017, Section 9.1.2.
|
||||
+
|
||||
+ hLen := hash.Size()
|
||||
+ if sLen == PSSSaltLengthEqualsHash {
|
||||
+ sLen = hLen
|
||||
+ }
|
||||
+ emLen := (emBits + 7) / 8
|
||||
+ if emLen != len(em) {
|
||||
+ return errors.New("rsa: internal error: inconsistent length")
|
||||
+ }
|
||||
+
|
||||
// 1. If the length of M is greater than the input limitation for the
|
||||
// hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
|
||||
// and stop.
|
||||
//
|
||||
// 2. Let mHash = Hash(M), an octet string of length hLen.
|
||||
- hLen := hash.Size()
|
||||
if hLen != len(mHash) {
|
||||
return ErrVerification
|
||||
}
|
||||
|
||||
// 3. If emLen < hLen + sLen + 2, output "inconsistent" and stop.
|
||||
- emLen := (emBits + 7) / 8
|
||||
if emLen < hLen+sLen+2 {
|
||||
return ErrVerification
|
||||
}
|
||||
|
||||
// 4. If the rightmost octet of EM does not have hexadecimal value
|
||||
// 0xbc, output "inconsistent" and stop.
|
||||
- if em[len(em)-1] != 0xBC {
|
||||
+ if em[emLen-1] != 0xbc {
|
||||
return ErrVerification
|
||||
}
|
||||
|
||||
// 5. Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
|
||||
// let H be the next hLen octets.
|
||||
db := em[:emLen-hLen-1]
|
||||
- h := em[emLen-hLen-1 : len(em)-1]
|
||||
+ h := em[emLen-hLen-1 : emLen-1]
|
||||
|
||||
// 6. If the leftmost 8 * emLen - emBits bits of the leftmost octet in
|
||||
// maskedDB are not all equal to zero, output "inconsistent" and
|
||||
// stop.
|
||||
- if em[0]&(0xFF<<uint(8-(8*emLen-emBits))) != 0 {
|
||||
+ var bitMask byte = 0xff >> (8*emLen - emBits)
|
||||
+ if em[0] & ^bitMask != 0 {
|
||||
return ErrVerification
|
||||
}
|
||||
|
||||
@@ -132,37 +155,30 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
|
||||
|
||||
// 9. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
|
||||
// to zero.
|
||||
- db[0] &= (0xFF >> uint(8*emLen-emBits))
|
||||
+ db[0] &= bitMask
|
||||
|
||||
+ // If we don't know the salt length, look for the 0x01 delimiter.
|
||||
if sLen == PSSSaltLengthAuto {
|
||||
- FindSaltLength:
|
||||
- for sLen = emLen - (hLen + 2); sLen >= 0; sLen-- {
|
||||
- switch db[emLen-hLen-sLen-2] {
|
||||
- case 1:
|
||||
- break FindSaltLength
|
||||
- case 0:
|
||||
- continue
|
||||
- default:
|
||||
- return ErrVerification
|
||||
- }
|
||||
- }
|
||||
- if sLen < 0 {
|
||||
+ psLen := bytes.IndexByte(db, 0x01)
|
||||
+ if psLen < 0 {
|
||||
return ErrVerification
|
||||
}
|
||||
- } else {
|
||||
- // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
|
||||
- // or if the octet at position emLen - hLen - sLen - 1 (the leftmost
|
||||
- // position is "position 1") does not have hexadecimal value 0x01,
|
||||
- // output "inconsistent" and stop.
|
||||
- for _, e := range db[:emLen-hLen-sLen-2] {
|
||||
- if e != 0x00 {
|
||||
- return ErrVerification
|
||||
- }
|
||||
- }
|
||||
- if db[emLen-hLen-sLen-2] != 0x01 {
|
||||
+ sLen = len(db) - psLen - 1
|
||||
+ }
|
||||
+
|
||||
+ // 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
|
||||
+ // or if the octet at position emLen - hLen - sLen - 1 (the leftmost
|
||||
+ // position is "position 1") does not have hexadecimal value 0x01,
|
||||
+ // output "inconsistent" and stop.
|
||||
+ psLen := emLen - hLen - sLen - 2
|
||||
+ for _, e := range db[:psLen] {
|
||||
+ if e != 0x00 {
|
||||
return ErrVerification
|
||||
}
|
||||
}
|
||||
+ if db[psLen] != 0x01 {
|
||||
+ return ErrVerification
|
||||
+ }
|
||||
|
||||
// 11. Let salt be the last sLen octets of DB.
|
||||
salt := db[len(db)-sLen:]
|
||||
@@ -181,19 +197,19 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
|
||||
h0 := hash.Sum(nil)
|
||||
|
||||
// 14. If H = H', output "consistent." Otherwise, output "inconsistent."
|
||||
- if !bytes.Equal(h0, h) {
|
||||
+ if !bytes.Equal(h0, h) { // TODO: constant time?
|
||||
return ErrVerification
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
-// signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt.
|
||||
+// signPSSWithSalt calculates the signature of hashed using PSS with specified salt.
|
||||
// Note that hashed must be the result of hashing the input message using the
|
||||
// given hash function. salt is a random sequence of bytes whose length will be
|
||||
// later used to verify the signature.
|
||||
func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) {
|
||||
- nBits := priv.N.BitLen()
|
||||
- em, err := emsaPSSEncode(hashed, nBits-1, salt, hash.New())
|
||||
+ emBits := priv.N.BitLen() - 1
|
||||
+ em, err := emsaPSSEncode(hashed, emBits, salt, hash.New())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -202,7 +218,7 @@ func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed,
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
- s = make([]byte, (nBits+7)/8)
|
||||
+ s = make([]byte, priv.Size())
|
||||
copyWithLeftPad(s, c.Bytes())
|
||||
return
|
||||
}
|
||||
@@ -223,16 +239,15 @@ type PSSOptions struct {
|
||||
// PSSSaltLength constants.
|
||||
SaltLength int
|
||||
|
||||
- // Hash, if not zero, overrides the hash function passed to SignPSS.
|
||||
- // This is the only way to specify the hash function when using the
|
||||
- // crypto.Signer interface.
|
||||
+ // Hash is the hash function used to generate the message digest. If not
|
||||
+ // zero, it overrides the hash function passed to SignPSS. It's required
|
||||
+ // when using PrivateKey.Sign.
|
||||
Hash crypto.Hash
|
||||
}
|
||||
|
||||
-// HashFunc returns pssOpts.Hash so that PSSOptions implements
|
||||
-// crypto.SignerOpts.
|
||||
-func (pssOpts *PSSOptions) HashFunc() crypto.Hash {
|
||||
- return pssOpts.Hash
|
||||
+// HashFunc returns opts.Hash so that PSSOptions implements crypto.SignerOpts.
|
||||
+func (opts *PSSOptions) HashFunc() crypto.Hash {
|
||||
+ return opts.Hash
|
||||
}
|
||||
|
||||
func (opts *PSSOptions) saltLength() int {
|
||||
@@ -242,56 +257,50 @@ func (opts *PSSOptions) saltLength() int {
|
||||
return opts.SaltLength
|
||||
}
|
||||
|
||||
-// SignPSS calculates the signature of hashed using RSASSA-PSS [1].
|
||||
-// Note that hashed must be the result of hashing the input message using the
|
||||
-// given hash function. The opts argument may be nil, in which case sensible
|
||||
-// defaults are used.
|
||||
-func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) ([]byte, error) {
|
||||
+// SignPSS calculates the signature of digest using PSS.
|
||||
+//
|
||||
+// digest must be the result of hashing the input message using the given hash
|
||||
+// function. The opts argument may be nil, in which case sensible defaults are
|
||||
+// used. If opts.Hash is set, it overrides hash.
|
||||
+func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte, opts *PSSOptions) ([]byte, error) {
|
||||
+ if opts != nil && opts.Hash != 0 {
|
||||
+ hash = opts.Hash
|
||||
+ }
|
||||
+
|
||||
saltLength := opts.saltLength()
|
||||
switch saltLength {
|
||||
case PSSSaltLengthAuto:
|
||||
- saltLength = (priv.N.BitLen()+7)/8 - 2 - hash.Size()
|
||||
+ saltLength = priv.Size() - 2 - hash.Size()
|
||||
case PSSSaltLengthEqualsHash:
|
||||
saltLength = hash.Size()
|
||||
}
|
||||
|
||||
- if opts != nil && opts.Hash != 0 {
|
||||
- hash = opts.Hash
|
||||
- }
|
||||
-
|
||||
salt := make([]byte, saltLength)
|
||||
if _, err := io.ReadFull(rand, salt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
- return signPSSWithSalt(rand, priv, hash, hashed, salt)
|
||||
+ return signPSSWithSalt(rand, priv, hash, digest, salt)
|
||||
}
|
||||
|
||||
// VerifyPSS verifies a PSS signature.
|
||||
-// hashed is the result of hashing the input message using the given hash
|
||||
-// function and sig is the signature. A valid signature is indicated by
|
||||
-// returning a nil error. The opts argument may be nil, in which case sensible
|
||||
-// defaults are used.
|
||||
-func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error {
|
||||
- return verifyPSS(pub, hash, hashed, sig, opts.saltLength())
|
||||
-}
|
||||
-
|
||||
-// verifyPSS verifies a PSS signature with the given salt length.
|
||||
-func verifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, saltLen int) error {
|
||||
- nBits := pub.N.BitLen()
|
||||
- if len(sig) != (nBits+7)/8 {
|
||||
+//
|
||||
+// A valid signature is indicated by returning a nil error. digest must be the
|
||||
+// result of hashing the input message using the given hash function. The opts
|
||||
+// argument may be nil, in which case sensible defaults are used. opts.Hash is
|
||||
+// ignored.
|
||||
+func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts *PSSOptions) error {
|
||||
+ if len(sig) != pub.Size() {
|
||||
return ErrVerification
|
||||
}
|
||||
s := new(big.Int).SetBytes(sig)
|
||||
m := encrypt(new(big.Int), pub, s)
|
||||
- emBits := nBits - 1
|
||||
+ emBits := pub.N.BitLen() - 1
|
||||
emLen := (emBits + 7) / 8
|
||||
- if emLen < len(m.Bytes()) {
|
||||
+ emBytes := m.Bytes()
|
||||
+ if emLen < len(emBytes) {
|
||||
return ErrVerification
|
||||
}
|
||||
em := make([]byte, emLen)
|
||||
- copyWithLeftPad(em, m.Bytes())
|
||||
- if saltLen == PSSSaltLengthEqualsHash {
|
||||
- saltLen = hash.Size()
|
||||
- }
|
||||
- return emsaPSSVerify(hashed, em, emBits, saltLen, hash.New())
|
||||
+ copyWithLeftPad(em, emBytes)
|
||||
+ return emsaPSSVerify(digest, em, emBits, opts.saltLength(), hash.New())
|
||||
}
|
||||
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
|
||||
index 5a42990640164..b4bfa13defbdf 100644
|
||||
--- a/src/crypto/rsa/rsa.go
|
||||
+++ b/src/crypto/rsa/rsa.go
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
-// Package rsa implements RSA encryption as specified in PKCS#1.
|
||||
+// Package rsa implements RSA encryption as specified in PKCS#1 and RFC 8017.
|
||||
//
|
||||
// RSA is a single, fundamental operation that is used in this package to
|
||||
// implement either public-key encryption or public-key signatures.
|
||||
@@ -10,13 +10,13 @@
|
||||
// The original specification for encryption and signatures with RSA is PKCS#1
|
||||
// and the terms "RSA encryption" and "RSA signatures" by default refer to
|
||||
// PKCS#1 version 1.5. However, that specification has flaws and new designs
|
||||
-// should use version two, usually called by just OAEP and PSS, where
|
||||
+// should use version 2, usually called by just OAEP and PSS, where
|
||||
// possible.
|
||||
//
|
||||
// Two sets of interfaces are included in this package. When a more abstract
|
||||
// interface isn't necessary, there are functions for encrypting/decrypting
|
||||
// with v1.5/OAEP and signing/verifying with v1.5/PSS. If one needs to abstract
|
||||
-// over the public-key primitive, the PrivateKey struct implements the
|
||||
+// over the public key primitive, the PrivateKey type implements the
|
||||
// Decrypter and Signer interfaces from the crypto package.
|
||||
//
|
||||
// The RSA operations in this package are not implemented using constant-time algorithms.
|
||||
@@ -111,7 +111,8 @@ func (priv *PrivateKey) Public() crypto.PublicKey {
|
||||
|
||||
// Sign signs digest with priv, reading randomness from rand. If opts is a
|
||||
// *PSSOptions then the PSS algorithm will be used, otherwise PKCS#1 v1.5 will
|
||||
-// be used.
|
||||
+// be used. digest must be the result of hashing the input message using
|
||||
+// opts.HashFunc().
|
||||
//
|
||||
// This method implements crypto.Signer, which is an interface to support keys
|
||||
// where the private part is kept in, for example, a hardware module. Common
|
||||
401
meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre2.patch
Normal file
401
meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre2.patch
Normal file
@@ -0,0 +1,401 @@
|
||||
From c9d5f60eaa4450ccf1ce878d55b4c6a12843f2f3 Mon Sep 17 00:00:00 2001
|
||||
From: Filippo Valsorda <filippo@golang.org>
|
||||
Date: Mon, 27 Apr 2020 21:52:38 -0400
|
||||
Subject: [PATCH] math/big: add (*Int).FillBytes
|
||||
|
||||
Replaced almost every use of Bytes with FillBytes.
|
||||
|
||||
Note that the approved proposal was for
|
||||
|
||||
func (*Int) FillBytes(buf []byte)
|
||||
|
||||
while this implements
|
||||
|
||||
func (*Int) FillBytes(buf []byte) []byte
|
||||
|
||||
because the latter was far nicer to use in all callsites.
|
||||
|
||||
Fixes #35833
|
||||
|
||||
Change-Id: Ia912df123e5d79b763845312ea3d9a8051343c0a
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/230397
|
||||
Reviewed-by: Robert Griesemer <gri@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/c9d5f60eaa4450ccf1ce878d55b4c6a12843f2f3]
|
||||
CVE: CVE-2023-45287 #Dependency Patch2
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/crypto/elliptic/elliptic.go | 13 ++++----
|
||||
src/crypto/rsa/pkcs1v15.go | 20 +++---------
|
||||
src/crypto/rsa/pss.go | 17 +++++------
|
||||
src/crypto/rsa/rsa.go | 32 +++----------------
|
||||
src/crypto/tls/key_schedule.go | 7 ++---
|
||||
src/crypto/x509/sec1.go | 7 ++---
|
||||
src/math/big/int.go | 15 +++++++++
|
||||
src/math/big/int_test.go | 54 +++++++++++++++++++++++++++++++++
|
||||
src/math/big/nat.go | 15 ++++++---
|
||||
9 files changed, 106 insertions(+), 74 deletions(-)
|
||||
|
||||
diff --git a/src/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go
|
||||
index e2f71cdb63bab..bd5168c5fd842 100644
|
||||
--- a/src/crypto/elliptic/elliptic.go
|
||||
+++ b/src/crypto/elliptic/elliptic.go
|
||||
@@ -277,7 +277,7 @@ var mask = []byte{0xff, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f}
|
||||
func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err error) {
|
||||
N := curve.Params().N
|
||||
bitSize := N.BitLen()
|
||||
- byteLen := (bitSize + 7) >> 3
|
||||
+ byteLen := (bitSize + 7) / 8
|
||||
priv = make([]byte, byteLen)
|
||||
|
||||
for x == nil {
|
||||
@@ -304,15 +304,14 @@ func GenerateKey(curve Curve, rand io.Reader) (priv []byte, x, y *big.Int, err e
|
||||
|
||||
// Marshal converts a point into the uncompressed form specified in section 4.3.6 of ANSI X9.62.
|
||||
func Marshal(curve Curve, x, y *big.Int) []byte {
|
||||
- byteLen := (curve.Params().BitSize + 7) >> 3
|
||||
+ byteLen := (curve.Params().BitSize + 7) / 8
|
||||
|
||||
ret := make([]byte, 1+2*byteLen)
|
||||
ret[0] = 4 // uncompressed point
|
||||
|
||||
- xBytes := x.Bytes()
|
||||
- copy(ret[1+byteLen-len(xBytes):], xBytes)
|
||||
- yBytes := y.Bytes()
|
||||
- copy(ret[1+2*byteLen-len(yBytes):], yBytes)
|
||||
+ x.FillBytes(ret[1 : 1+byteLen])
|
||||
+ y.FillBytes(ret[1+byteLen : 1+2*byteLen])
|
||||
+
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -320,7 +319,7 @@ func Marshal(curve Curve, x, y *big.Int) []byte {
|
||||
// It is an error if the point is not in uncompressed form or is not on the curve.
|
||||
// On error, x = nil.
|
||||
func Unmarshal(curve Curve, data []byte) (x, y *big.Int) {
|
||||
- byteLen := (curve.Params().BitSize + 7) >> 3
|
||||
+ byteLen := (curve.Params().BitSize + 7) / 8
|
||||
if len(data) != 1+2*byteLen {
|
||||
return
|
||||
}
|
||||
diff --git a/src/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go
|
||||
index 499242ffc5b57..3208119ae1ff4 100644
|
||||
--- a/src/crypto/rsa/pkcs1v15.go
|
||||
+++ b/src/crypto/rsa/pkcs1v15.go
|
||||
@@ -61,8 +61,7 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) ([]byte, error)
|
||||
m := new(big.Int).SetBytes(em)
|
||||
c := encrypt(new(big.Int), pub, m)
|
||||
|
||||
- copyWithLeftPad(em, c.Bytes())
|
||||
- return em, nil
|
||||
+ return c.FillBytes(em), nil
|
||||
}
|
||||
|
||||
// DecryptPKCS1v15 decrypts a plaintext using RSA and the padding scheme from PKCS#1 v1.5.
|
||||
@@ -150,7 +149,7 @@ func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid
|
||||
return
|
||||
}
|
||||
|
||||
- em = leftPad(m.Bytes(), k)
|
||||
+ em = m.FillBytes(make([]byte, k))
|
||||
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
|
||||
secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
|
||||
|
||||
@@ -256,8 +255,7 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
|
||||
return nil, err
|
||||
}
|
||||
|
||||
- copyWithLeftPad(em, c.Bytes())
|
||||
- return em, nil
|
||||
+ return c.FillBytes(em), nil
|
||||
}
|
||||
|
||||
// VerifyPKCS1v15 verifies an RSA PKCS#1 v1.5 signature.
|
||||
@@ -286,7 +284,7 @@ func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte)
|
||||
|
||||
c := new(big.Int).SetBytes(sig)
|
||||
m := encrypt(new(big.Int), pub, c)
|
||||
- em := leftPad(m.Bytes(), k)
|
||||
+ em := m.FillBytes(make([]byte, k))
|
||||
// EM = 0x00 || 0x01 || PS || 0x00 || T
|
||||
|
||||
ok := subtle.ConstantTimeByteEq(em[0], 0)
|
||||
@@ -323,13 +321,3 @@ func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte,
|
||||
}
|
||||
return
|
||||
}
|
||||
-
|
||||
-// copyWithLeftPad copies src to the end of dest, padding with zero bytes as
|
||||
-// needed.
|
||||
-func copyWithLeftPad(dest, src []byte) {
|
||||
- numPaddingBytes := len(dest) - len(src)
|
||||
- for i := 0; i < numPaddingBytes; i++ {
|
||||
- dest[i] = 0
|
||||
- }
|
||||
- copy(dest[numPaddingBytes:], src)
|
||||
-}
|
||||
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
|
||||
index f9844d87329a8..b2adbedb28fa8 100644
|
||||
--- a/src/crypto/rsa/pss.go
|
||||
+++ b/src/crypto/rsa/pss.go
|
||||
@@ -207,20 +207,19 @@ func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
|
||||
// Note that hashed must be the result of hashing the input message using the
|
||||
// given hash function. salt is a random sequence of bytes whose length will be
|
||||
// later used to verify the signature.
|
||||
-func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) {
|
||||
+func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) ([]byte, error) {
|
||||
emBits := priv.N.BitLen() - 1
|
||||
em, err := emsaPSSEncode(hashed, emBits, salt, hash.New())
|
||||
if err != nil {
|
||||
- return
|
||||
+ return nil, err
|
||||
}
|
||||
m := new(big.Int).SetBytes(em)
|
||||
c, err := decryptAndCheck(rand, priv, m)
|
||||
if err != nil {
|
||||
- return
|
||||
+ return nil, err
|
||||
}
|
||||
- s = make([]byte, priv.Size())
|
||||
- copyWithLeftPad(s, c.Bytes())
|
||||
- return
|
||||
+ s := make([]byte, priv.Size())
|
||||
+ return c.FillBytes(s), nil
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -296,11 +295,9 @@ func VerifyPSS(pub *PublicKey, hash crypto.Hash, digest []byte, sig []byte, opts
|
||||
m := encrypt(new(big.Int), pub, s)
|
||||
emBits := pub.N.BitLen() - 1
|
||||
emLen := (emBits + 7) / 8
|
||||
- emBytes := m.Bytes()
|
||||
- if emLen < len(emBytes) {
|
||||
+ if m.BitLen() > emLen*8 {
|
||||
return ErrVerification
|
||||
}
|
||||
- em := make([]byte, emLen)
|
||||
- copyWithLeftPad(em, emBytes)
|
||||
+ em := m.FillBytes(make([]byte, emLen))
|
||||
return emsaPSSVerify(digest, em, emBits, opts.saltLength(), hash.New())
|
||||
}
|
||||
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
|
||||
index b4bfa13defbdf..28eb5926c1a54 100644
|
||||
--- a/src/crypto/rsa/rsa.go
|
||||
+++ b/src/crypto/rsa/rsa.go
|
||||
@@ -416,16 +416,9 @@ func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, l
|
||||
m := new(big.Int)
|
||||
m.SetBytes(em)
|
||||
c := encrypt(new(big.Int), pub, m)
|
||||
- out := c.Bytes()
|
||||
|
||||
- if len(out) < k {
|
||||
- // If the output is too small, we need to left-pad with zeros.
|
||||
- t := make([]byte, k)
|
||||
- copy(t[k-len(out):], out)
|
||||
- out = t
|
||||
- }
|
||||
-
|
||||
- return out, nil
|
||||
+ out := make([]byte, k)
|
||||
+ return c.FillBytes(out), nil
|
||||
}
|
||||
|
||||
// ErrDecryption represents a failure to decrypt a message.
|
||||
@@ -597,12 +590,9 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
|
||||
lHash := hash.Sum(nil)
|
||||
hash.Reset()
|
||||
|
||||
- // Converting the plaintext number to bytes will strip any
|
||||
- // leading zeros so we may have to left pad. We do this unconditionally
|
||||
- // to avoid leaking timing information. (Although we still probably
|
||||
- // leak the number of leading zeros. It's not clear that we can do
|
||||
- // anything about this.)
|
||||
- em := leftPad(m.Bytes(), k)
|
||||
+ // We probably leak the number of leading zeros.
|
||||
+ // It's not clear that we can do anything about this.
|
||||
+ em := m.FillBytes(make([]byte, k))
|
||||
|
||||
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
|
||||
|
||||
@@ -643,15 +633,3 @@ func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext
|
||||
|
||||
return rest[index+1:], nil
|
||||
}
|
||||
-
|
||||
-// leftPad returns a new slice of length size. The contents of input are right
|
||||
-// aligned in the new slice.
|
||||
-func leftPad(input []byte, size int) (out []byte) {
|
||||
- n := len(input)
|
||||
- if n > size {
|
||||
- n = size
|
||||
- }
|
||||
- out = make([]byte, size)
|
||||
- copy(out[len(out)-n:], input)
|
||||
- return
|
||||
-}
|
||||
diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go
|
||||
index 2aab323202f7d..314016979afb8 100644
|
||||
--- a/src/crypto/tls/key_schedule.go
|
||||
+++ b/src/crypto/tls/key_schedule.go
|
||||
@@ -173,11 +173,8 @@ func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte {
|
||||
}
|
||||
|
||||
xShared, _ := curve.ScalarMult(x, y, p.privateKey)
|
||||
- sharedKey := make([]byte, (curve.Params().BitSize+7)>>3)
|
||||
- xBytes := xShared.Bytes()
|
||||
- copy(sharedKey[len(sharedKey)-len(xBytes):], xBytes)
|
||||
-
|
||||
- return sharedKey
|
||||
+ sharedKey := make([]byte, (curve.Params().BitSize+7)/8)
|
||||
+ return xShared.FillBytes(sharedKey)
|
||||
}
|
||||
|
||||
type x25519Parameters struct {
|
||||
diff --git a/src/crypto/x509/sec1.go b/src/crypto/x509/sec1.go
|
||||
index 0bfb90cd5464a..52c108ff1d624 100644
|
||||
--- a/src/crypto/x509/sec1.go
|
||||
+++ b/src/crypto/x509/sec1.go
|
||||
@@ -52,13 +52,10 @@ func MarshalECPrivateKey(key *ecdsa.PrivateKey) ([]byte, error) {
|
||||
// marshalECPrivateKey marshals an EC private key into ASN.1, DER format and
|
||||
// sets the curve ID to the given OID, or omits it if OID is nil.
|
||||
func marshalECPrivateKeyWithOID(key *ecdsa.PrivateKey, oid asn1.ObjectIdentifier) ([]byte, error) {
|
||||
- privateKeyBytes := key.D.Bytes()
|
||||
- paddedPrivateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
|
||||
- copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes)
|
||||
-
|
||||
+ privateKey := make([]byte, (key.Curve.Params().N.BitLen()+7)/8)
|
||||
return asn1.Marshal(ecPrivateKey{
|
||||
Version: 1,
|
||||
- PrivateKey: paddedPrivateKey,
|
||||
+ PrivateKey: key.D.FillBytes(privateKey),
|
||||
NamedCurveOID: oid,
|
||||
PublicKey: asn1.BitString{Bytes: elliptic.Marshal(key.Curve, key.X, key.Y)},
|
||||
})
|
||||
diff --git a/src/math/big/int.go b/src/math/big/int.go
|
||||
index 8816cf5266cc4..65f32487b58c0 100644
|
||||
--- a/src/math/big/int.go
|
||||
+++ b/src/math/big/int.go
|
||||
@@ -447,11 +447,26 @@ func (z *Int) SetBytes(buf []byte) *Int {
|
||||
}
|
||||
|
||||
// Bytes returns the absolute value of x as a big-endian byte slice.
|
||||
+//
|
||||
+// To use a fixed length slice, or a preallocated one, use FillBytes.
|
||||
func (x *Int) Bytes() []byte {
|
||||
buf := make([]byte, len(x.abs)*_S)
|
||||
return buf[x.abs.bytes(buf):]
|
||||
}
|
||||
|
||||
+// FillBytes sets buf to the absolute value of x, storing it as a zero-extended
|
||||
+// big-endian byte slice, and returns buf.
|
||||
+//
|
||||
+// If the absolute value of x doesn't fit in buf, FillBytes will panic.
|
||||
+func (x *Int) FillBytes(buf []byte) []byte {
|
||||
+ // Clear whole buffer. (This gets optimized into a memclr.)
|
||||
+ for i := range buf {
|
||||
+ buf[i] = 0
|
||||
+ }
|
||||
+ x.abs.bytes(buf)
|
||||
+ return buf
|
||||
+}
|
||||
+
|
||||
// BitLen returns the length of the absolute value of x in bits.
|
||||
// The bit length of 0 is 0.
|
||||
func (x *Int) BitLen() int {
|
||||
diff --git a/src/math/big/int_test.go b/src/math/big/int_test.go
|
||||
index e3a1587b3f0ad..3c8557323a032 100644
|
||||
--- a/src/math/big/int_test.go
|
||||
+++ b/src/math/big/int_test.go
|
||||
@@ -1840,3 +1840,57 @@ func BenchmarkDiv(b *testing.B) {
|
||||
})
|
||||
}
|
||||
}
|
||||
+
|
||||
+func TestFillBytes(t *testing.T) {
|
||||
+ checkResult := func(t *testing.T, buf []byte, want *Int) {
|
||||
+ t.Helper()
|
||||
+ got := new(Int).SetBytes(buf)
|
||||
+ if got.CmpAbs(want) != 0 {
|
||||
+ t.Errorf("got 0x%x, want 0x%x: %x", got, want, buf)
|
||||
+ }
|
||||
+ }
|
||||
+ panics := func(f func()) (panic bool) {
|
||||
+ defer func() { panic = recover() != nil }()
|
||||
+ f()
|
||||
+ return
|
||||
+ }
|
||||
+
|
||||
+ for _, n := range []string{
|
||||
+ "0",
|
||||
+ "1000",
|
||||
+ "0xffffffff",
|
||||
+ "-0xffffffff",
|
||||
+ "0xffffffffffffffff",
|
||||
+ "0x10000000000000000",
|
||||
+ "0xabababababababababababababababababababababababababa",
|
||||
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
+ } {
|
||||
+ t.Run(n, func(t *testing.T) {
|
||||
+ t.Logf(n)
|
||||
+ x, ok := new(Int).SetString(n, 0)
|
||||
+ if !ok {
|
||||
+ panic("invalid test entry")
|
||||
+ }
|
||||
+
|
||||
+ // Perfectly sized buffer.
|
||||
+ byteLen := (x.BitLen() + 7) / 8
|
||||
+ buf := make([]byte, byteLen)
|
||||
+ checkResult(t, x.FillBytes(buf), x)
|
||||
+
|
||||
+ // Way larger, checking all bytes get zeroed.
|
||||
+ buf = make([]byte, 100)
|
||||
+ for i := range buf {
|
||||
+ buf[i] = 0xff
|
||||
+ }
|
||||
+ checkResult(t, x.FillBytes(buf), x)
|
||||
+
|
||||
+ // Too small.
|
||||
+ if byteLen > 0 {
|
||||
+ buf = make([]byte, byteLen-1)
|
||||
+ if !panics(func() { x.FillBytes(buf) }) {
|
||||
+ t.Errorf("expected panic for small buffer and value %x", x)
|
||||
+ }
|
||||
+ }
|
||||
+ })
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/math/big/nat.go b/src/math/big/nat.go
|
||||
index c31ec5156b81d..6a3989bf9d82b 100644
|
||||
--- a/src/math/big/nat.go
|
||||
+++ b/src/math/big/nat.go
|
||||
@@ -1476,19 +1476,26 @@ func (z nat) expNNMontgomery(x, y, m nat) nat {
|
||||
}
|
||||
|
||||
// bytes writes the value of z into buf using big-endian encoding.
|
||||
-// len(buf) must be >= len(z)*_S. The value of z is encoded in the
|
||||
-// slice buf[i:]. The number i of unused bytes at the beginning of
|
||||
-// buf is returned as result.
|
||||
+// The value of z is encoded in the slice buf[i:]. If the value of z
|
||||
+// cannot be represented in buf, bytes panics. The number i of unused
|
||||
+// bytes at the beginning of buf is returned as result.
|
||||
func (z nat) bytes(buf []byte) (i int) {
|
||||
i = len(buf)
|
||||
for _, d := range z {
|
||||
for j := 0; j < _S; j++ {
|
||||
i--
|
||||
- buf[i] = byte(d)
|
||||
+ if i >= 0 {
|
||||
+ buf[i] = byte(d)
|
||||
+ } else if byte(d) != 0 {
|
||||
+ panic("math/big: buffer too small to fit value")
|
||||
+ }
|
||||
d >>= 8
|
||||
}
|
||||
}
|
||||
|
||||
+ if i < 0 {
|
||||
+ i = 0
|
||||
+ }
|
||||
for i < len(buf) && buf[i] == 0 {
|
||||
i++
|
||||
}
|
||||
86
meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre3.patch
Normal file
86
meta/recipes-devtools/go/go-1.14/CVE-2023-45287-pre3.patch
Normal file
@@ -0,0 +1,86 @@
|
||||
From 8f676144ad7b7c91adb0c6e1ec89aaa6283c6807 Mon Sep 17 00:00:00 2001
|
||||
From: Himanshu Kishna Srivastava <28himanshu@gmail.com>
|
||||
Date: Tue, 16 Mar 2021 22:37:46 +0530
|
||||
Subject: [PATCH] crypto/rsa: fix salt length calculation with
|
||||
PSSSaltLengthAuto
|
||||
|
||||
When PSSSaltLength is set, the maximum salt length must equal:
|
||||
|
||||
(modulus_key_size - 1 + 7)/8 - hash_length - 2
|
||||
and for example, with a 4096 bit modulus key, and a SHA-1 hash,
|
||||
it should be:
|
||||
|
||||
(4096 -1 + 7)/8 - 20 - 2 = 490
|
||||
Previously we'd encounter this error:
|
||||
|
||||
crypto/rsa: key size too small for PSS signature
|
||||
|
||||
Fixes #42741
|
||||
|
||||
Change-Id: I18bb82c41c511d564b3f4c443f4b3a38ab010ac5
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/302230
|
||||
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
|
||||
Reviewed-by: Filippo Valsorda <filippo@golang.org>
|
||||
Trust: Emmanuel Odeke <emmanuel@orijtech.com>
|
||||
Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
|
||||
TryBot-Result: Go Bot <gobot@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/8f676144ad7b7c91adb0c6e1ec89aaa6283c6807]
|
||||
CVE: CVE-2023-45287 #Dependency Patch3
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/crypto/rsa/pss.go | 2 +-
|
||||
src/crypto/rsa/pss_test.go | 20 +++++++++++++++++++-
|
||||
2 files changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
|
||||
index b2adbedb28fa8..814522de8181f 100644
|
||||
--- a/src/crypto/rsa/pss.go
|
||||
+++ b/src/crypto/rsa/pss.go
|
||||
@@ -269,7 +269,7 @@ func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, digest []byte,
|
||||
saltLength := opts.saltLength()
|
||||
switch saltLength {
|
||||
case PSSSaltLengthAuto:
|
||||
- saltLength = priv.Size() - 2 - hash.Size()
|
||||
+ saltLength = (priv.N.BitLen()-1+7)/8 - 2 - hash.Size()
|
||||
case PSSSaltLengthEqualsHash:
|
||||
saltLength = hash.Size()
|
||||
}
|
||||
diff --git a/src/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go
|
||||
index dfa8d8bb5ad02..c3a6d468497cd 100644
|
||||
--- a/src/crypto/rsa/pss_test.go
|
||||
+++ b/src/crypto/rsa/pss_test.go
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
_ "crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
- _ "crypto/sha256"
|
||||
+ "crypto/sha256"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"os"
|
||||
@@ -233,6 +233,24 @@ func TestPSSSigning(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+func TestSignWithPSSSaltLengthAuto(t *testing.T) {
|
||||
+ key, err := GenerateKey(rand.Reader, 513)
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ digest := sha256.Sum256([]byte("message"))
|
||||
+ signature, err := key.Sign(rand.Reader, digest[:], &PSSOptions{
|
||||
+ SaltLength: PSSSaltLengthAuto,
|
||||
+ Hash: crypto.SHA256,
|
||||
+ })
|
||||
+ if err != nil {
|
||||
+ t.Fatal(err)
|
||||
+ }
|
||||
+ if len(signature) == 0 {
|
||||
+ t.Fatal("empty signature returned")
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
func bigFromHex(hex string) *big.Int {
|
||||
n, ok := new(big.Int).SetString(hex, 16)
|
||||
if !ok {
|
||||
1697
meta/recipes-devtools/go/go-1.14/CVE-2023-45287.patch
Normal file
1697
meta/recipes-devtools/go/go-1.14/CVE-2023-45287.patch
Normal file
File diff suppressed because it is too large
Load Diff
121
meta/recipes-devtools/go/go-1.14/CVE-2023-45289.patch
Normal file
121
meta/recipes-devtools/go/go-1.14/CVE-2023-45289.patch
Normal file
@@ -0,0 +1,121 @@
|
||||
From 20586c0dbe03d144f914155f879fa5ee287591a1 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Thu, 11 Jan 2024 11:31:57 -0800
|
||||
Subject: [PATCH] [release-branch.go1.21] net/http, net/http/cookiejar: avoid
|
||||
subdomain matches on IPv6 zones
|
||||
|
||||
When deciding whether to forward cookies or sensitive headers
|
||||
across a redirect, do not attempt to interpret an IPv6 address
|
||||
as a domain name.
|
||||
|
||||
Avoids a case where a maliciously-crafted redirect to an
|
||||
IPv6 address with a scoped addressing zone could be
|
||||
misinterpreted as a within-domain redirect. For example,
|
||||
we could interpret "::1%.www.example.com" as a subdomain
|
||||
of "www.example.com".
|
||||
|
||||
Thanks to Juho Nurminen of Mattermost for reporting this issue.
|
||||
|
||||
Fixes CVE-2023-45289
|
||||
Fixes #65385
|
||||
For #65065
|
||||
|
||||
Change-Id: I8f463f59f0e700c8a18733d2b264a8bcb3a19599
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2131938
|
||||
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2173775
|
||||
Reviewed-by: Carlos Amedee <amedee@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/569239
|
||||
Reviewed-by: Carlos Amedee <carlos@golang.org>
|
||||
Auto-Submit: Michael Knyszek <mknyszek@google.com>
|
||||
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/20586c0dbe03d144f914155f879fa5ee287591a1]
|
||||
CVE: CVE-2023-45289
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/net/http/client.go | 6 ++++++
|
||||
src/net/http/client_test.go | 1 +
|
||||
src/net/http/cookiejar/jar.go | 7 +++++++
|
||||
src/net/http/cookiejar/jar_test.go | 10 ++++++++++
|
||||
4 files changed, 24 insertions(+)
|
||||
|
||||
diff --git a/src/net/http/client.go b/src/net/http/client.go
|
||||
index a496f1c..2031834 100644
|
||||
--- a/src/net/http/client.go
|
||||
+++ b/src/net/http/client.go
|
||||
@@ -973,6 +973,12 @@ func isDomainOrSubdomain(sub, parent string) bool {
|
||||
if sub == parent {
|
||||
return true
|
||||
}
|
||||
+ // If sub contains a :, it's probably an IPv6 address (and is definitely not a hostname).
|
||||
+ // Don't check the suffix in this case, to avoid matching the contents of a IPv6 zone.
|
||||
+ // For example, "::1%.www.example.com" is not a subdomain of "www.example.com".
|
||||
+ if strings.ContainsAny(sub, ":%") {
|
||||
+ return false
|
||||
+ }
|
||||
// If sub is "foo.example.com" and parent is "example.com",
|
||||
// that means sub must end in "."+parent.
|
||||
// Do it without allocating.
|
||||
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
|
||||
index 2b4f53f..442fe35 100644
|
||||
--- a/src/net/http/client_test.go
|
||||
+++ b/src/net/http/client_test.go
|
||||
@@ -1703,6 +1703,7 @@ func TestShouldCopyHeaderOnRedirect(t *testing.T) {
|
||||
{"cookie2", "http://foo.com/", "http://bar.com/", false},
|
||||
{"authorization", "http://foo.com/", "http://bar.com/", false},
|
||||
{"www-authenticate", "http://foo.com/", "http://bar.com/", false},
|
||||
+ {"authorization", "http://foo.com/", "http://[::1%25.foo.com]/", false},
|
||||
|
||||
// But subdomains should work:
|
||||
{"www-authenticate", "http://foo.com/", "http://foo.com/", true},
|
||||
diff --git a/src/net/http/cookiejar/jar.go b/src/net/http/cookiejar/jar.go
|
||||
index 9f19917..18cbfc2 100644
|
||||
--- a/src/net/http/cookiejar/jar.go
|
||||
+++ b/src/net/http/cookiejar/jar.go
|
||||
@@ -356,6 +356,13 @@ func jarKey(host string, psl PublicSuffixList) string {
|
||||
|
||||
// isIP reports whether host is an IP address.
|
||||
func isIP(host string) bool {
|
||||
+ if strings.ContainsAny(host, ":%") {
|
||||
+ // Probable IPv6 address.
|
||||
+ // Hostnames can't contain : or %, so this is definitely not a valid host.
|
||||
+ // Treating it as an IP is the more conservative option, and avoids the risk
|
||||
+ // of interpeting ::1%.www.example.com as a subtomain of www.example.com.
|
||||
+ return true
|
||||
+ }
|
||||
return net.ParseIP(host) != nil
|
||||
}
|
||||
|
||||
diff --git a/src/net/http/cookiejar/jar_test.go b/src/net/http/cookiejar/jar_test.go
|
||||
index 47fb1ab..fd8d40e 100644
|
||||
--- a/src/net/http/cookiejar/jar_test.go
|
||||
+++ b/src/net/http/cookiejar/jar_test.go
|
||||
@@ -251,6 +251,7 @@ var isIPTests = map[string]bool{
|
||||
"127.0.0.1": true,
|
||||
"1.2.3.4": true,
|
||||
"2001:4860:0:2001::68": true,
|
||||
+ "::1%zone": true,
|
||||
"example.com": false,
|
||||
"1.1.1.300": false,
|
||||
"www.foo.bar.net": false,
|
||||
@@ -613,6 +614,15 @@ var basicsTests = [...]jarTest{
|
||||
{"http://www.host.test:1234/", "a=1"},
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ "IPv6 zone is not treated as a host.",
|
||||
+ "https://example.com/",
|
||||
+ []string{"a=1"},
|
||||
+ "a=1",
|
||||
+ []query{
|
||||
+ {"https://[::1%25.example.com]:80/", ""},
|
||||
+ },
|
||||
+ },
|
||||
}
|
||||
|
||||
func TestBasics(t *testing.T) {
|
||||
--
|
||||
2.25.1
|
||||
|
||||
271
meta/recipes-devtools/go/go-1.14/CVE-2023-45290.patch
Normal file
271
meta/recipes-devtools/go/go-1.14/CVE-2023-45290.patch
Normal file
@@ -0,0 +1,271 @@
|
||||
From bf80213b121074f4ad9b449410a4d13bae5e9be0 Mon Sep 17 00:00:00 2001
|
||||
From: Damien Neil <dneil@google.com>
|
||||
Date: Tue, 16 Jan 2024 15:37:52 -0800
|
||||
Subject: [PATCH] [release-branch.go1.21] net/textproto, mime/multipart: avoid
|
||||
unbounded read in MIME header
|
||||
|
||||
mime/multipart.Reader.ReadForm allows specifying the maximum amount
|
||||
of memory that will be consumed by the form. While this limit is
|
||||
correctly applied to the parsed form data structure, it was not
|
||||
being applied to individual header lines in a form.
|
||||
|
||||
For example, when presented with a form containing a header line
|
||||
that never ends, ReadForm will continue to read the line until it
|
||||
runs out of memory.
|
||||
|
||||
Limit the amount of data consumed when reading a header.
|
||||
|
||||
Fixes CVE-2023-45290
|
||||
Fixes #65389
|
||||
For #65383
|
||||
|
||||
Change-Id: I7f9264d25752009e95f6b2c80e3d76aaf321d658
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2134435
|
||||
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
||||
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
|
||||
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2173776
|
||||
Reviewed-by: Carlos Amedee <amedee@google.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/569240
|
||||
Auto-Submit: Michael Knyszek <mknyszek@google.com>
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
Reviewed-by: Carlos Amedee <carlos@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/bf80213b121074f4ad9b449410a4d13bae5e9be0]
|
||||
CVE: CVE-2023-45290
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/mime/multipart/formdata_test.go | 42 +++++++++++++++++++++++++
|
||||
src/net/textproto/reader.go | 48 ++++++++++++++++++++---------
|
||||
src/net/textproto/reader_test.go | 12 ++++++++
|
||||
3 files changed, 87 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/src/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go
|
||||
index c78eeb7..f729da6 100644
|
||||
--- a/src/mime/multipart/formdata_test.go
|
||||
+++ b/src/mime/multipart/formdata_test.go
|
||||
@@ -421,6 +421,48 @@ func TestReadFormLimits(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+func TestReadFormEndlessHeaderLine(t *testing.T) {
|
||||
+ for _, test := range []struct {
|
||||
+ name string
|
||||
+ prefix string
|
||||
+ }{{
|
||||
+ name: "name",
|
||||
+ prefix: "X-",
|
||||
+ }, {
|
||||
+ name: "value",
|
||||
+ prefix: "X-Header: ",
|
||||
+ }, {
|
||||
+ name: "continuation",
|
||||
+ prefix: "X-Header: foo\r\n ",
|
||||
+ }} {
|
||||
+ t.Run(test.name, func(t *testing.T) {
|
||||
+ const eol = "\r\n"
|
||||
+ s := `--boundary` + eol
|
||||
+ s += `Content-Disposition: form-data; name="a"` + eol
|
||||
+ s += `Content-Type: text/plain` + eol
|
||||
+ s += test.prefix
|
||||
+ fr := io.MultiReader(
|
||||
+ strings.NewReader(s),
|
||||
+ neverendingReader('X'),
|
||||
+ )
|
||||
+ r := NewReader(fr, "boundary")
|
||||
+ _, err := r.ReadForm(1 << 20)
|
||||
+ if err != ErrMessageTooLarge {
|
||||
+ t.Fatalf("ReadForm(1 << 20): %v, want ErrMessageTooLarge", err)
|
||||
+ }
|
||||
+ })
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+type neverendingReader byte
|
||||
+
|
||||
+func (r neverendingReader) Read(p []byte) (n int, err error) {
|
||||
+ for i := range p {
|
||||
+ p[i] = byte(r)
|
||||
+ }
|
||||
+ return len(p), nil
|
||||
+}
|
||||
+
|
||||
func BenchmarkReadForm(b *testing.B) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go
|
||||
index ad2d777..cea6613 100644
|
||||
--- a/src/net/textproto/reader.go
|
||||
+++ b/src/net/textproto/reader.go
|
||||
@@ -17,6 +17,10 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
+// TODO: This should be a distinguishable error (ErrMessageTooLarge)
|
||||
+// to allow mime/multipart to detect it.
|
||||
+var errMessageTooLarge = errors.New("message too large")
|
||||
+
|
||||
// A Reader implements convenience methods for reading requests
|
||||
// or responses from a text protocol network connection.
|
||||
type Reader struct {
|
||||
@@ -38,13 +42,13 @@ func NewReader(r *bufio.Reader) *Reader {
|
||||
// ReadLine reads a single line from r,
|
||||
// eliding the final \n or \r\n from the returned string.
|
||||
func (r *Reader) ReadLine() (string, error) {
|
||||
- line, err := r.readLineSlice()
|
||||
+ line, err := r.readLineSlice(-1)
|
||||
return string(line), err
|
||||
}
|
||||
|
||||
// ReadLineBytes is like ReadLine but returns a []byte instead of a string.
|
||||
func (r *Reader) ReadLineBytes() ([]byte, error) {
|
||||
- line, err := r.readLineSlice()
|
||||
+ line, err := r.readLineSlice(-1)
|
||||
if line != nil {
|
||||
buf := make([]byte, len(line))
|
||||
copy(buf, line)
|
||||
@@ -53,7 +57,10 @@ func (r *Reader) ReadLineBytes() ([]byte, error) {
|
||||
return line, err
|
||||
}
|
||||
|
||||
-func (r *Reader) readLineSlice() ([]byte, error) {
|
||||
+// readLineSlice reads a single line from r,
|
||||
+// up to lim bytes long (or unlimited if lim is less than 0),
|
||||
+// eliding the final \r or \r\n from the returned string.
|
||||
+func (r *Reader) readLineSlice(lim int64) ([]byte, error) {
|
||||
r.closeDot()
|
||||
var line []byte
|
||||
for {
|
||||
@@ -61,6 +68,9 @@ func (r *Reader) readLineSlice() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
+ if lim >= 0 && int64(len(line))+int64(len(l)) > lim {
|
||||
+ return nil, errMessageTooLarge
|
||||
+ }
|
||||
// Avoid the copy if the first call produced a full line.
|
||||
if line == nil && !more {
|
||||
return l, nil
|
||||
@@ -93,7 +103,7 @@ func (r *Reader) readLineSlice() ([]byte, error) {
|
||||
// A line consisting of only white space is never continued.
|
||||
//
|
||||
func (r *Reader) ReadContinuedLine() (string, error) {
|
||||
- line, err := r.readContinuedLineSlice(noValidation)
|
||||
+ line, err := r.readContinuedLineSlice(-1, noValidation)
|
||||
return string(line), err
|
||||
}
|
||||
|
||||
@@ -114,7 +124,7 @@ func trim(s []byte) []byte {
|
||||
// ReadContinuedLineBytes is like ReadContinuedLine but
|
||||
// returns a []byte instead of a string.
|
||||
func (r *Reader) ReadContinuedLineBytes() ([]byte, error) {
|
||||
- line, err := r.readContinuedLineSlice(noValidation)
|
||||
+ line, err := r.readContinuedLineSlice(-1, noValidation)
|
||||
if line != nil {
|
||||
buf := make([]byte, len(line))
|
||||
copy(buf, line)
|
||||
@@ -127,13 +137,14 @@ func (r *Reader) ReadContinuedLineBytes() ([]byte, error) {
|
||||
// returning a byte slice with all lines. The validateFirstLine function
|
||||
// is run on the first read line, and if it returns an error then this
|
||||
// error is returned from readContinuedLineSlice.
|
||||
-func (r *Reader) readContinuedLineSlice(validateFirstLine func([]byte) error) ([]byte, error) {
|
||||
+// It reads up to lim bytes of data (or unlimited if lim is less than 0).
|
||||
+func (r *Reader) readContinuedLineSlice(lim int64, validateFirstLine func([]byte) error) ([]byte, error) {
|
||||
if validateFirstLine == nil {
|
||||
return nil, fmt.Errorf("missing validateFirstLine func")
|
||||
}
|
||||
|
||||
// Read the first line.
|
||||
- line, err := r.readLineSlice()
|
||||
+ line, err := r.readLineSlice(lim)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -161,13 +172,21 @@ func (r *Reader) readContinuedLineSlice(validateFirstLine func([]byte) error) ([
|
||||
// copy the slice into buf.
|
||||
r.buf = append(r.buf[:0], trim(line)...)
|
||||
|
||||
+ if lim < 0 {
|
||||
+ lim = math.MaxInt64
|
||||
+ }
|
||||
+ lim -= int64(len(r.buf))
|
||||
+
|
||||
// Read continuation lines.
|
||||
for r.skipSpace() > 0 {
|
||||
- line, err := r.readLineSlice()
|
||||
+ r.buf = append(r.buf, ' ')
|
||||
+ if int64(len(r.buf)) >= lim {
|
||||
+ return nil, errMessageTooLarge
|
||||
+ }
|
||||
+ line, err := r.readLineSlice(lim - int64(len(r.buf)))
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
- r.buf = append(r.buf, ' ')
|
||||
r.buf = append(r.buf, trim(line)...)
|
||||
}
|
||||
return r.buf, nil
|
||||
@@ -512,7 +531,8 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
|
||||
|
||||
// The first line cannot start with a leading space.
|
||||
if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
|
||||
- line, err := r.readLineSlice()
|
||||
+ const errorLimit = 80 // arbitrary limit on how much of the line we'll quote
|
||||
+ line, err := r.readLineSlice(errorLimit)
|
||||
if err != nil {
|
||||
return m, err
|
||||
}
|
||||
@@ -520,7 +540,7 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
|
||||
}
|
||||
|
||||
for {
|
||||
- kv, err := r.readContinuedLineSlice(mustHaveFieldNameColon)
|
||||
+ kv, err := r.readContinuedLineSlice(maxMemory, mustHaveFieldNameColon)
|
||||
if len(kv) == 0 {
|
||||
return m, err
|
||||
}
|
||||
@@ -541,7 +561,7 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
|
||||
|
||||
maxHeaders--
|
||||
if maxHeaders < 0 {
|
||||
- return nil, errors.New("message too large")
|
||||
+ return nil, errMessageTooLarge
|
||||
}
|
||||
|
||||
// backport 5c55ac9bf1e5f779220294c843526536605f42ab
|
||||
@@ -567,9 +587,7 @@ func readMIMEHeader(r *Reader, maxMemory, maxHeaders int64) (MIMEHeader, error)
|
||||
}
|
||||
maxMemory -= int64(len(value))
|
||||
if maxMemory < 0 {
|
||||
- // TODO: This should be a distinguishable error (ErrMessageTooLarge)
|
||||
- // to allow mime/multipart to detect it.
|
||||
- return m, errors.New("message too large")
|
||||
+ return m, errMessageTooLarge
|
||||
}
|
||||
if vv == nil && len(strs) > 0 {
|
||||
// More than likely this will be a single-element key.
|
||||
diff --git a/src/net/textproto/reader_test.go b/src/net/textproto/reader_test.go
|
||||
index 3ae0de1..db1ed91 100644
|
||||
--- a/src/net/textproto/reader_test.go
|
||||
+++ b/src/net/textproto/reader_test.go
|
||||
@@ -34,6 +34,18 @@ func TestReadLine(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+func TestReadLineLongLine(t *testing.T) {
|
||||
+ line := strings.Repeat("12345", 10000)
|
||||
+ r := reader(line + "\r\n")
|
||||
+ s, err := r.ReadLine()
|
||||
+ if err != nil {
|
||||
+ t.Fatalf("Line 1: %v", err)
|
||||
+ }
|
||||
+ if s != line {
|
||||
+ t.Fatalf("%v-byte line does not match expected %v-byte line", len(s), len(line))
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
func TestReadContinuedLine(t *testing.T) {
|
||||
r := reader("line1\nline\n 2\nline3\n")
|
||||
s, err := r.ReadContinuedLine()
|
||||
--
|
||||
2.25.1
|
||||
|
||||
205
meta/recipes-devtools/go/go-1.14/CVE-2024-24784.patch
Normal file
205
meta/recipes-devtools/go/go-1.14/CVE-2024-24784.patch
Normal file
@@ -0,0 +1,205 @@
|
||||
From 5330cd225ba54c7dc78c1b46dcdf61a4671a632c Mon Sep 17 00:00:00 2001
|
||||
From: Roland Shoemaker <bracewell@google.com>
|
||||
Date: Wed, 10 Jan 2024 11:02:14 -0800
|
||||
Subject: [PATCH] [release-branch.go1.22] net/mail: properly handle special
|
||||
characters in phrase and obs-phrase
|
||||
|
||||
Fixes a couple of misalignments with RFC 5322 which introduce
|
||||
significant diffs between (mostly) conformant parsers.
|
||||
|
||||
This change reverts the changes made in CL50911, which allowed certain
|
||||
special RFC 5322 characters to appear unquoted in the "phrase" syntax.
|
||||
It is unclear why this change was made in the first place, and created
|
||||
a divergence from comformant parsers. In particular this resulted in
|
||||
treating comments in display names incorrectly.
|
||||
|
||||
Additionally properly handle trailing malformed comments in the group
|
||||
syntax.
|
||||
|
||||
For #65083
|
||||
Fixed #65849
|
||||
|
||||
Change-Id: I00dddc044c6ae3381154e43236632604c390f672
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/555596
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/566215
|
||||
Reviewed-by: Carlos Amedee <carlos@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/5330cd225ba54c7dc78c1b46dcdf61a4671a632c]
|
||||
CVE: CVE-2024-24784
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
|
||||
src/net/mail/message.go | 30 +++++++++++++++------------
|
||||
src/net/mail/message_test.go | 40 ++++++++++++++++++++++++++----------
|
||||
2 files changed, 46 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
|
||||
index af516fc30f470..fc2a9e46f811b 100644
|
||||
--- a/src/net/mail/message.go
|
||||
+++ b/src/net/mail/message.go
|
||||
@@ -280,7 +280,7 @@ func (a *Address) String() string {
|
||||
// Add quotes if needed
|
||||
quoteLocal := false
|
||||
for i, r := range local {
|
||||
- if isAtext(r, false, false) {
|
||||
+ if isAtext(r, false) {
|
||||
continue
|
||||
}
|
||||
if r == '.' {
|
||||
@@ -444,7 +444,7 @@ func (p *addrParser) parseAddress(handleGroup bool) ([]*Address, error) {
|
||||
if !p.consume('<') {
|
||||
atext := true
|
||||
for _, r := range displayName {
|
||||
- if !isAtext(r, true, false) {
|
||||
+ if !isAtext(r, true) {
|
||||
atext = false
|
||||
break
|
||||
}
|
||||
@@ -479,7 +479,9 @@ func (p *addrParser) consumeGroupList() ([]*Address, error) {
|
||||
// handle empty group.
|
||||
p.skipSpace()
|
||||
if p.consume(';') {
|
||||
- p.skipCFWS()
|
||||
+ if !p.skipCFWS() {
|
||||
+ return nil, errors.New("mail: misformatted parenthetical comment")
|
||||
+ }
|
||||
return group, nil
|
||||
}
|
||||
|
||||
@@ -496,7 +498,9 @@ func (p *addrParser) consumeGroupList() ([]*Address, error) {
|
||||
return nil, errors.New("mail: misformatted parenthetical comment")
|
||||
}
|
||||
if p.consume(';') {
|
||||
- p.skipCFWS()
|
||||
+ if !p.skipCFWS() {
|
||||
+ return nil, errors.New("mail: misformatted parenthetical comment")
|
||||
+ }
|
||||
break
|
||||
}
|
||||
if !p.consume(',') {
|
||||
@@ -566,6 +570,12 @@ func (p *addrParser) consumePhrase() (phrase string, err error) {
|
||||
var words []string
|
||||
var isPrevEncoded bool
|
||||
for {
|
||||
+ // obs-phrase allows CFWS after one word
|
||||
+ if len(words) > 0 {
|
||||
+ if !p.skipCFWS() {
|
||||
+ return "", errors.New("mail: misformatted parenthetical comment")
|
||||
+ }
|
||||
+ }
|
||||
// word = atom / quoted-string
|
||||
var word string
|
||||
p.skipSpace()
|
||||
@@ -661,7 +671,6 @@ Loop:
|
||||
// If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
|
||||
// If permissive is true, consumeAtom will not fail on:
|
||||
// - leading/trailing/double dots in the atom (see golang.org/issue/4938)
|
||||
-// - special characters (RFC 5322 3.2.3) except '<', '>', ':' and '"' (see golang.org/issue/21018)
|
||||
func (p *addrParser) consumeAtom(dot bool, permissive bool) (atom string, err error) {
|
||||
i := 0
|
||||
|
||||
@@ -672,7 +681,7 @@ Loop:
|
||||
case size == 1 && r == utf8.RuneError:
|
||||
return "", fmt.Errorf("mail: invalid utf-8 in address: %q", p.s)
|
||||
|
||||
- case size == 0 || !isAtext(r, dot, permissive):
|
||||
+ case size == 0 || !isAtext(r, dot):
|
||||
break Loop
|
||||
|
||||
default:
|
||||
@@ -850,18 +859,13 @@ func (e charsetError) Error() string {
|
||||
|
||||
// isAtext reports whether r is an RFC 5322 atext character.
|
||||
// If dot is true, period is included.
|
||||
-// If permissive is true, RFC 5322 3.2.3 specials is included,
|
||||
-// except '<', '>', ':' and '"'.
|
||||
-func isAtext(r rune, dot, permissive bool) bool {
|
||||
+func isAtext(r rune, dot bool) bool {
|
||||
switch r {
|
||||
case '.':
|
||||
return dot
|
||||
|
||||
// RFC 5322 3.2.3. specials
|
||||
- case '(', ')', '[', ']', ';', '@', '\\', ',':
|
||||
- return permissive
|
||||
-
|
||||
- case '<', '>', '"', ':':
|
||||
+ case '(', ')', '<', '>', '[', ']', ':', ';', '@', '\\', ',', '"': // RFC 5322 3.2.3. specials
|
||||
return false
|
||||
}
|
||||
return isVchar(r)
|
||||
diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
|
||||
index 1e1bb4092f659..1f2f62afbf406 100644
|
||||
--- a/src/net/mail/message_test.go
|
||||
+++ b/src/net/mail/message_test.go
|
||||
@@ -385,8 +385,11 @@ func TestAddressParsingError(t *testing.T) {
|
||||
13: {"group not closed: null@example.com", "expected comma"},
|
||||
14: {"group: first@example.com, second@example.com;", "group with multiple addresses"},
|
||||
15: {"john.doe", "missing '@' or angle-addr"},
|
||||
- 16: {"john.doe@", "no angle-addr"},
|
||||
+ 16: {"john.doe@", "missing '@' or angle-addr"},
|
||||
17: {"John Doe@foo.bar", "no angle-addr"},
|
||||
+ 18: {" group: null@example.com; (asd", "misformatted parenthetical comment"},
|
||||
+ 19: {" group: ; (asd", "misformatted parenthetical comment"},
|
||||
+ 20: {`(John) Doe <jdoe@machine.example>`, "missing word in phrase:"},
|
||||
}
|
||||
|
||||
for i, tc := range mustErrTestCases {
|
||||
@@ -436,24 +439,19 @@ func TestAddressParsing(t *testing.T) {
|
||||
Address: "john.q.public@example.com",
|
||||
}},
|
||||
},
|
||||
- {
|
||||
- `"John (middle) Doe" <jdoe@machine.example>`,
|
||||
- []*Address{{
|
||||
- Name: "John (middle) Doe",
|
||||
- Address: "jdoe@machine.example",
|
||||
- }},
|
||||
- },
|
||||
+ // Comment in display name
|
||||
{
|
||||
`John (middle) Doe <jdoe@machine.example>`,
|
||||
[]*Address{{
|
||||
- Name: "John (middle) Doe",
|
||||
+ Name: "John Doe",
|
||||
Address: "jdoe@machine.example",
|
||||
}},
|
||||
},
|
||||
+ // Display name is quoted string, so comment is not a comment
|
||||
{
|
||||
- `John !@M@! Doe <jdoe@machine.example>`,
|
||||
+ `"John (middle) Doe" <jdoe@machine.example>`,
|
||||
[]*Address{{
|
||||
- Name: "John !@M@! Doe",
|
||||
+ Name: "John (middle) Doe",
|
||||
Address: "jdoe@machine.example",
|
||||
}},
|
||||
},
|
||||
@@ -788,6 +786,26 @@ func TestAddressParsing(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
+ // Comment in group display name
|
||||
+ {
|
||||
+ `group (comment:): a@example.com, b@example.com;`,
|
||||
+ []*Address{
|
||||
+ {
|
||||
+ Address: "a@example.com",
|
||||
+ },
|
||||
+ {
|
||||
+ Address: "b@example.com",
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
+ {
|
||||
+ `x(:"):"@a.example;("@b.example;`,
|
||||
+ []*Address{
|
||||
+ {
|
||||
+ Address: `@a.example;(@b.example`,
|
||||
+ },
|
||||
+ },
|
||||
+ },
|
||||
}
|
||||
for _, test := range tests {
|
||||
if len(test.exp) == 1 {
|
||||
197
meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch
Normal file
197
meta/recipes-devtools/go/go-1.14/CVE-2024-24785.patch
Normal file
@@ -0,0 +1,197 @@
|
||||
From 3643147a29352ca2894fd5d0d2069bc4b4335a7e Mon Sep 17 00:00:00 2001
|
||||
From: Roland Shoemaker <roland@golang.org>
|
||||
Date: Wed, 14 Feb 2024 17:18:36 -0800
|
||||
Subject: [PATCH] [release-branch.go1.21] html/template: escape additional
|
||||
tokens in MarshalJSON errors
|
||||
|
||||
Escape "</script" and "<!--" in errors returned from MarshalJSON errors
|
||||
when attempting to marshal types in script blocks. This prevents any
|
||||
user controlled content from prematurely terminating the script block.
|
||||
|
||||
Updates #65697
|
||||
Fixes #65968
|
||||
|
||||
Change-Id: Icf0e26c54ea7d9c1deed0bff11b6506c99ddef1b
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/564196
|
||||
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
|
||||
Reviewed-by: Damien Neil <dneil@google.com>
|
||||
(cherry picked from commit ccbc725f2d678255df1bd326fa511a492aa3a0aa)
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/567515
|
||||
Reviewed-by: Carlos Amedee <carlos@golang.org>
|
||||
|
||||
Upstream-Status: Backport [https://github.com/golang/go/commit/3643147a29352ca2894fd5d0d2069bc4b4335a7e]
|
||||
CVE: CVE-2024-24785
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/html/template/js.go | 22 ++++++++-
|
||||
src/html/template/js_test.go | 96 ++++++++++++++++++++----------------
|
||||
2 files changed, 74 insertions(+), 44 deletions(-)
|
||||
|
||||
diff --git a/src/html/template/js.go b/src/html/template/js.go
|
||||
index 35994f0..4d3b25d 100644
|
||||
--- a/src/html/template/js.go
|
||||
+++ b/src/html/template/js.go
|
||||
@@ -171,13 +171,31 @@ func jsValEscaper(args ...interface{}) string {
|
||||
// cyclic data. This may be an unacceptable DoS risk.
|
||||
b, err := json.Marshal(a)
|
||||
if err != nil {
|
||||
- // Put a space before comment so that if it is flush against
|
||||
+ // While the standard JSON marshaller does not include user controlled
|
||||
+ // information in the error message, if a type has a MarshalJSON method,
|
||||
+ // the content of the error message is not guaranteed. Since we insert
|
||||
+ // the error into the template, as part of a comment, we attempt to
|
||||
+ // prevent the error from either terminating the comment, or the script
|
||||
+ // block itself.
|
||||
+ //
|
||||
+ // In particular we:
|
||||
+ // * replace "*/" comment end tokens with "* /", which does not
|
||||
+ // terminate the comment
|
||||
+ // * replace "</script" with "\x3C/script", and "<!--" with
|
||||
+ // "\x3C!--", which prevents confusing script block termination
|
||||
+ // semantics
|
||||
+ //
|
||||
+ // We also put a space before the comment so that if it is flush against
|
||||
// a division operator it is not turned into a line comment:
|
||||
// x/{{y}}
|
||||
// turning into
|
||||
// x//* error marshaling y:
|
||||
// second line of error message */null
|
||||
- return fmt.Sprintf(" /* %s */null ", strings.ReplaceAll(err.Error(), "*/", "* /"))
|
||||
+ errStr := err.Error()
|
||||
+ errStr = strings.ReplaceAll(errStr, "*/", "* /")
|
||||
+ errStr = strings.ReplaceAll(errStr, "</script", `\x3C/script`)
|
||||
+ errStr = strings.ReplaceAll(errStr, "<!--", `\x3C!--`)
|
||||
+ return fmt.Sprintf(" /* %s */null ", errStr)
|
||||
}
|
||||
|
||||
// TODO: maybe post-process output to prevent it from containing
|
||||
diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go
|
||||
index de9ef28..3fc3baf 100644
|
||||
--- a/src/html/template/js_test.go
|
||||
+++ b/src/html/template/js_test.go
|
||||
@@ -5,6 +5,7 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
+ "errors"
|
||||
"bytes"
|
||||
"math"
|
||||
"strings"
|
||||
@@ -104,61 +105,72 @@ func TestNextJsCtx(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
+type jsonErrType struct{}
|
||||
+
|
||||
+func (e *jsonErrType) MarshalJSON() ([]byte, error) {
|
||||
+ return nil, errors.New("beep */ boop </script blip <!--")
|
||||
+}
|
||||
+
|
||||
func TestJSValEscaper(t *testing.T) {
|
||||
tests := []struct {
|
||||
- x interface{}
|
||||
- js string
|
||||
+ x interface{}
|
||||
+ js string
|
||||
+ skipNest bool
|
||||
}{
|
||||
- {int(42), " 42 "},
|
||||
- {uint(42), " 42 "},
|
||||
- {int16(42), " 42 "},
|
||||
- {uint16(42), " 42 "},
|
||||
- {int32(-42), " -42 "},
|
||||
- {uint32(42), " 42 "},
|
||||
- {int16(-42), " -42 "},
|
||||
- {uint16(42), " 42 "},
|
||||
- {int64(-42), " -42 "},
|
||||
- {uint64(42), " 42 "},
|
||||
- {uint64(1) << 53, " 9007199254740992 "},
|
||||
+ {int(42), " 42 ", false},
|
||||
+ {uint(42), " 42 ", false},
|
||||
+ {int16(42), " 42 ", false},
|
||||
+ {uint16(42), " 42 ", false},
|
||||
+ {int32(-42), " -42 ", false},
|
||||
+ {uint32(42), " 42 ", false},
|
||||
+ {int16(-42), " -42 ", false},
|
||||
+ {uint16(42), " 42 ", false},
|
||||
+ {int64(-42), " -42 ", false},
|
||||
+ {uint64(42), " 42 ", false},
|
||||
+ {uint64(1) << 53, " 9007199254740992 ", false},
|
||||
// ulp(1 << 53) > 1 so this loses precision in JS
|
||||
// but it is still a representable integer literal.
|
||||
- {uint64(1)<<53 + 1, " 9007199254740993 "},
|
||||
- {float32(1.0), " 1 "},
|
||||
- {float32(-1.0), " -1 "},
|
||||
- {float32(0.5), " 0.5 "},
|
||||
- {float32(-0.5), " -0.5 "},
|
||||
- {float32(1.0) / float32(256), " 0.00390625 "},
|
||||
- {float32(0), " 0 "},
|
||||
- {math.Copysign(0, -1), " -0 "},
|
||||
- {float64(1.0), " 1 "},
|
||||
- {float64(-1.0), " -1 "},
|
||||
- {float64(0.5), " 0.5 "},
|
||||
- {float64(-0.5), " -0.5 "},
|
||||
- {float64(0), " 0 "},
|
||||
- {math.Copysign(0, -1), " -0 "},
|
||||
- {"", `""`},
|
||||
- {"foo", `"foo"`},
|
||||
+ {uint64(1)<<53 + 1, " 9007199254740993 ", false},
|
||||
+ {float32(1.0), " 1 ", false},
|
||||
+ {float32(-1.0), " -1 ", false},
|
||||
+ {float32(0.5), " 0.5 ", false},
|
||||
+ {float32(-0.5), " -0.5 ", false},
|
||||
+ {float32(1.0) / float32(256), " 0.00390625 ", false},
|
||||
+ {float32(0), " 0 ", false},
|
||||
+ {math.Copysign(0, -1), " -0 ", false},
|
||||
+ {float64(1.0), " 1 ", false},
|
||||
+ {float64(-1.0), " -1 ", false},
|
||||
+ {float64(0.5), " 0.5 ", false},
|
||||
+ {float64(-0.5), " -0.5 ", false},
|
||||
+ {float64(0), " 0 ", false},
|
||||
+ {math.Copysign(0, -1), " -0 ", false},
|
||||
+ {"", `""`, false},
|
||||
+ {"foo", `"foo"`, false},
|
||||
// Newlines.
|
||||
- {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`},
|
||||
+ {"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`, false},
|
||||
// "\v" == "v" on IE 6 so use "\u000b" instead.
|
||||
- {"\t\x0b", `"\t\u000b"`},
|
||||
- {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`},
|
||||
- {[]interface{}{}, "[]"},
|
||||
- {[]interface{}{42, "foo", nil}, `[42,"foo",null]`},
|
||||
- {[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`},
|
||||
- {"<!--", `"\u003c!--"`},
|
||||
- {"-->", `"--\u003e"`},
|
||||
- {"<![CDATA[", `"\u003c![CDATA["`},
|
||||
- {"]]>", `"]]\u003e"`},
|
||||
- {"</script", `"\u003c/script"`},
|
||||
- {"\U0001D11E", "\"\U0001D11E\""}, // or "\uD834\uDD1E"
|
||||
- {nil, " null "},
|
||||
+ {"\t\x0b", `"\t\u000b"`, false},
|
||||
+ {struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`, false},
|
||||
+ {[]interface{}{}, "[]", false},
|
||||
+ {[]interface{}{42, "foo", nil}, `[42,"foo",null]`, false},
|
||||
+ {[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`, false},
|
||||
+ {"<!--", `"\u003c!--"`, false},
|
||||
+ {"-->", `"--\u003e"`, false},
|
||||
+ {"<![CDATA[", `"\u003c![CDATA["`, false},
|
||||
+ {"]]>", `"]]\u003e"`, false},
|
||||
+ {"</script", `"\u003c/script"`, false},
|
||||
+ {"\U0001D11E", "\"\U0001D11E\"", false}, // or "\uD834\uDD1E"
|
||||
+ {nil, " null ", false},
|
||||
+ {&jsonErrType{}, " /* json: error calling MarshalJSON for type *template.jsonErrType: beep * / boop \\x3C/script blip \\x3C!-- */null ", true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if js := jsValEscaper(test.x); js != test.js {
|
||||
t.Errorf("%+v: want\n\t%q\ngot\n\t%q", test.x, test.js, js)
|
||||
}
|
||||
+ if test.skipNest {
|
||||
+ continue
|
||||
+ }
|
||||
// Make sure that escaping corner cases are not broken
|
||||
// by nesting.
|
||||
a := []interface{}{test.x}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From 8b45a3c4cab95382beea1ecdddeb2e4a9ed14aba Mon Sep 17 00:00:00 2001
|
||||
From: Jo-Philipp Wich <jo@mein.io>
|
||||
Date: Wed, 1 Apr 2020 21:47:40 +0200
|
||||
Subject: [PATCH 001/104] file_util.c: fix possible bad memory access in
|
||||
file_read_line_alloc()
|
||||
|
||||
In the case of a zero length string being returned by fgets(), the condition
|
||||
checking for a trailing new line would perform a bad memory access outside
|
||||
of `buf`. This might happen when line with a leading null byte is read.
|
||||
|
||||
Avoid this case by checking that the string has a length of at least one
|
||||
byte. Also change the unsigned int types to size_t to store length values
|
||||
while we're at it.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/ndmsystems/opkg/commit/8b45a3c4cab95382beea1ecdddeb2e4a9ed14aba]
|
||||
|
||||
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
||||
Signed-off-by: Alejandro del Castillo <alejandro.delcastillo@ni.com>
|
||||
Signed-off-by: virendra thakur <virendrak@kpit.com>
|
||||
---
|
||||
libopkg/file_util.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libopkg/file_util.c b/libopkg/file_util.c
|
||||
index fbed7b4..ee9f59d 100644
|
||||
--- a/libopkg/file_util.c
|
||||
+++ b/libopkg/file_util.c
|
||||
@@ -127,17 +127,14 @@ char *file_readlink_alloc(const char *file_name)
|
||||
*/
|
||||
char *file_read_line_alloc(FILE * fp)
|
||||
{
|
||||
+ size_t buf_len, line_size;
|
||||
char buf[BUFSIZ];
|
||||
- unsigned int buf_len;
|
||||
char *line = NULL;
|
||||
- unsigned int line_size = 0;
|
||||
int got_nl = 0;
|
||||
|
||||
- buf[0] = '\0';
|
||||
-
|
||||
while (fgets(buf, BUFSIZ, fp)) {
|
||||
buf_len = strlen(buf);
|
||||
- if (buf[buf_len - 1] == '\n') {
|
||||
+ if (buf_len > 0 && buf[buf_len - 1] == '\n') {
|
||||
buf_len--;
|
||||
buf[buf_len] = '\0';
|
||||
got_nl = 1;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -16,6 +16,7 @@ SRC_URI = "http://downloads.yoctoproject.org/releases/${BPN}/${BPN}-${PV}.tar.gz
|
||||
file://opkg.conf \
|
||||
file://0001-opkg_conf-create-opkg.lock-in-run-instead-of-var-run.patch \
|
||||
file://sourcedateepoch.patch \
|
||||
file://0001-file_util.c-fix-possible-bad-memory-access-in-file_r.patch \
|
||||
file://run-ptest \
|
||||
"
|
||||
|
||||
|
||||
27
meta/recipes-devtools/perl/files/CVE-2023-31484.patch
Normal file
27
meta/recipes-devtools/perl/files/CVE-2023-31484.patch
Normal file
@@ -0,0 +1,27 @@
|
||||
CVE: CVE-2023-31484
|
||||
Upstream-Status: Backport [ import from Ubuntu perl_5.30.0-9ubuntu0.5
|
||||
upstream https://github.com/andk/cpanpm/commit/9c98370287f4e709924aee7c58ef21c85289a7f0 ]
|
||||
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
|
||||
|
||||
From 9c98370287f4e709924aee7c58ef21c85289a7f0 Mon Sep 17 00:00:00 2001
|
||||
From: Stig Palmquist <git@stig.io>
|
||||
Date: Tue, 28 Feb 2023 11:54:06 +0100
|
||||
Subject: [PATCH] Add verify_SSL=>1 to HTTP::Tiny to verify https server
|
||||
identity
|
||||
|
||||
---
|
||||
lib/CPAN/HTTP/Client.pm | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/cpan/CPAN/lib/CPAN/HTTP/Client.pm b/cpan/CPAN/lib/CPAN/HTTP/Client.pm
|
||||
index 4fc792c26..a616fee20 100644
|
||||
--- a/cpan/CPAN/lib/CPAN/HTTP/Client.pm
|
||||
+++ b/cpan/CPAN/lib/CPAN/HTTP/Client.pm
|
||||
@@ -32,6 +32,7 @@ sub mirror {
|
||||
|
||||
my $want_proxy = $self->_want_proxy($uri);
|
||||
my $http = HTTP::Tiny->new(
|
||||
+ verify_SSL => 1,
|
||||
$want_proxy ? (proxy => $self->{proxy}) : ()
|
||||
);
|
||||
|
||||
121
meta/recipes-devtools/perl/files/CVE-2023-47038.patch
Normal file
121
meta/recipes-devtools/perl/files/CVE-2023-47038.patch
Normal file
@@ -0,0 +1,121 @@
|
||||
as per https://ubuntu.com/security/CVE-2023-47100 , CVE-2023-47100 is duplicate of CVE-2023-47038
|
||||
CVE: CVE-2023-47038 CVE-2023-47100
|
||||
Upstream-Status: Backport [ import from ubuntu perl_5.30.0-9ubuntu0.5
|
||||
upstream https://github.com/Perl/perl5/commit/12c313ce49b36160a7ca2e9b07ad5bd92ee4a010 ]
|
||||
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>
|
||||
|
||||
Backport of:
|
||||
|
||||
From 12c313ce49b36160a7ca2e9b07ad5bd92ee4a010 Mon Sep 17 00:00:00 2001
|
||||
From: Karl Williamson <khw@cpan.org>
|
||||
Date: Sat, 9 Sep 2023 11:59:09 -0600
|
||||
Subject: [PATCH 1/2] Fix read/write past buffer end: perl-security#140
|
||||
|
||||
A package name may be specified in a \p{...} regular expression
|
||||
construct. If unspecified, "utf8::" is assumed, which is the package
|
||||
all official Unicode properties are in. By specifying a different
|
||||
package, one can create a user-defined property with the same
|
||||
unqualified name as a Unicode one. Such a property is defined by a sub
|
||||
whose name begins with "Is" or "In", and if the sub wishes to refer to
|
||||
an official Unicode property, it must explicitly specify the "utf8::".
|
||||
S_parse_uniprop_string() is used to parse the interior of both \p{} and
|
||||
the user-defined sub lines.
|
||||
|
||||
In S_parse_uniprop_string(), it parses the input "name" parameter,
|
||||
creating a modified copy, "lookup_name", malloc'ed with the same size as
|
||||
"name". The modifications are essentially to create a canonicalized
|
||||
version of the input, with such things as extraneous white-space
|
||||
stripped off. I found it convenient to strip off the package specifier
|
||||
"utf8::". To to so, the code simply pretends "lookup_name" begins just
|
||||
after the "utf8::", and adjusts various other values to compensate.
|
||||
However, it missed the adjustment of one required one.
|
||||
|
||||
This is only a problem when the property name begins with "perl" and
|
||||
isn't "perlspace" nor "perlword". All such ones are undocumented
|
||||
internal properties.
|
||||
|
||||
What happens in this case is that the input is reparsed with slightly
|
||||
different rules in effect as to what is legal versus illegal. The
|
||||
problem is that "lookup_name" no longer is pointing to its initial
|
||||
value, but "name" is. Thus the space allocated for filling "lookup_name"
|
||||
is now shorter than "name", and as this shortened "lookup_name" is
|
||||
filled by copying suitable portions of "name", the write can be to
|
||||
unallocated space.
|
||||
|
||||
The solution is to skip the "utf8::" when reparsing "name". Then both
|
||||
"lookup_name" and "name" are effectively shortened by the same amount,
|
||||
and there is no going off the end.
|
||||
|
||||
This commit also does white-space adjustment so that things align
|
||||
vertically for readability.
|
||||
|
||||
This can be easily backported to earlier Perl releases.
|
||||
---
|
||||
regcomp.c | 17 +++++++++++------
|
||||
t/re/pat_advanced.t | 8 ++++++++
|
||||
2 files changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/regcomp.c
|
||||
+++ b/regcomp.c
|
||||
@@ -22606,7 +22606,7 @@ Perl_parse_uniprop_string(pTHX_
|
||||
* compile perl to know about them) */
|
||||
bool is_nv_type = FALSE;
|
||||
|
||||
- unsigned int i, j = 0;
|
||||
+ unsigned int i = 0, i_zero = 0, j = 0;
|
||||
int equals_pos = -1; /* Where the '=' is found, or negative if none */
|
||||
int slash_pos = -1; /* Where the '/' is found, or negative if none */
|
||||
int table_index = 0; /* The entry number for this property in the table
|
||||
@@ -22717,9 +22717,13 @@ Perl_parse_uniprop_string(pTHX_
|
||||
* all of them are considered to be for that package. For the purposes of
|
||||
* parsing the rest of the property, strip it off */
|
||||
if (non_pkg_begin == STRLENs("utf8::") && memBEGINPs(name, name_len, "utf8::")) {
|
||||
- lookup_name += STRLENs("utf8::");
|
||||
- j -= STRLENs("utf8::");
|
||||
- equals_pos -= STRLENs("utf8::");
|
||||
+ lookup_name += STRLENs("utf8::");
|
||||
+ j -= STRLENs("utf8::");
|
||||
+ equals_pos -= STRLENs("utf8::");
|
||||
+ i_zero = STRLENs("utf8::"); /* When resetting 'i' to reparse
|
||||
+ from the beginning, it has to be
|
||||
+ set past what we're stripping
|
||||
+ off */
|
||||
}
|
||||
|
||||
/* Here, we are either done with the whole property name, if it was simple;
|
||||
@@ -22997,7 +23001,8 @@ Perl_parse_uniprop_string(pTHX_
|
||||
|
||||
/* We set the inputs back to 0 and the code below will reparse,
|
||||
* using strict */
|
||||
- i = j = 0;
|
||||
+ i = i_zero;
|
||||
+ j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23018,7 +23023,7 @@ Perl_parse_uniprop_string(pTHX_
|
||||
* separates two digits */
|
||||
if (cur == '_') {
|
||||
if ( stricter
|
||||
- && ( i == 0 || (int) i == equals_pos || i == name_len- 1
|
||||
+ && ( i == i_zero || (int) i == equals_pos || i == name_len- 1
|
||||
|| ! isDIGIT_A(name[i-1]) || ! isDIGIT_A(name[i+1])))
|
||||
{
|
||||
lookup_name[j++] = '_';
|
||||
--- a/t/re/pat_advanced.t
|
||||
+++ b/t/re/pat_advanced.t
|
||||
@@ -2524,6 +2524,14 @@ EOF
|
||||
"", {}, "*COMMIT caused positioning beyond EOS");
|
||||
}
|
||||
|
||||
+ { # perl-security#140, read/write past buffer end
|
||||
+ fresh_perl_like('qr/\p{utf8::perl x}/',
|
||||
+ qr/Illegal user-defined property name "utf8::perl x" in regex/,
|
||||
+ {}, "perl-security#140");
|
||||
+ fresh_perl_is('qr/\p{utf8::_perl_surrogate}/', "",
|
||||
+ {}, "perl-security#140");
|
||||
+ }
|
||||
+
|
||||
|
||||
# !!! NOTE that tests that aren't at all likely to crash perl should go
|
||||
# a ways above, above these last ones. There's a comment there that, like
|
||||
@@ -29,6 +29,8 @@ SRC_URI = "https://www.cpan.org/src/5.0/perl-${PV}.tar.gz;name=perl \
|
||||
file://CVE-2020-10878_1.patch \
|
||||
file://CVE-2020-10878_2.patch \
|
||||
file://CVE-2020-12723.patch \
|
||||
file://CVE-2023-31484.patch \
|
||||
file://CVE-2023-47038.patch \
|
||||
"
|
||||
SRC_URI_append_class-native = " \
|
||||
file://perl-configpm-switch.patch \
|
||||
@@ -44,6 +46,10 @@ SRC_URI[perl-cross.sha256sum] = "edce0b0c2f725e2db3f203d6d8e9f3f7161256f5d159055
|
||||
|
||||
S = "${WORKDIR}/perl-${PV}"
|
||||
|
||||
# This is windows only issue.
|
||||
# https://ubuntu.com/security/CVE-2023-47039
|
||||
CVE_CHECK_WHITELIST += "CVE-2023-47039"
|
||||
|
||||
inherit upstream-version-is-even update-alternatives
|
||||
|
||||
DEPENDS += "zlib virtual/crypt"
|
||||
|
||||
@@ -141,6 +141,9 @@ SRC_URI = "https://download.qemu.org/${BPN}-${PV}.tar.xz \
|
||||
file://CVE-2023-3354.patch \
|
||||
file://CVE-2023-3180.patch \
|
||||
file://CVE-2020-24165.patch \
|
||||
file://CVE-2023-5088.patch \
|
||||
file://9pfs-local-ignore-O_NOATIME-if-we-don-t-have-permiss.patch \
|
||||
file://CVE-2023-2861.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_REGEX = "qemu-(?P<pver>\d+(\.\d+)+)\.tar"
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
|
||||
index 6f132c5f..8329950c 100644
|
||||
index 300c9765..2823db7d 100644
|
||||
--- a/fsdev/virtfs-proxy-helper.c
|
||||
+++ b/fsdev/virtfs-proxy-helper.c
|
||||
@@ -13,7 +13,6 @@
|
||||
@@ -71,9 +71,9 @@ index 6f132c5f..8329950c 100644
|
||||
#include <sys/fsuid.h>
|
||||
#include <sys/vfs.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -27,7 +26,11 @@
|
||||
#include "9p-iov-marshal.h"
|
||||
@@ -28,7 +27,11 @@
|
||||
#include "hw/9pfs/9p-proxy.h"
|
||||
#include "hw/9pfs/9p-util.h"
|
||||
#include "fsdev/9p-iov-marshal.h"
|
||||
-
|
||||
+/*
|
||||
@@ -84,3 +84,6 @@ index 6f132c5f..8329950c 100644
|
||||
#define PROGNAME "virtfs-proxy-helper"
|
||||
|
||||
#ifndef XFS_SUPER_MAGIC
|
||||
--
|
||||
2.25.1
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From a5804fcf7b22fc7d1f9ec794dd284c7d504bd16b Mon Sep 17 00:00:00 2001
|
||||
From: Omar Sandoval <osandov@fb.com>
|
||||
Date: Thu, 14 May 2020 08:06:43 +0200
|
||||
Subject: [PATCH] 9pfs: local: ignore O_NOATIME if we don't have permissions
|
||||
|
||||
QEMU's local 9pfs server passes through O_NOATIME from the client. If
|
||||
the QEMU process doesn't have permissions to use O_NOATIME (namely, it
|
||||
does not own the file nor have the CAP_FOWNER capability), the open will
|
||||
fail. This causes issues when from the client's point of view, it
|
||||
believes it has permissions to use O_NOATIME (e.g., a process running as
|
||||
root in the virtual machine). Additionally, overlayfs on Linux opens
|
||||
files on the lower layer using O_NOATIME, so in this case a 9pfs mount
|
||||
can't be used as a lower layer for overlayfs (cf.
|
||||
https://github.com/osandov/drgn/blob/dabfe1971951701da13863dbe6d8a1d172ad9650/vmtest/onoatimehack.c
|
||||
and https://github.com/NixOS/nixpkgs/issues/54509).
|
||||
|
||||
Luckily, O_NOATIME is effectively a hint, and is often ignored by, e.g.,
|
||||
network filesystems. open(2) notes that O_NOATIME "may not be effective
|
||||
on all filesystems. One example is NFS, where the server maintains the
|
||||
access time." This means that we can honor it when possible but fall
|
||||
back to ignoring it.
|
||||
|
||||
Acked-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
Signed-off-by: Omar Sandoval <osandov@fb.com>
|
||||
Message-Id: <e9bee604e8df528584693a4ec474ded6295ce8ad.1587149256.git.osandov@fb.com>
|
||||
Signed-off-by: Greg Kurz <groug@kaod.org>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/a5804fcf7b22fc7d1f9ec794dd284c7d504bd16b]
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
hw/9pfs/9p-util.h | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
|
||||
index 79ed6b233e5..546f46dc7dc 100644
|
||||
--- a/hw/9pfs/9p-util.h
|
||||
+++ b/hw/9pfs/9p-util.h
|
||||
@@ -37,9 +37,22 @@ static inline int openat_file(int dirfd, const char *name, int flags,
|
||||
{
|
||||
int fd, serrno, ret;
|
||||
|
||||
+again:
|
||||
fd = openat(dirfd, name, flags | O_NOFOLLOW | O_NOCTTY | O_NONBLOCK,
|
||||
mode);
|
||||
if (fd == -1) {
|
||||
+ if (errno == EPERM && (flags & O_NOATIME)) {
|
||||
+ /*
|
||||
+ * The client passed O_NOATIME but we lack permissions to honor it.
|
||||
+ * Rather than failing the open, fall back without O_NOATIME. This
|
||||
+ * doesn't break the semantics on the client side, as the Linux
|
||||
+ * open(2) man page notes that O_NOATIME "may not be effective on
|
||||
+ * all filesystems". In particular, NFS and other network
|
||||
+ * filesystems ignore it entirely.
|
||||
+ */
|
||||
+ flags &= ~O_NOATIME;
|
||||
+ goto again;
|
||||
+ }
|
||||
return -1;
|
||||
}
|
||||
|
||||
--
|
||||
GitLab
|
||||
|
||||
178
meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch
Normal file
178
meta/recipes-devtools/qemu/qemu/CVE-2023-2861.patch
Normal file
@@ -0,0 +1,178 @@
|
||||
From f6b0de53fb87ddefed348a39284c8e2f28dc4eda Mon Sep 17 00:00:00 2001
|
||||
From: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
Date: Wed, 7 Jun 2023 18:29:33 +0200
|
||||
Subject: [PATCH] 9pfs: prevent opening special files (CVE-2023-2861)
|
||||
|
||||
The 9p protocol does not specifically define how server shall behave when
|
||||
client tries to open a special file, however from security POV it does
|
||||
make sense for 9p server to prohibit opening any special file on host side
|
||||
in general. A sane Linux 9p client for instance would never attempt to
|
||||
open a special file on host side, it would always handle those exclusively
|
||||
on its guest side. A malicious client however could potentially escape
|
||||
from the exported 9p tree by creating and opening a device file on host
|
||||
side.
|
||||
|
||||
With QEMU this could only be exploited in the following unsafe setups:
|
||||
|
||||
- Running QEMU binary as root AND 9p 'local' fs driver AND 'passthrough'
|
||||
security model.
|
||||
|
||||
or
|
||||
|
||||
- Using 9p 'proxy' fs driver (which is running its helper daemon as
|
||||
root).
|
||||
|
||||
These setups were already discouraged for safety reasons before,
|
||||
however for obvious reasons we are now tightening behaviour on this.
|
||||
|
||||
Fixes: CVE-2023-2861
|
||||
Reported-by: Yanwu Shen <ywsPlz@gmail.com>
|
||||
Reported-by: Jietao Xiao <shawtao1125@gmail.com>
|
||||
Reported-by: Jinku Li <jkli@xidian.edu.cn>
|
||||
Reported-by: Wenbo Shen <shenwenbo@zju.edu.cn>
|
||||
Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com>
|
||||
Reviewed-by: Greg Kurz <groug@kaod.org>
|
||||
Reviewed-by: Michael Tokarev <mjt@tls.msk.ru>
|
||||
Message-Id: <E1q6w7r-0000Q0-NM@lizzy.crudebyte.com>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/f6b0de53fb87ddefed348a39284c8e2f28dc4eda]
|
||||
CVE: CVE-2023-2861
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
fsdev/virtfs-proxy-helper.c | 27 +++++++++++++++++++++++--
|
||||
hw/9pfs/9p-util.h | 40 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 65 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fsdev/virtfs-proxy-helper.c b/fsdev/virtfs-proxy-helper.c
|
||||
index 6f132c5f..300c9765 100644
|
||||
--- a/fsdev/virtfs-proxy-helper.c
|
||||
+++ b/fsdev/virtfs-proxy-helper.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "qemu/xattr.h"
|
||||
#include "9p-iov-marshal.h"
|
||||
#include "hw/9pfs/9p-proxy.h"
|
||||
+#include "hw/9pfs/9p-util.h"
|
||||
#include "fsdev/9p-iov-marshal.h"
|
||||
|
||||
#define PROGNAME "virtfs-proxy-helper"
|
||||
@@ -350,6 +351,28 @@ static void resetugid(int suid, int sgid)
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Open regular file or directory. Attempts to open any special file are
|
||||
+ * rejected.
|
||||
+ *
|
||||
+ * returns file descriptor or -1 on error
|
||||
+ */
|
||||
+static int open_regular(const char *pathname, int flags, mode_t mode)
|
||||
+{
|
||||
+ int fd;
|
||||
+
|
||||
+ fd = open(pathname, flags, mode);
|
||||
+ if (fd < 0) {
|
||||
+ return fd;
|
||||
+ }
|
||||
+
|
||||
+ if (close_if_special_file(fd) < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* send response in two parts
|
||||
* 1) ProxyHeader
|
||||
@@ -694,7 +717,7 @@ static int do_create(struct iovec *iovec)
|
||||
if (ret < 0) {
|
||||
goto unmarshal_err_out;
|
||||
}
|
||||
- ret = open(path.data, flags, mode);
|
||||
+ ret = open_regular(path.data, flags, mode);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
}
|
||||
@@ -719,7 +742,7 @@ static int do_open(struct iovec *iovec)
|
||||
if (ret < 0) {
|
||||
goto err_out;
|
||||
}
|
||||
- ret = open(path.data, flags);
|
||||
+ ret = open_regular(path.data, flags, 0);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
}
|
||||
diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h
|
||||
index 546f46dc..79fdd2a3 100644
|
||||
--- a/hw/9pfs/9p-util.h
|
||||
+++ b/hw/9pfs/9p-util.h
|
||||
@@ -13,12 +13,16 @@
|
||||
#ifndef QEMU_9P_UTIL_H
|
||||
#define QEMU_9P_UTIL_H
|
||||
|
||||
+#include "qemu/error-report.h"
|
||||
+
|
||||
#ifdef O_PATH
|
||||
#define O_PATH_9P_UTIL O_PATH
|
||||
#else
|
||||
#define O_PATH_9P_UTIL 0
|
||||
#endif
|
||||
|
||||
+#define qemu_fstat fstat
|
||||
+
|
||||
static inline void close_preserve_errno(int fd)
|
||||
{
|
||||
int serrno = errno;
|
||||
@@ -26,6 +30,38 @@ static inline void close_preserve_errno(int fd)
|
||||
errno = serrno;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * close_if_special_file() - Close @fd if neither regular file nor directory.
|
||||
+ *
|
||||
+ * @fd: file descriptor of open file
|
||||
+ * Return: 0 on regular file or directory, -1 otherwise
|
||||
+ *
|
||||
+ * CVE-2023-2861: Prohibit opening any special file directly on host
|
||||
+ * (especially device files), as a compromised client could potentially gain
|
||||
+ * access outside exported tree under certain, unsafe setups. We expect
|
||||
+ * client to handle I/O on special files exclusively on guest side.
|
||||
+ */
|
||||
+static inline int close_if_special_file(int fd)
|
||||
+{
|
||||
+ struct stat stbuf;
|
||||
+
|
||||
+ if (qemu_fstat(fd, &stbuf) < 0) {
|
||||
+ close_preserve_errno(fd);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)) {
|
||||
+ error_report_once(
|
||||
+ "9p: broken or compromised client detected; attempt to open "
|
||||
+ "special file (i.e. neither regular file, nor directory)"
|
||||
+ );
|
||||
+ close(fd);
|
||||
+ errno = ENXIO;
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static inline int openat_dir(int dirfd, const char *name)
|
||||
{
|
||||
return openat(dirfd, name,
|
||||
@@ -56,6 +92,10 @@ again:
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ if (close_if_special_file(fd) < 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
serrno = errno;
|
||||
/* O_NONBLOCK was only needed to open the file. Let's drop it. We don't
|
||||
* do that with O_PATH since fcntl(F_SETFL) isn't supported, and openat()
|
||||
--
|
||||
2.25.1
|
||||
|
||||
114
meta/recipes-devtools/qemu/qemu/CVE-2023-5088.patch
Normal file
114
meta/recipes-devtools/qemu/qemu/CVE-2023-5088.patch
Normal file
@@ -0,0 +1,114 @@
|
||||
From 7d7512019fc40c577e2bdd61f114f31a9eb84a8e Mon Sep 17 00:00:00 2001
|
||||
From: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Date: Wed, 6 Sep 2023 15:09:21 +0200
|
||||
Subject: [PATCH] hw/ide: reset: cancel async DMA operation before resetting
|
||||
state
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If there is a pending DMA operation during ide_bus_reset(), the fact
|
||||
that the IDEState is already reset before the operation is canceled
|
||||
can be problematic. In particular, ide_dma_cb() might be called and
|
||||
then use the reset IDEState which contains the signature after the
|
||||
reset. When used to construct the IO operation this leads to
|
||||
ide_get_sector() returning 0 and nsector being 1. This is particularly
|
||||
bad, because a write command will thus destroy the first sector which
|
||||
often contains a partition table or similar.
|
||||
|
||||
Traces showing the unsolicited write happening with IDEState
|
||||
0x5595af6949d0 being used after reset:
|
||||
|
||||
> ahci_port_write ahci(0x5595af6923f0)[0]: port write [reg:PxSCTL] @ 0x2c: 0x00000300
|
||||
> ahci_reset_port ahci(0x5595af6923f0)[0]: reset port
|
||||
> ide_reset IDEstate 0x5595af6949d0
|
||||
> ide_reset IDEstate 0x5595af694da8
|
||||
> ide_bus_reset_aio aio_cancel
|
||||
> dma_aio_cancel dbs=0x7f64600089a0
|
||||
> dma_blk_cb dbs=0x7f64600089a0 ret=0
|
||||
> dma_complete dbs=0x7f64600089a0 ret=0 cb=0x5595acd40b30
|
||||
> ahci_populate_sglist ahci(0x5595af6923f0)[0]
|
||||
> ahci_dma_prepare_buf ahci(0x5595af6923f0)[0]: prepare buf limit=512 prepared=512
|
||||
> ide_dma_cb IDEState 0x5595af6949d0; sector_num=0 n=1 cmd=DMA WRITE
|
||||
> dma_blk_io dbs=0x7f6420802010 bs=0x5595ae2c6c30 offset=0 to_dev=1
|
||||
> dma_blk_cb dbs=0x7f6420802010 ret=0
|
||||
|
||||
> (gdb) p *qiov
|
||||
> $11 = {iov = 0x7f647c76d840, niov = 1, {{nalloc = 1, local_iov = {iov_base = 0x0,
|
||||
> iov_len = 512}}, {__pad = "\001\000\000\000\000\000\000\000\000\000\000",
|
||||
> size = 512}}}
|
||||
> (gdb) bt
|
||||
> #0 blk_aio_pwritev (blk=0x5595ae2c6c30, offset=0, qiov=0x7f6420802070, flags=0,
|
||||
> cb=0x5595ace6f0b0 <dma_blk_cb>, opaque=0x7f6420802010)
|
||||
> at ../block/block-backend.c:1682
|
||||
> #1 0x00005595ace6f185 in dma_blk_cb (opaque=0x7f6420802010, ret=<optimized out>)
|
||||
> at ../softmmu/dma-helpers.c:179
|
||||
> #2 0x00005595ace6f778 in dma_blk_io (ctx=0x5595ae0609f0,
|
||||
> sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
|
||||
> io_func=io_func@entry=0x5595ace6ee30 <dma_blk_write_io_func>,
|
||||
> io_func_opaque=io_func_opaque@entry=0x5595ae2c6c30,
|
||||
> cb=0x5595acd40b30 <ide_dma_cb>, opaque=0x5595af6949d0,
|
||||
> dir=DMA_DIRECTION_TO_DEVICE) at ../softmmu/dma-helpers.c:244
|
||||
> #3 0x00005595ace6f90a in dma_blk_write (blk=0x5595ae2c6c30,
|
||||
> sg=sg@entry=0x5595af694d00, offset=offset@entry=0, align=align@entry=512,
|
||||
> cb=cb@entry=0x5595acd40b30 <ide_dma_cb>, opaque=opaque@entry=0x5595af6949d0)
|
||||
> at ../softmmu/dma-helpers.c:280
|
||||
> #4 0x00005595acd40e18 in ide_dma_cb (opaque=0x5595af6949d0, ret=<optimized out>)
|
||||
> at ../hw/ide/core.c:953
|
||||
> #5 0x00005595ace6f319 in dma_complete (ret=0, dbs=0x7f64600089a0)
|
||||
> at ../softmmu/dma-helpers.c:107
|
||||
> #6 dma_blk_cb (opaque=0x7f64600089a0, ret=0) at ../softmmu/dma-helpers.c:127
|
||||
> #7 0x00005595ad12227d in blk_aio_complete (acb=0x7f6460005b10)
|
||||
> at ../block/block-backend.c:1527
|
||||
> #8 blk_aio_complete (acb=0x7f6460005b10) at ../block/block-backend.c:1524
|
||||
> #9 blk_aio_write_entry (opaque=0x7f6460005b10) at ../block/block-backend.c:1594
|
||||
> #10 0x00005595ad258cfb in coroutine_trampoline (i0=<optimized out>,
|
||||
> i1=<optimized out>) at ../util/coroutine-ucontext.c:177
|
||||
|
||||
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
|
||||
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
Tested-by: simon.rowe@nutanix.com
|
||||
Message-ID: <20230906130922.142845-1-f.ebner@proxmox.com>
|
||||
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.com/qemu-project/qemu/-/commit/7d7512019fc40c577e2bdd61f114f31a9eb84a8e]
|
||||
CVE: CVE-2023-5088
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
hw/ide/core.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/hw/ide/core.c b/hw/ide/core.c
|
||||
index b5e0dcd29b2..63ba665f3d2 100644
|
||||
--- a/hw/ide/core.c
|
||||
+++ b/hw/ide/core.c
|
||||
@@ -2515,19 +2515,19 @@ static void ide_dummy_transfer_stop(IDEState *s)
|
||||
|
||||
void ide_bus_reset(IDEBus *bus)
|
||||
{
|
||||
- bus->unit = 0;
|
||||
- bus->cmd = 0;
|
||||
- ide_reset(&bus->ifs[0]);
|
||||
- ide_reset(&bus->ifs[1]);
|
||||
- ide_clear_hob(bus);
|
||||
-
|
||||
- /* pending async DMA */
|
||||
+ /* pending async DMA - needs the IDEState before it is reset */
|
||||
if (bus->dma->aiocb) {
|
||||
trace_ide_bus_reset_aio();
|
||||
blk_aio_cancel(bus->dma->aiocb);
|
||||
bus->dma->aiocb = NULL;
|
||||
}
|
||||
|
||||
+ bus->unit = 0;
|
||||
+ bus->cmd = 0;
|
||||
+ ide_reset(&bus->ifs[0]);
|
||||
+ ide_reset(&bus->ifs[1]);
|
||||
+ ide_clear_hob(bus);
|
||||
+
|
||||
/* reset dma provider too */
|
||||
if (bus->dma->ops->reset) {
|
||||
bus->dma->ops->reset(bus->dma);
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
From fabef23bea6e9963c06e218586fda1a823e3c6bf Mon Sep 17 00:00:00 2001
|
||||
From: Wayne Davison <wayne@opencoder.net>
|
||||
Date: Mon, 8 Aug 2022 21:30:21 -0700
|
||||
Subject: [PATCH] Fix --relative when copying an absolute path.
|
||||
|
||||
CVE: CVE-2022-29154
|
||||
Upstream-Status: Backport [https://github.com/WayneD/rsync/commit/fabef23bea6e9963c06e218586fda1a823e3c6bf]
|
||||
Signed-off-by: Matthias Schmitz <matthias.schmitz@port4949.net>
|
||||
---
|
||||
exclude.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/exclude.c b/exclude.c
|
||||
index 2394023f..ba5ca5a3 100644
|
||||
--- a/exclude.c
|
||||
+++ b/exclude.c
|
||||
@@ -434,8 +434,10 @@ void add_implied_include(const char *arg)
|
||||
*p++ = *cp++;
|
||||
break;
|
||||
case '/':
|
||||
- if (p[-1] == '/') /* This is safe because of the initial slash. */
|
||||
+ if (p[-1] == '/') { /* This is safe because of the initial slash. */
|
||||
+ cp++;
|
||||
break;
|
||||
+ }
|
||||
if (relative_paths) {
|
||||
filter_rule const *ent;
|
||||
int found = 0;
|
||||
--
|
||||
2.39.2
|
||||
|
||||
@@ -17,6 +17,7 @@ SRC_URI = "https://download.samba.org/pub/${BPN}/src/${BP}.tar.gz \
|
||||
file://CVE-2016-9842.patch \
|
||||
file://CVE-2016-9843.patch \
|
||||
file://CVE-2022-29154.patch \
|
||||
file://0001-Fix-relative-when-copying-an-absolute-path.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "1581a588fde9d89f6bc6201e8129afaf"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
drd/tests/bar_bad
|
||||
drd/tests/bar_bad_xml
|
||||
gdbserver_tests/hginfo
|
||||
memcheck/tests/linux/timerfd-syscall
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
From 8c7bd787defa071c96289b7da9397f673fddb874 Mon Sep 17 00:00:00 2001
|
||||
From: Ken Sharp <ken.sharp@artifex.com>
|
||||
Date: Wed, 20 May 2020 16:02:07 +0100
|
||||
Subject: [PATCH] txtwrite - address memory problems
|
||||
|
||||
Bug #702229 " txtwrite: use after free in 9.51 on some files (regression from 9.50)"
|
||||
Also bug #702346 and the earlier report #701877.
|
||||
|
||||
The problems occur because its possible for a single character code in
|
||||
a PDF file to map to more than a single Unicode code point. In the case
|
||||
of the file for 701877 the character code maps to 'f' and 'i' (it is an
|
||||
fi ligature).
|
||||
|
||||
The code should deal with this, but we need to ensure we are using the
|
||||
correct index. In addition, if we do get more Unicode code points than
|
||||
we expected, we need to set the widths of the 'extra' code points to
|
||||
zero (we only want to consider the width of the original character).
|
||||
|
||||
This does mean increasing the size of the Widths array to cater for
|
||||
the possibility of more entries on output than there were on input.
|
||||
|
||||
While working on it I noticed that the Unicode remapping on little-
|
||||
endian machines was reversing the order of the Unicode values, when
|
||||
there was more than a single code point returned, so fixed that at
|
||||
the same time.
|
||||
|
||||
Upstream-Status: Backport [https://git.ghostscript.com/?p=ghostpdl.git;h=8c7bd787defa071c96289b7da9397f673fddb874]
|
||||
CVE: CVE-2020-36773
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
devices/vector/gdevtxtw.c | 26 ++++++++++++++++----------
|
||||
1 file changed, 16 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c
|
||||
index 87f9355..bddce5a 100644
|
||||
--- a/devices/vector/gdevtxtw.c
|
||||
+++ b/devices/vector/gdevtxtw.c
|
||||
@@ -1812,11 +1812,11 @@ static int get_unicode(textw_text_enum_t *penum, gs_font *font, gs_glyph glyph,
|
||||
#else
|
||||
b = (char *)Buffer;
|
||||
u = (char *)unicode;
|
||||
- while (l >= 0) {
|
||||
- *b++ = *(u + l);
|
||||
- l--;
|
||||
- }
|
||||
|
||||
+ for (l=0;l<length;l+=2, u+=2){
|
||||
+ *b++ = *(u+1);
|
||||
+ *b++ = *u;
|
||||
+ }
|
||||
#endif
|
||||
gs_free_object(penum->dev->memory, unicode, "free temporary unicode buffer");
|
||||
return length / sizeof(short);
|
||||
@@ -1963,7 +1963,7 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
|
||||
&penum->text_state->matrix, &wanted);
|
||||
pte->returned.total_width.x += wanted.x;
|
||||
pte->returned.total_width.y += wanted.y;
|
||||
- penum->Widths[pte->index - 1] = wanted.x;
|
||||
+ penum->Widths[penum->TextBufferIndex] = wanted.x;
|
||||
|
||||
if (pte->text.operation & TEXT_ADD_TO_ALL_WIDTHS) {
|
||||
gs_point tpt;
|
||||
@@ -1984,8 +1984,14 @@ txtwrite_process_plain_text(gs_text_enum_t *pte)
|
||||
pte->returned.total_width.x += dpt.x;
|
||||
pte->returned.total_width.y += dpt.y;
|
||||
|
||||
- penum->TextBufferIndex += get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
|
||||
- penum->Widths[pte->index - 1] += dpt.x;
|
||||
+ penum->Widths[penum->TextBufferIndex] += dpt.x;
|
||||
+ code = get_unicode(penum, (gs_font *)pte->orig_font, glyph, ch, &penum->TextBuffer[penum->TextBufferIndex]);
|
||||
+ /* If a single text code returned multiple Unicode values, then we need to set the
|
||||
+ * 'extra' code points' widths to 0.
|
||||
+ */
|
||||
+ if (code > 1)
|
||||
+ memset(&penum->Widths[penum->TextBufferIndex + 1], 0x00, (code - 1) * sizeof(float));
|
||||
+ penum->TextBufferIndex += code;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -2123,7 +2129,7 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
|
||||
if (!penum->text_state->Widths)
|
||||
return gs_note_error(gs_error_VMerror);
|
||||
memset(penum->text_state->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
|
||||
- memcpy(penum->text_state->Widths, penum->Widths, penum->text.size * sizeof(float));
|
||||
+ memcpy(penum->text_state->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
|
||||
|
||||
unsorted_entry->Unicode_Text = (unsigned short *)gs_malloc(tdev->memory->stable_memory,
|
||||
penum->TextBufferIndex, sizeof(unsigned short), "txtwrite alloc sorted text buffer");
|
||||
@@ -2136,7 +2142,7 @@ txt_add_fragment(gx_device_txtwrite_t *tdev, textw_text_enum_t *penum)
|
||||
if (!unsorted_entry->Widths)
|
||||
return gs_note_error(gs_error_VMerror);
|
||||
memset(unsorted_entry->Widths, 0x00, penum->TextBufferIndex * sizeof(float));
|
||||
- memcpy(unsorted_entry->Widths, penum->Widths, penum->text.size * sizeof(float));
|
||||
+ memcpy(unsorted_entry->Widths, penum->Widths, penum->TextBufferIndex * sizeof(float));
|
||||
|
||||
unsorted_entry->FontName = (char *)gs_malloc(tdev->memory->stable_memory,
|
||||
(strlen(penum->text_state->FontName) + 1), sizeof(unsigned char), "txtwrite alloc sorted text buffer");
|
||||
@@ -2192,7 +2198,7 @@ textw_text_process(gs_text_enum_t *pte)
|
||||
if (!penum->TextBuffer)
|
||||
return gs_note_error(gs_error_VMerror);
|
||||
penum->Widths = (float *)gs_malloc(tdev->memory->stable_memory,
|
||||
- pte->text.size, sizeof(float), "txtwrite temporary widths array");
|
||||
+ pte->text.size * 4, sizeof(float), "txtwrite temporary widths array");
|
||||
if (!penum->Widths)
|
||||
return gs_note_error(gs_error_VMerror);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -45,6 +45,7 @@ SRC_URI_BASE = "https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/d
|
||||
file://CVE-2023-36664-1.patch \
|
||||
file://CVE-2023-36664-2.patch \
|
||||
file://CVE-2023-43115.patch \
|
||||
file://CVE-2020-36773.patch \
|
||||
"
|
||||
|
||||
SRC_URI = "${SRC_URI_BASE} \
|
||||
|
||||
41
meta/recipes-extended/less/less/CVE-2022-48624.patch
Normal file
41
meta/recipes-extended/less/less/CVE-2022-48624.patch
Normal file
@@ -0,0 +1,41 @@
|
||||
From c6ac6de49698be84d264a0c4c0c40bb870b10144 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Nudelman <markn@greenwoodsoftware.com>
|
||||
Date: Sat, 25 Jun 2022 11:54:43 -0700
|
||||
Subject: [PATCH] Shell-quote filenames when invoking LESSCLOSE.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/gwsw/less/commit/c6ac6de49698be84d264a0c4c0c40bb870b10144]
|
||||
CVE: CVE-2022-48624
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
filename.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/filename.c b/filename.c
|
||||
index 5824e385..dff20c08 100644
|
||||
--- a/filename.c
|
||||
+++ b/filename.c
|
||||
@@ -972,6 +972,8 @@ close_altfile(altfilename, filename)
|
||||
{
|
||||
#if HAVE_POPEN
|
||||
char *lessclose;
|
||||
+ char *qfilename;
|
||||
+ char *qaltfilename;
|
||||
FILE *fd;
|
||||
char *cmd;
|
||||
int len;
|
||||
@@ -986,9 +988,13 @@ close_altfile(altfilename, filename)
|
||||
error("LESSCLOSE ignored; must contain no more than 2 %%s", NULL_PARG);
|
||||
return;
|
||||
}
|
||||
- len = (int) (strlen(lessclose) + strlen(filename) + strlen(altfilename) + 2);
|
||||
+ qfilename = shell_quote(filename);
|
||||
+ qaltfilename = shell_quote(altfilename);
|
||||
+ len = (int) (strlen(lessclose) + strlen(qfilename) + strlen(qaltfilename) + 2);
|
||||
cmd = (char *) ecalloc(len, sizeof(char));
|
||||
- SNPRINTF2(cmd, len, lessclose, filename, altfilename);
|
||||
+ SNPRINTF2(cmd, len, lessclose, qfilename, qaltfilename);
|
||||
+ free(qaltfilename);
|
||||
+ free(qfilename);
|
||||
fd = shellcmd(cmd);
|
||||
free(cmd);
|
||||
if (fd != NULL)
|
||||
@@ -26,6 +26,7 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504 \
|
||||
DEPENDS = "ncurses"
|
||||
|
||||
SRC_URI = "http://www.greenwoodsoftware.com/${BPN}/${BPN}-${PV}.tar.gz \
|
||||
file://CVE-2022-48624.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "4ad4408b06d7a6626a055cb453f36819"
|
||||
|
||||
59
meta/recipes-extended/pam/libpam/CVE-2024-22365.patch
Normal file
59
meta/recipes-extended/pam/libpam/CVE-2024-22365.patch
Normal file
@@ -0,0 +1,59 @@
|
||||
From 031bb5a5d0d950253b68138b498dc93be69a64cb Mon Sep 17 00:00:00 2001
|
||||
From: Matthias Gerstner <matthias.gerstner@suse.de>
|
||||
Date: Wed, 27 Dec 2023 14:01:59 +0100
|
||||
Subject: [PATCH] pam_namespace: protect_dir(): use O_DIRECTORY to prevent
|
||||
local DoS situations
|
||||
|
||||
Without O_DIRECTORY the path crawling logic is subject to e.g. FIFOs
|
||||
being placed in user controlled directories, causing the PAM module to
|
||||
block indefinitely during `openat()`.
|
||||
|
||||
Pass O_DIRECTORY to cause the `openat()` to fail if the path does not
|
||||
refer to a directory.
|
||||
|
||||
With this the check whether the final path element is a directory
|
||||
becomes unnecessary, drop it.
|
||||
|
||||
Upstream-Status: Backport [https://github.com/linux-pam/linux-pam/commit/031bb5a5d0d950253b68138b498dc93be69a64cb]
|
||||
CVE: CVE-2024-22365
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
modules/pam_namespace/pam_namespace.c | 18 +-----------------
|
||||
1 file changed, 1 insertion(+), 17 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
|
||||
index 2528cff86..f72d67189 100644
|
||||
--- a/modules/pam_namespace/pam_namespace.c
|
||||
+++ b/modules/pam_namespace/pam_namespace.c
|
||||
@@ -1201,7 +1201,7 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
|
||||
int dfd = AT_FDCWD;
|
||||
int dfd_next;
|
||||
int save_errno;
|
||||
- int flags = O_RDONLY;
|
||||
+ int flags = O_RDONLY | O_DIRECTORY;
|
||||
int rv = -1;
|
||||
struct stat st;
|
||||
|
||||
@@ -1255,22 +1255,6 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
|
||||
rv = openat(dfd, dir, flags);
|
||||
}
|
||||
|
||||
- if (rv != -1) {
|
||||
- if (fstat(rv, &st) != 0) {
|
||||
- save_errno = errno;
|
||||
- close(rv);
|
||||
- rv = -1;
|
||||
- errno = save_errno;
|
||||
- goto error;
|
||||
- }
|
||||
- if (!S_ISDIR(st.st_mode)) {
|
||||
- close(rv);
|
||||
- errno = ENOTDIR;
|
||||
- rv = -1;
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
if (flags & O_NOFOLLOW) {
|
||||
/* we are inside user-owned dir - protect */
|
||||
if (protect_mount(rv, p, idata) == -1) {
|
||||
@@ -24,6 +24,7 @@ SRC_URI = "https://github.com/linux-pam/linux-pam/releases/download/v${PV}/Linux
|
||||
file://pam-security-abstract-securetty-handling.patch \
|
||||
file://pam-unix-nullok-secure.patch \
|
||||
file://crypt_configure.patch \
|
||||
file://CVE-2024-22365.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "558ff53b0fc0563ca97f79e911822165"
|
||||
|
||||
146
meta/recipes-extended/shadow/files/CVE-2023-4641.patch
Normal file
146
meta/recipes-extended/shadow/files/CVE-2023-4641.patch
Normal file
@@ -0,0 +1,146 @@
|
||||
From 51731b01fd9a608397da22b7b9164e4996f3d4c6 Mon Sep 17 00:00:00 2001
|
||||
From: Alejandro Colomar <alx@kernel.org>
|
||||
Date: Sat, 10 Jun 2023 16:20:05 +0200
|
||||
Subject: [PATCH] gpasswd(1): Fix password leak
|
||||
|
||||
CVE: CVE-2023-4641
|
||||
Upstream-Status: Backport [https://github.com/shadow-maint/shadow/commit/65c88a43a23c2391dcc90c0abda3e839e9c57904]
|
||||
|
||||
How to trigger this password leak?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When gpasswd(1) asks for the new password, it asks twice (as is usual
|
||||
for confirming the new password). Each of those 2 password prompts
|
||||
uses agetpass() to get the password. If the second agetpass() fails,
|
||||
the first password, which has been copied into the 'static' buffer
|
||||
'pass' via STRFCPY(), wasn't being zeroed.
|
||||
|
||||
agetpass() is defined in <./libmisc/agetpass.c> (around line 91), and
|
||||
can fail for any of the following reasons:
|
||||
|
||||
- malloc(3) or readpassphrase(3) failure.
|
||||
|
||||
These are going to be difficult to trigger. Maybe getting the system
|
||||
to the limits of memory utilization at that exact point, so that the
|
||||
next malloc(3) gets ENOMEM, and possibly even the OOM is triggered.
|
||||
About readpassphrase(3), ENFILE and EINTR seem the only plausible
|
||||
ones, and EINTR probably requires privilege or being the same user;
|
||||
but I wouldn't discard ENFILE so easily, if a process starts opening
|
||||
files.
|
||||
|
||||
- The password is longer than PASS_MAX.
|
||||
|
||||
The is plausible with physical access. However, at that point, a
|
||||
keylogger will be a much simpler attack.
|
||||
|
||||
And, the attacker must be able to know when the second password is being
|
||||
introduced, which is not going to be easy.
|
||||
|
||||
How to read the password after the leak?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Provoking the leak yourself at the right point by entering a very long
|
||||
password is easy, and inspecting the process stack at that point should
|
||||
be doable. Try to find some consistent patterns.
|
||||
|
||||
Then, search for those patterns in free memory, right after the victim
|
||||
leaks their password.
|
||||
|
||||
Once you get the leak, a program should read all the free memory
|
||||
searching for patterns that gpasswd(1) leaves nearby the leaked
|
||||
password.
|
||||
|
||||
On 6/10/23 03:14, Seth Arnold wrote:
|
||||
> An attacker process wouldn't be able to use malloc(3) for this task.
|
||||
> There's a handful of tools available for userspace to allocate memory:
|
||||
>
|
||||
> - brk / sbrk
|
||||
> - mmap MAP_ANONYMOUS
|
||||
> - mmap /dev/zero
|
||||
> - mmap some other file
|
||||
> - shm_open
|
||||
> - shmget
|
||||
>
|
||||
> Most of these return only pages of zeros to a process. Using mmap of an
|
||||
> existing file, you can get some of the contents of the file demand-loaded
|
||||
> into the memory space on the first use.
|
||||
>
|
||||
> The MAP_UNINITIALIZED flag only works if the kernel was compiled with
|
||||
> CONFIG_MMAP_ALLOW_UNINITIALIZED. This is rare.
|
||||
>
|
||||
> malloc(3) doesn't zero memory, to our collective frustration, but all the
|
||||
> garbage in the allocations is from previous allocations in the current
|
||||
> process. It isn't leftover from other processes.
|
||||
>
|
||||
> The avenues available for reading the memory:
|
||||
> - /dev/mem and /dev/kmem (requires root, not available with Secure Boot)
|
||||
> - /proc/pid/mem (requires ptrace privileges, mediated by YAMA)
|
||||
> - ptrace (requires ptrace privileges, mediated by YAMA)
|
||||
> - causing memory to be swapped to disk, and then inspecting the swap
|
||||
>
|
||||
> These all require a certain amount of privileges.
|
||||
|
||||
How to fix it?
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
memzero(), which internally calls explicit_bzero(3), or whatever
|
||||
alternative the system provides with a slightly different name, will
|
||||
make sure that the buffer is zeroed in memory, and optimizations are not
|
||||
allowed to impede this zeroing.
|
||||
|
||||
This is not really 100% effective, since compilers may place copies of
|
||||
the string somewhere hidden in the stack. Those copies won't get zeroed
|
||||
by explicit_bzero(3). However, that's arguably a compiler bug, since
|
||||
compilers should make everything possible to avoid optimizing strings
|
||||
that are later passed to explicit_bzero(3). But we all know that
|
||||
sometimes it's impossible to have perfect knowledge in the compiler, so
|
||||
this is plausible. Nevertheless, there's nothing we can do against such
|
||||
issues, except minimizing the time such passwords are stored in plain
|
||||
text.
|
||||
|
||||
Security concerns
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
We believe this isn't easy to exploit. Nevertheless, and since the fix
|
||||
is trivial, this fix should probably be applied soon, and backported to
|
||||
all supported distributions, to prevent someone else having more
|
||||
imagination than us to find a way.
|
||||
|
||||
Affected versions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
All. Bug introduced in shadow 19990709. That's the second commit in
|
||||
the git history.
|
||||
|
||||
Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)")
|
||||
Reported-by: Alejandro Colomar <alx@kernel.org>
|
||||
Cc: Serge Hallyn <serge@hallyn.com>
|
||||
Cc: Iker Pedrosa <ipedrosa@redhat.com>
|
||||
Cc: Seth Arnold <seth.arnold@canonical.com>
|
||||
Cc: Christian Brauner <christian@brauner.io>
|
||||
Cc: Balint Reczey <rbalint@debian.org>
|
||||
Cc: Sam James <sam@gentoo.org>
|
||||
Cc: David Runge <dvzrv@archlinux.org>
|
||||
Cc: Andreas Jaeger <aj@suse.de>
|
||||
Cc: <~hallyn/shadow@lists.sr.ht>
|
||||
Signed-off-by: Alejandro Colomar <alx@kernel.org>
|
||||
Signed-off-by: Hugo SIMELIERE <hsimeliere.opensource@witekio.com>
|
||||
---
|
||||
src/gpasswd.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/gpasswd.c b/src/gpasswd.c
|
||||
index 4d75af96..a698b32a 100644
|
||||
--- a/src/gpasswd.c
|
||||
+++ b/src/gpasswd.c
|
||||
@@ -918,6 +918,7 @@ static void change_passwd (struct group *gr)
|
||||
strzero (cp);
|
||||
cp = getpass (_("Re-enter new password: "));
|
||||
if (NULL == cp) {
|
||||
+ memzero (pass, sizeof pass);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
--
|
||||
2.42.0
|
||||
|
||||
@@ -16,6 +16,7 @@ SRC_URI = "https://github.com/shadow-maint/shadow/releases/download/${PV}/${BP}.
|
||||
file://shadow-relaxed-usernames.patch \
|
||||
file://CVE-2023-29383.patch \
|
||||
file://0001-Overhaul-valid_field.patch \
|
||||
file://CVE-2023-4641.patch \
|
||||
"
|
||||
|
||||
SRC_URI_append_class-target = " \
|
||||
|
||||
64
meta/recipes-extended/tar/tar/CVE-2023-39804.patch
Normal file
64
meta/recipes-extended/tar/tar/CVE-2023-39804.patch
Normal file
@@ -0,0 +1,64 @@
|
||||
From a339f05cd269013fa133d2f148d73f6f7d4247e4 Mon Sep 17 00:00:00 2001
|
||||
From: Sergey Poznyakoff <gray@gnu.org>
|
||||
Date: Sat, 28 Aug 2021 16:02:12 +0300
|
||||
Subject: Fix handling of extended header prefixes
|
||||
|
||||
* src/xheader.c (locate_handler): Recognize prefix keywords only
|
||||
when followed by a dot.
|
||||
(xattr_decoder): Use xmalloc/xstrdup instead of alloc
|
||||
|
||||
Upstream-Status: Backport [https://git.savannah.gnu.org/cgit/tar.git/commit/?id=a339f05cd269013fa133d2f148d73f6f7d4247e4]
|
||||
CVE: CVE-2023-39804
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
src/xheader.c | 17 +++++++++--------
|
||||
1 file changed, 9 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/xheader.c b/src/xheader.c
|
||||
index 4f8b2b2..3cd694d 100644
|
||||
--- a/src/xheader.c
|
||||
+++ b/src/xheader.c
|
||||
@@ -637,11 +637,11 @@ static struct xhdr_tab const *
|
||||
locate_handler (char const *keyword)
|
||||
{
|
||||
struct xhdr_tab const *p;
|
||||
-
|
||||
for (p = xhdr_tab; p->keyword; p++)
|
||||
if (p->prefix)
|
||||
{
|
||||
- if (strncmp (p->keyword, keyword, strlen(p->keyword)) == 0)
|
||||
+ size_t kwlen = strlen (p->keyword);
|
||||
+ if (keyword[kwlen] == '.' && strncmp (p->keyword, keyword, kwlen) == 0)
|
||||
return p;
|
||||
}
|
||||
else
|
||||
@@ -1716,19 +1716,20 @@ xattr_decoder (struct tar_stat_info *st,
|
||||
char const *keyword, char const *arg, size_t size)
|
||||
{
|
||||
char *xstr, *xkey;
|
||||
-
|
||||
+
|
||||
/* copy keyword */
|
||||
- size_t klen_raw = strlen (keyword);
|
||||
- xkey = alloca (klen_raw + 1);
|
||||
- memcpy (xkey, keyword, klen_raw + 1) /* including null-terminating */;
|
||||
+ xkey = xstrdup (keyword);
|
||||
|
||||
/* copy value */
|
||||
- xstr = alloca (size + 1);
|
||||
+ xstr = xmalloc (size + 1);
|
||||
memcpy (xstr, arg, size + 1); /* separator included, for GNU tar '\n' */;
|
||||
|
||||
xattr_decode_keyword (xkey);
|
||||
|
||||
- xheader_xattr_add (st, xkey + strlen("SCHILY.xattr."), xstr, size);
|
||||
+ xheader_xattr_add (st, xkey + strlen ("SCHILY.xattr."), xstr, size);
|
||||
+
|
||||
+ free (xkey);
|
||||
+ free (xstr);
|
||||
}
|
||||
|
||||
static void
|
||||
--
|
||||
cgit v1.1
|
||||
|
||||
@@ -6,10 +6,13 @@ SECTION = "base"
|
||||
LICENSE = "GPLv3"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"
|
||||
|
||||
PR = "r1"
|
||||
|
||||
SRC_URI = "${GNU_MIRROR}/tar/tar-${PV}.tar.bz2 \
|
||||
file://musl_dirent.patch \
|
||||
file://CVE-2021-20193.patch \
|
||||
file://CVE-2022-48303.patch \
|
||||
file://CVE-2023-39804.patch \
|
||||
"
|
||||
|
||||
SRC_URI[md5sum] = "17917356fff5cb4bd3cd5a6c3e727b05"
|
||||
|
||||
@@ -6,7 +6,7 @@ SECTION = "base"
|
||||
LICENSE = "PD & BSD-3-Clause"
|
||||
LIC_FILES_CHKSUM = "file://LICENSE;md5=c679c9d6b02bc2757b3eaf8f53c43fba"
|
||||
|
||||
PV = "2023c"
|
||||
PV = "2024a"
|
||||
|
||||
SRC_URI =" http://www.iana.org/time-zones/repository/releases/tzcode${PV}.tar.gz;name=tzcode \
|
||||
http://www.iana.org/time-zones/repository/releases/tzdata${PV}.tar.gz;name=tzdata \
|
||||
@@ -14,5 +14,5 @@ SRC_URI =" http://www.iana.org/time-zones/repository/releases/tzcode${PV}.tar.gz
|
||||
|
||||
UPSTREAM_CHECK_URI = "http://www.iana.org/time-zones"
|
||||
|
||||
SRC_URI[tzcode.sha256sum] = "46d17f2bb19ad73290f03a203006152e0fa0d7b11e5b71467c4a823811b214e7"
|
||||
SRC_URI[tzdata.sha256sum] = "3f510b5d1b4ae9bb38e485aa302a776b317fb3637bdb6404c4adf7b6cadd965c"
|
||||
SRC_URI[tzcode.sha256sum] = "80072894adff5a458f1d143e16e4ca1d8b2a122c9c5399da482cb68cba6a1ff8"
|
||||
SRC_URI[tzdata.sha256sum] = "0d0434459acbd2059a7a8da1f3304a84a86591f6ed69c6248fffa502b6edffe3"
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
From 0c1a93d319558fe3ab2d94f51d174b4f93810afd Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Tue, 28 Nov 2023 15:19:04 +1000
|
||||
Subject: [PATCH] Xi: allocate enough XkbActions for our buttons
|
||||
|
||||
button->xkb_acts is supposed to be an array sufficiently large for all
|
||||
our buttons, not just a single XkbActions struct. Allocating
|
||||
insufficient memory here means when we memcpy() later in
|
||||
XkbSetDeviceInfo we write into memory that wasn't ours to begin with,
|
||||
leading to the usual security ooopsiedaisies.
|
||||
|
||||
CVE-2023-6377, ZDI-CAN-22412, ZDI-CAN-22413
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/0c1a93d319558fe3ab2d94f51d174b4f93810afd]
|
||||
CVE: CVE-2023-6377
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
Xi/exevents.c | 12 ++++++------
|
||||
dix/devices.c | 10 ++++++++++
|
||||
2 files changed, 16 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Xi/exevents.c b/Xi/exevents.c
|
||||
index dcd4efb3bc..54ea11a938 100644
|
||||
--- a/Xi/exevents.c
|
||||
+++ b/Xi/exevents.c
|
||||
@@ -611,13 +611,13 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||
}
|
||||
|
||||
if (from->button->xkb_acts) {
|
||||
- if (!to->button->xkb_acts) {
|
||||
- to->button->xkb_acts = calloc(1, sizeof(XkbAction));
|
||||
- if (!to->button->xkb_acts)
|
||||
- FatalError("[Xi] not enough memory for xkb_acts.\n");
|
||||
- }
|
||||
+ size_t maxbuttons = max(to->button->numButtons, from->button->numButtons);
|
||||
+ to->button->xkb_acts = xnfreallocarray(to->button->xkb_acts,
|
||||
+ maxbuttons,
|
||||
+ sizeof(XkbAction));
|
||||
+ memset(to->button->xkb_acts, 0, maxbuttons * sizeof(XkbAction));
|
||||
memcpy(to->button->xkb_acts, from->button->xkb_acts,
|
||||
- sizeof(XkbAction));
|
||||
+ from->button->numButtons * sizeof(XkbAction));
|
||||
}
|
||||
else {
|
||||
free(to->button->xkb_acts);
|
||||
diff --git a/dix/devices.c b/dix/devices.c
|
||||
index b063128df0..3f3224d626 100644
|
||||
--- a/dix/devices.c
|
||||
+++ b/dix/devices.c
|
||||
@@ -2539,6 +2539,8 @@ RecalculateMasterButtons(DeviceIntPtr slave)
|
||||
|
||||
if (master->button && master->button->numButtons != maxbuttons) {
|
||||
int i;
|
||||
+ int last_num_buttons = master->button->numButtons;
|
||||
+
|
||||
DeviceChangedEvent event = {
|
||||
.header = ET_Internal,
|
||||
.type = ET_DeviceChanged,
|
||||
@@ -2549,6 +2551,14 @@ RecalculateMasterButtons(DeviceIntPtr slave)
|
||||
};
|
||||
|
||||
master->button->numButtons = maxbuttons;
|
||||
+ if (last_num_buttons < maxbuttons) {
|
||||
+ master->button->xkb_acts = xnfreallocarray(master->button->xkb_acts,
|
||||
+ maxbuttons,
|
||||
+ sizeof(XkbAction));
|
||||
+ memset(&master->button->xkb_acts[last_num_buttons],
|
||||
+ 0,
|
||||
+ (maxbuttons - last_num_buttons) * sizeof(XkbAction));
|
||||
+ }
|
||||
|
||||
memcpy(&event.buttons.names, master->button->labels, maxbuttons *
|
||||
sizeof(Atom));
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
From 14f480010a93ff962fef66a16412fafff81ad632 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 27 Nov 2023 16:27:49 +1000
|
||||
Subject: [PATCH] randr: avoid integer truncation in length check of
|
||||
ProcRRChange*Property
|
||||
|
||||
Affected are ProcRRChangeProviderProperty and ProcRRChangeOutputProperty.
|
||||
See also xserver@8f454b79 where this same bug was fixed for the core
|
||||
protocol and XI.
|
||||
|
||||
This fixes an OOB read and the resulting information disclosure.
|
||||
|
||||
Length calculation for the request was clipped to a 32-bit integer. With
|
||||
the correct stuff->nUnits value the expected request size was
|
||||
truncated, passing the REQUEST_FIXED_SIZE check.
|
||||
|
||||
The server then proceeded with reading at least stuff->num_items bytes
|
||||
(depending on stuff->format) from the request and stuffing whatever it
|
||||
finds into the property. In the process it would also allocate at least
|
||||
stuff->nUnits bytes, i.e. 4GB.
|
||||
|
||||
CVE-2023-6478, ZDI-CAN-22561
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/14f480010a93ff962fef66a16412fafff81ad632]
|
||||
CVE: CVE-2023-6478
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
randr/rrproperty.c | 2 +-
|
||||
randr/rrproviderproperty.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/randr/rrproperty.c b/randr/rrproperty.c
|
||||
index 25469f57b2..c4fef8a1f6 100644
|
||||
--- a/randr/rrproperty.c
|
||||
+++ b/randr/rrproperty.c
|
||||
@@ -530,7 +530,7 @@ ProcRRChangeOutputProperty(ClientPtr client)
|
||||
char format, mode;
|
||||
unsigned long len;
|
||||
int sizeInBytes;
|
||||
- int totalSize;
|
||||
+ uint64_t totalSize;
|
||||
int err;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xRRChangeOutputPropertyReq);
|
||||
diff --git a/randr/rrproviderproperty.c b/randr/rrproviderproperty.c
|
||||
index b79c17f9bf..90c5a9a933 100644
|
||||
--- a/randr/rrproviderproperty.c
|
||||
+++ b/randr/rrproviderproperty.c
|
||||
@@ -498,7 +498,7 @@ ProcRRChangeProviderProperty(ClientPtr client)
|
||||
char format, mode;
|
||||
unsigned long len;
|
||||
int sizeInBytes;
|
||||
- int totalSize;
|
||||
+ uint64_t totalSize;
|
||||
int err;
|
||||
|
||||
REQUEST_AT_LEAST_SIZE(xRRChangeProviderPropertyReq);
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 9e2ecb2af8302dedc49cb6a63ebe063c58a9e7e3 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 14 Dec 2023 11:29:49 +1000
|
||||
Subject: [PATCH] dix: allocate enough space for logical button maps
|
||||
|
||||
Both DeviceFocusEvent and the XIQueryPointer reply contain a bit for
|
||||
each logical button currently down. Since buttons can be arbitrarily mapped
|
||||
to anything up to 255 make sure we have enough bits for the maximum mapping.
|
||||
|
||||
CVE-2023-6816, ZDI-CAN-22664, ZDI-CAN-22665
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/9e2ecb2af8302dedc49cb6a63ebe063c58a9e7e3]
|
||||
CVE: CVE-2023-6816
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
Xi/xiquerypointer.c | 3 +--
|
||||
dix/enterleave.c | 5 +++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
|
||||
index 5b77b1a444..2b05ac5f39 100644
|
||||
--- a/Xi/xiquerypointer.c
|
||||
+++ b/Xi/xiquerypointer.c
|
||||
@@ -149,8 +149,7 @@ ProcXIQueryPointer(ClientPtr client)
|
||||
if (pDev->button) {
|
||||
int i;
|
||||
|
||||
- rep.buttons_len =
|
||||
- bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
|
||||
+ rep.buttons_len = bytes_to_int32(bits_to_bytes(256)); /* button map up to 255 */
|
||||
rep.length += rep.buttons_len;
|
||||
buttons = calloc(rep.buttons_len, 4);
|
||||
if (!buttons)
|
||||
diff --git a/dix/enterleave.c b/dix/enterleave.c
|
||||
index 867ec74363..ded8679d76 100644
|
||||
--- a/dix/enterleave.c
|
||||
+++ b/dix/enterleave.c
|
||||
@@ -784,8 +784,9 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
|
||||
|
||||
mouse = IsFloating(dev) ? dev : GetMaster(dev, MASTER_POINTER);
|
||||
|
||||
- /* XI 2 event */
|
||||
- btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
|
||||
+ /* XI 2 event contains the logical button map - maps are CARD8
|
||||
+ * so we need 256 bits for the possibly maximum mapping */
|
||||
+ btlen = (mouse->button) ? bits_to_bytes(256) : 0;
|
||||
btlen = bytes_to_int32(btlen);
|
||||
len = sizeof(xXIFocusInEvent) + btlen * 4;
|
||||
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
From ece23be888a93b741aa1209d1dbf64636109d6a5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 18 Dec 2023 14:27:50 +1000
|
||||
Subject: [PATCH] dix: Allocate sufficient xEvents for our DeviceStateNotify
|
||||
|
||||
If a device has both a button class and a key class and numButtons is
|
||||
zero, we can get an OOB write due to event under-allocation.
|
||||
|
||||
This function seems to assume a device has either keys or buttons, not
|
||||
both. It has two virtually identical code paths, both of which assume
|
||||
they're applying to the first event in the sequence.
|
||||
|
||||
A device with both a key and button class triggered a logic bug - only
|
||||
one xEvent was allocated but the deviceStateNotify pointer was pushed on
|
||||
once per type. So effectively this logic code:
|
||||
|
||||
int count = 1;
|
||||
if (button && nbuttons > 32) count++;
|
||||
if (key && nbuttons > 0) count++;
|
||||
if (key && nkeys > 32) count++; // this is basically always true
|
||||
// count is at 2 for our keys + zero button device
|
||||
|
||||
ev = alloc(count * sizeof(xEvent));
|
||||
FixDeviceStateNotify(ev);
|
||||
if (button)
|
||||
FixDeviceStateNotify(ev++);
|
||||
if (key)
|
||||
FixDeviceStateNotify(ev++); // santa drops into the wrong chimney here
|
||||
|
||||
If the device has more than 3 valuators, the OOB is pushed back - we're
|
||||
off by one so it will happen when the last deviceValuator event is
|
||||
written instead.
|
||||
|
||||
Fix this by allocating the maximum number of events we may allocate.
|
||||
Note that the current behavior is not protocol-correct anyway, this
|
||||
patch fixes only the allocation issue.
|
||||
|
||||
Note that this issue does not trigger if the device has at least one
|
||||
button. While the server does not prevent a button class with zero
|
||||
buttons, it is very unlikely.
|
||||
|
||||
CVE-2024-0229, ZDI-CAN-22678
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/ece23be888a93b741aa1209d1dbf64636109d6a5]
|
||||
CVE: CVE-2024-0229
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
dix/enterleave.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dix/enterleave.c b/dix/enterleave.c
|
||||
index ded8679d76..17964b00a4 100644
|
||||
--- a/dix/enterleave.c
|
||||
+++ b/dix/enterleave.c
|
||||
@@ -675,7 +675,8 @@ static void
|
||||
DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
{
|
||||
int evcount = 1;
|
||||
- deviceStateNotify *ev, *sev;
|
||||
+ deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
|
||||
+ deviceStateNotify *ev;
|
||||
deviceKeyStateNotify *kev;
|
||||
deviceButtonStateNotify *bev;
|
||||
|
||||
@@ -714,7 +715,7 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
}
|
||||
}
|
||||
|
||||
- sev = ev = xallocarray(evcount, sizeof(xEvent));
|
||||
+ ev = sev;
|
||||
FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
|
||||
|
||||
if (b != NULL) {
|
||||
@@ -770,7 +771,6 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
|
||||
DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
|
||||
DeviceStateNotifyMask, NullGrab);
|
||||
- free(sev);
|
||||
}
|
||||
|
||||
void
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
From 219c54b8a3337456ce5270ded6a67bcde53553d5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Mon, 18 Dec 2023 12:26:20 +1000
|
||||
Subject: [PATCH] dix: fix DeviceStateNotify event calculation
|
||||
|
||||
The previous code only made sense if one considers buttons and keys to
|
||||
be mutually exclusive on a device. That is not necessarily true, causing
|
||||
a number of issues.
|
||||
|
||||
This function allocates and fills in the number of xEvents we need to
|
||||
send the device state down the wire. This is split across multiple
|
||||
32-byte devices including one deviceStateNotify event and optional
|
||||
deviceKeyStateNotify, deviceButtonStateNotify and (possibly multiple)
|
||||
deviceValuator events.
|
||||
|
||||
The previous behavior would instead compose a sequence
|
||||
of [state, buttonstate, state, keystate, valuator...]. This is not
|
||||
protocol correct, and on top of that made the code extremely convoluted.
|
||||
|
||||
Fix this by streamlining: add both button and key into the deviceStateNotify
|
||||
and then append the key state and button state, followed by the
|
||||
valuators. Finally, the deviceValuator events contain up to 6 valuators
|
||||
per event but we only ever sent through 3 at a time. Let's double that
|
||||
troughput.
|
||||
|
||||
CVE-2024-0229, ZDI-CAN-22678
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/219c54b8a3337456ce5270ded6a67bcde53553d5]
|
||||
CVE: CVE-2024-0229
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
dix/enterleave.c | 121 ++++++++++++++++++++---------------------------
|
||||
1 file changed, 52 insertions(+), 69 deletions(-)
|
||||
|
||||
diff --git a/dix/enterleave.c b/dix/enterleave.c
|
||||
index 17964b00a4..7b7ba1098b 100644
|
||||
--- a/dix/enterleave.c
|
||||
+++ b/dix/enterleave.c
|
||||
@@ -615,9 +615,15 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
|
||||
|
||||
ev->type = DeviceValuator;
|
||||
ev->deviceid = dev->id;
|
||||
- ev->num_valuators = nval < 3 ? nval : 3;
|
||||
+ ev->num_valuators = nval < 6 ? nval : 6;
|
||||
ev->first_valuator = first;
|
||||
switch (ev->num_valuators) {
|
||||
+ case 6:
|
||||
+ ev->valuator2 = v->axisVal[first + 5];
|
||||
+ case 5:
|
||||
+ ev->valuator2 = v->axisVal[first + 4];
|
||||
+ case 4:
|
||||
+ ev->valuator2 = v->axisVal[first + 3];
|
||||
case 3:
|
||||
ev->valuator2 = v->axisVal[first + 2];
|
||||
case 2:
|
||||
@@ -626,7 +632,6 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
|
||||
ev->valuator0 = v->axisVal[first];
|
||||
break;
|
||||
}
|
||||
- first += ev->num_valuators;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -646,7 +651,7 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
|
||||
ev->num_buttons = b->numButtons;
|
||||
memcpy((char *) ev->buttons, (char *) b->down, 4);
|
||||
}
|
||||
- else if (k) {
|
||||
+ if (k) {
|
||||
ev->classes_reported |= (1 << KeyClass);
|
||||
ev->num_keys = k->xkbInfo->desc->max_key_code -
|
||||
k->xkbInfo->desc->min_key_code;
|
||||
@@ -670,15 +675,26 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
|
||||
}
|
||||
}
|
||||
|
||||
-
|
||||
+/**
|
||||
+ * The device state notify event is split across multiple 32-byte events.
|
||||
+ * The first one contains the first 32 button state bits, the first 32
|
||||
+ * key state bits, and the first 3 valuator values.
|
||||
+ *
|
||||
+ * If a device has more than that, the server sends out:
|
||||
+ * - one deviceButtonStateNotify for buttons 32 and above
|
||||
+ * - one deviceKeyStateNotify for keys 32 and above
|
||||
+ * - one deviceValuator event per 6 valuators above valuator 4
|
||||
+ *
|
||||
+ * All events but the last one have the deviceid binary ORed with MORE_EVENTS,
|
||||
+ */
|
||||
static void
|
||||
DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
{
|
||||
+ /* deviceStateNotify, deviceKeyStateNotify, deviceButtonStateNotify
|
||||
+ * and one deviceValuator for each 6 valuators */
|
||||
+ deviceStateNotify sev[3 + (MAX_VALUATORS + 6)/6];
|
||||
int evcount = 1;
|
||||
- deviceStateNotify sev[6 + (MAX_VALUATORS + 2)/3];
|
||||
- deviceStateNotify *ev;
|
||||
- deviceKeyStateNotify *kev;
|
||||
- deviceButtonStateNotify *bev;
|
||||
+ deviceStateNotify *ev = sev;
|
||||
|
||||
KeyClassPtr k;
|
||||
ButtonClassPtr b;
|
||||
@@ -691,82 +707,49 @@ DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
|
||||
|
||||
if ((b = dev->button) != NULL) {
|
||||
nbuttons = b->numButtons;
|
||||
- if (nbuttons > 32)
|
||||
+ if (nbuttons > 32) /* first 32 are encoded in deviceStateNotify */
|
||||
evcount++;
|
||||
}
|
||||
if ((k = dev->key) != NULL) {
|
||||
nkeys = k->xkbInfo->desc->max_key_code - k->xkbInfo->desc->min_key_code;
|
||||
- if (nkeys > 32)
|
||||
+ if (nkeys > 32) /* first 32 are encoded in deviceStateNotify */
|
||||
evcount++;
|
||||
- if (nbuttons > 0) {
|
||||
- evcount++;
|
||||
- }
|
||||
}
|
||||
if ((v = dev->valuator) != NULL) {
|
||||
nval = v->numAxes;
|
||||
-
|
||||
- if (nval > 3)
|
||||
- evcount++;
|
||||
- if (nval > 6) {
|
||||
- if (!(k && b))
|
||||
- evcount++;
|
||||
- if (nval > 9)
|
||||
- evcount += ((nval - 7) / 3);
|
||||
- }
|
||||
+ /* first three are encoded in deviceStateNotify, then
|
||||
+ * it's 6 per deviceValuator event */
|
||||
+ evcount += ((nval - 3) + 6)/6;
|
||||
}
|
||||
|
||||
- ev = sev;
|
||||
- FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
|
||||
-
|
||||
- if (b != NULL) {
|
||||
- FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- if (nbuttons > 32) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- bev = (deviceButtonStateNotify *) ev++;
|
||||
- bev->type = DeviceButtonStateNotify;
|
||||
- bev->deviceid = dev->id;
|
||||
- memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
|
||||
- DOWN_LENGTH - 4);
|
||||
- }
|
||||
- if (nval > 0) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- }
|
||||
+ BUG_RETURN(evcount <= ARRAY_SIZE(sev));
|
||||
+
|
||||
+ FixDeviceStateNotify(dev, ev, k, b, v, first);
|
||||
+
|
||||
+ if (b != NULL && nbuttons > 32) {
|
||||
+ deviceButtonStateNotify *bev = (deviceButtonStateNotify *) ++ev;
|
||||
+ (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
+ bev->type = DeviceButtonStateNotify;
|
||||
+ bev->deviceid = dev->id;
|
||||
+ memcpy((char *) &bev->buttons[4], (char *) &b->down[4],
|
||||
+ DOWN_LENGTH - 4);
|
||||
}
|
||||
|
||||
- if (k != NULL) {
|
||||
- FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- if (nkeys > 32) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- kev = (deviceKeyStateNotify *) ev++;
|
||||
- kev->type = DeviceKeyStateNotify;
|
||||
- kev->deviceid = dev->id;
|
||||
- memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
|
||||
- }
|
||||
- if (nval > 0) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- }
|
||||
+ if (k != NULL && nkeys > 32) {
|
||||
+ deviceKeyStateNotify *kev = (deviceKeyStateNotify *) ++ev;
|
||||
+ (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
+ kev->type = DeviceKeyStateNotify;
|
||||
+ kev->deviceid = dev->id;
|
||||
+ memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
|
||||
}
|
||||
|
||||
+ first = 3;
|
||||
+ nval -= 3;
|
||||
while (nval > 0) {
|
||||
- FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- if (nval > 0) {
|
||||
- (ev - 1)->deviceid |= MORE_EVENTS;
|
||||
- FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
|
||||
- first += 3;
|
||||
- nval -= 3;
|
||||
- }
|
||||
+ ev->deviceid |= MORE_EVENTS;
|
||||
+ FixDeviceValuator(dev, (deviceValuator *) ++ev, v, first);
|
||||
+ first += 6;
|
||||
+ nval -= 6;
|
||||
}
|
||||
|
||||
DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
From df3c65706eb169d5938df0052059f3e0d5981b74 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 21 Dec 2023 13:48:10 +1000
|
||||
Subject: [PATCH] Xi: when creating a new ButtonClass, set the number of
|
||||
buttons
|
||||
|
||||
There's a racy sequence where a master device may copy the button class
|
||||
from the slave, without ever initializing numButtons. This leads to a
|
||||
device with zero buttons but a button class which is invalid.
|
||||
|
||||
Let's copy the numButtons value from the source - by definition if we
|
||||
don't have a button class yet we do not have any other slave devices
|
||||
with more than this number of buttons anyway.
|
||||
|
||||
CVE-2024-0229, ZDI-CAN-22678
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/df3c65706eb169d5938df0052059f3e0d5981b74]
|
||||
CVE: CVE-2024-0229
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
Xi/exevents.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Xi/exevents.c b/Xi/exevents.c
|
||||
index 54ea11a938..e161714682 100644
|
||||
--- a/Xi/exevents.c
|
||||
+++ b/Xi/exevents.c
|
||||
@@ -605,6 +605,7 @@ DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
|
||||
to->button = calloc(1, sizeof(ButtonClassRec));
|
||||
if (!to->button)
|
||||
FatalError("[Xi] no memory for class shift.\n");
|
||||
+ to->button->numButtons = from->button->numButtons;
|
||||
}
|
||||
else
|
||||
classes->button = NULL;
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
From 37539cb0bfe4ed96d4499bf371e6b1a474a740fe Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 21 Dec 2023 14:10:11 +1000
|
||||
Subject: [PATCH] Xi: require a pointer and keyboard device for
|
||||
XIAttachToMaster
|
||||
|
||||
If we remove a master device and specify which other master devices
|
||||
attached slaves should be returned to, enforce that those two are
|
||||
indeeed a pointer and a keyboard.
|
||||
|
||||
Otherwise we can try to attach the keyboards to pointers and vice versa,
|
||||
leading to possible crashes later.
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/37539cb0bfe4ed96d4499bf371e6b1a474a740fe]
|
||||
CVE: CVE-2024-0229
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
Xi/xichangehierarchy.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
|
||||
index 504defe566..d2d985848d 100644
|
||||
--- a/Xi/xichangehierarchy.c
|
||||
+++ b/Xi/xichangehierarchy.c
|
||||
@@ -270,7 +270,7 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
|
||||
- if (!IsMaster(newptr)) {
|
||||
+ if (!IsMaster(newptr) || !IsPointerDevice(newptr)) {
|
||||
client->errorValue = r->return_pointer;
|
||||
rc = BadDevice;
|
||||
goto unwind;
|
||||
@@ -281,7 +281,7 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
|
||||
- if (!IsMaster(newkeybd)) {
|
||||
+ if (!IsMaster(newkeybd) || !IsKeyboardDevice(newkeybd)) {
|
||||
client->errorValue = r->return_keyboard;
|
||||
rc = BadDevice;
|
||||
goto unwind;
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
From e5e8586a12a3ec915673edffa10dc8fe5e15dac3 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 6 Dec 2023 12:09:41 +0100
|
||||
Subject: [PATCH] glx: Call XACE hooks on the GLX buffer
|
||||
|
||||
The XSELINUX code will label resources at creation by checking the
|
||||
access mode. When the access mode is DixCreateAccess, it will call the
|
||||
function to label the new resource SELinuxLabelResource().
|
||||
|
||||
However, GLX buffers do not go through the XACE hooks when created,
|
||||
hence leaving the resource actually unlabeled.
|
||||
|
||||
When, later, the client tries to create another resource using that
|
||||
drawable (like a GC for example), the XSELINUX code would try to use
|
||||
the security ID of that object which has never been labeled, get a NULL
|
||||
pointer and crash when checking whether the requested permissions are
|
||||
granted for subject security ID.
|
||||
|
||||
To avoid the issue, make sure to call the XACE hooks when creating the
|
||||
GLX buffers.
|
||||
|
||||
Credit goes to Donn Seeley <donn@xmission.com> for providing the patch.
|
||||
|
||||
CVE-2024-0408
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/e5e8586a12a3ec915673edffa10dc8fe5e15dac3]
|
||||
CVE: CVE-2024-0408
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
glx/glxcmds.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
|
||||
index fc26a2e345..1e46d0c723 100644
|
||||
--- a/glx/glxcmds.c
|
||||
+++ b/glx/glxcmds.c
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "indirect_util.h"
|
||||
#include "protocol-versions.h"
|
||||
#include "glxvndabi.h"
|
||||
+#include "xace.h"
|
||||
|
||||
static char GLXServerVendorName[] = "SGI";
|
||||
|
||||
@@ -1392,6 +1393,13 @@ DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
|
||||
if (!pPixmap)
|
||||
return BadAlloc;
|
||||
|
||||
+ err = XaceHook(XACE_RESOURCE_ACCESS, client, glxDrawableId, RT_PIXMAP,
|
||||
+ pPixmap, RT_NONE, NULL, DixCreateAccess);
|
||||
+ if (err != Success) {
|
||||
+ (*pGlxScreen->pScreen->DestroyPixmap) (pPixmap);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
/* Assign the pixmap the same id as the pbuffer and add it as a
|
||||
* resource so it and the DRI2 drawable will be reclaimed when the
|
||||
* pbuffer is destroyed. */
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 2ef0f1116c65d5cb06d7b6d83f8a1aea702c94f7 Mon Sep 17 00:00:00 2001
|
||||
From: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Date: Wed, 6 Dec 2023 11:51:56 +0100
|
||||
Subject: [PATCH] ephyr,xwayland: Use the proper private key for cursor
|
||||
|
||||
The cursor in DIX is actually split in two parts, the cursor itself and
|
||||
the cursor bits, each with their own devPrivates.
|
||||
|
||||
The cursor itself includes the cursor bits, meaning that the cursor bits
|
||||
devPrivates in within structure of the cursor.
|
||||
|
||||
Both Xephyr and Xwayland were using the private key for the cursor bits
|
||||
to store the data for the cursor, and when using XSELINUX which comes
|
||||
with its own special devPrivates, the data stored in that cursor bits'
|
||||
devPrivates would interfere with the XSELINUX devPrivates data and the
|
||||
SELINUX security ID would point to some other unrelated data, causing a
|
||||
crash in the XSELINUX code when trying to (re)use the security ID.
|
||||
|
||||
CVE-2024-0409
|
||||
|
||||
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
|
||||
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/2ef0f1116c65d5cb06d7b6d83f8a1aea702c94f7]
|
||||
CVE: CVE-2024-0409
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
hw/kdrive/ephyr/ephyrcursor.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/kdrive/ephyr/ephyrcursor.c b/hw/kdrive/ephyr/ephyrcursor.c
|
||||
index f991899..3f192d0 100644
|
||||
--- a/hw/kdrive/ephyr/ephyrcursor.c
|
||||
+++ b/hw/kdrive/ephyr/ephyrcursor.c
|
||||
@@ -246,7 +246,7 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
|
||||
Bool
|
||||
ephyrCursorInit(ScreenPtr screen)
|
||||
{
|
||||
- if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR_BITS,
|
||||
+ if (!dixRegisterPrivateKey(&ephyrCursorPrivateKey, PRIVATE_CURSOR,
|
||||
sizeof(ephyrCursorRec)))
|
||||
return FALSE;
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
From 4a5e9b1895627d40d26045bd0b7ef3dce503cbd1 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Thu, 4 Jan 2024 10:01:24 +1000
|
||||
Subject: [PATCH] Xi: flush hierarchy events after adding/removing master
|
||||
devices
|
||||
|
||||
The `XISendDeviceHierarchyEvent()` function allocates space to store up
|
||||
to `MAXDEVICES` (256) `xXIHierarchyInfo` structures in `info`.
|
||||
|
||||
If a device with a given ID was removed and a new device with the same
|
||||
ID added both in the same operation, the single device ID will lead to
|
||||
two info structures being written to `info`.
|
||||
|
||||
Since this case can occur for every device ID at once, a total of two
|
||||
times `MAXDEVICES` info structures might be written to the allocation.
|
||||
|
||||
To avoid it, once one add/remove master is processed, send out the
|
||||
device hierarchy event for the current state and continue. That event
|
||||
thus only ever has exactly one of either added/removed in it (and
|
||||
optionally slave attached/detached).
|
||||
|
||||
CVE-2024-21885, ZDI-CAN-22744
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/4a5e9b1895627d40d26045bd0b7ef3dce503cbd1]
|
||||
CVE: CVE-2024-21885
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
Xi/xichangehierarchy.c | 27 ++++++++++++++++++++++-----
|
||||
1 file changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
|
||||
index d2d985848d..72d00451e3 100644
|
||||
--- a/Xi/xichangehierarchy.c
|
||||
+++ b/Xi/xichangehierarchy.c
|
||||
@@ -416,6 +416,11 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
size_t len; /* length of data remaining in request */
|
||||
int rc = Success;
|
||||
int flags[MAXDEVICES] = { 0 };
|
||||
+ enum {
|
||||
+ NO_CHANGE,
|
||||
+ FLUSH,
|
||||
+ CHANGED,
|
||||
+ } changes = NO_CHANGE;
|
||||
|
||||
REQUEST(xXIChangeHierarchyReq);
|
||||
REQUEST_AT_LEAST_SIZE(xXIChangeHierarchyReq);
|
||||
@@ -465,8 +470,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = add_master(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
- }
|
||||
+ changes = FLUSH;
|
||||
break;
|
||||
+ }
|
||||
case XIRemoveMaster:
|
||||
{
|
||||
xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any;
|
||||
@@ -475,8 +481,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = remove_master(client, r, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
- }
|
||||
+ changes = FLUSH;
|
||||
break;
|
||||
+ }
|
||||
case XIDetachSlave:
|
||||
{
|
||||
xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any;
|
||||
@@ -485,8 +492,9 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = detach_slave(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
- }
|
||||
+ changes = CHANGED;
|
||||
break;
|
||||
+ }
|
||||
case XIAttachSlave:
|
||||
{
|
||||
xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any;
|
||||
@@ -495,16 +503,25 @@ ProcXIChangeHierarchy(ClientPtr client)
|
||||
rc = attach_slave(client, c, flags);
|
||||
if (rc != Success)
|
||||
goto unwind;
|
||||
+ changes = CHANGED;
|
||||
+ break;
|
||||
}
|
||||
+ default:
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (changes == FLUSH) {
|
||||
+ XISendDeviceHierarchyEvent(flags);
|
||||
+ memset(flags, 0, sizeof(flags));
|
||||
+ changes = NO_CHANGE;
|
||||
+ }
|
||||
+
|
||||
len -= any->length * 4;
|
||||
any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4);
|
||||
}
|
||||
|
||||
unwind:
|
||||
-
|
||||
- XISendDeviceHierarchyEvent(flags);
|
||||
+ if (changes != NO_CHANGE)
|
||||
+ XISendDeviceHierarchyEvent(flags);
|
||||
return rc;
|
||||
}
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
From bc1fdbe46559dd947674375946bbef54dd0ce36b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jexposit@redhat.com>
|
||||
Date: Fri, 22 Dec 2023 18:28:31 +0100
|
||||
Subject: [PATCH] Xi: do not keep linked list pointer during recursion
|
||||
|
||||
The `DisableDevice()` function is called whenever an enabled device
|
||||
is disabled and it moves the device from the `inputInfo.devices` linked
|
||||
list to the `inputInfo.off_devices` linked list.
|
||||
|
||||
However, its link/unlink operation has an issue during the recursive
|
||||
call to `DisableDevice()` due to the `prev` pointer pointing to a
|
||||
removed device.
|
||||
|
||||
This issue leads to a length mismatch between the total number of
|
||||
devices and the number of device in the list, leading to a heap
|
||||
overflow and, possibly, to local privilege escalation.
|
||||
|
||||
Simplify the code that checked whether the device passed to
|
||||
`DisableDevice()` was in `inputInfo.devices` or not and find the
|
||||
previous device after the recursion.
|
||||
|
||||
CVE-2024-21886, ZDI-CAN-22840
|
||||
|
||||
This vulnerability was discovered by:
|
||||
Jan-Niklas Sohn working with Trend Micro Zero Day Initiative
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/bc1fdbe46559dd947674375946bbef54dd0ce36b]
|
||||
CVE: CVE-2024-21886
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
dix/devices.c | 15 ++++++++++++---
|
||||
1 file changed, 12 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dix/devices.c b/dix/devices.c
|
||||
index dca98c8d1b..389d28a23c 100644
|
||||
--- a/dix/devices.c
|
||||
+++ b/dix/devices.c
|
||||
@@ -453,14 +453,20 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||
{
|
||||
DeviceIntPtr *prev, other;
|
||||
BOOL enabled;
|
||||
+ BOOL dev_in_devices_list = FALSE;
|
||||
int flags[MAXDEVICES] = { 0 };
|
||||
|
||||
if (!dev->enabled)
|
||||
return TRUE;
|
||||
|
||||
- for (prev = &inputInfo.devices;
|
||||
- *prev && (*prev != dev); prev = &(*prev)->next);
|
||||
- if (*prev != dev)
|
||||
+ for (other = inputInfo.devices; other; other = other->next) {
|
||||
+ if (other == dev) {
|
||||
+ dev_in_devices_list = TRUE;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!dev_in_devices_list)
|
||||
return FALSE;
|
||||
|
||||
TouchEndPhysicallyActiveTouches(dev);
|
||||
@@ -511,6 +517,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||
LeaveWindow(dev);
|
||||
SetFocusOut(dev);
|
||||
|
||||
+ for (prev = &inputInfo.devices;
|
||||
+ *prev && (*prev != dev); prev = &(*prev)->next);
|
||||
+
|
||||
*prev = dev->next;
|
||||
dev->next = inputInfo.off_devices;
|
||||
inputInfo.off_devices = dev;
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From 26769aa71fcbe0a8403b7fb13b7c9010cc07c3a8 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hutterer <peter.hutterer@who-t.net>
|
||||
Date: Fri, 5 Jan 2024 09:40:27 +1000
|
||||
Subject: [PATCH] dix: when disabling a master, float disabled slaved devices
|
||||
too
|
||||
|
||||
Disabling a master device floats all slave devices but we didn't do this
|
||||
to already-disabled slave devices. As a result those devices kept their
|
||||
reference to the master device resulting in access to already freed
|
||||
memory if the master device was removed before the corresponding slave
|
||||
device.
|
||||
|
||||
And to match this behavior, also forcibly reset that pointer during
|
||||
CloseDownDevices().
|
||||
|
||||
Related to CVE-2024-21886, ZDI-CAN-22840
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/26769aa71fcbe0a8403b7fb13b7c9010cc07c3a8]
|
||||
CVE: CVE-2024-21886
|
||||
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
|
||||
---
|
||||
dix/devices.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/dix/devices.c b/dix/devices.c
|
||||
index 389d28a23c..84a6406d13 100644
|
||||
--- a/dix/devices.c
|
||||
+++ b/dix/devices.c
|
||||
@@ -483,6 +483,13 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
|
||||
flags[other->id] |= XISlaveDetached;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ for (other = inputInfo.off_devices; other; other = other->next) {
|
||||
+ if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
|
||||
+ AttachDevice(NULL, other, NULL);
|
||||
+ flags[other->id] |= XISlaveDetached;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
else {
|
||||
for (other = inputInfo.devices; other; other = other->next) {
|
||||
@@ -1088,6 +1095,11 @@ CloseDownDevices(void)
|
||||
dev->master = NULL;
|
||||
}
|
||||
|
||||
+ for (dev = inputInfo.off_devices; dev; dev = dev->next) {
|
||||
+ if (!IsMaster(dev) && !IsFloating(dev))
|
||||
+ dev->master = NULL;
|
||||
+ }
|
||||
+
|
||||
CloseDeviceList(&inputInfo.devices);
|
||||
CloseDeviceList(&inputInfo.off_devices);
|
||||
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 96798fc1967491c80a4d0c8d9e0a80586cb2152b Mon Sep 17 00:00:00 2001
|
||||
From: Alan Coopersmith <alan.coopersmith@oracle.com>
|
||||
Date: Fri, 22 Mar 2024 18:51:45 -0700
|
||||
Subject: [PATCH] Xi: ProcXIGetSelectedEvents needs to use unswapped length to
|
||||
send reply
|
||||
|
||||
CVE-2024-31080
|
||||
|
||||
Reported-by: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69762
|
||||
Fixes: 53e821ab4 ("Xi: add request processing for XIGetSelectedEvents.")
|
||||
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/96798fc1967491c80a4d0c8d9e0a80586cb2152b]
|
||||
CVE: CVE-2024-31080
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
|
||||
Xi/xiselectev.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c
|
||||
index edcb8a0d36..ac14949871 100644
|
||||
--- a/Xi/xiselectev.c
|
||||
+++ b/Xi/xiselectev.c
|
||||
@@ -349,6 +349,7 @@ ProcXIGetSelectedEvents(ClientPtr client)
|
||||
InputClientsPtr others = NULL;
|
||||
xXIEventMask *evmask = NULL;
|
||||
DeviceIntPtr dev;
|
||||
+ uint32_t length;
|
||||
|
||||
REQUEST(xXIGetSelectedEventsReq);
|
||||
REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq);
|
||||
@@ -418,10 +419,12 @@ ProcXIGetSelectedEvents(ClientPtr client)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* save the value before SRepXIGetSelectedEvents swaps it */
|
||||
+ length = reply.length;
|
||||
WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply);
|
||||
|
||||
if (reply.num_masks)
|
||||
- WriteToClient(client, reply.length * 4, buffer);
|
||||
+ WriteToClient(client, length * 4, buffer);
|
||||
|
||||
free(buffer);
|
||||
return Success;
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From 3e77295f888c67fc7645db5d0c00926a29ffecee Mon Sep 17 00:00:00 2001
|
||||
From: Alan Coopersmith <alan.coopersmith@oracle.com>
|
||||
Date: Fri, 22 Mar 2024 18:56:27 -0700
|
||||
Subject: [PATCH] Xi: ProcXIPassiveGrabDevice needs to use unswapped length to
|
||||
send reply
|
||||
|
||||
CVE-2024-31081
|
||||
|
||||
Fixes: d220d6907 ("Xi: add GrabButton and GrabKeysym code.")
|
||||
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
|
||||
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1463>
|
||||
|
||||
Upstream-Status: Backport [https://gitlab.freedesktop.org/xorg/xserver/-/commit/3e77295f888c67fc7645db5d0c00926a29ffecee]
|
||||
CVE: CVE-2024-31081
|
||||
Signed-off-by: Ashish Sharma <asharma@mvista.com>
|
||||
|
||||
Xi/xipassivegrab.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c
|
||||
index c9ac2f8553..896233bec2 100644
|
||||
--- a/Xi/xipassivegrab.c
|
||||
+++ b/Xi/xipassivegrab.c
|
||||
@@ -93,6 +93,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
||||
GrabParameters param;
|
||||
void *tmp;
|
||||
int mask_len;
|
||||
+ uint32_t length;
|
||||
|
||||
REQUEST(xXIPassiveGrabDeviceReq);
|
||||
REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq,
|
||||
@@ -247,9 +248,11 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
||||
}
|
||||
}
|
||||
|
||||
+ /* save the value before SRepXIPassiveGrabDevice swaps it */
|
||||
+ length = rep.length;
|
||||
WriteReplyToClient(client, sizeof(rep), &rep);
|
||||
if (rep.num_modifiers)
|
||||
- WriteToClient(client, rep.length * 4, modifiers_failed);
|
||||
+ WriteToClient(client, length * 4, modifiers_failed);
|
||||
|
||||
out:
|
||||
free(modifiers_failed);
|
||||
--
|
||||
GitLab
|
||||
|
||||
@@ -18,6 +18,20 @@ SRC_URI += "file://0001-xf86pciBus.c-use-Intel-ddx-only-for-pre-gen4-hardwar.pat
|
||||
file://CVE-2023-1393.patch \
|
||||
file://CVE-2023-5367.patch \
|
||||
file://CVE-2023-5380.patch \
|
||||
file://CVE-2023-6377.patch \
|
||||
file://CVE-2023-6478.patch \
|
||||
file://CVE-2023-6816.patch \
|
||||
file://CVE-2024-0229-1.patch \
|
||||
file://CVE-2024-0229-2.patch \
|
||||
file://CVE-2024-0229-3.patch \
|
||||
file://CVE-2024-0229-4.patch \
|
||||
file://CVE-2024-21885.patch \
|
||||
file://CVE-2024-21886-1.patch \
|
||||
file://CVE-2024-21886-2.patch \
|
||||
file://CVE-2024-0408.patch \
|
||||
file://CVE-2024-0409.patch \
|
||||
file://CVE-2024-31081.patch \
|
||||
file://CVE-2024-31080.patch \
|
||||
"
|
||||
SRC_URI[md5sum] = "453fc86aac8c629b3a5b77e8dcca30bf"
|
||||
SRC_URI[sha256sum] = "54b199c9280ff8bf0f73a54a759645bd0eeeda7255d1c99310d5b7595f3ac066"
|
||||
|
||||
@@ -134,7 +134,7 @@ LIC_FILES_CHKSUM = "file://LICENCE.Abilis;md5=b5ee3f410780e56711ad48eadc22b8bc \
|
||||
"
|
||||
# WHENCE checksum is defined separately to ease overriding it if
|
||||
# class-devupstream is selected.
|
||||
WHENCE_CHKSUM = "41f9a48bf27971b126a36f9344594dcd"
|
||||
WHENCE_CHKSUM = "a344e6c28970fc7daafa81c10247aeb6"
|
||||
|
||||
# These are not common licenses, set NO_GENERIC_LICENSE for them
|
||||
# so that the license files will be copied from fetched source
|
||||
@@ -212,7 +212,7 @@ SRC_URI:class-devupstream = "git://git.kernel.org/pub/scm/linux/kernel/git/firmw
|
||||
# Pin this to the 20220509 release, override this in local.conf
|
||||
SRCREV:class-devupstream ?= "b19cbdca78ab2adfd210c91be15a22568e8b8cae"
|
||||
|
||||
SRC_URI[sha256sum] = "88d46c543847ee3b03404d4941d91c92974690ee1f6fdcbee9cef3e5f97db688"
|
||||
SRC_URI[sha256sum] = "bf0f239dc0801e9d6bf5d5fb3e2f549575632cf4688f4348184199cb02c2bcd7"
|
||||
|
||||
inherit allarch
|
||||
|
||||
@@ -223,7 +223,8 @@ do_compile() {
|
||||
}
|
||||
|
||||
do_install() {
|
||||
oe_runmake 'DESTDIR=${D}' 'FIRMWAREDIR=${nonarch_base_libdir}/firmware' install
|
||||
# install-nodedup avoids rdfind dependency
|
||||
oe_runmake 'DESTDIR=${D}' 'FIRMWAREDIR=${nonarch_base_libdir}/firmware' install-nodedup
|
||||
cp GPL-2 LICEN[CS]E.* WHENCE ${D}${nonarch_base_libdir}/firmware/
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user