summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorP Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>2023-07-08 01:05:27 +0300
committerP Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>2023-12-31 16:58:43 +0300
commit7f53998bd3726c808abf8b0c4950e25db29d9ea2 (patch)
tree72543541bb498087ff726a8996bddebfe87229ac
parent9ad1806592d6c8e3111b9c26db1882f2af49d64c (diff)
downloadopenbmc-7f53998bd3726c808abf8b0c4950e25db29d9ea2.tar.xz
Update to internal 1-1.11-1
Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
-rw-r--r--meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/u-boot-aspeed-sdk_%.bbappend6
-rw-r--r--meta-openbmc-mods/meta-common/classes/github-releases.bbclass3
-rw-r--r--meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi/CVE-2023-1981.patch53
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0003-Add-support-for-io_pgetevents_time64-syscall.patch62
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0004-Fixup-support-for-io_pgetevents_time64-syscall.patch99
-rw-r--r--meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1u.bb (renamed from meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1l.bb)55
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/busybox/busybox/CVE-2022-30065.patch48
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/busybox/busybox_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42010.patch114
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42011.patch55
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42012.patch71
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/dbus/dbus_%.bbappend6
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/expat/expat/CVE-2022-43680.patch109
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/expat/expat_2.4.5.bb1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2021-3998.patch173
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2023-0687.patch77
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/glibc/glibc_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40303.patch618
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40304.patch101
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses.inc327
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-Fix-heap-buffer-overflow-in-captoinfo.patch47
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-patch-20230408-CVE-2023-29491.patch1432
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-tic-hang.patch43
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-Fix-added-to-mitigate-CVE-2022-29458.patch65
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-configure-reproducible.patch33
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0003-gen-pkgconfig.in-Do-not-include-LDFLAGS-in-generated.patch30
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/exit_prototype.patch32
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_%.bbappend4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_6.4.bb20
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/CVE-2022-3821.patch24
-rw-r--r--meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-devtools/python/python3_%.bbappend4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality/pwquality.conf7
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality_%.bbappend15
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/0001-run-xtests.sh-check-whether-files-exist.patch65
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/99_pam1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/CVE-2022-28321-0002.patch205
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.service10
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.sh48
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/faillock.conf2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/libpam-xtests.patch37
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam-volatiles.conf1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-account27
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-auth26
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-password27
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session19
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session-noninteractive19
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/other24
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/run-ptest32
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_%.bbappend74
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_1.5.2.bb186
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/CVE-2022-24903.patch164
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend6
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_1.patch42
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_2.patch58
-rw-r--r--meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow_%.bbappend4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0004-soc-aspeed-lpc-mbox-Don-t-allow-partial-reads.patch40
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0005-ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr-h.patch42
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2020-36516.patch62
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2978.patch62
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3543.patch97
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3623.patch175
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-42703.patch169
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-1.patch107
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-2.patch40
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-0394.patch43
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1073.patch34
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1077.patch50
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1252.patch89
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1582.patch228
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2269.patch56
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2513.patch120
-rw-r--r--meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend17
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/0008-dynamic-threshold-configuration-for-SOLUM-PSU.patch90
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/0001-add-Associations-endpoints-change-delay-timer.patch978
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd/0001-Avoid-negated-postcode-write-to-D-Bus.patch58
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_%.bbappend9
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_git.bbappend4
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0009-virtual_media-Fix-for-bmcweb-crash.patch47
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb2
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0017-psusensor-Determine-PSU-threshold-dynamically.patch160
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0001-Change-to-pam_faillock-and-pam-pwquality.patch492
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue/0001-Old-password-input-in-change-password-screen.patch135
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue_%.bbappend1
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl/0001-replace-krb5-config-with-pkg-config.patch44
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32205-cookie-apply-limits.patch171
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32206-return-error-on-too-many-compression-steps.patch48
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32207-fopen-add-Curl_fopen-for-better-overwriting-of-fi.patch280
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32208-krb5-return-error-properly-on-decode-errors.patch64
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl/disable-tests28
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl/run-ptest6
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/curl/curl_8.1.0.bb (renamed from meta-openbmc-mods/meta-common/recipes-support/curl/curl_7.83.1.bb)73
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-ensure-the-XATTR_NAME_CAPS-is-defined-when-it-is-use.patch32
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-nativesdk-libcap-Raise-the-size-of-arrays-containing.patch34
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/libcap/files/0002-tests-do-not-run-target-executables.patch30
-rw-r--r--meta-openbmc-mods/meta-common/recipes-support/libcap/libcap_2.69.bb79
104 files changed, 8350 insertions, 771 deletions
diff --git a/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/u-boot-aspeed-sdk_%.bbappend b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/u-boot-aspeed-sdk_%.bbappend
index 22f2eb540..d1b1ca9bc 100644
--- a/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/u-boot-aspeed-sdk_%.bbappend
+++ b/meta-openbmc-mods/meta-ast2600/recipes-bsp/u-boot/u-boot-aspeed-sdk_%.bbappend
@@ -41,7 +41,6 @@ SRC_URI:append:intel-ast2600 = " \
file://0034-Implement-the-IPMI-commands-in-FFUJ-mode-in-u-boot.patch \
file://0036-Disable-BMC-MMIO-Decode-on-VGA-SCU-register-bit.patch \
file://0037-Enable-I2C-clock-stretching-and-multi-master-support.patch \
- file://0038-Disabling-serial-console-if-FFUJ-is-enabled.patch \
file://0044-Enable-WDT2-for-causing-reset-in-Kernel-u-boot-hang.patch \
"
@@ -103,12 +102,13 @@ PFR_SRC_URI = " \
file://0045-PFR-Skip-counting-WDT2-event-when-EXTRST-is-set.patch \
"
-AUTOBOOT_SRC_URI = " \
+U_BOOT_RELEASE_FEATURE = " \
file://0035-Remove-u-boot-delay-before-autoboot-in-release-image.patch \
+ file://0038-Disabling-serial-console-if-FFUJ-is-enabled.patch \
"
SRC_URI:append:intel-ast2600 += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', PFR_SRC_URI, '', d)}"
-SRC_URI:append:intel-ast2600 += "${@bb.utils.contains('EXTRA_IMAGE_FEATURES', 'debug-tweaks', '', AUTOBOOT_SRC_URI, d)}"
+SRC_URI:append:intel-ast2600 += "${@bb.utils.contains('EXTRA_IMAGE_FEATURES', 'debug-tweaks', '', U_BOOT_RELEASE_FEATURE, d)}"
do_install:append () {
install -m 0644 ${WORKDIR}/fw_env.config ${D}${sysconfdir}/fw_env.config
diff --git a/meta-openbmc-mods/meta-common/classes/github-releases.bbclass b/meta-openbmc-mods/meta-common/classes/github-releases.bbclass
new file mode 100644
index 000000000..ed83b8373
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/classes/github-releases.bbclass
@@ -0,0 +1,3 @@
+GITHUB_BASE_URI ?= "https://github.com/${BPN}/${BPN}/releases/"
+UPSTREAM_CHECK_URI ?= "${GITHUB_BASE_URI}"
+UPSTREAM_CHECK_REGEX ?= "releases/tag/v?(?P<pver>\d+(\.\d+)+)"
diff --git a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
index b0227e381..fe1e2b30d 100644
--- a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
+++ b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass
@@ -76,7 +76,6 @@ IMAGE_INSTALL:append = " \
configure-usb-c \
zip \
peci-pcie \
- collectd \
"
IMAGE_INSTALL:append = " ${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', 'pfr-manager', '', d)}"
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi/CVE-2023-1981.patch b/meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi/CVE-2023-1981.patch
new file mode 100644
index 000000000..d1f05b7b7
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi/CVE-2023-1981.patch
@@ -0,0 +1,53 @@
+From a2696da2f2c50ac43b6c4903f72290d5c3fa9f6f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
+Date: Thu, 17 Nov 2022 01:51:53 +0100
+Subject: [PATCH] Emit error if requested service is not found
+
+It currently just crashes instead of replying with error. Check return
+value and emit error instead of passing NULL pointer to reply.
+
+Fixes #375
+---
+ avahi-daemon/dbus-protocol.c | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c
+index 70d7687bc..406d0b441 100644
+--- a/avahi-daemon/dbus-protocol.c
++++ b/avahi-daemon/dbus-protocol.c
+@@ -375,10 +375,14 @@ static DBusHandlerResult dbus_get_alternative_host_name(DBusConnection *c, DBusM
+ }
+
+ t = avahi_alternative_host_name(n);
+- avahi_dbus_respond_string(c, m, t);
+- avahi_free(t);
++ if (t) {
++ avahi_dbus_respond_string(c, m, t);
++ avahi_free(t);
+
+- return DBUS_HANDLER_RESULT_HANDLED;
++ return DBUS_HANDLER_RESULT_HANDLED;
++ } else {
++ return avahi_dbus_respond_error(c, m, AVAHI_ERR_NOT_FOUND, "Hostname not found");
++ }
+ }
+
+ static DBusHandlerResult dbus_get_alternative_service_name(DBusConnection *c, DBusMessage *m, DBusError *error) {
+@@ -389,10 +393,14 @@ static DBusHandlerResult dbus_get_alternative_service_name(DBusConnection *c, DB
+ }
+
+ t = avahi_alternative_service_name(n);
+- avahi_dbus_respond_string(c, m, t);
+- avahi_free(t);
++ if (t) {
++ avahi_dbus_respond_string(c, m, t);
++ avahi_free(t);
+
+- return DBUS_HANDLER_RESULT_HANDLED;
++ return DBUS_HANDLER_RESULT_HANDLED;
++ } else {
++ return avahi_dbus_respond_error(c, m, AVAHI_ERR_NOT_FOUND, "Service not found");
++ }
+ }
+
+ static DBusHandlerResult dbus_create_new_entry_group(DBusConnection *c, DBusMessage *m, DBusError *error) {
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi_%.bbappend b/meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi_%.bbappend
index fa58d9726..06343a29d 100644
--- a/meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/avahi/avahi_%.bbappend
@@ -1,4 +1,5 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += " \
+ file://CVE-2023-1981.patch \
"
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0003-Add-support-for-io_pgetevents_time64-syscall.patch b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0003-Add-support-for-io_pgetevents_time64-syscall.patch
new file mode 100644
index 000000000..d62b9344c
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0003-Add-support-for-io_pgetevents_time64-syscall.patch
@@ -0,0 +1,62 @@
+From 5b5e2985f355c8e99c196d9ce5d02c15bebadfbc Mon Sep 17 00:00:00 2001
+From: Alistair Francis <alistair.francis@wdc.com>
+Date: Thu, 29 Aug 2019 13:56:21 -0700
+Subject: [PATCH] Add support for io_pgetevents_time64 syscall
+
+32-bit architectures that are y2038 safe don't include syscalls that use
+32-bit time_t. Instead these architectures have suffixed syscalls that
+always use a 64-bit time_t. In the case of the io_getevents syscall the
+syscall has been replaced with the io_pgetevents_time64 syscall instead.
+
+This patch changes the io_getevents() function to use the correct
+syscall based on the avaliable syscalls and the time_t size. We will
+only use the new 64-bit time_t syscall if the architecture is using a
+64-bit time_t. This is to avoid having to deal with 32/64-bit
+conversions and relying on a 64-bit timespec struct on 32-bit time_t
+platforms. As of Linux 5.3 there are no 32-bit time_t architectures
+without __NR_io_getevents. In the future if a 32-bit time_t architecture
+wants to use the 64-bit syscalls we can handle the conversion.
+
+This fixes build failures on 32-bit RISC-V.
+
+Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
+
+Reviewed-by: Richard Levitte <levitte@openssl.org>
+Reviewed-by: Paul Dale <paul.dale@oracle.com>
+(Merged from https://github.com/openssl/openssl/pull/9819)
+Upstream-Status: Accepted
+---
+ engines/e_afalg.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/engines/e_afalg.c b/engines/e_afalg.c
+index dacbe358cb..99516cb1bb 100644
+--- a/engines/e_afalg.c
++++ b/engines/e_afalg.c
+@@ -125,7 +125,23 @@ static ossl_inline int io_getevents(aio_context_t ctx, long min, long max,
+ struct io_event *events,
+ struct timespec *timeout)
+ {
++#if defined(__NR_io_getevents)
+ return syscall(__NR_io_getevents, ctx, min, max, events, timeout);
++#elif defined(__NR_io_pgetevents_time64)
++ /* Let's only support the 64 suffix syscalls for 64-bit time_t.
++ * This simplifies the code for us as we don't need to use a 64-bit
++ * version of timespec with a 32-bit time_t and handle converting
++ * between 64-bit and 32-bit times and check for overflows.
++ */
++ if (sizeof(timeout->tv_sec) == 8)
++ return syscall(__NR_io_pgetevents_time64, ctx, min, max, events, timeout, NULL);
++ else {
++ errno = ENOSYS;
++ return -1;
++ }
++#else
++# error "We require either the io_getevents syscall or __NR_io_pgetevents_time64."
++#endif
+ }
+
+ static void afalg_waitfd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key,
+--
+2.30.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0004-Fixup-support-for-io_pgetevents_time64-syscall.patch b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0004-Fixup-support-for-io_pgetevents_time64-syscall.patch
new file mode 100644
index 000000000..c8bc6f5c6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl/0004-Fixup-support-for-io_pgetevents_time64-syscall.patch
@@ -0,0 +1,99 @@
+From e5499a3cac1e823c3e0697e8667e952317b70cc8 Mon Sep 17 00:00:00 2001
+From: Alistair Francis <alistair.francis@wdc.com>
+Date: Thu, 4 Mar 2021 12:10:11 -0500
+Subject: [PATCH] Fixup support for io_pgetevents_time64 syscall
+
+This is a fixup for the original commit 5b5e2985f355c8e99c196d9ce5d02c15bebadfbc
+"Add support for io_pgetevents_time64 syscall" that didn't correctly
+work for 32-bit architecutres with a 64-bit time_t that aren't RISC-V.
+
+For a full discussion of the issue see:
+https://github.com/openssl/openssl/commit/5b5e2985f355c8e99c196d9ce5d02c15bebadfbc
+
+Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
+
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+Reviewed-by: Paul Dale <pauli@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/14432)
+Upstream-Status: Accepted
+---
+ engines/e_afalg.c | 55 ++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 42 insertions(+), 13 deletions(-)
+
+diff --git a/engines/e_afalg.c b/engines/e_afalg.c
+index 9480d7c24b..4e9d67db2d 100644
+--- a/engines/e_afalg.c
++++ b/engines/e_afalg.c
+@@ -124,27 +124,56 @@ static ossl_inline int io_read(aio_context_t ctx, long n, struct iocb **iocb)
+ return syscall(__NR_io_submit, ctx, n, iocb);
+ }
+
++/* A version of 'struct timespec' with 32-bit time_t and nanoseconds. */
++struct __timespec32
++{
++ __kernel_long_t tv_sec;
++ __kernel_long_t tv_nsec;
++};
++
+ static ossl_inline int io_getevents(aio_context_t ctx, long min, long max,
+ struct io_event *events,
+ struct timespec *timeout)
+ {
++#if defined(__NR_io_pgetevents_time64)
++ /* Check if we are a 32-bit architecture with a 64-bit time_t */
++ if (sizeof(*timeout) != sizeof(struct __timespec32)) {
++ int ret = syscall(__NR_io_pgetevents_time64, ctx, min, max, events,
++ timeout, NULL);
++ if (ret == 0 || errno != ENOSYS)
++ return ret;
++ }
++#endif
++
+ #if defined(__NR_io_getevents)
+- return syscall(__NR_io_getevents, ctx, min, max, events, timeout);
+-#elif defined(__NR_io_pgetevents_time64)
+- /* Let's only support the 64 suffix syscalls for 64-bit time_t.
+- * This simplifies the code for us as we don't need to use a 64-bit
+- * version of timespec with a 32-bit time_t and handle converting
+- * between 64-bit and 32-bit times and check for overflows.
+- */
+- if (sizeof(timeout->tv_sec) == 8)
+- return syscall(__NR_io_pgetevents_time64, ctx, min, max, events, timeout, NULL);
++ if (sizeof(*timeout) == sizeof(struct __timespec32))
++ /*
++ * time_t matches our architecture length, we can just use
++ * __NR_io_getevents
++ */
++ return syscall(__NR_io_getevents, ctx, min, max, events, timeout);
+ else {
+- errno = ENOSYS;
+- return -1;
++ /*
++ * We don't have __NR_io_pgetevents_time64, but we are using a
++ * 64-bit time_t on a 32-bit architecture. If we can fit the
++ * timeout value in a 32-bit time_t, then let's do that
++ * and then use the __NR_io_getevents syscall.
++ */
++ if (timeout && timeout->tv_sec == (long)timeout->tv_sec) {
++ struct __timespec32 ts32;
++
++ ts32.tv_sec = (__kernel_long_t) timeout->tv_sec;
++ ts32.tv_nsec = (__kernel_long_t) timeout->tv_nsec;
++
++ return syscall(__NR_io_getevents, ctx, min, max, events, ts32);
++ } else {
++ return syscall(__NR_io_getevents, ctx, min, max, events, NULL);
++ }
+ }
+-#else
+-# error "We require either the io_getevents syscall or __NR_io_pgetevents_time64."
+ #endif
++
++ errno = ENOSYS;
++ return -1;
+ }
+
+ static void afalg_waitfd_cleanup(ASYNC_WAIT_CTX *ctx, const void *key,
+--
+2.30.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1l.bb b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1u.bb
index dc2a8ccff..6e0ad9ac4 100644
--- a/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1l.bb
+++ b/meta-openbmc-mods/meta-common/recipes-connectivity/openssl/openssl_1.1.1u.bb
@@ -11,23 +11,28 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=d343e62fc9c833710bbbed25f27364c8"
DEPENDS = "hostperl-runtime-native"
-SRC_URI = "http://www.openssl.org/source/openssl-${PV}.tar.gz \
+PV = "1.0+git${SRCPV}"
+
+S = "${WORKDIR}/git"
+
+SRCREV = "3f499b24f3bcd66db022074f7e8b4f6ee266a3ae"
+
+SRC_URI = "git://github.com/openssl/openssl.git;branch=OpenSSL_1_1_1-stable;protocol=https \
file://run-ptest \
file://0001-skip-test_symbol_presence.patch \
file://0001-buildinfo-strip-sysroot-and-debug-prefix-map-from-co.patch \
file://afalg.patch \
file://reproducible.patch \
- file://CVE-2022-0778.patch \
- file://CVE-2022-1292-Fix-openssl-c_rehash.patch \
- file://CVE-2022-2068-Fix-file-operations-in-c_rehash.patch \
- file://CVE-2022-2097-openssl-Fix-AES-OCB-encryptdecrypt-for-x86-AES-NI.patch \
"
SRC_URI:append:class-nativesdk = " \
file://environment.d-openssl.sh \
"
-SRC_URI[sha256sum] = "0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1"
+SRC_URI:append:riscv32 = " \
+ file://0003-Add-support-for-io_pgetevents_time64-syscall.patch \
+ file://0004-Fixup-support-for-io_pgetevents_time64-syscall.patch \
+ "
inherit lib_package multilib_header multilib_script ptest
MULTILIB_SCRIPTS = "${PN}-bin:${bindir}/c_rehash"
@@ -37,6 +42,8 @@ PACKAGECONFIG:class-native = ""
PACKAGECONFIG:class-nativesdk = ""
PACKAGECONFIG[cryptodev-linux] = "enable-devcryptoeng,disable-devcryptoeng,cryptodev-linux,,cryptodev-module"
+PACKAGECONFIG[no-tls1] = "no-tls1"
+PACKAGECONFIG[no-tls1_1] = "no-tls1_1"
B = "${WORKDIR}/build"
do_configure[cleandirs] = "${B}"
@@ -56,6 +63,20 @@ EXTRA_OECONF:class-nativesdk = "--with-rand-seed=os,devrandom"
CFLAGS:append:class-native = " -DOPENSSLDIR=/not/builtin -DENGINESDIR=/not/builtin"
CFLAGS:append:class-nativesdk = " -DOPENSSLDIR=/not/builtin -DENGINESDIR=/not/builtin"
+# Disable deprecated crypto algorithms
+# Retained for compatibilty
+# des (curl)
+# dh (python-ssl)
+# dsa (rpm)
+# md4 (cyrus-sasl freeradius hostapd)
+# bf (wvstreams postgresql x11vnc crda znc cfengine)
+# rc4 (freerdp librtorrent ettercap xrdp transmission pam-ssh-agent-auth php)
+# rc2 (mailx)
+# psk (qt5)
+# srp (libest)
+# whirlpool (qca)
+DEPRECATED_CRYPTO_FLAGS = "no-ssl no-idea no-rc5 no-md2 no-camellia no-mdc2 no-scrypt no-seed no-siphash no-sm2 no-sm3 no-sm4"
+
do_configure () {
os=${HOST_OS}
case $os in
@@ -117,6 +138,9 @@ do_configure () {
linux-sparc | linux-supersparc)
target=linux-sparcv9
;;
+ mingw32-x86_64)
+ target=mingw64
+ ;;
esac
useprefix=${prefix}
@@ -126,7 +150,7 @@ do_configure () {
# WARNING: do not set compiler/linker flags (-I/-D etc.) in EXTRA_OECONF, as they will fully replace the
# environment variables set by bitbake. Adjust the environment variables instead.
HASHBANGPERL="/usr/bin/env perl" PERL=perl PERL5LIB="${S}/external/perl/Text-Template-1.46/lib/" \
- perl ${S}/Configure ${EXTRA_OECONF} ${PACKAGECONFIG_CONFARGS} --prefix=$useprefix --openssldir=${libdir}/ssl-1.1 --libdir=${libdir} $target
+ perl ${S}/Configure ${EXTRA_OECONF} ${PACKAGECONFIG_CONFARGS} ${DEPRECATED_CRYPTO_FLAGS} --prefix=$useprefix --openssldir=${libdir}/ssl-1.1 --libdir=${libdir} $target
perl ${B}/configdata.pm --dump
}
@@ -184,6 +208,10 @@ do_install_ptest () {
install -d ${D}${PTEST_PATH}/engines
install -m755 ${B}/engines/ossltest.so ${D}${PTEST_PATH}/engines
+
+ # seems to be needed with perl 5.32.1
+ install -d ${D}${PTEST_PATH}/util/perl/recipes
+ cp ${D}${PTEST_PATH}/test/recipes/tconversion.pl ${D}${PTEST_PATH}/util/perl/recipes/
}
# Add the openssl.cnf file to the openssl-conf package. Make the libcrypto
@@ -195,21 +223,30 @@ PACKAGES =+ "libcrypto libssl openssl-conf ${PN}-engines ${PN}-misc"
FILES:libcrypto = "${libdir}/libcrypto${SOLIBS}"
FILES:libssl = "${libdir}/libssl${SOLIBS}"
-FILES:openssl-conf = "${sysconfdir}/ssl/openssl.cnf"
+FILES:openssl-conf = "${sysconfdir}/ssl/openssl.cnf \
+ ${libdir}/ssl-1.1/openssl.cnf* \
+ "
FILES:${PN}-engines = "${libdir}/engines-1.1"
-FILES:${PN}-misc = "${libdir}/ssl-1.1/misc"
+# ${prefix} comes from what we pass into --prefix at configure time (which is used for INSTALLTOP)
+FILES:${PN}-engines:append:mingw32:class-nativesdk = " ${prefix}${libdir}/engines-1_1"
+FILES:${PN}-misc = "${libdir}/ssl-1.1/misc ${bindir}/c_rehash"
FILES:${PN} =+ "${libdir}/ssl-1.1/*"
FILES:${PN}:append:class-nativesdk = " ${SDKPATHNATIVE}/environment-setup.d/openssl.sh"
CONFFILES:openssl-conf = "${sysconfdir}/ssl/openssl.cnf"
RRECOMMENDS:libcrypto += "openssl-conf"
+RDEPENDS:${PN}-misc = "perl"
RDEPENDS:${PN}-ptest += "openssl-bin perl perl-modules bash"
+RDEPENDS:${PN}-bin += "openssl-conf"
+
BBCLASSEXTEND = "native nativesdk"
CVE_PRODUCT = "openssl:openssl"
+CVE_VERSION_SUFFIX = "alphabetical"
+
# Only affects OpenSSL >= 1.1.1 in combination with Apache < 2.4.37
# Apache in meta-webserver is already recent enough
CVE_CHECK_WHITELIST += "CVE-2019-0190"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/busybox/busybox/CVE-2022-30065.patch b/meta-openbmc-mods/meta-common/recipes-core/busybox/busybox/CVE-2022-30065.patch
new file mode 100644
index 000000000..2f23931be
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/busybox/busybox/CVE-2022-30065.patch
@@ -0,0 +1,48 @@
+From 4bae4300986d0ed3d43f92600bd291ae3d302a99 Mon Sep 17 00:00:00 2001
+From: Yaswanth Reddy M <yaswanthx.reddy.munukuru@intel.com>
+Date: Fri, 5 May 2023 08:55:31 +0000
+Subject: [PATCH] Subject: awk: fix use after free (CVE-2022-30065)
+
+fixes https://bugs.busybox.net/show_bug.cgi?id=14781
+
+function old new delta
+evaluate 3343 3357 +14
+
+Signed-off-by: Yaswanth Reddy M <yaswanthx.reddy.munukuru@intel.com>
+---
+ editors/awk.c | 3 +++
+ testsuite/awk.tests | 5 +++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/editors/awk.c b/editors/awk.c
+index 3adbca7..43a17c0 100644
+--- a/editors/awk.c
++++ b/editors/awk.c
+@@ -3094,6 +3094,9 @@ static var *evaluate(node *op, var *res)
+
+ case XC( OC_MOVE ):
+ debug_printf_eval("MOVE\n");
++ /* make sure that we never return a temp var */
++ if (L.v == TMPVAR0)
++ L.v = res;
+ /* if source is a temporary string, jusk relink it to dest */
+ if (R.v == TMPVAR1
+ && !(R.v->type & VF_NUMBER)
+diff --git a/testsuite/awk.tests b/testsuite/awk.tests
+index dc2ae2e..072c8fc 100755
+--- a/testsuite/awk.tests
++++ b/testsuite/awk.tests
+@@ -462,5 +462,10 @@ testing "awk \"cmd\" | getline" \
+ "awk 'BEGIN { \"echo HELLO\" | getline; print }'" \
+ "HELLO\n" \
+ '' ''
++testing 'awk assign while test' \
++ "awk '\$1==\$1=\"foo\" {print \$1}'" \
++ "foo\n" \
++ "" \
++ "foo"
+
+ exit $FAILCOUNT
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/busybox/busybox_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/busybox/busybox_%.bbappend
index 42a52e0d7..b9c654068 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/busybox/busybox_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/busybox/busybox_%.bbappend
@@ -4,6 +4,7 @@ SRC_URI += " \
file://enable.cfg \
file://CVE-2022-28391_1.patch \
file://CVE-2022-28391_2.patch \
+ file://CVE-2022-30065.patch \
"
SRC_URI += "${@bb.utils.contains('EXTRA_IMAGE_FEATURES', 'debug-tweaks','file://dev-only.cfg','',d)}"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42010.patch b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42010.patch
new file mode 100644
index 000000000..d2693ed69
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42010.patch
@@ -0,0 +1,114 @@
+From 9d07424e9011e3bbe535e83043d335f3093d2916 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv@collabora.com>
+Date: Tue, 13 Sep 2022 15:10:22 +0100
+Subject: [PATCH] dbus-marshal-validate: Check brackets in signature nest
+correctly
+
+In debug builds with assertions enabled, a signature with incorrectly
+nested `()` and `{}`, for example `a{i(u}` or `(a{ii)}`, could result
+in an assertion failure.
+
+In production builds without assertions enabled, a signature with
+incorrectly nested `()` and `{}` could potentially result in a crash
+or incorrect message parsing, although we do not have a concrete example
+of either of these failure modes.
+
+Thanks: Evgeny Vereshchagin
+Resolves: https://gitlab.freedesktop.org/dbus/dbus/-/issues/418
+Resolves: CVE-2022-42010
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+---
+ dbus/dbus-marshal-validate.c | 38 +++++++++++++++++++++++++++++++++++-
+ 1 file changed, 37 insertions(+), 1 deletion(-)
+
+diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c
+index 4d492f3f3..ae68414dd 100644
+--- a/dbus/dbus-marshal-validate.c
++++ b/dbus/dbus-marshal-validate.c
+@@ -62,6 +62,8 @@ _dbus_validate_signature_with_reason (const DBusString *type_str,
+
+ int element_count;
+ DBusList *element_count_stack;
++ char opened_brackets[DBUS_MAXIMUM_TYPE_RECURSION_DEPTH * 2 + 1] = { '\0' };
++ char last_bracket;
+
+ result = DBUS_VALID;
+ element_count_stack = NULL;
+@@ -93,6 +95,10 @@ _dbus_validate_signature_with_reason (const DBusString *type_str,
+
+ while (p != end)
+ {
++ _dbus_assert (struct_depth + dict_entry_depth >= 0);
++ _dbus_assert (struct_depth + dict_entry_depth < _DBUS_N_ELEMENTS (opened_brackets));
++ _dbus_assert (opened_brackets[struct_depth + dict_entry_depth] == '\0');
++
+ switch (*p)
+ {
+ case DBUS_TYPE_BYTE:
+@@ -136,6 +142,10 @@ _dbus_validate_signature_with_reason (const DBusString *type_str,
+ goto out;
+ }
+
++ _dbus_assert (struct_depth + dict_entry_depth >= 1);
++ _dbus_assert (struct_depth + dict_entry_depth < _DBUS_N_ELEMENTS (opened_brackets));
++ _dbus_assert (opened_brackets[struct_depth + dict_entry_depth - 1] == '\0');
++ opened_brackets[struct_depth + dict_entry_depth - 1] = DBUS_STRUCT_BEGIN_CHAR;
+ break;
+
+ case DBUS_STRUCT_END_CHAR:
+@@ -151,9 +161,20 @@ _dbus_validate_signature_with_reason (const DBusString *type_str,
+ goto out;
+ }
+
++ _dbus_assert (struct_depth + dict_entry_depth >= 1);
++ _dbus_assert (struct_depth + dict_entry_depth < _DBUS_N_ELEMENTS (opened_brackets));
++ last_bracket = opened_brackets[struct_depth + dict_entry_depth - 1];
++
++ if (last_bracket != DBUS_STRUCT_BEGIN_CHAR)
++ {
++ result = DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED;
++ goto out;
++ }
++
+ _dbus_list_pop_last (&element_count_stack);
+
+ struct_depth -= 1;
++ opened_brackets[struct_depth + dict_entry_depth] = '\0';
+ break;
+
+ case DBUS_DICT_ENTRY_BEGIN_CHAR:
+@@ -178,6 +199,10 @@ _dbus_validate_signature_with_reason (const DBusString *type_str,
+ goto out;
+ }
+
++ _dbus_assert (struct_depth + dict_entry_depth >= 1);
++ _dbus_assert (struct_depth + dict_entry_depth < _DBUS_N_ELEMENTS (opened_brackets));
++ _dbus_assert (opened_brackets[struct_depth + dict_entry_depth - 1] == '\0');
++ opened_brackets[struct_depth + dict_entry_depth - 1] = DBUS_DICT_ENTRY_BEGIN_CHAR;
+ break;
+
+ case DBUS_DICT_ENTRY_END_CHAR:
+@@ -186,8 +211,19 @@ _dbus_validate_signature_with_reason (const DBusString *type_str,
+ result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
+ goto out;
+ }
+-
++
++ _dbus_assert (struct_depth + dict_entry_depth >= 1);
++ _dbus_assert (struct_depth + dict_entry_depth < _DBUS_N_ELEMENTS (opened_brackets));
++ last_bracket = opened_brackets[struct_depth + dict_entry_depth - 1];
++
++ if (last_bracket != DBUS_DICT_ENTRY_BEGIN_CHAR)
++ {
++ result = DBUS_INVALID_DICT_ENTRY_ENDED_BUT_NOT_STARTED;
++ goto out;
++ }
++
+ dict_entry_depth -= 1;
++ opened_brackets[struct_depth + dict_entry_depth] = '\0';
+
+ element_count =
+ _DBUS_POINTER_TO_INT (_dbus_list_pop_last (&element_count_stack));
+--
+GitLab
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42011.patch b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42011.patch
new file mode 100644
index 000000000..9284dd666
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42011.patch
@@ -0,0 +1,55 @@
+From 079bbf16186e87fb0157adf8951f19864bc2ed69 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv@collabora.com>
+Date: Mon, 12 Sep 2022 13:14:18 +0100
+Subject: [PATCH] dbus-marshal-validate: Validate length of arrays of
+ fixed-length items
+
+This fast-path previously did not check that the array was made up
+of an integer number of items. This could lead to assertion failures
+and out-of-bounds accesses during subsequent message processing (which
+assumes that the message has already been validated), particularly after
+the addition of _dbus_header_remove_unknown_fields(), which makes it
+more likely that dbus-daemon will apply non-trivial edits to messages.
+
+Thanks: Evgeny Vereshchagin
+Fixes: e61f13cf "Bug 18064 - more efficient validation for fixed-size type arrays"
+Resolves: https://gitlab.freedesktop.org/dbus/dbus/-/issues/413
+Resolves: CVE-2022-42011
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+---
+ dbus/dbus-marshal-validate.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/dbus/dbus-marshal-validate.c b/dbus/dbus-marshal-validate.c
+index ae68414dd..7d0d6cf72 100644
+--- a/dbus/dbus-marshal-validate.c
++++ b/dbus/dbus-marshal-validate.c
+@@ -503,13 +503,24 @@ validate_body_helper (DBusTypeReader *reader,
+ */
+ if (dbus_type_is_fixed (array_elem_type))
+ {
++ /* Note that fixed-size types all have sizes equal to
++ * their alignments, so this is really the item size. */
++ alignment = _dbus_type_get_alignment (array_elem_type);
++ _dbus_assert (alignment == 1 || alignment == 2 ||
++ alignment == 4 || alignment == 8);
++
++ /* Because the alignment is a power of 2, this is
++ * equivalent to: (claimed_len % alignment) != 0,
++ * but avoids slower integer division */
++ if ((claimed_len & (alignment - 1)) != 0)
++ return DBUS_INVALID_ARRAY_LENGTH_INCORRECT;
++
+ /* bools need to be handled differently, because they can
+ * have an invalid value
+ */
+ if (array_elem_type == DBUS_TYPE_BOOLEAN)
+ {
+ dbus_uint32_t v;
+- alignment = _dbus_type_get_alignment (array_elem_type);
+
+ while (p < array_end)
+ {
+--
+GitLab
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42012.patch b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42012.patch
new file mode 100644
index 000000000..53b0e92ff
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus/CVE-2022-42012.patch
@@ -0,0 +1,71 @@
+From 236f16e444e88a984cf12b09225e0f8efa6c5b44 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv@collabora.com>
+Date: Fri, 30 Sep 2022 13:46:31 +0100
+Subject: [PATCH] dbus-marshal-byteswap: Byte-swap Unix fd indexes if needed
+
+When a D-Bus message includes attached file descriptors, the body of the
+message contains unsigned 32-bit indexes pointing into an out-of-band
+array of file descriptors. Some D-Bus APIs like GLib's GDBus refer to
+these indexes as "handles" for the associated fds (not to be confused
+with a Windows HANDLE, which is a kernel object).
+
+The assertion message removed by this commit is arguably correct up to
+a point: fd-passing is only reasonable on a local machine, and no known
+operating system allows processes of differing endianness even on a
+multi-endian ARM or PowerPC CPU, so it makes little sense for the sender
+to specify a byte-order that differs from the byte-order of the recipient.
+
+However, this doesn't account for the fact that a malicious sender
+doesn't have to restrict itself to only doing things that make sense.
+On a system with untrusted local users, a message sender could crash
+the system dbus-daemon (a denial of service) by sending a message in
+the opposite endianness that contains handles to file descriptors.
+
+Before this commit, if assertions are enabled, attempting to byteswap
+a fd index would cleanly crash the message recipient with an assertion
+failure. If assertions are disabled, attempting to byteswap a fd index
+would silently do nothing without advancing the pointer p, causing the
+message's type and the pointer into its contents to go out of sync, which
+can result in a subsequent crash (the crash demonstrated by fuzzing was
+a use-after-free, but other failure modes might be possible).
+
+In principle we could resolve this by rejecting wrong-endianness messages
+from a local sender, but it's actually simpler and less code to treat
+wrong-endianness messages as valid and byteswap them.
+
+Thanks: Evgeny Vereshchagin
+Fixes: ba7daa60 "unix-fd: add basic marshalling code for unix fds"
+Resolves: https://gitlab.freedesktop.org/dbus/dbus/-/issues/417
+Resolves: CVE-2022-42012
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+---
+ dbus/dbus-marshal-byteswap.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/dbus/dbus-marshal-byteswap.c b/dbus/dbus-marshal-byteswap.c
+index e9de6f02a..9dd1246f9 100644
+--- a/dbus/dbus-marshal-byteswap.c
++++ b/dbus/dbus-marshal-byteswap.c
+@@ -62,6 +62,7 @@ byteswap_body_helper (DBusTypeReader *reader,
+ case DBUS_TYPE_BOOLEAN:
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
++ case DBUS_TYPE_UNIX_FD:
+ {
+ p = _DBUS_ALIGN_ADDRESS (p, 4);
+ *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
+@@ -192,11 +193,6 @@ byteswap_body_helper (DBusTypeReader *reader,
+ }
+ break;
+
+- case DBUS_TYPE_UNIX_FD:
+- /* fds can only be passed on a local machine, so byte order must always match */
+- _dbus_assert_not_reached("attempted to byteswap unix fds which makes no sense");
+- break;
+-
+ default:
+ _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
+ break;
+--
+GitLab
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus_%.bbappend
new file mode 100644
index 000000000..af073e92a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/dbus/dbus_%.bbappend
@@ -0,0 +1,6 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+SRC_URI += " \
+ file://CVE-2022-42010.patch \
+ file://CVE-2022-42011.patch \
+ file://CVE-2022-42012.patch \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-core/expat/expat/CVE-2022-43680.patch b/meta-openbmc-mods/meta-common/recipes-core/expat/expat/CVE-2022-43680.patch
new file mode 100644
index 000000000..b19647736
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/expat/expat/CVE-2022-43680.patch
@@ -0,0 +1,109 @@
+From 5290462a7ea1278a8d5c0d5b2860d4e244f997e4 Mon Sep 17 00:00:00 2001
+From: Sebastian Pipping <sebastian@pipping.org>
+Date: Tue, 20 Sep 2022 02:44:34 +0200
+Subject: [PATCH 1/3] lib: Fix overeager DTD destruction in
+ XML_ExternalEntityParserCreate
+
+---
+ lib/xmlparse.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/lib/xmlparse.c b/lib/xmlparse.c
+index aacd6e7fc..57bf103cc 100644
+--- a/lib/xmlparse.c
++++ b/lib/xmlparse.c
+@@ -1068,6 +1068,14 @@ parserCreate(const XML_Char *encodingName,
+ parserInit(parser, encodingName);
+
+ if (encodingName && ! parser->m_protocolEncodingName) {
++ if (dtd) {
++ // We need to stop the upcoming call to XML_ParserFree from happily
++ // destroying parser->m_dtd because the DTD is shared with the parent
++ // parser and the only guard that keeps XML_ParserFree from destroying
++ // parser->m_dtd is parser->m_isParamEntity but it will be set to
++ // XML_TRUE only later in XML_ExternalEntityParserCreate (or not at all).
++ parser->m_dtd = NULL;
++ }
+ XML_ParserFree(parser);
+ return NULL;
+ }
+
+From 43992e4ae25fc3dc0eec0cd3a29313555d56aee2 Mon Sep 17 00:00:00 2001
+From: Sebastian Pipping <sebastian@pipping.org>
+Date: Mon, 19 Sep 2022 18:16:15 +0200
+Subject: [PATCH 2/3] tests: Cover overeager DTD destruction in
+ XML_ExternalEntityParserCreate
+
+---
+ tests/runtests.c | 49 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 49 insertions(+)
+
+diff --git a/tests/runtests.c b/tests/runtests.c
+index 245fe9bda..acb744dd4 100644
+--- a/tests/runtests.c
++++ b/tests/runtests.c
+@@ -10208,6 +10208,53 @@ START_TEST(test_alloc_long_notation) {
+ }
+ END_TEST
+
++static int XMLCALL
++external_entity_parser_create_alloc_fail_handler(XML_Parser parser,
++ const XML_Char *context,
++ const XML_Char *base,
++ const XML_Char *systemId,
++ const XML_Char *publicId) {
++ UNUSED_P(base);
++ UNUSED_P(systemId);
++ UNUSED_P(publicId);
++
++ if (context != NULL)
++ fail("Unexpected non-NULL context");
++
++ // The following number intends to fail the upcoming allocation in line
++ // "parser->m_protocolEncodingName = copyString(encodingName,
++ // &(parser->m_mem));" in function parserInit.
++ allocation_count = 3;
++
++ const XML_Char *const encodingName = XCS("UTF-8"); // needs something non-NULL
++ const XML_Parser ext_parser
++ = XML_ExternalEntityParserCreate(parser, context, encodingName);
++ if (ext_parser != NULL)
++ fail(
++ "Call to XML_ExternalEntityParserCreate was expected to fail out-of-memory");
++
++ allocation_count = ALLOC_ALWAYS_SUCCEED;
++ return XML_STATUS_ERROR;
++}
++
++START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
++ const char *const text = "<!DOCTYPE doc SYSTEM 'foo'><doc/>";
++
++ XML_SetExternalEntityRefHandler(
++ g_parser, external_entity_parser_create_alloc_fail_handler);
++ XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
++
++ if (XML_Parse(g_parser, text, (int)strlen(text), XML_TRUE)
++ != XML_STATUS_ERROR)
++ fail("Call to parse was expected to fail");
++
++ if (XML_GetErrorCode(g_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
++ fail("Call to parse was expected to fail from the external entity handler");
++
++ XML_ParserReset(g_parser, NULL);
++}
++END_TEST
++
+ static void
+ nsalloc_setup(void) {
+ XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
+@@ -12401,6 +12448,8 @@ make_suite(void) {
+ tcase_add_test(tc_alloc, test_alloc_long_public_id);
+ tcase_add_test(tc_alloc, test_alloc_long_entity_value);
+ tcase_add_test(tc_alloc, test_alloc_long_notation);
++ tcase_add_test__ifdef_xml_dtd(
++ tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
+
+ suite_add_tcase(s, tc_nsalloc);
+ tcase_add_checked_fixture(tc_nsalloc, nsalloc_setup, nsalloc_teardown);
+
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/expat/expat_2.4.5.bb b/meta-openbmc-mods/meta-common/recipes-core/expat/expat_2.4.5.bb
index 852ba0baf..616838aa3 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/expat/expat_2.4.5.bb
+++ b/meta-openbmc-mods/meta-common/recipes-core/expat/expat_2.4.5.bb
@@ -12,6 +12,7 @@ SRC_URI = "https://github.com/libexpat/libexpat/releases/download/R_${VERSION_TA
file://run-ptest \
file://CVE-2022-40674_1.patch \
file://CVE-2022-40674_2.patch \
+ file://CVE-2022-43680.patch \
"
UPSTREAM_CHECK_URI = "https://github.com/libexpat/libexpat/releases/"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2021-3998.patch b/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2021-3998.patch
new file mode 100644
index 000000000..8a6533070
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2021-3998.patch
@@ -0,0 +1,173 @@
+From a48cfb100aa47d349cd1b80d0efcca3231b6bfcd Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Thu, 13 Jan 2022 11:28:36 +0530
+Subject: [PATCH 1/2] realpath: Set errno to ENAMETOOLONG for result larger
+ than PATH_MAX [BZ #28770]
+
+realpath returns an allocated string when the result exceeds PATH_MAX,
+which is unexpected when its second argument is not NULL. This results
+in the second argument (resolved) being uninitialized and also results
+in a memory leak since the caller expects resolved to be the same as the
+returned value.
+
+Return NULL and set errno to ENAMETOOLONG if the result exceeds
+PATH_MAX. This fixes [BZ #28770], which is CVE-2021-3998.
+
+Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit ee8d5e33adb284601c00c94687bc907e10aec9bb)
+(cherry picked from commit f7a79879c0b2bef0dadd6caaaeeb0d26423e04e5
+ with conflict resoluation in stdlib/Makefile and NEWS)
+---
+ NEWS | 4 +++
+ stdlib/Makefile | 2 +-
+ stdlib/canonicalize.c | 12 +++++++--
+ stdlib/tst-realpath-toolong.c | 49 +++++++++++++++++++++++++++++++++++
+ 4 files changed, 64 insertions(+), 3 deletions(-)
+ create mode 100644 stdlib/tst-realpath-toolong.c
+
+diff --git a/NEWS b/NEWS
+index 028ed04ca2..0c3b1c2556 100644
+--- a/NEWS
++++ b/NEWS
+@@ -210,6 +210,10 @@ Security related changes:
+ legacy function could result in a stack-based buffer overflow when
+ using the "unix" protocol. Reported by Martin Sebor.
+
++ CVE-2021-3998: Passing a path longer than PATH_MAX to the realpath
++ function could result in a memory leak and potential access of
++ uninitialized memory. Reported by Qualys.
++
+ The following bugs are resolved with this release:
+
+ [4737] libc: fork is not async-signal-safe
+diff --git a/stdlib/Makefile b/stdlib/Makefile
+index 7c15549caf..22de3867be 100644
+--- a/stdlib/Makefile
++++ b/stdlib/Makefile
+@@ -88,7 +88,7 @@ tests := tst-strtol tst-strtod testmb testrand testsort testdiv \
+ tst-swapcontext1 tst-setcontext4 tst-setcontext5 \
+ tst-setcontext6 tst-setcontext7 tst-setcontext8 \
+ tst-setcontext9 tst-bz20544 tst-canon-bz26341 \
+- tst-realpath
++ tst-realpath tst-realpath-toolong
+
+ tests-internal := tst-strtod1i tst-strtod3 tst-strtod4 tst-strtod5i \
+ tst-tls-atexit tst-tls-atexit-nodelete
+diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
+index cac1f73d74..20033b4885 100644
+--- a/stdlib/canonicalize.c
++++ b/stdlib/canonicalize.c
+@@ -400,8 +400,16 @@ realpath_stk (const char *name, char *resolved,
+
+ error:
+ *dest++ = '\0';
+- if (resolved != NULL && dest - rname <= get_path_max ())
+- rname = strcpy (resolved, rname);
++ if (resolved != NULL)
++ {
++ if (dest - rname <= get_path_max ())
++ rname = strcpy (resolved, rname);
++ else
++ {
++ failed = true;
++ __set_errno (ENAMETOOLONG);
++ }
++ }
+
+ error_nomem:
+ scratch_buffer_free (&extra_buffer);
+diff --git a/stdlib/tst-realpath-toolong.c b/stdlib/tst-realpath-toolong.c
+new file mode 100644
+index 0000000000..8bed772460
+--- /dev/null
++++ b/stdlib/tst-realpath-toolong.c
+@@ -0,0 +1,49 @@
++/* Verify that realpath returns NULL with ENAMETOOLONG if the result exceeds
++ NAME_MAX.
++ 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 <errno.h>
++#include <limits.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <support/check.h>
++#include <support/temp_file.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++
++#define BASENAME "tst-realpath-toolong."
++
++int
++do_test (void)
++{
++ char *base = support_create_and_chdir_toolong_temp_directory (BASENAME);
++
++ char buf[PATH_MAX + 1];
++ const char *res = realpath (".", buf);
++
++ /* canonicalize.c states that if the real path is >= PATH_MAX, then
++ realpath returns NULL and sets ENAMETOOLONG. */
++ TEST_VERIFY (res == NULL);
++ TEST_VERIFY (errno == ENAMETOOLONG);
++
++ free (base);
++ return 0;
++}
++
++#include <support/test-driver.c>
+--
+2.25.1
+
+
+From a4bc5841640e57f8d216e818b07cdd4c74f62815 Mon Sep 17 00:00:00 2001
+From: Siddhesh Poyarekar <siddhesh@sourceware.org>
+Date: Mon, 24 Jan 2022 21:36:41 +0530
+Subject: [PATCH 2/2] realpath: Avoid overwriting preexisting error
+ (CVE-2021-3998)
+
+Set errno and failure for paths that are too long only if no other error
+occurred earlier.
+
+Related: BZ #28770
+
+Reviewed-by: Andreas Schwab <schwab@linux-m68k.org>
+Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
+(cherry picked from commit 84d2d0fe20bdf94feed82b21b4d7d136db471f03)
+(cherry picked from commit d084965adc7baa8ea804427cccf973cea556d697)
+---
+ stdlib/canonicalize.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/stdlib/canonicalize.c b/stdlib/canonicalize.c
+index 20033b4885..fdeca42b83 100644
+--- a/stdlib/canonicalize.c
++++ b/stdlib/canonicalize.c
+@@ -404,7 +404,7 @@ error:
+ {
+ if (dest - rname <= get_path_max ())
+ rname = strcpy (resolved, rname);
+- else
++ else if (!failed)
+ {
+ failed = true;
+ __set_errno (ENAMETOOLONG);
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2023-0687.patch b/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2023-0687.patch
new file mode 100644
index 000000000..da0e43686
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc/CVE-2023-0687.patch
@@ -0,0 +1,77 @@
+From 801af9fafd4689337ebf27260aa115335a0cb2bc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?=
+ =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= <leo@yuriev.ru>
+Date: Sat, 4 Feb 2023 14:41:38 +0300
+Subject: [PATCH] gmon: Fix allocated buffer overflow (bug 29444)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The `__monstartup()` allocates a buffer used to store all the data
+accumulated by the monitor.
+
+The size of this buffer depends on the size of the internal structures
+used and the address range for which the monitor is activated, as well
+as on the maximum density of call instructions and/or callable functions
+that could be potentially on a segment of executable code.
+
+In particular a hash table of arcs is placed at the end of this buffer.
+The size of this hash table is calculated in bytes as
+ p->fromssize = p->textsize / HASHFRACTION;
+
+but actually should be
+ p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms));
+
+This results in writing beyond the end of the allocated buffer when an
+added arc corresponds to a call near from the end of the monitored
+address range, since `_mcount()` check the incoming caller address for
+monitored range but not the intermediate result hash-like index that
+uses to write into the table.
+
+It should be noted that when the results are output to `gmon.out`, the
+table is read to the last element calculated from the allocated size in
+bytes, so the arcs stored outside the buffer boundary did not fall into
+`gprof` for analysis. Thus this "feature" help me to found this bug
+during working with https://sourceware.org/bugzilla/show_bug.cgi?id=29438
+
+Just in case, I will explicitly note that the problem breaks the
+`make test t=gmon/tst-gmon-dso` added for Bug 29438.
+There, the arc of the `f3()` call disappears from the output, since in
+the DSO case, the call to `f3` is located close to the end of the
+monitored range.
+
+Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
+
+Another minor error seems a related typo in the calculation of
+`kcountsize`, but since kcounts are smaller than froms, this is
+actually to align the p->froms data.
+
+Co-authored-by: DJ Delorie <dj@redhat.com>
+Reviewed-by: Carlos O'Donell <carlos@redhat.com>
+---
+ gmon/gmon.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/gmon/gmon.c b/gmon/gmon.c
+index dee64803ada..bf76358d5b1 100644
+--- a/gmon/gmon.c
++++ b/gmon/gmon.c
+@@ -132,6 +132,8 @@ __monstartup (u_long lowpc, u_long highpc)
+ p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER));
+ p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER));
+ p->textsize = p->highpc - p->lowpc;
++ /* This looks like a typo, but it's here to align the p->froms
++ section. */
+ p->kcountsize = ROUNDUP(p->textsize / HISTFRACTION, sizeof(*p->froms));
+ p->hashfraction = HASHFRACTION;
+ p->log_hashfraction = -1;
+@@ -142,7 +144,7 @@ __monstartup (u_long lowpc, u_long highpc)
+ instead of integer division. Precompute shift amount. */
+ p->log_hashfraction = ffs(p->hashfraction * sizeof(*p->froms)) - 1;
+ }
+- p->fromssize = p->textsize / HASHFRACTION;
++ p->fromssize = ROUNDUP(p->textsize / HASHFRACTION, sizeof(*p->froms));
+ p->tolimit = p->textsize * ARCDENSITY / 100;
+ if (p->tolimit < MINARCS)
+ p->tolimit = MINARCS;
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc_%.bbappend
index be793e5e8..96c4947ad 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/glibc/glibc_%.bbappend
@@ -8,4 +8,6 @@ SRC_URI += " \
file://0001-CVE-2022-23219.patch \
file://0002-CVE-2022-23219.patch \
file://CVE-2021-43396.patch \
+ file://CVE-2021-3998.patch \
+ file://CVE-2023-0687.patch \
"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40303.patch b/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40303.patch
new file mode 100644
index 000000000..ecb134edf
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40303.patch
@@ -0,0 +1,618 @@
+From c846986356fc149915a74972bf198abc266bc2c0 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Thu, 25 Aug 2022 17:43:08 +0200
+Subject: [PATCH] [CVE-2022-40303] Fix integer overflows with XML_PARSE_HUGE
+
+Also impose size limits when XML_PARSE_HUGE is set. Limit size of names
+to XML_MAX_TEXT_LENGTH (10 million bytes) and other content to
+XML_MAX_HUGE_LENGTH (1 billion bytes).
+
+Move some the length checks to the end of the respective loop to make
+them strict.
+
+xmlParseEntityValue didn't have a length limitation at all. But without
+XML_PARSE_HUGE, this should eventually trigger an error in xmlGROW.
+
+Thanks to Maddie Stone working with Google Project Zero for the report!
+---
+ parser.c | 233 +++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 121 insertions(+), 112 deletions(-)
+
+diff --git a/parser.c b/parser.c
+index 93f031be..79479979 100644
+--- a/parser.c
++++ b/parser.c
+@@ -102,6 +102,8 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt);
+ * *
+ ************************************************************************/
+
++#define XML_MAX_HUGE_LENGTH 1000000000
++
+ #define XML_PARSER_BIG_ENTITY 1000
+ #define XML_PARSER_LOT_ENTITY 5000
+
+@@ -552,7 +554,7 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
+ errmsg = "Malformed declaration expecting version";
+ break;
+ case XML_ERR_NAME_TOO_LONG:
+- errmsg = "Name too long use XML_PARSE_HUGE option";
++ errmsg = "Name too long";
+ break;
+ #if 0
+ case:
+@@ -3202,6 +3204,9 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ int len = 0, l;
+ int c;
+ int count = 0;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+
+ #ifdef DEBUG
+ nbParseNameComplex++;
+@@ -3267,7 +3272,8 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
+ }
+- len += l;
++ if (len <= INT_MAX - l)
++ len += l;
+ NEXTL(l);
+ c = CUR_CHAR(l);
+ }
+@@ -3293,13 +3299,13 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
+ }
+- len += l;
++ if (len <= INT_MAX - l)
++ len += l;
+ NEXTL(l);
+ c = CUR_CHAR(l);
+ }
+ }
+- if ((len > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if (len > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
+ return(NULL);
+ }
+@@ -3338,7 +3344,10 @@ const xmlChar *
+ xmlParseName(xmlParserCtxtPtr ctxt) {
+ const xmlChar *in;
+ const xmlChar *ret;
+- int count = 0;
++ size_t count = 0;
++ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+
+ GROW;
+
+@@ -3362,8 +3371,7 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
+ in++;
+ if ((*in > 0) && (*in < 0x80)) {
+ count = in - ctxt->input->cur;
+- if ((count > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if (count > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
+ return(NULL);
+ }
+@@ -3384,6 +3392,9 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+ int len = 0, l;
+ int c;
+ int count = 0;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+ size_t startPosition = 0;
+
+ #ifdef DEBUG
+@@ -3404,17 +3415,13 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+ while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
+ (xmlIsNameChar(ctxt, c) && (c != ':'))) {
+ if (count++ > XML_PARSER_CHUNK_SIZE) {
+- if ((len > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
+- return(NULL);
+- }
+ count = 0;
+ GROW;
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
+ }
+- len += l;
++ if (len <= INT_MAX - l)
++ len += l;
+ NEXTL(l);
+ c = CUR_CHAR(l);
+ if (c == 0) {
+@@ -3432,8 +3439,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
+ c = CUR_CHAR(l);
+ }
+ }
+- if ((len > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if (len > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
+ return(NULL);
+ }
+@@ -3459,7 +3465,10 @@ static const xmlChar *
+ xmlParseNCName(xmlParserCtxtPtr ctxt) {
+ const xmlChar *in, *e;
+ const xmlChar *ret;
+- int count = 0;
++ size_t count = 0;
++ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+
+ #ifdef DEBUG
+ nbParseNCName++;
+@@ -3484,8 +3493,7 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
+ goto complex;
+ if ((*in > 0) && (*in < 0x80)) {
+ count = in - ctxt->input->cur;
+- if ((count > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if (count > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
+ return(NULL);
+ }
+@@ -3567,6 +3575,9 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
+ const xmlChar *cur = *str;
+ int len = 0, l;
+ int c;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+
+ #ifdef DEBUG
+ nbParseStringName++;
+@@ -3602,12 +3613,6 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
+ if (len + 10 > max) {
+ xmlChar *tmp;
+
+- if ((len > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
+- xmlFree(buffer);
+- return(NULL);
+- }
+ max *= 2;
+ tmp = (xmlChar *) xmlRealloc(buffer,
+ max * sizeof(xmlChar));
+@@ -3621,14 +3626,18 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
+ COPY_BUF(l,buffer,len,c);
+ cur += l;
+ c = CUR_SCHAR(cur, l);
++ if (len > maxLength) {
++ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
++ xmlFree(buffer);
++ return(NULL);
++ }
+ }
+ buffer[len] = 0;
+ *str = cur;
+ return(buffer);
+ }
+ }
+- if ((len > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if (len > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
+ return(NULL);
+ }
+@@ -3655,6 +3664,9 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ int len = 0, l;
+ int c;
+ int count = 0;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+
+ #ifdef DEBUG
+ nbParseNmToken++;
+@@ -3706,12 +3718,6 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ if (len + 10 > max) {
+ xmlChar *tmp;
+
+- if ((max > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
+- xmlFree(buffer);
+- return(NULL);
+- }
+ max *= 2;
+ tmp = (xmlChar *) xmlRealloc(buffer,
+ max * sizeof(xmlChar));
+@@ -3725,6 +3731,11 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ COPY_BUF(l,buffer,len,c);
+ NEXTL(l);
+ c = CUR_CHAR(l);
++ if (len > maxLength) {
++ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
++ xmlFree(buffer);
++ return(NULL);
++ }
+ }
+ buffer[len] = 0;
+ return(buffer);
+@@ -3732,8 +3743,7 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
+ }
+ if (len == 0)
+ return(NULL);
+- if ((len > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if (len > maxLength) {
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
+ return(NULL);
+ }
+@@ -3759,6 +3769,9 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
+ int len = 0;
+ int size = XML_PARSER_BUFFER_SIZE;
+ int c, l;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_HUGE_LENGTH :
++ XML_MAX_TEXT_LENGTH;
+ xmlChar stop;
+ xmlChar *ret = NULL;
+ const xmlChar *cur = NULL;
+@@ -3818,6 +3831,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
+ GROW;
+ c = CUR_CHAR(l);
+ }
++
++ if (len > maxLength) {
++ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
++ "entity value too long\n");
++ goto error;
++ }
+ }
+ buf[len] = 0;
+ if (ctxt->instate == XML_PARSER_EOF)
+@@ -3905,6 +3924,9 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ xmlChar *rep = NULL;
+ size_t len = 0;
+ size_t buf_size = 0;
++ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_HUGE_LENGTH :
++ XML_MAX_TEXT_LENGTH;
+ int c, l, in_space = 0;
+ xmlChar *current = NULL;
+ xmlEntityPtr ent;
+@@ -3936,16 +3958,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ while (((NXT(0) != limit) && /* checked */
+ (IS_CHAR(c)) && (c != '<')) &&
+ (ctxt->instate != XML_PARSER_EOF)) {
+- /*
+- * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
+- * special option is given
+- */
+- if ((len > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+- "AttValue length too long\n");
+- goto mem_error;
+- }
+ if (c == '&') {
+ in_space = 0;
+ if (NXT(1) == '#') {
+@@ -4093,6 +4105,11 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ }
+ GROW;
+ c = CUR_CHAR(l);
++ if (len > maxLength) {
++ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
++ "AttValue length too long\n");
++ goto mem_error;
++ }
+ }
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto error;
+@@ -4114,16 +4131,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
+ } else
+ NEXT;
+
+- /*
+- * There we potentially risk an overflow, don't allow attribute value of
+- * length more than INT_MAX it is a very reasonable assumption !
+- */
+- if (len >= INT_MAX) {
+- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+- "AttValue length too long\n");
+- goto mem_error;
+- }
+-
+ if (attlen != NULL) *attlen = (int) len;
+ return(buf);
+
+@@ -4194,6 +4201,9 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+ int len = 0;
+ int size = XML_PARSER_BUFFER_SIZE;
+ int cur, l;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+ xmlChar stop;
+ int state = ctxt->instate;
+ int count = 0;
+@@ -4221,13 +4231,6 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+ if (len + 5 >= size) {
+ xmlChar *tmp;
+
+- if ((size > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
+- xmlFree(buf);
+- ctxt->instate = (xmlParserInputState) state;
+- return(NULL);
+- }
+ size *= 2;
+ tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+ if (tmp == NULL) {
+@@ -4256,6 +4259,12 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
+ SHRINK;
+ cur = CUR_CHAR(l);
+ }
++ if (len > maxLength) {
++ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
++ xmlFree(buf);
++ ctxt->instate = (xmlParserInputState) state;
++ return(NULL);
++ }
+ }
+ buf[len] = 0;
+ ctxt->instate = (xmlParserInputState) state;
+@@ -4283,6 +4292,9 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+ xmlChar *buf = NULL;
+ int len = 0;
+ int size = XML_PARSER_BUFFER_SIZE;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_TEXT_LENGTH :
++ XML_MAX_NAME_LENGTH;
+ xmlChar cur;
+ xmlChar stop;
+ int count = 0;
+@@ -4310,12 +4322,6 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+ if (len + 1 >= size) {
+ xmlChar *tmp;
+
+- if ((size > XML_MAX_NAME_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
+- xmlFree(buf);
+- return(NULL);
+- }
+ size *= 2;
+ tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
+ if (tmp == NULL) {
+@@ -4343,6 +4349,11 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
+ SHRINK;
+ cur = CUR;
+ }
++ if (len > maxLength) {
++ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
++ xmlFree(buf);
++ return(NULL);
++ }
+ }
+ buf[len] = 0;
+ if (cur != stop) {
+@@ -4742,6 +4753,9 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
+ int r, rl;
+ int cur, l;
+ size_t count = 0;
++ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_HUGE_LENGTH :
++ XML_MAX_TEXT_LENGTH;
+ int inputid;
+
+ inputid = ctxt->input->id;
+@@ -4787,13 +4801,6 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
+ if ((r == '-') && (q == '-')) {
+ xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
+ }
+- if ((len > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+- "Comment too big found", NULL);
+- xmlFree (buf);
+- return;
+- }
+ if (len + 5 >= size) {
+ xmlChar *new_buf;
+ size_t new_size;
+@@ -4831,6 +4838,13 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
+ GROW;
+ cur = CUR_CHAR(l);
+ }
++
++ if (len > maxLength) {
++ xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
++ "Comment too big found", NULL);
++ xmlFree (buf);
++ return;
++ }
+ }
+ buf[len] = 0;
+ if (cur == 0) {
+@@ -4875,6 +4889,9 @@ xmlParseComment(xmlParserCtxtPtr ctxt) {
+ xmlChar *buf = NULL;
+ size_t size = XML_PARSER_BUFFER_SIZE;
+ size_t len = 0;
++ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_HUGE_LENGTH :
++ XML_MAX_TEXT_LENGTH;
+ xmlParserInputState state;
+ const xmlChar *in;
+ size_t nbchar = 0;
+@@ -4958,8 +4975,7 @@ get_more:
+ buf[len] = 0;
+ }
+ }
+- if ((len > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if (len > maxLength) {
+ xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
+ "Comment too big found", NULL);
+ xmlFree (buf);
+@@ -5159,6 +5175,9 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ xmlChar *buf = NULL;
+ size_t len = 0;
+ size_t size = XML_PARSER_BUFFER_SIZE;
++ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_HUGE_LENGTH :
++ XML_MAX_TEXT_LENGTH;
+ int cur, l;
+ const xmlChar *target;
+ xmlParserInputState state;
+@@ -5234,14 +5253,6 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ return;
+ }
+ count = 0;
+- if ((len > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
+- "PI %s too big found", target);
+- xmlFree(buf);
+- ctxt->instate = state;
+- return;
+- }
+ }
+ COPY_BUF(l,buf,len,cur);
+ NEXTL(l);
+@@ -5251,15 +5262,14 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
+ GROW;
+ cur = CUR_CHAR(l);
+ }
++ if (len > maxLength) {
++ xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
++ "PI %s too big found", target);
++ xmlFree(buf);
++ ctxt->instate = state;
++ return;
++ }
+ }
+- if ((len > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
+- "PI %s too big found", target);
+- xmlFree(buf);
+- ctxt->instate = state;
+- return;
+- }
+ buf[len] = 0;
+ if (cur != '?') {
+ xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
+@@ -8954,6 +8964,9 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ const xmlChar *in = NULL, *start, *end, *last;
+ xmlChar *ret = NULL;
+ int line, col;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_HUGE_LENGTH :
++ XML_MAX_TEXT_LENGTH;
+
+ GROW;
+ in = (xmlChar *) CUR_PTR;
+@@ -8993,8 +9006,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ start = in;
+ if (in >= end) {
+ GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
+- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if ((in - start) > maxLength) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ "AttValue length too long\n");
+ return(NULL);
+@@ -9007,8 +9019,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ if ((*in++ == 0x20) && (*in == 0x20)) break;
+ if (in >= end) {
+ GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
+- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if ((in - start) > maxLength) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ "AttValue length too long\n");
+ return(NULL);
+@@ -9041,16 +9052,14 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ last = last + delta;
+ }
+ end = ctxt->input->end;
+- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if ((in - start) > maxLength) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ "AttValue length too long\n");
+ return(NULL);
+ }
+ }
+ }
+- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if ((in - start) > maxLength) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ "AttValue length too long\n");
+ return(NULL);
+@@ -9063,8 +9072,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ col++;
+ if (in >= end) {
+ GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
+- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if ((in - start) > maxLength) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ "AttValue length too long\n");
+ return(NULL);
+@@ -9072,8 +9080,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
+ }
+ }
+ last = in;
+- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
++ if ((in - start) > maxLength) {
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
+ "AttValue length too long\n");
+ return(NULL);
+@@ -9763,6 +9770,9 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+ int s, sl;
+ int cur, l;
+ int count = 0;
++ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
++ XML_MAX_HUGE_LENGTH :
++ XML_MAX_TEXT_LENGTH;
+
+ /* Check 2.6.0 was NXT(0) not RAW */
+ if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
+@@ -9796,13 +9806,6 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+ if (len + 5 >= size) {
+ xmlChar *tmp;
+
+- if ((size > XML_MAX_TEXT_LENGTH) &&
+- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
+- xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
+- "CData section too big found", NULL);
+- xmlFree (buf);
+- return;
+- }
+ tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
+ if (tmp == NULL) {
+ xmlFree(buf);
+@@ -9829,6 +9832,12 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
+ }
+ NEXTL(l);
+ cur = CUR_CHAR(l);
++ if (len > maxLength) {
++ xmlFatalErrMsg(ctxt, XML_ERR_CDATA_NOT_FINISHED,
++ "CData section too big found\n");
++ xmlFree(buf);
++ return;
++ }
+ }
+ buf[len] = 0;
+ ctxt->instate = XML_PARSER_CONTENT;
+--
+GitLab
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40304.patch b/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40304.patch
new file mode 100644
index 000000000..b6a48587d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2/CVE-2022-40304.patch
@@ -0,0 +1,101 @@
+From 1b41ec4e9433b05bb0376be4725804c54ef1d80b Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Wed, 31 Aug 2022 22:11:25 +0200
+Subject: [PATCH] [CVE-2022-40304] Fix dict corruption caused by entity
+ reference cycles
+
+When an entity reference cycle is detected, the entity content is
+cleared by setting its first byte to zero. But the entity content might
+be allocated from a dict. In this case, the dict entry becomes corrupted
+leading to all kinds of logic errors, including memory errors like
+double-frees.
+
+Stop storing entity content, orig, ExternalID and SystemID in a dict.
+These values are unlikely to occur multiple times in a document, so they
+shouldn't have been stored in a dict in the first place.
+
+Thanks to Ned Williamson and Nathan Wachholz working with Google Project
+Zero for the report!
+---
+ entities.c | 55 ++++++++++++++++--------------------------------------
+ 1 file changed, 16 insertions(+), 39 deletions(-)
+
+diff --git a/entities.c b/entities.c
+index 84435515..d4e5412e 100644
+--- a/entities.c
++++ b/entities.c
+@@ -128,36 +128,19 @@ xmlFreeEntity(xmlEntityPtr entity)
+ if ((entity->children) && (entity->owner == 1) &&
+ (entity == (xmlEntityPtr) entity->children->parent))
+ xmlFreeNodeList(entity->children);
+- if (dict != NULL) {
+- if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name)))
+- xmlFree((char *) entity->name);
+- if ((entity->ExternalID != NULL) &&
+- (!xmlDictOwns(dict, entity->ExternalID)))
+- xmlFree((char *) entity->ExternalID);
+- if ((entity->SystemID != NULL) &&
+- (!xmlDictOwns(dict, entity->SystemID)))
+- xmlFree((char *) entity->SystemID);
+- if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI)))
+- xmlFree((char *) entity->URI);
+- if ((entity->content != NULL)
+- && (!xmlDictOwns(dict, entity->content)))
+- xmlFree((char *) entity->content);
+- if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig)))
+- xmlFree((char *) entity->orig);
+- } else {
+- if (entity->name != NULL)
+- xmlFree((char *) entity->name);
+- if (entity->ExternalID != NULL)
+- xmlFree((char *) entity->ExternalID);
+- if (entity->SystemID != NULL)
+- xmlFree((char *) entity->SystemID);
+- if (entity->URI != NULL)
+- xmlFree((char *) entity->URI);
+- if (entity->content != NULL)
+- xmlFree((char *) entity->content);
+- if (entity->orig != NULL)
+- xmlFree((char *) entity->orig);
+- }
++ if ((entity->name != NULL) &&
++ ((dict == NULL) || (!xmlDictOwns(dict, entity->name))))
++ xmlFree((char *) entity->name);
++ if (entity->ExternalID != NULL)
++ xmlFree((char *) entity->ExternalID);
++ if (entity->SystemID != NULL)
++ xmlFree((char *) entity->SystemID);
++ if (entity->URI != NULL)
++ xmlFree((char *) entity->URI);
++ if (entity->content != NULL)
++ xmlFree((char *) entity->content);
++ if (entity->orig != NULL)
++ xmlFree((char *) entity->orig);
+ xmlFree(entity);
+ }
+
+@@ -193,18 +176,12 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
+ ret->SystemID = xmlStrdup(SystemID);
+ } else {
+ ret->name = xmlDictLookup(dict, name, -1);
+- if (ExternalID != NULL)
+- ret->ExternalID = xmlDictLookup(dict, ExternalID, -1);
+- if (SystemID != NULL)
+- ret->SystemID = xmlDictLookup(dict, SystemID, -1);
++ ret->ExternalID = xmlStrdup(ExternalID);
++ ret->SystemID = xmlStrdup(SystemID);
+ }
+ if (content != NULL) {
+ ret->length = xmlStrlen(content);
+- if ((dict != NULL) && (ret->length < 5))
+- ret->content = (xmlChar *)
+- xmlDictLookup(dict, content, ret->length);
+- else
+- ret->content = xmlStrndup(content, ret->length);
++ ret->content = xmlStrndup(content, ret->length);
+ } else {
+ ret->length = 0;
+ ret->content = NULL;
+--
+GitLab
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2_%.bbappend
index 4011c8759..1d2993a8d 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/libxml/libxml2_%.bbappend
@@ -2,4 +2,6 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://CVE-2022-23308-Use-after-free-of-ID-and-IDREF.patch \
file://CVE-2022-29824-Fix-integer-overflows-in-xmlBuf-and-xmlBuffer.patch \
+ file://CVE-2022-40303.patch \
+ file://CVE-2022-40304.patch \
"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses.inc b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses.inc
new file mode 100644
index 000000000..367f3b19f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses.inc
@@ -0,0 +1,327 @@
+SUMMARY = "The New Curses library"
+DESCRIPTION = "SVr4 and XSI-Curses compatible curses library and terminfo tools including tic, infocmp, captoinfo. Supports color, multiple highlights, forms-drawing characters, and automatic recognition of keypad and function-key sequences. Extensions include resizable windows and mouse support on both xterm and Linux console using the gpm library."
+HOMEPAGE = "http://www.gnu.org/software/ncurses/ncurses.html"
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://COPYING;md5=c5a4600fdef86384c41ca33ecc70a4b8;endline=27"
+SECTION = "libs"
+DEPENDS = "ncurses-native"
+DEPENDS:class-native = ""
+
+BINCONFIG = "${bindir}/ncurses5-config ${bindir}/ncursesw5-config \
+ ${bindir}/ncurses6-config ${bindir}/ncursesw6-config"
+
+inherit autotools binconfig-disabled multilib_header pkgconfig
+
+# Upstream has useful patches at times at ftp://invisible-island.net/ncurses/
+SRC_URI = "git://github.com/mirror/ncurses.git;protocol=https;branch=master"
+
+EXTRA_AUTORECONF = "-I m4"
+
+CACHED_CONFIGUREVARS = "cf_cv_func_nanosleep=yes"
+CACHED_CONFIGUREVARS:append:linux = " cf_cv_working_poll=yes"
+
+EXTRASITECONFIG = "CFLAGS='${CFLAGS} -I${SYSROOT_DESTDIR}${includedir}'"
+
+# Whether to enable separate widec libraries; must be 'true' or 'false'
+#
+# TODO: remove this variable when widec is supported in every setup?
+ENABLE_WIDEC ?= "true"
+
+# _GNU_SOURCE is required for widec stuff and is detected automatically
+# for target objects. But it must be set manually for native and sdk
+# builds.
+BUILD_CPPFLAGS += "-D_GNU_SOURCE"
+
+# natives don't generally look in base_libdir
+base_libdir:class-native = "${libdir}"
+
+# Display corruption occurs on 64 bit hosts without these settings
+# This was derrived from the upstream debian ncurses which uses
+# these settings for 32 and 64 bit hosts.
+EXCONFIG_ARGS = ""
+EXCONFIG_ARGS:class-native = " \
+ --disable-lp64 \
+ --with-chtype='long' \
+ --with-mmask-t='long'"
+EXCONFIG_ARGS:class-nativesdk = " \
+ --disable-lp64 \
+ --with-chtype='long' \
+ --with-mmask-t='long'"
+
+PACKAGES_DYNAMIC = "^${PN}-lib.*"
+
+# Fall back to the host termcap / terminfo for -nativesdk and -native
+# The reality is a work around for strange problems with things like
+# "bitbake -c menuconfig busybox" where it cannot find the terminfo
+# because the sstate had a hard coded search path. Until this is fixed
+# another way this is deemed good enough.
+EX_TERMCAP = ""
+EX_TERMCAP:class-native = ":/etc/termcap:/usr/share/misc/termcap"
+EX_TERMCAP:class-nativesdk = ":/etc/termcap:/usr/share/misc/termcap"
+EX_TERMINFO = ""
+EX_TERMINFO:class-native = ":/etc/terminfo:/usr/share/terminfo:/usr/share/misc/terminfo:/lib/terminfo"
+EX_TERMINFO:class-nativesdk = ":/etc/terminfo:/usr/share/terminfo:/usr/share/misc/terminfo:/lib/terminfo"
+EX_TERMLIB ?= "tinfo"
+
+# Helper function for do_configure to allow multiple configurations
+# $1 the directory to run configure in
+# $@ the arguments to pass to configure
+ncurses_configure() {
+ mkdir -p $1
+ cd $1
+ shift
+ oe_runconf \
+ --without-debug \
+ --without-ada \
+ --without-gpm \
+ --enable-hard-tabs \
+ --enable-xmc-glitch \
+ --enable-colorfgbg \
+ --with-termpath='${sysconfdir}/termcap:${datadir}/misc/termcap${EX_TERMCAP}' \
+ --with-terminfo-dirs='${sysconfdir}/terminfo:${datadir}/terminfo${EX_TERMINFO}' \
+ --with-shared \
+ --disable-big-core \
+ --program-prefix= \
+ --with-ticlib \
+ --with-termlib=${EX_TERMLIB} \
+ --enable-sigwinch \
+ --enable-pc-files \
+ --disable-rpath-hack \
+ ${EXCONFIG_ARGS} \
+ --with-manpage-format=normal \
+ --without-manpage-renames \
+ --disable-stripping \
+ "$@" || return 1
+ cd ..
+}
+
+# Override the function from the autotools class; ncurses requires a
+# patched autoconf213 to generate the configure script. This autoconf
+# is not available so that the shipped script will be used.
+do_configure() {
+ #Remove ${includedir} from CPPFLAGS, need for cross compile
+ sed -i 's#-I${cf_includedir}##g' ${S}/configure || die "sed CPPFLAGS"
+
+ # The --enable-pc-files requires PKG_CONFIG_LIBDIR existed
+ mkdir -p ${PKG_CONFIG_LIBDIR}
+ ( cd ${S}; gnu-configize --force )
+ ncurses_configure "narrowc" || \
+ return 1
+ ! ${ENABLE_WIDEC} || \
+ ncurses_configure "widec" "--enable-widec" "--without-progs"
+
+}
+
+do_compile() {
+ oe_runmake -C narrowc libs
+ oe_runmake -C narrowc/progs
+
+ ! ${ENABLE_WIDEC} || \
+ oe_runmake -C widec libs
+}
+
+# set of expected differences between narrowc and widec header
+#
+# TODO: the NCURSES_CH_T difference can cause real problems :(
+_unifdef_cleanup = " \
+ -e '\!/\* \$Id: curses.wide,v!,\!/\* \$Id: curses.tail,v!d' \
+ -e '/^#define NCURSES_CH_T /d' \
+ -e '/^#include <wchar.h>/d' \
+ -e '\!^/\* .* \*/!d' \
+"
+
+do_test[depends] = "unifdef-native:do_populate_sysroot"
+do_test[dirs] = "${S}"
+do_test() {
+ ${ENABLE_WIDEC} || return 0
+
+ # make sure that the narrow and widec header are compatible
+ # and differ only in minor details.
+ unifdef -k narrowc/include/curses.h | \
+ sed ${_unifdef_cleanup} > curses-narrowc.h
+ unifdef -k widec/include/curses.h | \
+ sed ${_unifdef_cleanup} > curses-widec.h
+
+ diff curses-narrowc.h curses-widec.h
+}
+
+# Split original _install_opts to two parts.
+# One is the options to install contents, the other is the parameters \
+# when running command "make install"
+# Note that install.libs will also implicitly install header files,
+# so we do not need to explicitly specify install.includes.
+# Doing so could in fact result in a race condition, as both targets
+# (install.libs and install.includes) would install the same headers
+# at the same time
+
+_install_opts = " install.libs install.man "
+
+_install_cfgs = "\
+ DESTDIR='${D}' \
+ PKG_CONFIG_LIBDIR='${libdir}/pkgconfig' \
+"
+
+do_install() {
+ # Order of installation is important; widec installs a 'curses.h'
+ # header with more definitions and must be installed last hence.
+ # Compatibility of these headers will be checked in 'do_test()'.
+ oe_runmake -C narrowc ${_install_cfgs} ${_install_opts} \
+ install.progs
+
+ # The install.data should run after install.libs, otherwise
+ # there would be a race issue in a very critical conditon, since
+ # tic will be run by install.data, and tic needs libtinfo.so
+ # which would be regenerated by install.libs.
+ oe_runmake -C narrowc ${_install_cfgs} \
+ install.data
+
+
+ ! ${ENABLE_WIDEC} || \
+ oe_runmake -C widec ${_install_cfgs} ${_install_opts}
+
+ cd narrowc
+
+ # include some basic terminfo files
+ # stolen ;) from gentoo and modified a bit
+ for x in ansi console dumb linux rxvt screen screen-256color sun vt52 vt100 vt102 vt200 vt220 xterm-color xterm-xfree86 xterm-256color
+ do
+ local termfile="$(find "${D}${datadir}/terminfo/" -name "${x}" 2>/dev/null)"
+ local basedir="$(basename $(dirname "${termfile}"))"
+
+ if [ -n "${termfile}" ]
+ then
+ install -d ${D}${sysconfdir}/terminfo/${basedir}
+ mv ${termfile} ${D}${sysconfdir}/terminfo/${basedir}/
+ ln -s /etc/terminfo/${basedir}/${x} \
+ ${D}${datadir}/terminfo/${basedir}/${x}
+ fi
+ done
+ # i think we can use xterm-color as default xterm
+ if [ -e ${D}${sysconfdir}/terminfo/x/xterm-color ]
+ then
+ ln -sf xterm-color ${D}${sysconfdir}/terminfo/x/xterm
+ fi
+
+ # When changing ${libdir} to e.g. /usr/lib/myawesomelib/ ncurses
+ # still installs '/usr/lib/terminfo', so try to rm both
+ # the proper path and a slightly hardcoded one
+ rm -f ${D}${libdir}/terminfo ${D}${prefix}/lib/terminfo
+
+ # create linker scripts for libcurses.so and libncurses to
+ # link against -ltinfo when needed. Some builds might break
+ # else when '-Wl,--no-copy-dt-needed-entries' has been set in
+ # linker flags.
+ for i in libncurses libncursesw; do
+ f=${D}${libdir}/$i.so
+ test -h $f || continue
+ rm -f $f
+ echo '/* GNU ld script */' >$f
+ echo "INPUT($i.so.5 AS_NEEDED(-ltinfo))" >>$f
+ done
+
+ # Make sure that libcurses is linked so that it gets -ltinfo
+ # also, this should be addressed upstream really.
+ ln -sf libncurses.so ${D}${libdir}/libcurses.so
+
+ # create libtermcap.so linker script for backward compatibility
+ f=${D}${libdir}/libtermcap.so
+ echo '/* GNU ld script */' >$f
+ echo 'INPUT(AS_NEEDED(-ltinfo))' >>$f
+
+ if [ ! -d "${D}${base_libdir}" ]; then
+ # Setting base_libdir to libdir as is done in the -native
+ # case will skip this code
+ mkdir -p ${D}${base_libdir}
+ mv ${D}${libdir}/libncurses.so.* ${D}${base_libdir}
+ ! ${ENABLE_WIDEC} || \
+ mv ${D}${libdir}/libncursesw.so.* ${D}${base_libdir}
+
+ mv ${D}${libdir}/libtinfo.so.* ${D}${base_libdir}
+ rm ${D}${libdir}/libtinfo.so
+
+ # Use ln -rs to ensure this is a relative link despite absolute paths
+ # (as we can't know the relationship between base_libdir and libdir).
+ ln -rs ${D}${base_libdir}/libtinfo.so.5 ${D}${libdir}/libtinfo.so
+ fi
+ if [ -d "${D}${includedir}/ncurses" ]; then
+ for f in `find ${D}${includedir}/ncurses -name "*.h"`
+ do
+ f=`basename $f`
+ test -e ${D}${includedir}/$f && continue
+ ln -sf ncurses/$f ${D}${includedir}/$f
+ done
+ fi
+ oe_multilib_header curses.h
+}
+
+python populate_packages:prepend () {
+ libdir = d.expand("${libdir}")
+ base_libdir = d.expand("${base_libdir}")
+ pnbase = d.expand("${PN}-lib%s")
+ do_split_packages(d, libdir, r'^lib(.*)\.so\..*', pnbase, 'ncurses %s library', prepend=True, extra_depends = '', allow_links=True)
+ if libdir is not base_libdir:
+ do_split_packages(d, base_libdir, r'^lib(.*)\.so\..*', pnbase, 'ncurses %s library', prepend=True, extra_depends = '', allow_links=True)
+}
+
+
+inherit update-alternatives
+
+ALTERNATIVE_PRIORITY = "100"
+
+ALTERNATIVE:ncurses-tools:class-target = "clear reset"
+ALTERNATIVE:ncurses-terminfo:class-target = "st st-256color"
+
+ALTERNATIVE_LINK_NAME[st] = "${datadir}/terminfo/s/st"
+
+ALTERNATIVE_LINK_NAME[st-256color] = "${datadir}/terminfo/s/st-256color"
+
+BBCLASSEXTEND = "native nativesdk"
+
+PACKAGES += " \
+ ${PN}-tools \
+ ${PN}-terminfo-base \
+ ${PN}-terminfo \
+"
+
+FILES:${PN} = "\
+ ${bindir}/tput \
+ ${bindir}/tset \
+ ${bindir}/ncurses5-config \
+ ${bindir}/ncursesw5-config \
+ ${bindir}/ncurses6-config \
+ ${bindir}/ncursesw6-config \
+ ${datadir}/tabset \
+"
+
+# This keeps only tput/tset in ncurses
+# clear/reset are in already busybox
+FILES:${PN}-tools = "\
+ ${bindir}/tic \
+ ${bindir}/toe \
+ ${bindir}/infotocap \
+ ${bindir}/captoinfo \
+ ${bindir}/infocmp \
+ ${bindir}/clear${@['', '.${BPN}']['${CLASSOVERRIDE}' == 'class-target']} \
+ ${bindir}/reset${@['', '.${BPN}']['${CLASSOVERRIDE}' == 'class-target']} \
+ ${bindir}/tack \
+ ${bindir}/tabs \
+"
+
+# 'reset' is a symlink to 'tset' which is in the 'ncurses' package
+RDEPENDS:${PN}-tools = "${PN} ${PN}-terminfo-base"
+
+FILES:${PN}-terminfo = "\
+ ${datadir}/terminfo \
+"
+
+FILES:${PN}-terminfo-base = "\
+ ${sysconfdir}/terminfo \
+"
+
+RSUGGESTS:${PN}-libtinfo = "${PN}-terminfo"
+RRECOMMENDS:${PN}-libtinfo = "${PN}-terminfo-base"
+
+# Putting terminfo into the sysroot adds around 2800 files to
+# each recipe specific sysroot. We can live without this, particularly
+# as many recipes may have native and target copies.
+SYSROOT_DIRS:remove = "${datadir}"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-Fix-heap-buffer-overflow-in-captoinfo.patch b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-Fix-heap-buffer-overflow-in-captoinfo.patch
deleted file mode 100644
index 420a19b41..000000000
--- a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-Fix-heap-buffer-overflow-in-captoinfo.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From ad135388ac66b7c8276b0899d9b43433e2faffa6 Mon Sep 17 00:00:00 2001
-From: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
-Date: Tue, 7 Dec 2021 23:58:53 +0000
-Subject: [PATCH] Fix heap-buffer-overflow in captoinfo
-
-This has been picked up from http://cvsweb.netbsd.org/
-bsdweb.cgi/pkgsrc/devel/ncurses/patches/Attic/
-patch-ncurses_tinfo_captoinfo.c
-?rev=1.1&content-type=text/x-cvsweb-markup
-
-Thomas Dickey is the owner of this patch.
-This fix is a part of
-https://github.com/ThomasDickey/ncurses-snapshots/
-commit/63ca9e061f4644795d6f3f559557f3e1ed8c738b#diff-
-7e95c7bc5f213e9be438e69a9d5d0f261a14952bcbd692f7b9014217b8047340
-
-Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com>
----
- ncurses/tinfo/captoinfo.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
-diff --git a/ncurses/tinfo/captoinfo.c b/ncurses/tinfo/captoinfo.c
-index 8b3b83d1..c9741405 100644
---- a/ncurses/tinfo/captoinfo.c
-+++ b/ncurses/tinfo/captoinfo.c
-@@ -216,12 +216,15 @@ cvtchar(register const char *sp)
- }
- break;
- case '^':
-+ len = 2;
- c = UChar(*++sp);
-- if (c == '?')
-+ if (c == '?') {
- c = 127;
-- else
-+ } else if (c == '\0') {
-+ len = 1;
-+ } else {
- c &= 0x1f;
-- len = 2;
-+ }
- break;
- default:
- c = UChar(*sp);
---
-2.17.1
-
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-patch-20230408-CVE-2023-29491.patch b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-patch-20230408-CVE-2023-29491.patch
new file mode 100644
index 000000000..6e4301e35
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-patch-20230408-CVE-2023-29491.patch
@@ -0,0 +1,1432 @@
+From 50dd6dac94847a1aec06deb324eedef627f1829c Mon Sep 17 00:00:00 2001
+From: Saravanan Palanisamy <saravanan.palanisamy@intel.com>
+Date: Wed, 24 May 2023 12:45:20 +0000
+Subject: [PATCH] ncurses 6.4 - patch 20230408 (for CVE-2023-29491)
+
+From eb51b1ea1f75a0ec17c9c5937cb28df1e8eeec56 Mon Sep 17 00:00:00 2001
+From: "Thomas E. Dickey" <dickey@invisible-island.net>
+Date: Sun, 9 Apr 2023 00:08:25 +0000
+Subject: [PATCH 1/1] ncurses 6.4 - patch 20230408
+
++ document limitations of tparm, and error-returns in curs_terminfo.3x
++ document limitations of tgoto, and error-returns in curs_termcap.3x
++ add xterm+focus to alacritty+common (patch by Christian Duerr).
++ add "-v" option to tput, to show warnings.
+> improve checks for malformed terminfo data (report/analysis by
+ Jonathan Bar Or, Michael Pearse, Emanuele Cozzi).
+ + make the parameter type/count checks in _nc_tiparm() more stringent
+ + update tgoto() to account for _nc_tiparm() changes
+ + add checks in tparm() and tiparm() for misuse of string parameters
+ + add special cases in tput to handle extensions Cs/Ms parameters
+ + ignore compiled-terminfo where the array sizes exceed the standard
+
+Note:
+Did not cherrypick below changes from original patch as it is not applicable
+Intel OpenBMC:
+ package/debian-mingw/changelog
+ package/debian-mingw64/changelog
+ package/debian/changelog
+ package/mingw-ncurses.nsi
+ package/mingw-ncurses.spec
+---
+ NEWS | 15 ++-
+ VERSION | 2 +-
+ dist.mk | 4 +-
+ doc/html/man/adacurses6-config.1.html | 2 +-
+ doc/html/man/captoinfo.1m.html | 2 +-
+ doc/html/man/clear.1.html | 2 +-
+ doc/html/man/curs_termcap.3x.html | 141 +++++++++++++++-----------
+ doc/html/man/curs_terminfo.3x.html | 41 +++++++-
+ doc/html/man/form.3x.html | 2 +-
+ doc/html/man/infocmp.1m.html | 2 +-
+ doc/html/man/infotocap.1m.html | 2 +-
+ doc/html/man/menu.3x.html | 2 +-
+ doc/html/man/ncurses.3x.html | 2 +-
+ doc/html/man/ncurses6-config.1.html | 2 +-
+ doc/html/man/panel.3x.html | 2 +-
+ doc/html/man/tabs.1.html | 2 +-
+ doc/html/man/terminfo.5.html | 2 +-
+ doc/html/man/tic.1m.html | 2 +-
+ doc/html/man/toe.1m.html | 2 +-
+ doc/html/man/tput.1.html | 2 +-
+ doc/html/man/tset.1.html | 2 +-
+ man/curs_termcap.3x | 26 ++++-
+ man/curs_terminfo.3x | 41 +++++++-
+ misc/terminfo.src | 9 +-
+ ncurses/tinfo/lib_tgoto.c | 14 ++-
+ ncurses/tinfo/lib_tparm.c | 120 +++++++++++++++++++---
+ ncurses/tinfo/read_entry.c | 7 +-
+ package/ncurses.spec | 2 +-
+ package/ncursest.spec | 2 +-
+ progs/tic.c | 10 +-
+ progs/tparm_type.c | 13 ++-
+ progs/tparm_type.h | 6 +-
+ progs/tput.c | 61 +++++++++--
+ 33 files changed, 418 insertions(+), 128 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 66e63a39..ab0c10a2 100644
+--- a/NEWS
++++ b/NEWS
+@@ -26,7 +26,7 @@
+ -- sale, use or other dealings in this Software without prior written --
+ -- authorization. --
+ -------------------------------------------------------------------------------
+--- $Id: NEWS,v 1.3895 2022/12/31 20:43:21 tom Exp $
++-- $Id: NEWS,v 1.3929 2023/04/08 22:24:09 tom Exp $
+ -------------------------------------------------------------------------------
+
+ This is a log of changes that ncurses has gone through since Zeyd started
+@@ -46,6 +46,19 @@ See the AUTHORS file for the corresponding full names.
+ Changes through 1.9.9e did not credit all contributions;
+ it is not possible to add this information.
+
++20230408
++ + document limitations of tparm, and error-returns in curs_terminfo.3x
++ + document limitations of tgoto, and error-returns in curs_termcap.3x
++ + add xterm+focus to alacritty+common (patch by Christian Duerr).
++ + add "-v" option to tput, to show warnings.
++ > improve checks for malformed terminfo data (report/analysis by
++ Jonathan Bar Or, Michael Pearse, Emanuele Cozzi).
++ + make the parameter type/count checks in _nc_tiparm() more stringent
++ + update tgoto() to account for _nc_tiparm() changes
++ + add checks in tparm() and tiparm() for misuse of string parameters
++ + add special cases in tput to handle extensions Cs/Ms parameters
++ + ignore compiled-terminfo where the array sizes exceed the standard
++
+ 20221231 6.4 release for upload to ftp.gnu.org
+ + update release notes
+ + regenerate llib-* files.
+diff --git a/VERSION b/VERSION
+index e2dff67c..78269eab 100644
+--- a/VERSION
++++ b/VERSION
+@@ -1 +1 @@
+-5:0:10 6.4 20221231
++5:0:10 6.4 20230408
+diff --git a/dist.mk b/dist.mk
+index ee07796b..a2986a57 100644
+--- a/dist.mk
++++ b/dist.mk
+@@ -26,7 +26,7 @@
+ # use or other dealings in this Software without prior written #
+ # authorization. #
+ ##############################################################################
+-# $Id: dist.mk,v 1.1519 2022/12/31 20:43:21 tom Exp $
++# $Id: dist.mk,v 1.1534 2023/04/08 13:33:20 tom Exp $
+ # Makefile for creating ncurses distributions.
+ #
+ # This only needs to be used directly as a makefile by developers, but
+@@ -38,7 +38,7 @@ SHELL = /bin/sh
+ # These define the major/minor/patch versions of ncurses.
+ NCURSES_MAJOR = 6
+ NCURSES_MINOR = 4
+-NCURSES_PATCH = 20221231
++NCURSES_PATCH = 20230408
+
+ # We don't append the patch to the version, since this only applies to releases
+ VERSION = $(NCURSES_MAJOR).$(NCURSES_MINOR)
+diff --git a/doc/html/man/adacurses6-config.1.html b/doc/html/man/adacurses6-config.1.html
+index 90587e45..fe563fe2 100644
+--- a/doc/html/man/adacurses6-config.1.html
++++ b/doc/html/man/adacurses6-config.1.html
+@@ -126,7 +126,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/captoinfo.1m.html b/doc/html/man/captoinfo.1m.html
+index ab99a7cf..2c914951 100644
+--- a/doc/html/man/captoinfo.1m.html
++++ b/doc/html/man/captoinfo.1m.html
+@@ -199,7 +199,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="infocmp.1m.html">infocmp(1m)</A></STRONG>, <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>, <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+ </PRE><H2><a name="h2-AUTHOR">AUTHOR</a></H2><PRE>
+diff --git a/doc/html/man/clear.1.html b/doc/html/man/clear.1.html
+index 74f5198b..243d57ed 100644
+--- a/doc/html/man/clear.1.html
++++ b/doc/html/man/clear.1.html
+@@ -150,7 +150,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="tput.1.html">tput(1)</A></STRONG>, <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>, <STRONG>xterm(1)</STRONG>.
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/curs_termcap.3x.html b/doc/html/man/curs_termcap.3x.html
+index 9cd555ec..32699b3c 100644
+--- a/doc/html/man/curs_termcap.3x.html
++++ b/doc/html/man/curs_termcap.3x.html
+@@ -1,6 +1,6 @@
+ <!--
+ ****************************************************************************
+- * Copyright 2018-2022,2022 Thomas E. Dickey *
++ * Copyright 2018-2022,2023 Thomas E. Dickey *
+ * Copyright 1998-2017,2018 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -27,7 +27,7 @@
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************
+- * @Id: curs_termcap.3x,v 1.56 2022/02/12 20:05:11 tom Exp @
++ * @Id: curs_termcap.3x,v 1.57 2023/04/08 21:43:01 tom Exp @
+ -->
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+ <HTML>
+@@ -148,27 +148,32 @@
+ first parameter is merely a placeholder.
+
+ <STRONG>o</STRONG> Normally the ncurses library is compiled with terminfo support. In
+- that case, <STRONG>tgoto</STRONG> uses <STRONG><A HREF="curs_terminfo.3x.html">tparm(3x)</A></STRONG> (a more capable formatter).
++ that case, <STRONG>tgoto</STRONG> uses an internal version of <STRONG><A HREF="curs_terminfo.3x.html">tparm(3x)</A></STRONG> (a more ca-
++ pable formatter).
+
+- However, <STRONG>tparm</STRONG> is not a <EM>termcap</EM> feature, and portable <EM>termcap</EM> ap-
++ With terminfo support, <STRONG>tgoto</STRONG> is able to use some of the terminfo
++ features, but not all. In particular, it allows only numeric pa-
++ rameters; <STRONG>tparm</STRONG> supports string parameters.
++
++ However, <STRONG>tparm</STRONG> is not a <EM>termcap</EM> feature, and portable <EM>termcap</EM> ap-
+ plications should not rely upon its availability.
+
+- The <STRONG>tputs</STRONG> routine is described on the <STRONG><A HREF="curs_terminfo.3x.html">curs_terminfo(3x)</A></STRONG> manual page.
++ The <STRONG>tputs</STRONG> routine is described on the <STRONG><A HREF="curs_terminfo.3x.html">curs_terminfo(3x)</A></STRONG> manual page.
+ It can retrieve capabilities by either termcap or terminfo name.
+
+
+ </PRE><H3><a name="h3-Global-Variables">Global Variables</a></H3><PRE>
+- The variables <STRONG>PC</STRONG>, <STRONG>UP</STRONG> and <STRONG>BC</STRONG> are set by <STRONG>tgetent</STRONG> to the terminfo entry's
++ The variables <STRONG>PC</STRONG>, <STRONG>UP</STRONG> and <STRONG>BC</STRONG> are set by <STRONG>tgetent</STRONG> to the terminfo entry's
+ data for <STRONG>pad_char</STRONG>, <STRONG>cursor_up</STRONG> and <STRONG>backspace_if_not_bs</STRONG>, respectively. <STRONG>UP</STRONG>
+- is not used by ncurses. <STRONG>PC</STRONG> is used in the <STRONG>tdelay_output</STRONG> function. <STRONG>BC</STRONG>
+- is used in the <STRONG>tgoto</STRONG> emulation. The variable <STRONG>ospeed</STRONG> is set by ncurses
++ is not used by ncurses. <STRONG>PC</STRONG> is used in the <STRONG>tdelay_output</STRONG> function. <STRONG>BC</STRONG>
++ is used in the <STRONG>tgoto</STRONG> emulation. The variable <STRONG>ospeed</STRONG> is set by ncurses
+ in a system-specific coding to reflect the terminal speed.
+
+
+ </PRE><H3><a name="h3-Releasing-Memory">Releasing Memory</a></H3><PRE>
+- The termcap functions provide no means for freeing memory, because
+- legacy termcap implementations used only the buffer areas provided by
+- the caller via <STRONG>tgetent</STRONG> and <STRONG>tgetstr</STRONG>. Those buffers are unused in ter-
++ The termcap functions provide no means for freeing memory, because
++ legacy termcap implementations used only the buffer areas provided by
++ the caller via <STRONG>tgetent</STRONG> and <STRONG>tgetstr</STRONG>. Those buffers are unused in ter-
+ minfo.
+
+ On the other hand, terminfo allocates memory. It uses <STRONG>setupterm</STRONG> to re-
+@@ -178,41 +183,55 @@
+ <STRONG>del_curterm(cur_term);</STRONG>
+
+
+- to free this memory, but there is an additional complication with
+- ncurses. It uses a fixed-size <EM>pool</EM> of storage locations, one per set-
+- ting of the <STRONG>TERM</STRONG> variable when <STRONG>tgetent</STRONG> is called. The <STRONG>screen(1)</STRONG> pro-
++ to free this memory, but there is an additional complication with
++ ncurses. It uses a fixed-size <EM>pool</EM> of storage locations, one per set-
++ ting of the <STRONG>TERM</STRONG> variable when <STRONG>tgetent</STRONG> is called. The <STRONG>screen(1)</STRONG> pro-
+ gram relies upon this arrangement, to improve its performance.
+
+- An application which uses only the low-level termcap functions could
++ An application which uses only the low-level termcap functions could
+ free the memory using <STRONG>del_curterm</STRONG>, because the pool is freed using oth-
+ er functions (see <STRONG><A HREF="curs_memleaks.3x.html">curs_memleaks(3x)</A></STRONG>).
+
+
+ </PRE><H2><a name="h2-RETURN-VALUE">RETURN VALUE</a></H2><PRE>
+- Except where explicitly noted, routines that return an integer return
+- <STRONG>ERR</STRONG> upon failure and <STRONG>OK</STRONG> (SVr4 only specifies "an integer value other
++ Except where explicitly noted, routines that return an integer return
++ <STRONG>ERR</STRONG> upon failure and <STRONG>OK</STRONG> (SVr4 only specifies "an integer value other
+ than <STRONG>ERR</STRONG>") upon successful completion.
+
+ Routines that return pointers return <STRONG>NULL</STRONG> on error.
+
++ A few special cases apply:
++
++ <STRONG>o</STRONG> If the terminal database has not been initialized, these return an
++ error.
++
++ <STRONG>o</STRONG> The calls with a string parameter (<STRONG>tgoto</STRONG>, <STRONG>tputs</STRONG>) check if the
++ string is null, or cancelled. Those return an error.
++
++ <STRONG>o</STRONG> A call to <STRONG>tgoto</STRONG> using a capability with string parameters is an er-
++ ror.
++
++ <STRONG>o</STRONG> A call to <STRONG>tgoto</STRONG> using a capability with no parameters, or more than
++ two is an error.
++
+
+ </PRE><H2><a name="h2-BUGS">BUGS</a></H2><PRE>
+- If you call <STRONG>tgetstr</STRONG> to fetch <STRONG>ca</STRONG> or any other parameterized string, be
+- aware that it will be returned in terminfo notation, not the older and
++ If you call <STRONG>tgetstr</STRONG> to fetch <STRONG>ca</STRONG> or any other parameterized string, be
++ aware that it will be returned in terminfo notation, not the older and
+ not-quite-compatible termcap notation. This will not cause problems if
+- all you do with it is call <STRONG>tgoto</STRONG> or <STRONG>tparm</STRONG>, which both expand terminfo-
+- style strings as terminfo. (The <STRONG>tgoto</STRONG> function, if configured to sup-
+- port termcap, will check if the string is indeed terminfo-style by
+- looking for "%p" parameters or "$&lt;..&gt;" delays, and invoke a termcap-
++ all you do with it is call <STRONG>tgoto</STRONG> or <STRONG>tparm</STRONG>, which both expand terminfo-
++ style strings as terminfo. (The <STRONG>tgoto</STRONG> function, if configured to sup-
++ port termcap, will check if the string is indeed terminfo-style by
++ looking for "%p" parameters or "$&lt;..&gt;" delays, and invoke a termcap-
+ style parser if the string does not appear to be terminfo).
+
+- Because terminfo conventions for representing padding in string capa-
++ Because terminfo conventions for representing padding in string capa-
+ bilities differ from termcap's, users can be surprised:
+
+ <STRONG>o</STRONG> <STRONG>tputs("50")</STRONG> in a terminfo system will put out a literal "50" rather
+ than busy-waiting for 50 milliseconds.
+
+- <STRONG>o</STRONG> However, if ncurses is configured to support termcap, it may also
++ <STRONG>o</STRONG> However, if ncurses is configured to support termcap, it may also
+ have been configured to support the BSD-style padding.
+
+ In that case, <STRONG>tputs</STRONG> inspects strings passed to it, looking for dig-
+@@ -221,9 +240,9 @@
+ <STRONG>tputs("50")</STRONG> in a termcap system may wait for 50 milliseconds rather
+ than put out a literal "50"
+
+- Note that termcap has nothing analogous to terminfo's <STRONG>sgr</STRONG> string. One
+- consequence of this is that termcap applications assume <STRONG>me</STRONG> (terminfo
+- <STRONG>sgr0</STRONG>) does not reset the alternate character set. This implementation
++ Note that termcap has nothing analogous to terminfo's <STRONG>sgr</STRONG> string. One
++ consequence of this is that termcap applications assume <STRONG>me</STRONG> (terminfo
++ <STRONG>sgr0</STRONG>) does not reset the alternate character set. This implementation
+ checks for, and modifies the data shown to the termcap interface to ac-
+ commodate termcap's limitation in this respect.
+
+@@ -231,22 +250,22 @@
+ </PRE><H2><a name="h2-PORTABILITY">PORTABILITY</a></H2><PRE>
+
+ </PRE><H3><a name="h3-Standards">Standards</a></H3><PRE>
+- These functions are provided for supporting legacy applications, and
++ These functions are provided for supporting legacy applications, and
+ should not be used in new programs:
+
+ <STRONG>o</STRONG> The XSI Curses standard, Issue 4 describes these functions. Howev-
+- er, they are marked TO BE WITHDRAWN and may be removed in future
++ er, they are marked TO BE WITHDRAWN and may be removed in future
+ versions.
+
+ <STRONG>o</STRONG> X/Open Curses, Issue 5 (December 2007) marked the termcap interface
+ (along with <STRONG>vwprintw</STRONG> and <STRONG>vwscanw</STRONG>) as withdrawn.
+
+- Neither the XSI Curses standard nor the SVr4 man pages documented the
+- return values of <STRONG>tgetent</STRONG> correctly, though all three were in fact re-
+- turned ever since SVr1. In particular, an omission in the XSI Curses
+- documentation has been misinterpreted to mean that <STRONG>tgetent</STRONG> returns <STRONG>OK</STRONG>
+- or <STRONG>ERR</STRONG>. Because the purpose of these functions is to provide compati-
+- bility with the <EM>termcap</EM> library, that is a defect in XCurses, Issue 4,
++ Neither the XSI Curses standard nor the SVr4 man pages documented the
++ return values of <STRONG>tgetent</STRONG> correctly, though all three were in fact re-
++ turned ever since SVr1. In particular, an omission in the XSI Curses
++ documentation has been misinterpreted to mean that <STRONG>tgetent</STRONG> returns <STRONG>OK</STRONG>
++ or <STRONG>ERR</STRONG>. Because the purpose of these functions is to provide compati-
++ bility with the <EM>termcap</EM> library, that is a defect in XCurses, Issue 4,
+ Version 2 rather than in ncurses.
+
+
+@@ -254,68 +273,68 @@
+ External variables are provided for support of certain termcap applica-
+ tions. However, termcap applications' use of those variables is poorly
+ documented, e.g., not distinguishing between input and output. In par-
+- ticular, some applications are reported to declare and/or modify <STRONG>os-</STRONG>
++ ticular, some applications are reported to declare and/or modify <STRONG>os-</STRONG>
+ <STRONG>peed</STRONG>.
+
+- The comment that only the first two characters of the <STRONG>id</STRONG> parameter are
++ The comment that only the first two characters of the <STRONG>id</STRONG> parameter are
+ used escapes many application developers. The original BSD 4.2 termcap
+ library (and historical relics thereof) did not require a trailing null
+- NUL on the parameter name passed to <STRONG>tgetstr</STRONG>, <STRONG>tgetnum</STRONG> and <STRONG>tgetflag</STRONG>.
+- Some applications assume that the termcap interface does not require
++ NUL on the parameter name passed to <STRONG>tgetstr</STRONG>, <STRONG>tgetnum</STRONG> and <STRONG>tgetflag</STRONG>.
++ Some applications assume that the termcap interface does not require
+ the trailing NUL for the parameter name. Taking into account these is-
+ sues:
+
+- <STRONG>o</STRONG> As a special case, <STRONG>tgetflag</STRONG> matched against a single-character
+- identifier provided that was at the end of the terminal descrip-
++ <STRONG>o</STRONG> As a special case, <STRONG>tgetflag</STRONG> matched against a single-character
++ identifier provided that was at the end of the terminal descrip-
+ tion. You should not rely upon this behavior in portable programs.
+- This implementation disallows matches against single-character ca-
++ This implementation disallows matches against single-character ca-
+ pability names.
+
+- <STRONG>o</STRONG> This implementation disallows matches by the termcap interface
++ <STRONG>o</STRONG> This implementation disallows matches by the termcap interface
+ against extended capability names which are longer than two charac-
+ ters.
+
+ The BSD termcap function <STRONG>tgetent</STRONG> returns the text of a termcap entry in
+- the buffer passed as an argument. This library (like other terminfo
++ the buffer passed as an argument. This library (like other terminfo
+ implementations) does not store terminal descriptions as text. It sets
+ the buffer contents to a null-terminated string.
+
+
+ </PRE><H3><a name="h3-Other-Compatibility">Other Compatibility</a></H3><PRE>
+- This library includes a termcap.h header, for compatibility with other
+- implementations. But the header is rarely used because the other im-
++ This library includes a termcap.h header, for compatibility with other
++ implementations. But the header is rarely used because the other im-
+ plementations are not strictly compatible.
+
+ The original BSD termcap (through 4.3BSD) had no header file which gave
+ function prototypes, because that was a feature of ANSI C. BSD termcap
+- was written several years before C was standardized. However, there
++ was written several years before C was standardized. However, there
+ were two different termcap.h header files in the BSD sources:
+
+- <STRONG>o</STRONG> One was used internally by the <STRONG>jove</STRONG> editor in 2BSD through 4.4BSD.
++ <STRONG>o</STRONG> One was used internally by the <STRONG>jove</STRONG> editor in 2BSD through 4.4BSD.
+ It defined global symbols for the termcap variables which it used.
+
+- <STRONG>o</STRONG> The other appeared in 4.4BSD Lite Release 2 (mid-1993) as part of
++ <STRONG>o</STRONG> The other appeared in 4.4BSD Lite Release 2 (mid-1993) as part of
+ <EM>libedit</EM> (also known as the <EM>editline</EM> library). The CSRG source his-
+- tory shows that this was added in mid-1992. The <EM>libedit</EM> header
+- file was used internally, as a convenience for compiling the <EM>edit-</EM>
++ tory shows that this was added in mid-1992. The <EM>libedit</EM> header
++ file was used internally, as a convenience for compiling the <EM>edit-</EM>
+ <EM>line</EM> library. It declared function prototypes, but no global vari-
+ ables.
+
+- The header file from <EM>libedit</EM> was added to NetBSD's termcap library in
++ The header file from <EM>libedit</EM> was added to NetBSD's termcap library in
+ mid-1994.
+
+- Meanwhile, GNU termcap was under development, starting in 1990. The
+- first release (termcap 1.0) in 1991 included a termcap.h header. The
+- second release (termcap 1.1) in September 1992 modified the header to
++ Meanwhile, GNU termcap was under development, starting in 1990. The
++ first release (termcap 1.0) in 1991 included a termcap.h header. The
++ second release (termcap 1.1) in September 1992 modified the header to
+ use <STRONG>const</STRONG> for the function prototypes in the header where one would ex-
+- pect the parameters to be read-only. This was a difference versus the
+- original BSD termcap. The prototype for <STRONG>tputs</STRONG> also differed, but in
++ pect the parameters to be read-only. This was a difference versus the
++ original BSD termcap. The prototype for <STRONG>tputs</STRONG> also differed, but in
+ that instance, it was <EM>libedit</EM> which differed from BSD termcap.
+
+ A copy of GNU termcap 1.3 was bundled with <EM>bash</EM> in mid-1993, to support
+ the <STRONG>readline(3)</STRONG> library.
+
+- A termcap.h file was provided in ncurses 1.8.1 (November 1993). That
++ A termcap.h file was provided in ncurses 1.8.1 (November 1993). That
+ reflected influence by <STRONG>emacs(1)</STRONG> (rather than <STRONG>jove(1)</STRONG>) and GNU termcap:
+
+ <STRONG>o</STRONG> it provided declarations for a few global symbols used by <STRONG>emacs</STRONG>
+@@ -325,8 +344,8 @@
+ <STRONG>o</STRONG> a prototype for <STRONG>tparam</STRONG> (a GNU termcap feature) was provided.
+
+ Later (in mid-1996) the <STRONG>tparam</STRONG> function was removed from ncurses. As a
+- result, there are differences between any of the four implementations,
+- which must be taken into account by programs which can work with all
++ result, there are differences between any of the four implementations,
++ which must be taken into account by programs which can work with all
+ termcap library interfaces.
+
+
+diff --git a/doc/html/man/curs_terminfo.3x.html b/doc/html/man/curs_terminfo.3x.html
+index c50d7db3..480cafce 100644
+--- a/doc/html/man/curs_terminfo.3x.html
++++ b/doc/html/man/curs_terminfo.3x.html
+@@ -1,6 +1,6 @@
+ <!--
+ ****************************************************************************
+- * Copyright 2018-2022,2022 Thomas E. Dickey *
++ * Copyright 2018-2022,2023 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -27,7 +27,7 @@
+ * sale, use or other dealings in this Software without prior written *
+ * authorization. *
+ ****************************************************************************
+- * @Id: curs_terminfo.3x,v 1.82 2022/06/04 22:47:05 tom Exp @
++ * @Id: curs_terminfo.3x,v 1.83 2023/04/08 22:54:21 tom Exp @
+ * ***************************************************************************
+ * ***************************************************************************
+ * ***************************************************************************
+@@ -83,6 +83,9 @@
+ <STRONG>int</STRONG> <STRONG>restartterm(const</STRONG> <STRONG>char</STRONG> <STRONG>*</STRONG><EM>term</EM><STRONG>,</STRONG> <STRONG>int</STRONG> <EM>filedes</EM><STRONG>,</STRONG> <STRONG>int</STRONG> <STRONG>*</STRONG><EM>errret</EM><STRONG>);</STRONG>
+
+ <STRONG>char</STRONG> <STRONG>*tparm(const</STRONG> <STRONG>char</STRONG> <STRONG>*</STRONG><EM>str</EM><STRONG>,</STRONG> <STRONG>...);</STRONG>
++ <EM>or</EM>
++ <STRONG>char</STRONG> <STRONG>*tparm(const</STRONG> <STRONG>char</STRONG> <STRONG>*</STRONG><EM>str</EM><STRONG>,</STRONG> <STRONG>long</STRONG> <EM>p1</EM> <EM>...</EM> <STRONG>long</STRONG> <EM>p9</EM><STRONG>);</STRONG>
++
+ <STRONG>int</STRONG> <STRONG>tputs(const</STRONG> <STRONG>char</STRONG> <STRONG>*</STRONG><EM>str</EM><STRONG>,</STRONG> <STRONG>int</STRONG> <EM>affcnt</EM><STRONG>,</STRONG> <STRONG>int</STRONG> <STRONG>(*</STRONG><EM>putc</EM><STRONG>)(int));</STRONG>
+ <STRONG>int</STRONG> <STRONG>putp(const</STRONG> <STRONG>char</STRONG> <STRONG>*</STRONG><EM>str</EM><STRONG>);</STRONG>
+
+@@ -398,6 +401,11 @@
+ the initial windows (stdscr, curscr, newscr). Other error con-
+ ditions are documented above.
+
++ <STRONG>tparm</STRONG>
++ returns a null if the capability would require unexpected pa-
++ rameters, e.g., too many, too few, or incorrect types (strings
++ where integers are expected, or vice versa).
++
+ <STRONG>tputs</STRONG>
+ returns an error if the string parameter is null. It does not
+ detect I/O errors: X/Open states that <STRONG>tputs</STRONG> ignores the return
+@@ -466,7 +474,6 @@
+ <STRONG>Function</STRONG> <STRONG>Description</STRONG>
+ -------------------------------------------
+ tigetflag get boolean entry for given <EM>id</EM>
+-
+ tigetnum get numeric entry for given <EM>id</EM>
+ tigetstr get string entry for given <EM>id</EM>
+
+@@ -568,6 +575,34 @@
+ In response to review comments by Thomas E. Dickey, X/Open Curses
+ Issue 7 proposed the <STRONG>tiparm</STRONG> function in mid-2009.
+
++ While <STRONG>tiparm</STRONG> is always provided in ncurses, the older form is only
++ available as a build-time configuration option. If not specially
++ configured, <STRONG>tparm</STRONG> is the same as <STRONG>tiparm</STRONG>.
++
++ Both forms of <STRONG>tparm</STRONG> have drawbacks:
++
++ <STRONG>o</STRONG> Most of the calls to <STRONG>tparm</STRONG> use only one or two parameters. Passing
++ nine on each call is awkward.
++
++ Using <STRONG>long</STRONG> for the numeric parameter type is a workaround to make
++ the parameter use the same amount of stack as a pointer. That ap-
++ proach dates back to the mid-1980s, before C was standarized.
++ Since then, there is a standard (and pointers are not required to
++ fit in a long).
++
++ <STRONG>o</STRONG> Providing the right number of parameters for a variadic function
++ such as <STRONG>tiparm</STRONG> can be a problem, in particular for string parame-
++ ters. However, only a few terminfo capabilities use string parame-
++ ters (e.g., the ones used for programmable function keys).
++
++ The ncurses library checks usage of these capabilities, and returns
++ an error if the capability mishandles string parameters. But it
++ cannot check if a calling program provides strings in the right
++ places for the <STRONG>tparm</STRONG> calls.
++
++ The <STRONG><A HREF="tput.3x.html">tput(3x)</A></STRONG> program checks its use of these capabilities with a
++ table, so that it calls <STRONG>tparm</STRONG> correctly.
++
+
+ </PRE><H3><a name="h3-Special-TERM-treatment">Special TERM treatment</a></H3><PRE>
+ If configured to use the terminal-driver, e.g., for the MinGW port,
+diff --git a/doc/html/man/form.3x.html b/doc/html/man/form.3x.html
+index 422171c8..9551b458 100644
+--- a/doc/html/man/form.3x.html
++++ b/doc/html/man/form.3x.html
+@@ -248,7 +248,7 @@
+ <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG> and related pages whose names begin "form_" for detailed
+ descriptions of the entry points.
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/infocmp.1m.html b/doc/html/man/infocmp.1m.html
+index 81b95ac5..a72af34b 100644
+--- a/doc/html/man/infocmp.1m.html
++++ b/doc/html/man/infocmp.1m.html
+@@ -514,7 +514,7 @@
+
+ https://invisible-island.net/ncurses/tctest.html
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+ </PRE><H2><a name="h2-AUTHOR">AUTHOR</a></H2><PRE>
+diff --git a/doc/html/man/infotocap.1m.html b/doc/html/man/infotocap.1m.html
+index 1ea690cb..1ab52071 100644
+--- a/doc/html/man/infotocap.1m.html
++++ b/doc/html/man/infotocap.1m.html
+@@ -91,7 +91,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="infocmp.1m.html">infocmp(1m)</A></STRONG>, <STRONG><A HREF="tic.1m.html">tic(1m)</A></STRONG>, <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>, <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+ </PRE><H2><a name="h2-AUTHOR">AUTHOR</a></H2><PRE>
+diff --git a/doc/html/man/menu.3x.html b/doc/html/man/menu.3x.html
+index a8f2c961..8f4641bf 100644
+--- a/doc/html/man/menu.3x.html
++++ b/doc/html/man/menu.3x.html
+@@ -223,7 +223,7 @@
+ <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG> and related pages whose names begin "menu_" for detailed
+ descriptions of the entry points.
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/ncurses.3x.html b/doc/html/man/ncurses.3x.html
+index ab2b69d1..9cf27bf5 100644
+--- a/doc/html/man/ncurses.3x.html
++++ b/doc/html/man/ncurses.3x.html
+@@ -60,7 +60,7 @@
+ method of updating character screens with reasonable optimization.
+ This implementation is "new curses" (ncurses) and is the approved
+ replacement for 4.4BSD classic curses, which has been discontinued.
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+ The <STRONG>ncurses</STRONG> library emulates the curses library of System V Release 4
+ UNIX, and XPG4 (X/Open Portability Guide) curses (also known as XSI
+diff --git a/doc/html/man/ncurses6-config.1.html b/doc/html/man/ncurses6-config.1.html
+index 0f64e3de..9cd27f50 100644
+--- a/doc/html/man/ncurses6-config.1.html
++++ b/doc/html/man/ncurses6-config.1.html
+@@ -113,7 +113,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/panel.3x.html b/doc/html/man/panel.3x.html
+index 761a0fbd..0fd84723 100644
+--- a/doc/html/man/panel.3x.html
++++ b/doc/html/man/panel.3x.html
+@@ -281,7 +281,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>, <STRONG><A HREF="curs_variables.3x.html">curs_variables(3x)</A></STRONG>,
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+ </PRE><H2><a name="h2-AUTHOR">AUTHOR</a></H2><PRE>
+diff --git a/doc/html/man/tabs.1.html b/doc/html/man/tabs.1.html
+index 3e9f0f9d..228e17d8 100644
+--- a/doc/html/man/tabs.1.html
++++ b/doc/html/man/tabs.1.html
+@@ -252,7 +252,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="infocmp.1m.html">infocmp(1m)</A></STRONG>, <STRONG><A HREF="tset.1.html">tset(1)</A></STRONG>, <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>, <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>.
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/terminfo.5.html b/doc/html/man/terminfo.5.html
+index 23b27bfb..88986bf7 100644
+--- a/doc/html/man/terminfo.5.html
++++ b/doc/html/man/terminfo.5.html
+@@ -106,7 +106,7 @@
+ have, by specifying how to perform screen operations, and by specifying
+ padding requirements and initialization sequences.
+
+- This manual describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This manual describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+ </PRE><H3><a name="h3-Terminfo-Entry-Syntax">Terminfo Entry Syntax</a></H3><PRE>
+diff --git a/doc/html/man/tic.1m.html b/doc/html/man/tic.1m.html
+index cced3343..6c12f037 100644
+--- a/doc/html/man/tic.1m.html
++++ b/doc/html/man/tic.1m.html
+@@ -469,7 +469,7 @@
+ <STRONG><A HREF="captoinfo.1m.html">captoinfo(1m)</A></STRONG>, <STRONG><A HREF="infocmp.1m.html">infocmp(1m)</A></STRONG>, <STRONG><A HREF="infotocap.1m.html">infotocap(1m)</A></STRONG>, <STRONG><A HREF="toe.1m.html">toe(1m)</A></STRONG>, <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>,
+ <STRONG><A HREF="term.5.html">term(5)</A></STRONG>. <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>. <STRONG><A HREF="user_caps.5.html">user_caps(5)</A></STRONG>.
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+ </PRE><H2><a name="h2-AUTHOR">AUTHOR</a></H2><PRE>
+diff --git a/doc/html/man/toe.1m.html b/doc/html/man/toe.1m.html
+index a9151184..38859624 100644
+--- a/doc/html/man/toe.1m.html
++++ b/doc/html/man/toe.1m.html
+@@ -171,7 +171,7 @@
+ <STRONG><A HREF="captoinfo.1m.html">captoinfo(1m)</A></STRONG>, <STRONG><A HREF="infocmp.1m.html">infocmp(1m)</A></STRONG>, <STRONG><A HREF="infotocap.1m.html">infotocap(1m)</A></STRONG>, <STRONG><A HREF="tic.1m.html">tic(1m)</A></STRONG>, <STRONG><A HREF="ncurses.3x.html">curses(3x)</A></STRONG>,
+ <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>.
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/tput.1.html b/doc/html/man/tput.1.html
+index 6a330a55..ee231640 100644
+--- a/doc/html/man/tput.1.html
++++ b/doc/html/man/tput.1.html
+@@ -545,7 +545,7 @@
+ </PRE><H2><a name="h2-SEE-ALSO">SEE ALSO</a></H2><PRE>
+ <STRONG><A HREF="clear.1.html">clear(1)</A></STRONG>, <STRONG>stty(1)</STRONG>, <STRONG><A HREF="tabs.1.html">tabs(1)</A></STRONG>, <STRONG><A HREF="tset.1.html">tset(1)</A></STRONG>, <STRONG><A HREF="curs_termcap.3x.html">curs_termcap(3x)</A></STRONG>, <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>.
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/doc/html/man/tset.1.html b/doc/html/man/tset.1.html
+index c610a8c8..19396d91 100644
+--- a/doc/html/man/tset.1.html
++++ b/doc/html/man/tset.1.html
+@@ -391,7 +391,7 @@
+ <STRONG>csh(1)</STRONG>, <STRONG>sh(1)</STRONG>, <STRONG>stty(1)</STRONG>, <STRONG><A HREF="curs_terminfo.3x.html">curs_terminfo(3x)</A></STRONG>, <STRONG>tty(4)</STRONG>, <STRONG><A HREF="terminfo.5.html">terminfo(5)</A></STRONG>,
+ <STRONG>ttys(5)</STRONG>, <STRONG>environ(7)</STRONG>
+
+- This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20221231).
++ This describes <STRONG>ncurses</STRONG> version 6.4 (patch 20230408).
+
+
+
+diff --git a/man/curs_termcap.3x b/man/curs_termcap.3x
+index e073d940..1630658d 100644
+--- a/man/curs_termcap.3x
++++ b/man/curs_termcap.3x
+@@ -1,5 +1,5 @@
+ .\"***************************************************************************
+-.\" Copyright 2018-2022,2022 Thomas E. Dickey *
++.\" Copyright 2018-2022,2023 Thomas E. Dickey *
+ .\" Copyright 1998-2017,2018 Free Software Foundation, Inc. *
+ .\" *
+ .\" Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -27,7 +27,7 @@
+ .\" authorization. *
+ .\"***************************************************************************
+ .\"
+-.\" $Id: curs_termcap.3x,v 1.56 2022/02/12 20:05:11 tom Exp $
++.\" $Id: curs_termcap.3x,v 1.57 2023/04/08 21:43:01 tom Exp $
+ .TH curs_termcap 3X ""
+ .ie \n(.g .ds `` \(lq
+ .el .ds `` ``
+@@ -173,7 +173,13 @@ It does this also for calls requiring only a single parameter.
+ In that case, the first parameter is merely a placeholder.
+ .bP
+ Normally the ncurses library is compiled with terminfo support.
+-In that case, \fBtgoto\fP uses \fBtparm\fP(3X) (a more capable formatter).
++In that case, \fBtgoto\fP uses an internal version of
++\fBtparm\fP(3X) (a more capable formatter).
++.IP
++With terminfo support, \fBtgoto\fP is able to use some of the terminfo
++features, but not all.
++In particular, it allows only numeric parameters;
++\fBtparm\fP supports string parameters.
+ .IP
+ However, \fBtparm\fP is not a \fItermcap\fP feature,
+ and portable \fItermcap\fP applications should not rely upon its availability.
+@@ -229,6 +235,20 @@ routines that return an integer return \fBERR\fP upon failure and \fBOK\fP
+ completion.
+ .PP
+ Routines that return pointers return \fBNULL\fP on error.
++.PP
++A few special cases apply:
++.bP
++If the terminal database has not been initialized,
++these return an error.
++.bP
++The calls with a string parameter (\fBtgoto\fP, \fBtputs\fP)
++check if the string is null, or cancelled.
++Those return an error.
++.bP
++A call to \fBtgoto\fP using a capability with string parameters is an error.
++.bP
++A call to \fBtgoto\fP using a capability with no parameters,
++or more than two is an error.
+ .SH BUGS
+ If you call \fBtgetstr\fP to fetch \fBca\fP or any other parameterized string,
+ be aware that it will be returned in terminfo notation, not the older and
+diff --git a/man/curs_terminfo.3x b/man/curs_terminfo.3x
+index 00ae1349..5ea01ee6 100644
+--- a/man/curs_terminfo.3x
++++ b/man/curs_terminfo.3x
+@@ -1,5 +1,5 @@
+ .\"***************************************************************************
+-.\" Copyright 2018-2022,2022 Thomas E. Dickey *
++.\" Copyright 2018-2022,2023 Thomas E. Dickey *
+ .\" Copyright 1998-2016,2017 Free Software Foundation, Inc. *
+ .\" *
+ .\" Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -27,7 +27,7 @@
+ .\" authorization. *
+ .\"***************************************************************************
+ .\"
+-.\" $Id: curs_terminfo.3x,v 1.82 2022/06/04 22:47:05 tom Exp $
++.\" $Id: curs_terminfo.3x,v 1.83 2023/04/08 22:54:21 tom Exp $
+ .TH curs_terminfo 3X ""
+ .ie \n(.g .ds `` \(lq
+ .el .ds `` ``
+@@ -86,6 +86,10 @@
+ .sp
+ \fBchar *tparm(const char *\fIstr\fB, ...);\fR
+ .br
++ \fIor\fP
++.br
++\fBchar *tparm(const char *\fIstr\fB, long \fIp1 ... \fBlong \fIp9\fB);\fR
++.sp
+ \fBint tputs(const char *\fIstr\fB, int \fIaffcnt\fB, int (*\fIputc\fB)(int));\fR
+ .br
+ \fBint putp(const char *\fIstr\fB);\fR
+@@ -463,6 +467,11 @@ if it cannot allocate enough memory, or
+ create the initial windows (stdscr, curscr, newscr).
+ Other error conditions are documented above.
+ .TP 5
++\fBtparm\fP
++returns a null if the capability would require unexpected parameters,
++e.g., too many, too few, or incorrect types
++(strings where integers are expected, or vice versa).
++.TP 5
+ \fBtputs\fP
+ returns an error if the string parameter is null.
+ It does not detect I/O errors:
+@@ -663,6 +672,34 @@ zeroes are fine for this purpose.
+ .IP
+ In response to review comments by Thomas E. Dickey,
+ X/Open Curses Issue 7 proposed the \fBtiparm\fP function in mid-2009.
++.IP
++While \fBtiparm\fP is always provided in ncurses,
++the older form is only available as a build-time configuration option.
++If not specially configured, \fBtparm\fP is the same as \fBtiparm\fP.
++.PP
++Both forms of \fBtparm\fP have drawbacks:
++.bP
++Most of the calls to \fBtparm\fP use only one or two parameters.
++Passing nine on each call is awkward.
++.IP
++Using \fBlong\fP for the numeric parameter type is a workaround
++to make the parameter use the same amount of stack as a pointer.
++That approach dates back to the mid-1980s, before C was standarized.
++Since then, there is a standard
++(and pointers are not required to fit in a long).
++.bP
++Providing the right number of parameters for a variadic function
++such as \fBtiparm\fP can be a problem, in particular for string parameters.
++However, only a few terminfo capabilities use string parameters
++(e.g., the ones used for programmable function keys).
++.IP
++The ncurses library checks usage of these capabilities,
++and returns an error if the capability mishandles string parameters.
++But it cannot check if a calling program provides strings in the right
++places for the \fBtparm\fP calls.
++.IP
++The \fBtput\fR(3X) program checks its use of these capabilities with a table,
++so that it calls \fBtparm\fP correctly.
+ .SS Special TERM treatment
+ .PP
+ If configured to use the terminal-driver,
+diff --git a/misc/terminfo.src b/misc/terminfo.src
+index ef78948a..07713a81 100644
+--- a/misc/terminfo.src
++++ b/misc/terminfo.src
+@@ -6,8 +6,8 @@
+ # Report bugs and new terminal descriptions to
+ # bug-ncurses@gnu.org
+ #
+-# $Revision: 1.1041 $
+-# $Date: 2022/12/29 20:11:56 $
++# $Revision: 1.1057 $
++# $Date: 2023/04/08 21:08:00 $
+ #
+ # The original header is preserved below for reference. It is noted that there
+ # is a "newer" version which differs in some cosmetic details (but actually
+@@ -7756,7 +7756,7 @@ alacritty+common|base fragment for alacritty,
+ use=xterm-basic, use=xterm+app, use=ansi+rep,
+ use=xterm+tmux, use=ecma+strikeout, use=xterm+sl-twm,
+ use=ecma+italics, use=xterm+pce2, use=xterm+pcc2,
+- use=xterm+pcf2, use=bracketed+paste,
++ use=xterm+pcf2, use=bracketed+paste, use=xterm+focus,
+
+ #### Kitty
+ # https://github.com/kovidgoyal/kitty
+@@ -27717,4 +27717,7 @@ v3220|LANPAR Vision II model 3220/3221/3222,
+ # + correct PS vs PE names in bracketed+paste (report by Bram Moolenaar)
+ # -TD
+ #
++# 2023-04-08
++# + add xterm+focus to alacritty+common (patch by Christian Duerr).
++#
+ ######## SHANTIH! SHANTIH! SHANTIH!
+diff --git a/ncurses/tinfo/lib_tgoto.c b/ncurses/tinfo/lib_tgoto.c
+index 9cf5e100..084a322f 100644
+--- a/ncurses/tinfo/lib_tgoto.c
++++ b/ncurses/tinfo/lib_tgoto.c
+@@ -1,5 +1,5 @@
+ /****************************************************************************
+- * Copyright 2018-2019,2020 Thomas E. Dickey *
++ * Copyright 2018-2020,2023 Thomas E. Dickey *
+ * Copyright 2000-2008,2012 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -36,7 +36,7 @@
+ #include <ctype.h>
+ #include <termcap.h>
+
+-MODULE_ID("$Id: lib_tgoto.c,v 1.21 2020/05/27 23:55:56 tom Exp $")
++MODULE_ID("$Id: lib_tgoto.c,v 1.22 2023/04/08 13:48:58 tom Exp $")
+
+ #if !PURE_TERMINFO
+ static bool
+@@ -207,6 +207,14 @@ tgoto(const char *string, int x, int y)
+ result = tgoto_internal(string, x, y);
+ else
+ #endif
+- result = TIPARM_2(string, y, x);
++ if ((result = TIPARM_2(string, y, x)) == NULL) {
++ /*
++ * Because termcap did not provide a more general solution such as
++ * tparm(), it was necessary to handle single-parameter capabilities
++ * using tgoto(). The internal _nc_tiparm() function returns a NULL
++ * for that case; retry for the single-parameter case.
++ */
++ result = TIPARM_1(string, y);
++ }
+ returnPtr(result);
+ }
+diff --git a/ncurses/tinfo/lib_tparm.c b/ncurses/tinfo/lib_tparm.c
+index d9bdfd8f..8988a3d4 100644
+--- a/ncurses/tinfo/lib_tparm.c
++++ b/ncurses/tinfo/lib_tparm.c
+@@ -1,5 +1,5 @@
+ /****************************************************************************
+- * Copyright 2018-2020,2021 Thomas E. Dickey *
++ * Copyright 2018-2021,2023 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -53,7 +53,7 @@
+ #include <ctype.h>
+ #include <tic.h>
+
+-MODULE_ID("$Id: lib_tparm.c,v 1.137 2021/11/20 23:29:15 tom Exp $")
++MODULE_ID("$Id: lib_tparm.c,v 1.141 2023/04/08 18:24:18 tom Exp $")
+
+ /*
+ * char *
+@@ -1086,6 +1086,64 @@ tparam_internal(TPARM_STATE *tps, const char *string, TPARM_DATA *data)
+ return (TPS(out_buff));
+ }
+
++#ifdef CUR
++/*
++ * Only a few standard capabilities accept string parameters. The others that
++ * are parameterized accept only numeric parameters.
++ */
++static bool
++check_string_caps(TPARM_DATA *data, const char *string)
++{
++ bool result = FALSE;
++
++#define CHECK_CAP(name) (VALID_STRING(name) && !strcmp(name, string))
++
++ /*
++ * Disallow string parameters unless we can check them against a terminal
++ * description.
++ */
++ if (cur_term != NULL) {
++ int want_type = 0;
++
++ if (CHECK_CAP(pkey_key))
++ want_type = 2; /* function key #1, type string #2 */
++ else if (CHECK_CAP(pkey_local))
++ want_type = 2; /* function key #1, execute string #2 */
++ else if (CHECK_CAP(pkey_xmit))
++ want_type = 2; /* function key #1, transmit string #2 */
++ else if (CHECK_CAP(plab_norm))
++ want_type = 2; /* label #1, show string #2 */
++ else if (CHECK_CAP(pkey_plab))
++ want_type = 6; /* function key #1, type string #2, show string #3 */
++#if NCURSES_XNAMES
++ else {
++ char *check;
++
++ check = tigetstr("Cs");
++ if (CHECK_CAP(check))
++ want_type = 1; /* style #1 */
++
++ check = tigetstr("Ms");
++ if (CHECK_CAP(check))
++ want_type = 3; /* storage unit #1, content #2 */
++ }
++#endif
++
++ if (want_type == data->tparm_type) {
++ result = TRUE;
++ } else {
++ T(("unexpected string-parameter"));
++ }
++ }
++ return result;
++}
++
++#define ValidCap() (myData.tparm_type == 0 || \
++ check_string_caps(&myData, string))
++#else
++#define ValidCap() 1
++#endif
++
+ #if NCURSES_TPARM_VARARGS
+
+ NCURSES_EXPORT(char *)
+@@ -1100,7 +1158,7 @@ tparm(const char *string, ...)
+ tps->tname = "tparm";
+ #endif /* TRACE */
+
+- if (tparm_setup(cur_term, string, &myData) == OK) {
++ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
+ va_list ap;
+
+ va_start(ap, string);
+@@ -1135,7 +1193,7 @@ tparm(const char *string,
+ tps->tname = "tparm";
+ #endif /* TRACE */
+
+- if (tparm_setup(cur_term, string, &myData) == OK) {
++ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
+
+ myData.param[0] = a1;
+ myData.param[1] = a2;
+@@ -1166,7 +1224,7 @@ tiparm(const char *string, ...)
+ tps->tname = "tiparm";
+ #endif /* TRACE */
+
+- if (tparm_setup(cur_term, string, &myData) == OK) {
++ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
+ va_list ap;
+
+ va_start(ap, string);
+@@ -1179,7 +1237,25 @@ tiparm(const char *string, ...)
+ }
+
+ /*
+- * The internal-use flavor ensures that the parameters are numbers, not strings
++ * The internal-use flavor ensures that parameters are numbers, not strings.
++ * In addition to ensuring that they are numbers, it ensures that the parameter
++ * count is consistent with intended usage.
++ *
++ * Unlike the general-purpose tparm/tiparm, these internal calls are fairly
++ * well defined:
++ *
++ * expected == 0 - not applicable
++ * expected == 1 - set color, or vertical/horizontal addressing
++ * expected == 2 - cursor addressing
++ * expected == 4 - initialize color or color pair
++ * expected == 9 - set attributes
++ *
++ * Only for the last case (set attributes) should a parameter be optional.
++ * Also, a capability which calls for more parameters than expected should be
++ * ignored.
++ *
++ * Return a null if the parameter-checks fail. Otherwise, return a pointer to
++ * the formatted capability string.
+ */
+ NCURSES_EXPORT(char *)
+ _nc_tiparm(int expected, const char *string, ...)
+@@ -1189,22 +1265,36 @@ _nc_tiparm(int expected, const char *string, ...)
+ char *result = NULL;
+
+ _nc_tparm_err = 0;
++ T((T_CALLED("_nc_tiparm(%d, %s, ...)"), expected, _nc_visbuf(string)));
+ #ifdef TRACE
+ tps->tname = "_nc_tiparm";
+ #endif /* TRACE */
+
+- if (tparm_setup(cur_term, string, &myData) == OK
+- && myData.num_actual <= expected
+- && myData.tparm_type == 0) {
+- va_list ap;
++ if (tparm_setup(cur_term, string, &myData) == OK && ValidCap()) {
++ if (myData.num_actual == 0) {
++ T(("missing parameter%s, expected %s%d",
++ expected > 1 ? "s" : "",
++ expected == 9 ? "up to " : "",
++ expected));
++ } else if (myData.num_actual > expected) {
++ T(("too many parameters, have %d, expected %d",
++ myData.num_actual,
++ expected));
++ } else if (expected != 9 && myData.num_actual != expected) {
++ T(("expected %d parameters, have %d",
++ myData.num_actual,
++ expected));
++ } else {
++ va_list ap;
+
+- va_start(ap, string);
+- tparm_copy_valist(&myData, FALSE, ap);
+- va_end(ap);
++ va_start(ap, string);
++ tparm_copy_valist(&myData, FALSE, ap);
++ va_end(ap);
+
+- result = tparam_internal(tps, string, &myData);
++ result = tparam_internal(tps, string, &myData);
++ }
+ }
+- return result;
++ returnPtr(result);
+ }
+
+ /*
+diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c
+index 2b1875ed..9c6e9b0e 100644
+--- a/ncurses/tinfo/read_entry.c
++++ b/ncurses/tinfo/read_entry.c
+@@ -1,5 +1,5 @@
+ /****************************************************************************
+- * Copyright 2018-2021,2022 Thomas E. Dickey *
++ * Copyright 2018-2022,2023 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -42,7 +42,7 @@
+
+ #include <tic.h>
+
+-MODULE_ID("$Id: read_entry.c,v 1.164 2022/05/08 00:11:44 tom Exp $")
++MODULE_ID("$Id: read_entry.c,v 1.165 2023/04/08 20:14:49 tom Exp $")
+
+ #define MyNumber(n) (short) LOW_MSB(n)
+
+@@ -323,6 +323,9 @@ _nc_read_termtype(TERMTYPE2 *ptr, char *buffer, int limit)
+ || bool_count < 0
+ || num_count < 0
+ || str_count < 0
++ || bool_count > BOOLCOUNT
++ || num_count > NUMCOUNT
++ || str_count > STRCOUNT
+ || str_size < 0) {
+ returnDB(TGETENT_NO);
+ }
+diff --git a/package/ncurses.spec b/package/ncurses.spec
+index 72d4e245..a7572864 100644
+--- a/package/ncurses.spec
++++ b/package/ncurses.spec
+@@ -1,7 +1,7 @@
+ Summary: shared libraries for terminal handling
+ Name: ncurses6
+ Version: 6.4
+-Release: 20221231
++Release: 20230408
+ License: X11
+ Group: Development/Libraries
+ Source: ncurses-%{version}-%{release}.tgz
+diff --git a/package/ncursest.spec b/package/ncursest.spec
+index 8729842d..f1d073d1 100644
+--- a/package/ncursest.spec
++++ b/package/ncursest.spec
+@@ -1,7 +1,7 @@
+ Summary: Curses library with POSIX thread support.
+ Name: ncursest6
+ Version: 6.4
+-Release: 20221231
++Release: 20230408
+ License: X11
+ Group: Development/Libraries
+ Source: ncurses-%{version}-%{release}.tgz
+diff --git a/progs/tic.c b/progs/tic.c
+index 93a0b491..7ae61677 100644
+--- a/progs/tic.c
++++ b/progs/tic.c
+@@ -1,5 +1,5 @@
+ /****************************************************************************
+- * Copyright 2018-2021,2022 Thomas E. Dickey *
++ * Copyright 2018-2022,2023 Thomas E. Dickey *
+ * Copyright 1998-2017,2018 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -49,7 +49,7 @@
+ #include <parametrized.h>
+ #include <transform.h>
+
+-MODULE_ID("$Id: tic.c,v 1.320 2022/09/17 18:55:28 tom Exp $")
++MODULE_ID("$Id: tic.c,v 1.321 2023/04/08 15:51:57 tom Exp $")
+
+ #define STDIN_NAME "<stdin>"
+
+@@ -2270,9 +2270,15 @@ check_1_infotocap(const char *name, NCURSES_CONST char *value, int count)
+
+ _nc_reset_tparm(NULL);
+ switch (actual) {
++ case Str:
++ result = TPARM_1(value, strings[1]);
++ break;
+ case Num_Str:
+ result = TPARM_2(value, numbers[1], strings[2]);
+ break;
++ case Str_Str:
++ result = TPARM_2(value, strings[1], strings[2]);
++ break;
+ case Num_Str_Str:
+ result = TPARM_3(value, numbers[1], strings[2], strings[3]);
+ break;
+diff --git a/progs/tparm_type.c b/progs/tparm_type.c
+index 3da4a077..4fed96a5 100644
+--- a/progs/tparm_type.c
++++ b/progs/tparm_type.c
+@@ -1,5 +1,5 @@
+ /****************************************************************************
+- * Copyright 2020 Thomas E. Dickey *
++ * Copyright 2020,2023 Thomas E. Dickey *
+ * Copyright 2014,2015 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -33,7 +33,7 @@
+
+ #include <tparm_type.h>
+
+-MODULE_ID("$Id: tparm_type.c,v 1.4 2020/10/24 17:30:32 tom Exp $")
++MODULE_ID("$Id: tparm_type.c,v 1.5 2023/04/08 15:57:01 tom Exp $")
+
+ /*
+ * Lookup the type of call we should make to tparm(). This ignores the actual
+@@ -47,6 +47,7 @@ tparm_type(const char *name)
+ {code, {longname} }, \
+ {code, {ti} }, \
+ {code, {tc} }
++#define XD(code, onlyname) TD(code, onlyname, onlyname, onlyname)
+ TParams result = Numbers;
+ /* *INDENT-OFF* */
+ static const struct {
+@@ -58,6 +59,10 @@ tparm_type(const char *name)
+ TD(Num_Str, "pkey_xmit", "pfx", "px"),
+ TD(Num_Str, "plab_norm", "pln", "pn"),
+ TD(Num_Str_Str, "pkey_plab", "pfxl", "xl"),
++#if NCURSES_XNAMES
++ XD(Str, "Cs"),
++ XD(Str_Str, "Ms"),
++#endif
+ };
+ /* *INDENT-ON* */
+
+@@ -80,12 +85,16 @@ guess_tparm_type(int nparam, char **p_is_s)
+ case 1:
+ if (!p_is_s[0])
+ result = Numbers;
++ if (p_is_s[0])
++ result = Str;
+ break;
+ case 2:
+ if (!p_is_s[0] && !p_is_s[1])
+ result = Numbers;
+ if (!p_is_s[0] && p_is_s[1])
+ result = Num_Str;
++ if (p_is_s[0] && p_is_s[1])
++ result = Str_Str;
+ break;
+ case 3:
+ if (!p_is_s[0] && !p_is_s[1] && !p_is_s[2])
+diff --git a/progs/tparm_type.h b/progs/tparm_type.h
+index 7c102a30..2f7bd077 100644
+--- a/progs/tparm_type.h
++++ b/progs/tparm_type.h
+@@ -1,5 +1,5 @@
+ /****************************************************************************
+- * Copyright 2020 Thomas E. Dickey *
++ * Copyright 2020,2023 Thomas E. Dickey *
+ * Copyright 2014 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -32,7 +32,7 @@
+ ****************************************************************************/
+
+ /*
+- * $Id: tparm_type.h,v 1.3 2020/10/24 17:11:33 tom Exp $
++ * $Id: tparm_type.h,v 1.4 2023/04/08 15:41:20 tom Exp $
+ *
+ * determine expected/actual number of parameters to setup for tparm
+ */
+@@ -45,8 +45,10 @@
+ typedef enum {
+ Other = -1
+ ,Numbers = 0
++ ,Str
+ ,Num_Str
+ ,Num_Str_Str
++ ,Str_Str
+ } TParams;
+
+ extern TParams tparm_type(const char *name);
+diff --git a/progs/tput.c b/progs/tput.c
+index 4cd0c5ba..41508b72 100644
+--- a/progs/tput.c
++++ b/progs/tput.c
+@@ -1,5 +1,5 @@
+ /****************************************************************************
+- * Copyright 2018-2021,2022 Thomas E. Dickey *
++ * Copyright 2018-2022,2023 Thomas E. Dickey *
+ * Copyright 1998-2016,2017 Free Software Foundation, Inc. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a *
+@@ -47,12 +47,15 @@
+ #include <transform.h>
+ #include <tty_settings.h>
+
+-MODULE_ID("$Id: tput.c,v 1.99 2022/02/26 23:19:31 tom Exp $")
++MODULE_ID("$Id: tput.c,v 1.102 2023/04/08 16:26:36 tom Exp $")
+
+ #define PUTS(s) fputs(s, stdout)
+
+ const char *_nc_progname = "tput";
+
++static bool opt_v = FALSE; /* quiet, do not show warnings */
++static bool opt_x = FALSE; /* clear scrollback if possible */
++
+ static bool is_init = FALSE;
+ static bool is_reset = FALSE;
+ static bool is_clear = FALSE;
+@@ -81,6 +84,7 @@ usage(const char *optstring)
+ KEEP(" -S << read commands from standard input")
+ KEEP(" -T TERM use this instead of $TERM")
+ KEEP(" -V print curses-version")
++ KEEP(" -v verbose, show warnings")
+ KEEP(" -x do not try to clear scrollback")
+ KEEP("")
+ KEEP("Commands:")
+@@ -148,7 +152,7 @@ exit_code(int token, int value)
+ * Returns nonzero on error.
+ */
+ static int
+-tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
++tput_cmd(int fd, TTY * settings, int argc, char **argv, int *used)
+ {
+ NCURSES_CONST char *name;
+ char *s;
+@@ -231,7 +235,9 @@ tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
+ } else if (VALID_STRING(s)) {
+ if (argc > 1) {
+ int k;
++ int narg;
+ int analyzed;
++ int provided;
+ int popcount;
+ long numbers[1 + NUM_PARM];
+ char *strings[1 + NUM_PARM];
+@@ -271,14 +277,45 @@ tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
+
+ popcount = 0;
+ _nc_reset_tparm(NULL);
++ /*
++ * Count the number of numeric parameters which are provided.
++ */
++ provided = 0;
++ for (narg = 1; narg < argc; ++narg) {
++ char *ending = NULL;
++ long check = strtol(argv[narg], &ending, 10);
++ if (check < 0 || ending == argv[narg] || *ending != '\0')
++ break;
++ provided = narg;
++ }
+ switch (paramType) {
++ case Str:
++ s = TPARM_1(s, strings[1]);
++ analyzed = 1;
++ if (provided == 0 && argc >= 1)
++ provided++;
++ break;
++ case Str_Str:
++ s = TPARM_2(s, strings[1], strings[2]);
++ analyzed = 2;
++ if (provided == 0 && argc >= 1)
++ provided++;
++ if (provided == 1 && argc >= 2)
++ provided++;
++ break;
+ case Num_Str:
+ s = TPARM_2(s, numbers[1], strings[2]);
+ analyzed = 2;
++ if (provided == 1 && argc >= 2)
++ provided++;
+ break;
+ case Num_Str_Str:
+ s = TPARM_3(s, numbers[1], strings[2], strings[3]);
+ analyzed = 3;
++ if (provided == 1 && argc >= 2)
++ provided++;
++ if (provided == 2 && argc >= 3)
++ provided++;
+ break;
+ case Numbers:
+ analyzed = _nc_tparm_analyze(NULL, s, p_is_s, &popcount);
+@@ -316,7 +353,13 @@ tput_cmd(int fd, TTY * settings, bool opt_x, int argc, char **argv, int *used)
+ if (analyzed < popcount) {
+ analyzed = popcount;
+ }
+- *used += analyzed;
++ if (opt_v && (analyzed != provided)) {
++ fprintf(stderr, "%s: %s parameters for \"%s\"\n",
++ _nc_progname,
++ (analyzed < provided ? "extra" : "missing"),
++ argv[0]);
++ }
++ *used += provided;
+ }
+
+ /* use putp() in order to perform padding */
+@@ -339,7 +382,6 @@ main(int argc, char **argv)
+ int used;
+ TTY old_settings;
+ TTY tty_settings;
+- bool opt_x = FALSE; /* clear scrollback if possible */
+ bool is_alias;
+ bool need_tty;
+
+@@ -348,7 +390,7 @@ main(int argc, char **argv)
+
+ term = getenv("TERM");
+
+- while ((c = getopt(argc, argv, is_alias ? "T:Vx" : "ST:Vx")) != -1) {
++ while ((c = getopt(argc, argv, is_alias ? "T:Vvx" : "ST:Vvx")) != -1) {
+ switch (c) {
+ case 'S':
+ cmdline = FALSE;
+@@ -361,6 +403,9 @@ main(int argc, char **argv)
+ case 'V':
+ puts(curses_version());
+ ExitProgram(EXIT_SUCCESS);
++ case 'v': /* verbose */
++ opt_v = TRUE;
++ break;
+ case 'x': /* do not try to clear scrollback */
+ opt_x = TRUE;
+ break;
+@@ -404,7 +449,7 @@ main(int argc, char **argv)
+ usage(NULL);
+ while (argc > 0) {
+ tty_settings = old_settings;
+- code = tput_cmd(fd, &tty_settings, opt_x, argc, argv, &used);
++ code = tput_cmd(fd, &tty_settings, argc, argv, &used);
+ if (code != 0)
+ break;
+ argc -= used;
+@@ -439,7 +484,7 @@ main(int argc, char **argv)
+ while (argnum > 0) {
+ int code;
+ tty_settings = old_settings;
+- code = tput_cmd(fd, &tty_settings, opt_x, argnum, argnow, &used);
++ code = tput_cmd(fd, &tty_settings, argnum, argnow, &used);
+ if (code != 0) {
+ if (result == 0)
+ result = ErrSystem(0); /* will return value >4 */
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-tic-hang.patch b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-tic-hang.patch
new file mode 100644
index 000000000..f98a943e5
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0001-tic-hang.patch
@@ -0,0 +1,43 @@
+From 168ba7a681be73ac024438e33e14fde1d5aea97d Mon Sep 17 00:00:00 2001
+From: Hongxu Jia <hongxu.jia@windriver.com>
+Date: Fri, 30 Mar 2018 10:02:24 +0800
+Subject: [PATCH 1/2] tic hang
+
+Upstream-Status: Inappropriate [configuration]
+
+'tic' of some linux distributions (e.g. fedora 11) hang in an infinite
+loop when processing the original file.
+
+Signed-off-by: anonymous
+
+Rebase to 6.1
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+---
+ misc/terminfo.src | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+diff --git a/misc/terminfo.src b/misc/terminfo.src
+index 84f4810..6b385ec 100644
+--- a/misc/terminfo.src
++++ b/misc/terminfo.src
+@@ -5562,12 +5562,11 @@ konsole-xf3x|KDE console window with keyboard for XFree86 3.x xterm,
+ # The value for kbs (see konsole-vt100) reflects local customization rather
+ # than the settings used for XFree86 xterm.
+ konsole-xf4x|KDE console window with keyboard for XFree86 4.x xterm,
+- kend=\EOF, khome=\EOH, use=konsole+pcfkeys,
+- use=konsole-vt100,
+-
+-konsole+pcfkeys|konsole subset of xterm+pcfkeys,
+- kcbt=\E[Z, use=xterm+pcc2, use=xterm+pcf0,
+- use=xterm+pce2,
++ kend=\EOF, kf1=\EOP, kf13=\EO2P, kf14=\EO2Q, kf15=\EO2R,
++ kf16=\EO2S, kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~,
++ kf2=\EOQ, kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~,
++ kf23=\E[23;2~, kf24=\E[24;2~, kf3=\EOR, kf4=\EOS,
++ khome=\EOH, use=konsole-vt100,
+
+ # Obsolete: vt100.keymap
+ # KDE's "vt100" keyboard has no relationship to any terminal that DEC made, but
+--
+1.8.3.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-Fix-added-to-mitigate-CVE-2022-29458.patch b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-Fix-added-to-mitigate-CVE-2022-29458.patch
deleted file mode 100644
index 1cef2e810..000000000
--- a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-Fix-added-to-mitigate-CVE-2022-29458.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-From 0ed8a4953f9179d0f077f24779f1cb51c8e9a126 Mon Sep 17 00:00:00 2001
-From: ankita prasad <ankita.prasad@intel.com>
-Date: Tue, 12 Jul 2022 17:51:01 +0000
-Subject: [PATCH] Fix added to mitigate CVE-2022-29458
-
-ncurses 6.3 before patch 20220416 has an out-of-bounds read
-and segmentation violation in convert_strings in tinfo/read_entry.c
-in the terminfo library.
-The fix is picked from - https://github.com/mirror/ncurses/commit/4c9f63c460cb7134f142aa65f6866c175ed77605
-for the file tinfo/read_entry.c.
-
-Signed-off-by: Ankita Prasad <ankita.prasad@intel.com>
----
- ncurses/tinfo/read_entry.c | 21 +++++++++++++++++----
- 1 file changed, 17 insertions(+), 4 deletions(-)
-
-diff --git a/ncurses/tinfo/read_entry.c b/ncurses/tinfo/read_entry.c
-index 5b570b0f..06c0c437 100644
---- a/ncurses/tinfo/read_entry.c
-+++ b/ncurses/tinfo/read_entry.c
-@@ -145,6 +145,7 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table)
- {
- int i;
- char *p;
-+ bool corrupt = FALSE;
-
- for (i = 0; i < count; i++) {
- if (IS_NEG1(buf + 2 * i)) {
-@@ -154,17 +155,29 @@ convert_strings(char *buf, char **Strings, int count, int size, char *table)
- } else if (MyNumber(buf + 2 * i) > size) {
- Strings[i] = ABSENT_STRING;
- } else {
-- Strings[i] = (MyNumber(buf + 2 * i) + table);
-- TR(TRACE_DATABASE, ("Strings[%d] = %s", i, _nc_visbuf(Strings[i])));
-+ int nn = MyNumber(buf + 2 * i);
-+ if (nn >= 0 && nn < size) {
-+ Strings[i] = (nn + table);
-+ TR(TRACE_DATABASE, ("Strings[%d] = %s", i,
-+ _nc_visbuf(Strings[i])));
-+ } else {
-+ if (!corrupt) {
-+ corrupt = TRUE;
-+ TR(TRACE_DATABASE,
-+ ("ignore out-of-range index %d to Strings[]", nn));
-+ _nc_warning("corrupt data found in convert_strings");
-+ }
-+ Strings[i] = ABSENT_STRING;
-+ }
- }
-
- /* make sure all strings are NUL terminated */
- if (VALID_STRING(Strings[i])) {
-- for (p = Strings[i]; p <= table + size; p++)
-+ for (p = Strings[i]; p < table + size; p++)
- if (*p == '\0')
- break;
- /* if there is no NUL, ignore the string */
-- if (p > table + size)
-+ if (p >= table + size)
- Strings[i] = ABSENT_STRING;
- }
- }
---
-2.25.1
-
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-configure-reproducible.patch b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-configure-reproducible.patch
new file mode 100644
index 000000000..66f26c06a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0002-configure-reproducible.patch
@@ -0,0 +1,33 @@
+From ec87e53066a9942e9aaba817d71268342f5e83b9 Mon Sep 17 00:00:00 2001
+From: Hongxu Jia <hongxu.jia@windriver.com>
+Date: Wed, 16 Aug 2017 14:45:27 +0800
+Subject: [PATCH] configure: reproducible
+
+"configure" enforces -U for ar flags, breaking deterministic builds.
+The flag was added to fix some vaguely specified "recent POSIX binutil
+build problems" in 2015.
+
+Upstream-Status: Pending
+Signed-off-by: Juro Bystricky <juro.bystricky@intel.com>
+
+Rebase to 6.1
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+
+---
+ configure | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure b/configure
+index 421cf859..a1b7840d 100755
+--- a/configure
++++ b/configure
+@@ -5072,7 +5072,7 @@ else
+ ;;
+ (*)
+ cf_cv_ar_flags=unknown
+- for cf_ar_flags in -curvU -curv curv -crv crv -cqv cqv -rv rv
++ for cf_ar_flags in -curv curv -crv crv -cqv cqv -rv rv
+ do
+
+ # check if $ARFLAGS already contains this choice
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0003-gen-pkgconfig.in-Do-not-include-LDFLAGS-in-generated.patch b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0003-gen-pkgconfig.in-Do-not-include-LDFLAGS-in-generated.patch
new file mode 100644
index 000000000..a15694d4d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/0003-gen-pkgconfig.in-Do-not-include-LDFLAGS-in-generated.patch
@@ -0,0 +1,30 @@
+From 10cd0c12a6e14fb4f0498c299c1dd32720b710da Mon Sep 17 00:00:00 2001
+From: Nathan Rossi <nathan@nathanrossi.com>
+Date: Mon, 14 Dec 2020 13:39:02 +1000
+Subject: [PATCH] gen-pkgconfig.in: Do not include LDFLAGS in generated pc
+ files
+
+Including the LDFLAGS in the pkgconfig output is problematic as OE
+includes build host specific paths and options (e.g. uninative and
+'-Wl,--dynamic-linker=').
+
+Upstream-Status: Inappropriate [OE Specific]
+Signed-off-by: Nathan Rossi <nathan@nathanrossi.com>
+
+---
+ misc/gen-pkgconfig.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/misc/gen-pkgconfig.in b/misc/gen-pkgconfig.in
+index a45dd54f..85273054 100644
+--- a/misc/gen-pkgconfig.in
++++ b/misc/gen-pkgconfig.in
+@@ -83,7 +83,7 @@ if [ "$includedir" != "/usr/include" ]; then
+ fi
+
+ lib_flags=
+-for opt in -L$libdir @EXTRA_PKG_LDFLAGS@ @LIBS@
++for opt in -L$libdir @LIBS@
+ do
+ case $opt in
+ -l*) # LIBS is handled specially below
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/exit_prototype.patch b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/exit_prototype.patch
new file mode 100644
index 000000000..fd961512e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses/exit_prototype.patch
@@ -0,0 +1,32 @@
+From 4a769a441d7e57a23017c3037cde3e53fb9f35fe Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Tue, 30 Aug 2022 15:58:32 -0700
+Subject: [PATCH] Add needed headers for including mbstate_t and exit()
+
+Upstream-Status: Inappropriate [Reconfigure will solve it]
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+
+---
+ configure | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/configure b/configure
+index f377f551..163f8899 100755
+--- a/configure
++++ b/configure
+@@ -3423,6 +3423,7 @@ rm -f "conftest.$ac_objext" "conftest.$ac_ext"
+ cat >"conftest.$ac_ext" <<_ACEOF
+ #line 3424 "configure"
+ #include "confdefs.h"
++#include <stdlib.h>
+ $ac_declaration
+ int
+ main (void)
+@@ -13111,6 +13112,7 @@ cat >"conftest.$ac_ext" <<_ACEOF
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <stdio.h>
++#include <wchar.h>
+ #ifdef HAVE_LIBUTF8_H
+ #include <libutf8.h>
+ #endif
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_%.bbappend
deleted file mode 100644
index 7f1ce36c2..000000000
--- a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_%.bbappend
+++ /dev/null
@@ -1,4 +0,0 @@
-FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
-SRC_URI += "file://0001-Fix-heap-buffer-overflow-in-captoinfo.patch \
- file://0002-Fix-added-to-mitigate-CVE-2022-29458.patch \
- "
diff --git a/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_6.4.bb b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_6.4.bb
new file mode 100644
index 000000000..c72c3e30e
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/ncurses/ncurses_6.4.bb
@@ -0,0 +1,20 @@
+require ncurses.inc
+
+SRC_URI += "file://0001-tic-hang.patch \
+ file://0002-configure-reproducible.patch \
+ file://0003-gen-pkgconfig.in-Do-not-include-LDFLAGS-in-generated.patch \
+ file://exit_prototype.patch \
+ "
+
+#Include CVE mitigation patches.
+SRC_URI += "file://0001-patch-20230408-CVE-2023-29491.patch \
+ "
+
+# commit id corresponds to the revision in package version
+SRCREV = "79b9071f2be20a24c7be031655a5638f6032f29f"
+S = "${WORKDIR}/git"
+EXTRA_OECONF += "--with-abi-version=5"
+UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+(\.\d+)+)$"
+
+# This is needed when using patchlevel versions like 6.1+20181013
+#CVE_VERSION = "${@d.getVar("PV").split('+')[0]}.${@d.getVar("PV").split('+')[1]}"
diff --git a/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/CVE-2022-3821.patch b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/CVE-2022-3821.patch
new file mode 100644
index 000000000..5e32866f1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd/CVE-2022-3821.patch
@@ -0,0 +1,24 @@
+From 8d2d0895229cfbe39c1c5c16e61e426812a72e8b Mon Sep 17 00:00:00 2001
+From: Yu Watanabe <watanabe.yu+github@gmail.com>
+Date: Thu, 7 Jul 2022 18:27:02 +0900
+Subject: [PATCH] time-util: fix buffer-over-run
+
+Fixes #23928.
+---
+ src/basic/time-util.c | 2 +-
+ src/test/test-time-util.c | 5 +++++
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/src/basic/time-util.c b/src/basic/time-util.c
+index abbc4ad5cd70..26d59de12348 100644
+--- a/src/basic/time-util.c
++++ b/src/basic/time-util.c
+@@ -591,7 +591,7 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
+ t = b;
+ }
+
+- n = MIN((size_t) k, l);
++ n = MIN((size_t) k, l-1);
+
+ l -= n;
+ p += n;
diff --git a/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend
index 262f557e0..66d3a9bdc 100644
--- a/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-core/systemd/systemd_%.bbappend
@@ -4,6 +4,7 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI += "file://0002-Add-event-log-for-system-time-synchronization.patch \
file://0003-Added-timeout-to-systemd-networkd-wait-online.servic.patch \
+ file://CVE-2022-3821.patch \
"
# We don't support loadable modules in kernel config
diff --git a/meta-openbmc-mods/meta-common/recipes-devtools/python/python3_%.bbappend b/meta-openbmc-mods/meta-common/recipes-devtools/python/python3_%.bbappend
new file mode 100644
index 000000000..4b8688184
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-devtools/python/python3_%.bbappend
@@ -0,0 +1,4 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+
+#Needed for ncurses_6.4 compilation.
+DEPENDS += "ncurses"
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality/pwquality.conf b/meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality/pwquality.conf
new file mode 100644
index 000000000..048c0fd7d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality/pwquality.conf
@@ -0,0 +1,7 @@
+enforce_for_root
+minlen=8
+difok=0
+lcredit=0
+ocredit=0
+dcredit=0
+ucredit=0
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality_%.bbappend b/meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality_%.bbappend
new file mode 100644
index 000000000..5c7a6ad5b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/libpwquality/libpwquality_%.bbappend
@@ -0,0 +1,15 @@
+EXTRA_OECONF:append = " --enable-python-bindings=no"
+EXTRA_OECONF:append = " --with-securedir=${base_libdir}/security"
+FILES:${PN} += "${base_libdir}/security/pam_pwquality.so"
+RDEPENDS:${PN}:remove:class-target = " ${PYTHON_PN}-core"
+RDEPENDS:${PN}-runtime += "libpwquality"
+
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+SRC_URI += " \
+ file://pwquality.conf \
+ "
+
+do_install:append() {
+ install -d ${D}/etc/security
+ install -m 0644 ${WORKDIR}/pwquality.conf ${D}/etc/security
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/0001-run-xtests.sh-check-whether-files-exist.patch b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/0001-run-xtests.sh-check-whether-files-exist.patch
new file mode 100644
index 000000000..40040a873
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/0001-run-xtests.sh-check-whether-files-exist.patch
@@ -0,0 +1,65 @@
+From e8e8ccfd57e0274b431bc5717bf37c488285b07b Mon Sep 17 00:00:00 2001
+From: Mingli Yu <mingli.yu@windriver.com>
+Date: Wed, 27 Oct 2021 10:30:46 +0800
+Subject: [PATCH] run-xtests.sh: check whether files exist
+
+Fixes:
+ # ./run-xtests.sh . tst-pam_access1
+ mv: cannot stat '/etc/security/opasswd': No such file or directory
+ PASS: tst-pam_access1
+ mv: cannot stat '/etc/security/opasswd-pam-xtests': No such file or directory
+ ==================
+ 1 tests passed
+ 0 tests not run
+ ==================
+
+Upstream-Status: Backport [https://github.com/linux-pam/linux-pam/commit/e8e8ccfd57e0274b431bc5717bf37c488285b07b]
+
+Signed-off-by: Mingli Yu <mingli.yu@windriver.com>
+---
+ xtests/run-xtests.sh | 20 +++++++++++++-------
+ 1 file changed, 13 insertions(+), 7 deletions(-)
+
+diff --git a/xtests/run-xtests.sh b/xtests/run-xtests.sh
+index 14f585d9..ff9a4dc1 100755
+--- a/xtests/run-xtests.sh
++++ b/xtests/run-xtests.sh
+@@ -18,10 +18,12 @@ all=0
+
+ mkdir -p /etc/security
+ for config in access.conf group.conf time.conf limits.conf ; do
+- cp /etc/security/$config /etc/security/$config-pam-xtests
++ [ -f "/etc/security/$config" ] &&
++ mv /etc/security/$config /etc/security/$config-pam-xtests
+ install -m 644 "${SRCDIR}"/$config /etc/security/$config
+ done
+-mv /etc/security/opasswd /etc/security/opasswd-pam-xtests
++[ -f /etc/security/opasswd ] &&
++ mv /etc/security/opasswd /etc/security/opasswd-pam-xtests
+
+ for testname in $XTESTS ; do
+ for cfg in "${SRCDIR}"/$testname*.pamd ; do
+@@ -47,11 +49,15 @@ for testname in $XTESTS ; do
+ all=`expr $all + 1`
+ rm -f /etc/pam.d/$testname*
+ done
+-mv /etc/security/access.conf-pam-xtests /etc/security/access.conf
+-mv /etc/security/group.conf-pam-xtests /etc/security/group.conf
+-mv /etc/security/time.conf-pam-xtests /etc/security/time.conf
+-mv /etc/security/limits.conf-pam-xtests /etc/security/limits.conf
+-mv /etc/security/opasswd-pam-xtests /etc/security/opasswd
++
++for config in access.conf group.conf time.conf limits.conf opasswd ; do
++ if [ -f "/etc/security/$config-pam-xtests" ]; then
++ mv /etc/security/$config-pam-xtests /etc/security/$config
++ else
++ rm -f /etc/security/$config
++ fi
++done
++
+ if test "$failed" -ne 0; then
+ echo "==================="
+ echo "$failed of $all tests failed"
+--
+2.32.0
+
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/99_pam b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/99_pam
new file mode 100644
index 000000000..a88247be1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/99_pam
@@ -0,0 +1 @@
+d root root 0755 /run/sepermit none
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/CVE-2022-28321-0002.patch b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/CVE-2022-28321-0002.patch
new file mode 100644
index 000000000..e7bf03f9f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/CVE-2022-28321-0002.patch
@@ -0,0 +1,205 @@
+From 23393bef92c1e768eda329813d7af55481c6ca9f Mon Sep 17 00:00:00 2001
+From: Thorsten Kukuk <kukuk@suse.com>
+Date: Thu, 24 Feb 2022 10:37:32 +0100
+Subject: [PATCH 2/2] pam_access: handle hostnames in access.conf
+
+According to the manual page, the following entry is valid but does not
+work:
+-:root:ALL EXCEPT localhost
+
+See https://bugzilla.suse.com/show_bug.cgi?id=1019866
+
+Patched is based on PR#226 from Josef Moellers
+
+Upstream-Status: Backport
+CVE: CVE-2022-28321
+
+Reference to upstream patch:
+[https://github.com/linux-pam/linux-pam/commit/23393bef92c1e768eda329813d7af55481c6ca9f]
+
+Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
+---
+ modules/pam_access/pam_access.c | 95 ++++++++++++++++++++++++++-------
+ 1 file changed, 76 insertions(+), 19 deletions(-)
+
+diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
+index 277192b..bca424f 100644
+--- a/modules/pam_access/pam_access.c
++++ b/modules/pam_access/pam_access.c
+@@ -637,7 +637,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
+ if ((str_len = strlen(string)) > tok_len
+ && strcasecmp(tok, string + str_len - tok_len) == 0)
+ return YES;
+- } else if (tok[tok_len - 1] == '.') {
++ } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */
+ struct addrinfo hint;
+
+ memset (&hint, '\0', sizeof (hint));
+@@ -678,7 +678,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
+ return NO;
+ }
+
+- /* Assume network/netmask with an IP of a host. */
++ /* Assume network/netmask, IP address or hostname. */
+ return network_netmask_match(pamh, tok, string, item);
+ }
+
+@@ -696,7 +696,7 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
+ /*
+ * If the token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the string.
+- * "NONE" token matches NULL string.
++ * "NONE" token matches NULL string.
+ */
+
+ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
+@@ -714,7 +714,8 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string,
+
+ /* network_netmask_match - match a string against one token
+ * where string is a hostname or ip (v4,v6) address and tok
+- * represents either a single ip (v4,v6) address or a network/netmask
++ * represents either a hostname, a single ip (v4,v6) address
++ * or a network/netmask
+ */
+ static int
+ network_netmask_match (pam_handle_t *pamh,
+@@ -723,10 +724,12 @@ network_netmask_match (pam_handle_t *pamh,
+ char *netmask_ptr;
+ char netmask_string[MAXHOSTNAMELEN + 1];
+ int addr_type;
++ struct addrinfo *ai = NULL;
+
+ if (item->debug)
+- pam_syslog (pamh, LOG_DEBUG,
++ pam_syslog (pamh, LOG_DEBUG,
+ "network_netmask_match: tok=%s, item=%s", tok, string);
++
+ /* OK, check if tok is of type addr/mask */
+ if ((netmask_ptr = strchr(tok, '/')) != NULL)
+ {
+@@ -760,54 +763,108 @@ network_netmask_match (pam_handle_t *pamh,
+ netmask_ptr = number_to_netmask(netmask, addr_type,
+ netmask_string, MAXHOSTNAMELEN);
+ }
+- }
++
++ /*
++ * Construct an addrinfo list from the IP address.
++ * This should not fail as the input is a correct IP address...
++ */
++ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
++ {
++ return NO;
++ }
++ }
+ else
+- /* NO, then check if it is only an addr */
+- if (isipaddr(tok, NULL, NULL) != YES)
++ {
++ /*
++ * It is either an IP address or a hostname.
++ * Let getaddrinfo sort everything out
++ */
++ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
+ {
++ pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok);
++
+ return NO;
+ }
++ netmask_ptr = NULL;
++ }
+
+ if (isipaddr(string, NULL, NULL) != YES)
+ {
+- /* Assume network/netmask with a name of a host. */
+ struct addrinfo hint;
+
++ /* Assume network/netmask with a name of a host. */
+ memset (&hint, '\0', sizeof (hint));
+ hint.ai_flags = AI_CANONNAME;
+ hint.ai_family = AF_UNSPEC;
+
+ if (item->gai_rv != 0)
++ {
++ freeaddrinfo(ai);
+ return NO;
++ }
+ else if (!item->res &&
+ (item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0)
++ {
++ freeaddrinfo(ai);
+ return NO;
++ }
+ else
+ {
+ struct addrinfo *runp = item->res;
++ struct addrinfo *runp1;
+
+ while (runp != NULL)
+ {
+ char buf[INET6_ADDRSTRLEN];
+
+- DIAG_PUSH_IGNORE_CAST_ALIGN;
+- inet_ntop (runp->ai_family,
+- runp->ai_family == AF_INET
+- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
+- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
+- buf, sizeof (buf));
+- DIAG_POP_IGNORE_CAST_ALIGN;
++ if (getnameinfo (runp->ai_addr, runp->ai_addrlen, buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) != 0)
++ {
++ freeaddrinfo(ai);
++ return NO;
++ }
+
+- if (are_addresses_equal(buf, tok, netmask_ptr))
++ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
+ {
+- return YES;
++ char buf1[INET6_ADDRSTRLEN];
++
++ if (runp->ai_family != runp1->ai_family)
++ continue;
++
++ if (getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST) != 0)
++ {
++ freeaddrinfo(ai);
++ return NO;
++ }
++
++ if (are_addresses_equal (buf, buf1, netmask_ptr))
++ {
++ freeaddrinfo(ai);
++ return YES;
++ }
+ }
+ runp = runp->ai_next;
+ }
+ }
+ }
+ else
+- return (are_addresses_equal(string, tok, netmask_ptr));
++ {
++ struct addrinfo *runp1;
++
++ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
++ {
++ char buf1[INET6_ADDRSTRLEN];
++
++ (void) getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST);
++
++ if (are_addresses_equal(string, buf1, netmask_ptr))
++ {
++ freeaddrinfo(ai);
++ return YES;
++ }
++ }
++ }
++
++ freeaddrinfo(ai);
+
+ return NO;
+ }
+--
+2.37.3
+
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.service b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.service
new file mode 100644
index 000000000..099a5c6e0
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Convert PAM config files
+
+[Service]
+RemainAfterExit=yes
+Type=oneshot
+ExecStart=/usr/bin/convert-pam-configs.sh
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.sh b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.sh
new file mode 100644
index 000000000..f66f40beb
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/convert-pam-configs.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+# Convert OpenBMC linux-PAM config files
+
+# Location of config files this script modifies:
+# PAM_CONF_DIR - path to the PAM config files
+# SECURITY_CONF_DIR - path to the security config files
+PAM_CONF_DIR=/etc/pam.d
+SECURITY_CONF_DIR=/etc/security
+
+# Handle common-password:
+# Change cracklib to pwquality and handle the minlen parameter
+pam_cracklib=$(grep "^password.*pam_cracklib.so" ${PAM_CONF_DIR}/common-password)
+if [ -n "${pam_cracklib}" ]
+then
+ echo "Changing ${PAM_CONF_DIR}/common-password to use pam_pwquality.so (was pam_cracklib.so)" >&2
+ minlen=$(echo ${pam_cracklib} | sed -e "s/.*minlen=\([[:alnum:]]*\).*/\1/")
+ echo " Converting parameter minlen=${minlen} to ${SECURITY_CONF_DIR}/pwquality.conf minlen" >&2
+ sed -i.bak -e "s/^minlen=.*/minlen=$minlen/" ${SECURITY_CONF_DIR}/pwquality.conf
+ pwquality='password [success=ok default=die] pam_pwquality.so debug'
+ sed -i.bak -e "s/^password.*pam_cracklib.so.*/$pwquality/" ${PAM_CONF_DIR}/common-password
+ echo "# This file was converted by $0" >>${PAM_CONF_DIR}/common-password
+fi
+
+# Handle common-auth:
+# Change tally2 to faillock and handle the deny & unlock_time parameters
+pam_tally2=$(grep "^auth.*pam_tally2.so" ${PAM_CONF_DIR}/common-auth)
+if [ -n "${pam_tally2}" ]
+then
+ echo "Changing ${PAM_CONF_DIR}/common-auth to use pam_faillock.so (was pam_tally2.so)" >&2
+ deny=$(echo ${pam_tally2} | sed -e "s/.*deny=\([[:alnum:]]*\).*/\1/")
+ unlock_time=$(echo ${pam_tally2} | sed -e "s/.*unlock_time=\([[:alnum:]]*\).*/\1/")
+ # Change faillock.conf parameters
+ echo " Converting parameter deny=${deny} to ${SECURITY_CONF_DIR}/faillock.conf deny" >&2
+ echo " Converting parameter unlock_time=${unlock_time} to ${SECURITY_CONF_DIR}/faillock.conf unlock_time" >&2
+ sed -i.bak \
+ -e "s/^deny=.*/deny=$deny/" \
+ -e "s/^unlock_time=.*/unlock_time=$unlock_time/" \
+ ${SECURITY_CONF_DIR}/faillock.conf
+ # Change pam_tally2 to pam_faillock (changes the overall auth stack)
+ authfail='auth [default=die] pam_faillock.so authfail'
+ authsucc='auth sufficient pam_faillock.so authsucc'
+ sed -i.bak \
+ -e "/^auth.*pam_tally2.so.*$/d" \
+ -e "/^auth.*pam_deny.so/i $authfail\n$authsucc" \
+ ${PAM_CONF_DIR}/common-auth
+ echo "# This file was converted by $0" >>${PAM_CONF_DIR}/common-auth
+fi
+
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/faillock.conf b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/faillock.conf
new file mode 100644
index 000000000..68a658411
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/faillock.conf
@@ -0,0 +1,2 @@
+deny=10
+unlock_time=300
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/libpam-xtests.patch b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/libpam-xtests.patch
new file mode 100644
index 000000000..ea145899b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/libpam-xtests.patch
@@ -0,0 +1,37 @@
+This patch is used to create a new sub package libpam-xtests to do more checks.
+
+Upstream-Status: Pending
+
+Signed-off-by: Kang Kai <kai.kang@windriver.com>
+Index: Linux-PAM-1.3.0/xtests/Makefile.am
+===================================================================
+--- Linux-PAM-1.3.0.orig/xtests/Makefile.am
++++ Linux-PAM-1.3.0/xtests/Makefile.am
+@@ -7,7 +7,7 @@ AM_CFLAGS = -DLIBPAM_COMPILE -I$(top_src
+ LDADD = $(top_builddir)/libpam/libpam.la \
+ $(top_builddir)/libpam_misc/libpam_misc.la
+
+-CLEANFILES = *~ $(XTESTS)
++CLEANFILES = *~
+
+ EXTRA_DIST = run-xtests.sh tst-pam_dispatch1.pamd tst-pam_dispatch2.pamd \
+ tst-pam_dispatch3.pamd tst-pam_dispatch4.pamd \
+@@ -51,3 +51,18 @@ EXTRA_PROGRAMS = $(XTESTS)
+
+ xtests: $(XTESTS) run-xtests.sh
+ "$(srcdir)"/run-xtests.sh "$(srcdir)" ${XTESTS} ${NOSRCTESTS}
++
++all: $(XTESTS)
++
++install: install_xtests
++
++install_xtests:
++ $(INSTALL) -d $(DESTDIR)$(pkgdatadir)/xtests
++ for file in $(EXTRA_DIST) ; do \
++ $(INSTALL) $(srcdir)/$$file $(DESTDIR)$(pkgdatadir)/xtests ; \
++ done
++ for file in $(XTESTS); do \
++ $(INSTALL) .libs/$$file $(DESTDIR)$(pkgdatadir)/xtests ; \
++ done
++
++.PHONY: all install_xtests
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam-volatiles.conf b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam-volatiles.conf
new file mode 100644
index 000000000..1263feb03
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam-volatiles.conf
@@ -0,0 +1 @@
+d /run/sepermit 0755 root root - -
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-account b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-account
new file mode 100644
index 000000000..4ebbca8d4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-account
@@ -0,0 +1,27 @@
+#
+# /etc/pam.d/common-account - authorization settings common to all services
+#
+# This file is included from other service-specific PAM config files,
+# and should contain a list of the authorization modules that define
+# the central access policy for use on the system. The default is to
+# only deny service to users whose accounts are expired in /etc/shadow.
+#
+# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
+# To take advantage of this, it is recommended that you configure any
+# local modules either before or after the default block, and use
+# pam-auth-update to manage selection of other modules. See
+# pam-auth-update(8) for details.
+#
+
+# here are the per-package modules (the "Primary" block)
+account [success=1 new_authtok_reqd=done default=ignore] pam_unix.so
+# here's the fallback if no module succeeds
+account requisite pam_deny.so
+# Announce if faillock is blocking access
+account required pam_faillock.so
+# prime the stack with a positive return value if there isn't one already;
+# this avoids us returning an error just because nothing sets a success code
+# since the modules above will each just jump around
+account required pam_permit.so
+# and here are more per-package modules (the "Additional" block)
+# end of pam-auth-update config
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-auth b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-auth
new file mode 100644
index 000000000..c051ab7e6
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-auth
@@ -0,0 +1,26 @@
+#
+# /etc/pam.d/common-auth - authentication settings common to all services
+#
+# This file is included from other service-specific PAM config files,
+# and should contain a list of the authentication modules that define
+# the central authentication scheme for use on the system
+# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the
+# traditional Unix authentication mechanisms.
+
+# here are the per-package modules (the "Primary" block)
+# Try for local user first, and then try for ldap
+auth [success=2 default=ignore] pam_unix.so quiet
+-auth [success=1 default=ignore] pam_ldap.so ignore_unknown_user ignore_authinfo_unavail
+# Control gets here when no authentication module succeeds. Increment the
+# failure tally and return failure status to PAM.
+auth [default=die] pam_faillock.so authfail
+# Control gets here when authentication succeeds. Check if the user is locked
+# out due to consecutive authentication failures and return status accordingly.
+auth sufficient pam_faillock.so authsucc
+# If authsucc failed, deny access
+auth requisite pam_deny.so
+# prime the stack with a positive return value if there isn't one already;
+# this avoids us returning an error just because nothing sets a success code
+# since the modules above will each just jump around
+auth required pam_permit.so
+# and here are more per-package modules (the "Additional" block)
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-password b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-password
new file mode 100644
index 000000000..2fc4011b2
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-password
@@ -0,0 +1,27 @@
+#
+# /etc/pam.d/common-password - password-related modules common to all services
+#
+# This file is included from other service-specific PAM config files,
+# and should contain a list of modules that define the services to be
+# used to change user passwords. The default is pam_unix.
+
+# Explanation of pam_unix options:
+#
+# The "sha512" option enables salted SHA512 passwords. Without this option,
+# the default is Unix crypt. Prior releases used the option "md5".
+#
+# See the pam_unix manpage for other options.
+
+# here are the per-package modules (the "Primary" block)
+password [success=ok default=die] pam_pwquality.so debug
+password [success=ok default=die] pam_ipmicheck.so spec_grp_name=ipmi use_authtok
+password [success=ok ignore=ignore default=die] pam_pwhistory.so debug enforce_for_root remember=0 use_authtok
+password [success=ok default=die] pam_unix.so sha512 use_authtok
+password [success=1 default=die] pam_ipmisave.so spec_grp_name=ipmi spec_pass_file=/etc/ipmi_pass key_file=/etc/key_file
+# here's the fallback if no module succeeds
+password requisite pam_deny.so
+# prime the stack with a positive return value if there isn't one already;
+# this avoids us returning an error just because nothing sets a success code
+# since the modules above will each just jump around
+password required pam_permit.so
+# and here are more per-package modules (the "Additional" block)
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session
new file mode 100644
index 000000000..a4a551f71
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session
@@ -0,0 +1,19 @@
+#
+# /etc/pam.d/common-session - session-related modules common to all services
+#
+# This file is included from other service-specific PAM config files,
+# and should contain a list of modules that define tasks to be performed
+# at the start and end of sessions of *any* kind (both interactive and
+# non-interactive).
+#
+
+# here are the per-package modules (the "Primary" block)
+session [default=1] pam_permit.so
+# here's the fallback if no module succeeds
+session requisite pam_deny.so
+# prime the stack with a positive return value if there isn't one already;
+# this avoids us returning an error just because nothing sets a success code
+# since the modules above will each just jump around
+session required pam_permit.so
+# and here are more per-package modules (the "Additional" block)
+session required pam_unix.so
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session-noninteractive b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session-noninteractive
new file mode 100644
index 000000000..b110bb2b4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/common-session-noninteractive
@@ -0,0 +1,19 @@
+#
+# /etc/pam.d/common-session-noninteractive - session-related modules
+# common to all non-interactive services
+#
+# This file is included from other service-specific PAM config files,
+# and should contain a list of modules that define tasks to be performed
+# at the start and end of all non-interactive sessions.
+#
+
+# here are the per-package modules (the "Primary" block)
+session [default=1] pam_permit.so
+# here's the fallback if no module succeeds
+session requisite pam_deny.so
+# prime the stack with a positive return value if there isn't one already;
+# this avoids us returning an error just because nothing sets a success code
+# since the modules above will each just jump around
+session required pam_permit.so
+# and here are more per-package modules (the "Additional" block)
+session required pam_unix.so
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/other b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/other
new file mode 100644
index 000000000..ec970ecbe
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/pam.d/other
@@ -0,0 +1,24 @@
+#
+# /etc/pam.d/other - specify the PAM fallback behaviour
+#
+# Note that this file is used for any unspecified service; for example
+#if /etc/pam.d/cron specifies no session modules but cron calls
+#pam_open_session, the session module out of /etc/pam.d/other is
+#used.
+
+# We use pam_warn.so to generate syslog notes that the 'other'
+#fallback rules are being used (as a hint to suggest you should setup
+#specific PAM rules for the service and aid to debugging). Then to be
+#secure, deny access to all services by default.
+
+auth required pam_warn.so
+auth required pam_deny.so
+
+account required pam_warn.so
+account required pam_deny.so
+
+password required pam_warn.so
+password required pam_deny.so
+
+session required pam_warn.so
+session required pam_deny.so
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/run-ptest b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/run-ptest
new file mode 100644
index 000000000..9c304aee4
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam/run-ptest
@@ -0,0 +1,32 @@
+#! /bin/sh
+
+cd tests
+
+export srcdir=.
+
+failed=0
+all=0
+for f in tst-*; do
+ "./$f" > /dev/null 2>&1
+ case "$?" in
+ 0)
+ echo "PASS: $f"
+ all=$((all + 1))
+ ;;
+ 77)
+ echo "SKIP: $f"
+ ;;
+ *)
+ echo "FAIL: $f"
+ failed=$((failed + 1))
+ all=$((all + 1))
+ ;;
+ esac
+done
+
+if [ "$failed" -eq 0 ] ; then
+ echo "All $all tests passed"
+else
+ echo "$failed of $all tests failed"
+fi
+unset srcdir
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_%.bbappend b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_%.bbappend
index 21e1d88ea..65a4d6d68 100644
--- a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_%.bbappend
@@ -1,7 +1,75 @@
RDEPENDS:${PN}-runtime += "${MLPREFIX}pam-plugin-localuser-${libpam_suffix}"
+RDEPENDS:${PN}-runtime += "${MLPREFIX}pam-plugin-faillock-${libpam_suffix}"
+RDEPENDS:${PN}-runtime += "libpwquality"
+RDEPENDS:${PN}-runtime:remove = "${MLPREFIX}pam-plugin-cracklib-${libpam_suffix}"
+RDEPENDS:${PN}-runtime:remove = "${MLPREFIX}pam-plugin-tally2-${libpam_suffix}"
+
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+SRC_URI += " file://pam.d/common-password \
+ file://pam.d/common-account \
+ file://pam.d/common-auth \
+ file://pam.d/common-session \
+ file://faillock.conf \
+ file://convert-pam-configs.service \
+ file://convert-pam-configs.sh \
+ "
+
+inherit systemd
+SYSTEMD_SERVICE:${PN} += "convert-pam-configs.service"
+
+FILES:${PN} += "${bindir}/convert-pam-configs.sh \
+ ${systemd_system_unitdir}/convert-pam-configs.service \
+ "
-#Default settings lockout duration to 300 seconds and threshold value to 10
do_install:append() {
- sed -i 's/deny=0/deny=10/' ${D}${sysconfdir}/pam.d/common-auth
- sed -i 's/unlock_time=0/unlock_time=300/' ${D}${sysconfdir}/pam.d/common-auth
+ install -d ${D}/etc/security
+ install -m 0644 ${WORKDIR}/faillock.conf ${D}/etc/security
+
+ install -d ${D}${bindir}
+ install -m 0755 ${WORKDIR}/convert-pam-configs.sh ${D}${bindir}
+
+ install -d ${D}${systemd_system_unitdir}
+ install -m 0644 ${WORKDIR}/convert-pam-configs.service ${D}${systemd_system_unitdir}
}
+
+#
+# Background:
+# 1. Linux-PAM modules tally2 and cracklib were removed in libpam_1.5,
+# which prompted OpenBMC to change to the faillock and pwquality modules.
+# The PAM config files under /etc/pam.d were changed accordingly.
+# 2. OpenBMC implementations store Redfish property values in PAM config files.
+# For example, the D-Bus property maxLoginAttemptBeforeLockout is stored in
+# /etc/pam.d/common-auth as the pam_tally2.so deny= parameter value.
+# 3. The /etc directory is readonly and has a readwrite overlayfs. That
+# means when a config file changes, an overlay file is created which hides
+# the readonly version.
+#
+# Problem scenario:
+# 1. Begin with a BMC that has a firmware image which has the old PAM
+# modules and the old PAM config files which have modified parameters.
+# For example, there is an overlay file for /etc/pam.d/common-auth.
+# 2. Perform a firmware update to a firmware image which has the new PAM
+# modules. The updated image will have not have the old PAM modules.
+# It will have the new PAM config files in its readonly file system and
+# the old PAM config files in its readwrite overlay.
+# 3. Note that PAM authentication will always fail at this point because
+# the old PAM config files in the overlay tell PAM to use the old PAM
+# modules which are not present on the system.
+#
+# Two possible recoveries are:
+# A. Factory reset the BMC. This will clear the readwrite overlay,
+# allowing PAM to use the readonly version.
+# B. Convert the old PAM config files to the new style. See below.
+#
+# Service: The convert-pam-configs.service updates the old-style PAM config
+# files on the BMC: it changes uses of the old modules to the new modules
+# and carries forward configuration parameters. A key point is that files
+# are written to *only* as needed to convert uses of the old modules to the
+# new modules. See the conversion tool for details.
+#
+# This service can be removed when the BMC no longer supports a direct
+# firware update path from a version which has the old PAM configs to a
+# version which has the new PAM configs.
+#
+# In case of downgrade, Factory reset is recommended. Current logic in existing
+# images won't be able to take care of these settings during downgrade.
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_1.5.2.bb b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_1.5.2.bb
new file mode 100644
index 000000000..5197f1813
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/pam/libpam_1.5.2.bb
@@ -0,0 +1,186 @@
+DISABLE_STATIC = ""
+SUMMARY = "Linux-PAM (Pluggable Authentication Modules)"
+DESCRIPTION = "Linux-PAM (Pluggable Authentication Modules for Linux), a flexible mechanism for authenticating users"
+HOMEPAGE = "https://fedorahosted.org/linux-pam/"
+BUGTRACKER = "https://fedorahosted.org/linux-pam/newticket"
+SECTION = "base"
+# PAM is dual licensed under GPL and BSD.
+# /etc/pam.d comes from Debian libpam-runtime in 2009-11 (at that time
+# libpam-runtime-1.0.1 is GPL-2.0-or-later), by openembedded
+LICENSE = "GPL-2.0-or-later | BSD-3-Clause"
+LIC_FILES_CHKSUM = "file://COPYING;md5=7eb5c1bf854e8881005d673599ee74d3 \
+ file://libpamc/License;md5=a4da476a14c093fdc73be3c3c9ba8fb3 \
+ "
+
+SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/Linux-PAM-${PV}.tar.xz \
+ file://99_pam \
+ file://pam.d/common-account \
+ file://pam.d/common-auth \
+ file://pam.d/common-password \
+ file://pam.d/common-session \
+ file://pam.d/common-session-noninteractive \
+ file://pam.d/other \
+ file://libpam-xtests.patch \
+ file://0001-run-xtests.sh-check-whether-files-exist.patch \
+ file://run-ptest \
+ file://pam-volatiles.conf \
+ file://CVE-2022-28321-0002.patch \
+ "
+
+SRC_URI[sha256sum] = "e4ec7131a91da44512574268f493c6d8ca105c87091691b8e9b56ca685d4f94d"
+
+DEPENDS = "bison-native flex-native cracklib libxml2-native virtual/crypt"
+
+EXTRA_OECONF = "--includedir=${includedir}/security \
+ --libdir=${base_libdir} \
+ --with-systemdunitdir=${systemd_system_unitdir} \
+ --disable-nis \
+ --disable-regenerate-docu \
+ --disable-doc \
+ --disable-prelude"
+
+CFLAGS:append = " -fPIC "
+
+S = "${WORKDIR}/Linux-PAM-${PV}"
+
+inherit autotools gettext pkgconfig systemd ptest github-releases
+
+PACKAGECONFIG ??= ""
+PACKAGECONFIG[audit] = "--enable-audit,--disable-audit,audit,"
+PACKAGECONFIG[userdb] = "--enable-db=db,--enable-db=no,db,"
+
+PACKAGES += "${PN}-runtime ${PN}-xtests"
+FILES:${PN} = "${base_libdir}/lib*${SOLIBS}"
+FILES:${PN}-dev += "${base_libdir}/security/*.la ${base_libdir}/*.la ${base_libdir}/lib*${SOLIBSDEV}"
+FILES:${PN}-runtime = "${sysconfdir} ${sbindir} ${systemd_system_unitdir}"
+FILES:${PN}-xtests = "${datadir}/Linux-PAM/xtests"
+
+PACKAGES_DYNAMIC += "^${MLPREFIX}pam-plugin-.*"
+
+def get_multilib_bit(d):
+ baselib = d.getVar('baselib') or ''
+ return baselib.replace('lib', '')
+
+libpam_suffix = "suffix${@get_multilib_bit(d)}"
+
+RPROVIDES:${PN} += "${PN}-${libpam_suffix}"
+RPROVIDES:${PN}-runtime += "${PN}-runtime-${libpam_suffix}"
+
+RDEPENDS:${PN}-runtime = "${PN}-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-deny-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-permit-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-warn-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-unix-${libpam_suffix} \
+ "
+RDEPENDS:${PN}-xtests = "${PN}-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-access-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-debug-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-pwhistory-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-succeed-if-${libpam_suffix} \
+ ${MLPREFIX}pam-plugin-time-${libpam_suffix} \
+ bash coreutils"
+
+# FIXME: Native suffix breaks here, disable it for now
+RRECOMMENDS:${PN} = "${PN}-runtime-${libpam_suffix}"
+RRECOMMENDS:${PN}:class-native = ""
+
+python populate_packages:prepend () {
+ def pam_plugin_hook(file, pkg, pattern, format, basename):
+ pn = d.getVar('PN')
+ libpam_suffix = d.getVar('libpam_suffix')
+
+ rdeps = d.getVar('RDEPENDS:' + pkg)
+ if rdeps:
+ rdeps = rdeps + " " + pn + "-" + libpam_suffix
+ else:
+ rdeps = pn + "-" + libpam_suffix
+ d.setVar('RDEPENDS:' + pkg, rdeps)
+
+ provides = d.getVar('RPROVIDES:' + pkg)
+ if provides:
+ provides = provides + " " + pkg + "-" + libpam_suffix
+ else:
+ provides = pkg + "-" + libpam_suffix
+ d.setVar('RPROVIDES:' + pkg, provides)
+
+ mlprefix = d.getVar('MLPREFIX') or ''
+ dvar = d.expand('${WORKDIR}/package')
+ pam_libdir = d.expand('${base_libdir}/security')
+ pam_sbindir = d.expand('${sbindir}')
+ pam_filterdir = d.expand('${base_libdir}/security/pam_filter')
+ pam_pkgname = mlprefix + 'pam-plugin%s'
+
+ do_split_packages(d, pam_libdir, r'^pam(.*)\.so$', pam_pkgname,
+ 'PAM plugin for %s', hook=pam_plugin_hook, extra_depends='')
+ do_split_packages(d, pam_filterdir, r'^(.*)$', 'pam-filter-%s', 'PAM filter for %s', extra_depends='')
+}
+
+do_compile_ptest() {
+ cd tests
+ sed -i -e 's/$(MAKE) $(AM_MAKEFLAGS) check-TESTS//' Makefile
+ oe_runmake check-am
+ cd -
+}
+
+do_install() {
+ autotools_do_install
+
+ # don't install /var/run when populating rootfs. Do it through volatile
+ rm -rf ${D}${localstatedir}
+
+ if ${@bb.utils.contains('DISTRO_FEATURES','sysvinit','false','true',d)}; then
+ rm -rf ${D}${sysconfdir}/init.d/
+ rm -rf ${D}${sysconfdir}/rc*
+ install -d ${D}${sysconfdir}/tmpfiles.d
+ install -m 0644 ${WORKDIR}/pam-volatiles.conf \
+ ${D}${sysconfdir}/tmpfiles.d/pam.conf
+ else
+ install -d ${D}${sysconfdir}/default/volatiles
+ install -m 0644 ${WORKDIR}/99_pam \
+ ${D}${sysconfdir}/default/volatiles/
+ fi
+
+ install -d ${D}${sysconfdir}/pam.d/
+ install -m 0644 ${WORKDIR}/pam.d/* ${D}${sysconfdir}/pam.d/
+
+ # The lsb requires unix_chkpwd has setuid permission
+ chmod 4755 ${D}${sbindir}/unix_chkpwd
+
+ if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
+ echo "session optional pam_systemd.so" >> ${D}${sysconfdir}/pam.d/common-session
+ fi
+ if ${@bb.utils.contains('DISTRO_FEATURES','usrmerge','false','true',d)}; then
+ install -d ${D}/${libdir}/
+ mv ${D}/${base_libdir}/pkgconfig ${D}/${libdir}/
+ fi
+}
+
+do_install_ptest() {
+ if [ ${PTEST_ENABLED} = "1" ]; then
+ mkdir -p ${D}${PTEST_PATH}/tests
+ install -m 0755 ${B}/tests/.libs/* ${D}${PTEST_PATH}/tests
+ install -m 0644 ${S}/tests/confdir ${D}${PTEST_PATH}/tests
+ fi
+}
+
+pkg_postinst:${PN}() {
+ if [ -z "$D" ] && [ -e /etc/init.d/populate-volatile.sh ] ; then
+ /etc/init.d/populate-volatile.sh update
+ fi
+}
+
+inherit features_check
+REQUIRED_DISTRO_FEATURES = "pam"
+
+BBCLASSEXTEND = "nativesdk native"
+
+CONFFILES:${PN}-runtime += "${sysconfdir}/pam.d/common-session"
+CONFFILES:${PN}-runtime += "${sysconfdir}/pam.d/common-auth"
+CONFFILES:${PN}-runtime += "${sysconfdir}/pam.d/common-password"
+CONFFILES:${PN}-runtime += "${sysconfdir}/pam.d/common-session-noninteractive"
+CONFFILES:${PN}-runtime += "${sysconfdir}/pam.d/common-account"
+CONFFILES:${PN}-runtime += "${sysconfdir}/security/limits.conf"
+
+GITHUB_BASE_URI = "https://github.com/linux-pam/linux-pam/releases"
+
+CVE_PRODUCT = "linux-pam"
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/CVE-2022-24903.patch b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/CVE-2022-24903.patch
new file mode 100644
index 000000000..f7d70352b
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog/CVE-2022-24903.patch
@@ -0,0 +1,164 @@
+From d59de97be98ab70ee38d9efa11d04d8015e23df6 Mon Sep 17 00:00:00 2001
+From: Rainer Gerhards <rgerhards@adiscon.com>
+Date: Fri, 22 Apr 2022 09:49:46 +0200
+Subject: [PATCH 1/2] net bugfix: potential buffer overrun
+
+---
+ contrib/imhttp/imhttp.c | 4 +++-
+ plugins/imptcp/imptcp.c | 4 +++-
+ runtime/tcps_sess.c | 4 +++-
+ 3 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/contrib/imhttp/imhttp.c b/contrib/imhttp/imhttp.c
+index f09260b586..95704af985 100644
+--- a/contrib/imhttp/imhttp.c
++++ b/contrib/imhttp/imhttp.c
+@@ -487,7 +487,9 @@ processOctetMsgLen(const instanceConf_t *const inst, struct conn_wrkr_s *connWrk
+ connWrkr->parseState.iOctetsRemain = connWrkr->parseState.iOctetsRemain * 10 + ch - '0';
+ }
+ // temporarily save this character into the message buffer
+- connWrkr->pMsg[connWrkr->iMsg++] = ch;
++ if(connWrkr->iMsg + 1 < s_iMaxLine) {
++ connWrkr->pMsg[connWrkr->iMsg++] = ch;
++ }
+ } else {
+ const char *remoteAddr = "";
+ if (connWrkr->propRemoteAddr) {
+diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c
+index 2df46a236c..c32dec5851 100644
+--- a/plugins/imptcp/imptcp.c
++++ b/plugins/imptcp/imptcp.c
+@@ -1107,7 +1107,9 @@ processDataRcvd(ptcpsess_t *const __restrict__ pThis,
+ if(pThis->iOctetsRemain <= 200000000) {
+ pThis->iOctetsRemain = pThis->iOctetsRemain * 10 + c - '0';
+ }
+- *(pThis->pMsg + pThis->iMsg++) = c;
++ if(pThis->iMsg < iMaxLine) {
++ *(pThis->pMsg + pThis->iMsg++) = c;
++ }
+ } else { /* done with the octet count, so this must be the SP terminator */
+ DBGPRINTF("TCP Message with octet-counter, size %d.\n", pThis->iOctetsRemain);
+ prop.GetString(pThis->peerName, &propPeerName, &lenPeerName);
+diff --git a/runtime/tcps_sess.c b/runtime/tcps_sess.c
+index 0efa2c23c4..c5442f7638 100644
+--- a/runtime/tcps_sess.c
++++ b/runtime/tcps_sess.c
+@@ -390,7 +390,9 @@ processDataRcvd(tcps_sess_t *pThis,
+ if(pThis->iOctetsRemain <= 200000000) {
+ pThis->iOctetsRemain = pThis->iOctetsRemain * 10 + c - '0';
+ }
+- *(pThis->pMsg + pThis->iMsg++) = c;
++ if(pThis->iMsg < iMaxLine) {
++ *(pThis->pMsg + pThis->iMsg++) = c;
++ }
+ } else { /* done with the octet count, so this must be the SP terminator */
+ DBGPRINTF("TCP Message with octet-counter, size %d.\n", pThis->iOctetsRemain);
+ prop.GetString(pThis->fromHost, &propPeerName, &lenPeerName);
+
+From 30ccf7cd4c00bfc38c2e0b1461b799b1a412d7fb Mon Sep 17 00:00:00 2001
+From: Rainer Gerhards <rgerhards@adiscon.com>
+Date: Mon, 25 Apr 2022 10:18:46 +0200
+Subject: [PATCH 2/2] testbench: new tests for potential buffer overrun
+
+---
+ tests/Makefile.am | 4 ++++
+ tests/imptcp-octet-framing-too-long-vg.sh | 23 +++++++++++++++++++++++
+ tests/imtcp-octet-framing-too-long-vg.sh | 23 +++++++++++++++++++++++
+ 3 files changed, 50 insertions(+)
+ create mode 100755 tests/imptcp-octet-framing-too-long-vg.sh
+ create mode 100755 tests/imtcp-octet-framing-too-long-vg.sh
+
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index 330546890e..805949ec8b 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -283,6 +283,7 @@ TESTS += \
+ allowed-sender-tcp-fail.sh \
+ allowed-sender-tcp-hostname-ok.sh \
+ allowed-sender-tcp-hostname-fail.sh \
++ imtcp-octet-framing-too-long-vg.sh \
+ imtcp-discard-truncated-msg.sh \
+ imtcp-basic.sh \
+ imtcp-basic-hup.sh \
+@@ -1074,6 +1075,7 @@ if ENABLE_IMPTCP
+ # need to be disabled if we do not have this module
+ TESTS += \
+ manyptcp.sh \
++ imptcp-octet-framing-too-long-vg.sh \
+ imptcp_framing_regex.sh \
+ imptcp_framing_regex-oversize.sh \
+ imptcp_large.sh \
+@@ -2121,6 +2123,7 @@ EXTRA_DIST= \
+ mmjsonparse_simple.sh \
+ mmjsonparse-invalid-containerName.sh \
+ wtpShutdownAll-assertionFailure.sh \
++ imptcp-octet-framing-too-long-vg.sh \
+ imptcp-oversize-message-display.sh \
+ imptcp-msg-truncation-on-number.sh \
+ imptcp-msg-truncation-on-number2.sh \
+@@ -2199,6 +2202,7 @@ EXTRA_DIST= \
+ allowed-sender-tcp-fail.sh \
+ allowed-sender-tcp-hostname-ok.sh \
+ allowed-sender-tcp-hostname-fail.sh \
++ imtcp-octet-framing-too-long-vg.sh \
+ imtcp-discard-truncated-msg.sh \
+ imtcp-basic.sh \
+ imtcp-basic-hup.sh \
+diff --git a/tests/imptcp-octet-framing-too-long-vg.sh b/tests/imptcp-octet-framing-too-long-vg.sh
+new file mode 100755
+index 0000000000..d5b2c9adce
+--- /dev/null
++++ b/tests/imptcp-octet-framing-too-long-vg.sh
+@@ -0,0 +1,23 @@
++#!/bin/bash
++# added 2022-04-25 by RGerhards, released under ASL 2.0
++. ${srcdir:=.}/diag.sh init
++generate_conf
++add_conf '
++$MaxMessageSize 128
++global(processInternalMessages="on"
++ oversizemsg.input.mode="accept")
++module(load="../plugins/imptcp/.libs/imptcp")
++input(type="imptcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
++
++action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
++'
++startup_vg
++echo "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000 <120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncatedtest1 test2 test3 test4 test5 ab" > $RSYSLOG_DYNNAME.inputfile
++tcpflood -I $RSYSLOG_DYNNAME.inputfile
++shutdown_when_empty
++wait_shutdown_vg
++check_exit_vg
++
++# the prime objective is to see if valgrind check is ok, but we also do a quick content check (just in case)
++content_check "received oversize message from peer"
++exit_test
+diff --git a/tests/imtcp-octet-framing-too-long-vg.sh b/tests/imtcp-octet-framing-too-long-vg.sh
+new file mode 100755
+index 0000000000..88e8a14fb9
+--- /dev/null
++++ b/tests/imtcp-octet-framing-too-long-vg.sh
+@@ -0,0 +1,23 @@
++#!/bin/bash
++# added 2022-04-25 by RGerhards, released under ASL 2.0
++. ${srcdir:=.}/diag.sh init
++generate_conf
++add_conf '
++$MaxMessageSize 128
++global(processInternalMessages="on"
++ oversizemsg.input.mode="accept")
++module(load="../plugins/imtcp/.libs/imtcp")
++input(type="imtcp" port="0" listenPortFileName="'$RSYSLOG_DYNNAME'.tcpflood_port")
++
++action(type="omfile" file="'$RSYSLOG_OUT_LOG'")
++'
++startup_vg
++echo "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000 <120> 2011-03-01T11:22:12Z host tag: this is a way too long message that has to be truncatedtest1 test2 test3 test4 test5 ab" > $RSYSLOG_DYNNAME.inputfile
++tcpflood -I $RSYSLOG_DYNNAME.inputfile
++shutdown_when_empty
++wait_shutdown_vg
++check_exit_vg
++
++# the prime objective is to see if valgrind check is ok, but we also do a quick content check (just in case)
++content_check "received oversize message from peer"
++exit_test
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend
index de026d919..650c40b41 100644
--- a/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-extended/rsyslog/rsyslog_%.bbappend
@@ -1,5 +1,9 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+SRC_URI += " \
+ file://CVE-2022-24903.patch \
+ "
+
do_install:append() {
sed -i -e"s/ network-online.target//g" ${D}${systemd_system_unitdir}/rsyslog.service
-} \ No newline at end of file
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_1.patch b/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_1.patch
new file mode 100644
index 000000000..37be3f907
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_1.patch
@@ -0,0 +1,42 @@
+From e5905c4b84d4fb90aefcd96ee618411ebfac663d Mon Sep 17 00:00:00 2001
+From: tomspiderlabs <128755403+tomspiderlabs@users.noreply.github.com>
+Date: Thu, 23 Mar 2023 23:39:38 +0000
+Subject: [PATCH] Added control character check
+
+Added control character check, returning -1 (to "err") if control characters are present.
+---
+ lib/fields.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/lib/fields.c b/lib/fields.c
+index 640be931f..fb51b5829 100644
+--- a/lib/fields.c
++++ b/lib/fields.c
+@@ -21,9 +21,9 @@
+ *
+ * The supplied field is scanned for non-printable and other illegal
+ * characters.
+- * + -1 is returned if an illegal character is present.
+- * + 1 is returned if no illegal characters are present, but the field
+- * contains a non-printable character.
++ * + -1 is returned if an illegal or control character is present.
++ * + 1 is returned if no illegal or control characters are present,
++ * but the field contains a non-printable character.
+ * + 0 is returned otherwise.
+ */
+ int valid_field (const char *field, const char *illegal)
+@@ -45,10 +45,13 @@ int valid_field (const char *field, const char *illegal)
+ }
+
+ if (0 == err) {
+- /* Search if there are some non-printable characters */
++ /* Search if there are non-printable or control characters */
+ for (cp = field; '\0' != *cp; cp++) {
+ if (!isprint (*cp)) {
+ err = 1;
++ }
++ if (!iscntrl (*cp)) {
++ err = -1;
+ break;
+ }
+ }
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_2.patch b/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_2.patch
new file mode 100644
index 000000000..7def7fc7d
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow/CVE-2023-29383_2.patch
@@ -0,0 +1,58 @@
+From 2eaea70111f65b16d55998386e4ceb4273c19eb4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
+Date: Fri, 31 Mar 2023 14:46:50 +0200
+Subject: [PATCH] Overhaul valid_field()
+
+e5905c4b ("Added control character check") introduced checking for
+control characters but had the logic inverted, so it rejects all
+characters that are not control ones.
+
+Cast the character to `unsigned char` before passing to the character
+checking functions to avoid UB.
+
+Use strpbrk(3) for the illegal character test and return early.
+---
+ lib/fields.c | 24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/lib/fields.c b/lib/fields.c
+index fb51b5829..539292485 100644
+--- a/lib/fields.c
++++ b/lib/fields.c
+@@ -37,26 +37,22 @@ int valid_field (const char *field, const char *illegal)
+
+ /* For each character of field, search if it appears in the list
+ * of illegal characters. */
++ if (illegal && NULL != strpbrk (field, illegal)) {
++ return -1;
++ }
++
++ /* Search if there are non-printable or control characters */
+ for (cp = field; '\0' != *cp; cp++) {
+- if (strchr (illegal, *cp) != NULL) {
++ unsigned char c = *cp;
++ if (!isprint (c)) {
++ err = 1;
++ }
++ if (iscntrl (c)) {
+ err = -1;
+ break;
+ }
+ }
+
+- if (0 == err) {
+- /* Search if there are non-printable or control characters */
+- for (cp = field; '\0' != *cp; cp++) {
+- if (!isprint (*cp)) {
+- err = 1;
+- }
+- if (!iscntrl (*cp)) {
+- err = -1;
+- break;
+- }
+- }
+- }
+-
+ return err;
+ }
+
diff --git a/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow_%.bbappend b/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow_%.bbappend
index 31952588b..15fd63096 100644
--- a/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-extended/shadow/shadow_%.bbappend
@@ -2,3 +2,7 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
PAM_SRC_URI += "file://pam.d/login \
"
+SRC_URI += " \
+ file://CVE-2023-29383_1.patch \
+ file://CVE-2023-29383_2.patch \
+ "
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0004-soc-aspeed-lpc-mbox-Don-t-allow-partial-reads.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0004-soc-aspeed-lpc-mbox-Don-t-allow-partial-reads.patch
new file mode 100644
index 000000000..e041e665a
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0004-soc-aspeed-lpc-mbox-Don-t-allow-partial-reads.patch
@@ -0,0 +1,40 @@
+From d655ada2fc4b5065c2be6943f28aa4e4f694a1a3 Mon Sep 17 00:00:00 2001
+From: Iwona Winiarska <iwona.winiarska@intel.com>
+Date: Mon, 9 Jan 2023 21:09:44 +0100
+Subject: [PATCH] soc: aspeed: lpc-mbox: Don't allow partial reads
+
+IRQ handler always adds all registers to the fifo, while the userspace
+can potentially consume a smaller amount. Unfortunately, when smaller
+amount is consumed, it permanently shifts the fifo.
+Serialize the "empty" state check to avoid partial reads.
+
+Fixes: 60fde6cf7114 ("soc: aspeed: lpc-mbox: Avoid calling kfifo_to_user in atomic context")
+Reported-by: Arun P. Mohanan <arun.p.m@linux.intel.com>
+Signed-off-by: Iwona Winiarska <iwona.winiarska@intel.com>
+---
+ drivers/soc/aspeed/aspeed-lpc-mbox.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/aspeed/aspeed-lpc-mbox.c b/drivers/soc/aspeed/aspeed-lpc-mbox.c
+index 7941792abacb..564c7318da10 100644
+--- a/drivers/soc/aspeed/aspeed-lpc-mbox.c
++++ b/drivers/soc/aspeed/aspeed-lpc-mbox.c
+@@ -172,7 +172,14 @@ static ssize_t aspeed_mbox_read(struct file *file, char __user *buf,
+ }
+
+ mutex_lock(&mbox->mutex);
+- if (kfifo_is_empty(&mbox->fifo)) {
++ /*
++ * Since fifo on the producer side will drop the oldest values, causing
++ * a shift if the data is not consumed fully, when we're using count ==
++ * num_regs reads, we need to serialize with the producer to make
++ * sure that all regs were inserted into fifo (avoiding a partial
++ * read).
++ */
++ if (kfifo_is_empty_spinlocked(&mbox->fifo, &mbox->lock)) {
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ goto out_unlock;
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0005-ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr-h.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0005-ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr-h.patch
new file mode 100644
index 000000000..b4a5465fe
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0005-ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr-h.patch
@@ -0,0 +1,42 @@
+From 179b14152dcb6a24c3415200603aebca70ff13af Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Thu, 16 Jun 2022 10:13:55 +0800
+Subject: [PATCH] ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h
+
+When adding an xattr to an inode, we must ensure that the inode_size is
+not less than EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad. Otherwise,
+the end position may be greater than the start position, resulting in UAF.
+
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Link: https://lore.kernel.org/r/20220616021358.2504451-2-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+---
+ fs/ext4/xattr.h | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h
+index 77efb9a627ad21..f885f362add4af 100644
+--- a/fs/ext4/xattr.h
++++ b/fs/ext4/xattr.h
+@@ -95,6 +95,19 @@ struct ext4_xattr_entry {
+
+ #define EXT4_ZERO_XATTR_VALUE ((void *)-1)
+
++/*
++ * If we want to add an xattr to the inode, we should make sure that
++ * i_extra_isize is not 0 and that the inode size is not less than
++ * EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad.
++ * EXT4_GOOD_OLD_INODE_SIZE extra_isize header entry pad data
++ * |--------------------------|------------|------|---------|---|-------|
++ */
++#define EXT4_INODE_HAS_XATTR_SPACE(inode) \
++ ((EXT4_I(inode)->i_extra_isize != 0) && \
++ (EXT4_GOOD_OLD_INODE_SIZE + EXT4_I(inode)->i_extra_isize + \
++ sizeof(struct ext4_xattr_ibody_header) + EXT4_XATTR_PAD <= \
++ EXT4_INODE_SIZE((inode)->i_sb)))
++
+ struct ext4_xattr_info {
+ const char *name;
+ const void *value;
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2020-36516.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2020-36516.patch
new file mode 100644
index 000000000..dd44c9ce7
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2020-36516.patch
@@ -0,0 +1,62 @@
+From 23f57406b82de51809d5812afd96f210f8b627f3 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 26 Jan 2022 17:10:22 -0800
+Subject: [PATCH] ipv4: avoid using shared IP generator for connected sockets
+
+ip_select_ident_segs() has been very conservative about using
+the connected socket private generator only for packets with IP_DF
+set, claiming it was needed for some VJ compression implementations.
+
+As mentioned in this referenced document, this can be abused.
+(Ref: Off-Path TCP Exploits of the Mixed IPID Assignment)
+
+Before switching to pure random IPID generation and possibly hurt
+some workloads, lets use the private inet socket generator.
+
+Not only this will remove one vulnerability, this will also
+improve performance of TCP flows using pmtudisc==IP_PMTUDISC_DONT
+
+Fixes: 73f156a6e8c1 ("inetpeer: get rid of ip_id_count")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reported-by: Ray Che <xijiache@gmail.com>
+Cc: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/net/ip.h | 21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 81e23a102a0d5e..b51bae43b0ddb0 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -525,19 +525,18 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
+ {
+ struct iphdr *iph = ip_hdr(skb);
+
++ /* We had many attacks based on IPID, use the private
++ * generator as much as we can.
++ */
++ if (sk && inet_sk(sk)->inet_daddr) {
++ iph->id = htons(inet_sk(sk)->inet_id);
++ inet_sk(sk)->inet_id += segs;
++ return;
++ }
+ if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
+- /* This is only to work around buggy Windows95/2000
+- * VJ compression implementations. If the ID field
+- * does not change, they drop every other packet in
+- * a TCP stream using header compression.
+- */
+- if (sk && inet_sk(sk)->inet_daddr) {
+- iph->id = htons(inet_sk(sk)->inet_id);
+- inet_sk(sk)->inet_id += segs;
+- } else {
+- iph->id = 0;
+- }
++ iph->id = 0;
+ } else {
++ /* Unfortunately we need the big hammer to get a suitable IPID */
+ __ip_select_ident(net, iph, segs);
+ }
+ }
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2978.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2978.patch
new file mode 100644
index 000000000..c43941f9f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-2978.patch
@@ -0,0 +1,62 @@
+From 2a96b532098284ecf8e4849b8b9e5fc7a28bdee9 Mon Sep 17 00:00:00 2001
+From: Dongliang Mu <mudongliangabcd@gmail.com>
+Date: Tue, 16 Aug 2022 12:08:58 +0800
+Subject: [PATCH] fs: fix UAF/GPF bug in nilfs_mdt_destroy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+commit 2e488f13755ffbb60f307e991b27024716a33b29 upstream.
+
+In alloc_inode, inode_init_always() could return -ENOMEM if
+security_inode_alloc() fails, which causes inode->i_private
+uninitialized. Then nilfs_is_metadata_file_inode() returns
+true and nilfs_free_inode() wrongly calls nilfs_mdt_destroy(),
+which frees the uninitialized inode->i_private
+and leads to crashes(e.g., UAF/GPF).
+
+Fix this by moving security_inode_alloc just prior to
+this_cpu_inc(nr_inodes)
+
+Link: https://lkml.kernel.org/r/CAFcO6XOcf1Jj2SeGt=jJV59wmhESeSKpfR0omdFRq+J9nD1vfQ@mail.gmail.com
+Reported-by: butt3rflyh4ck <butterflyhuangxx@gmail.com>
+Reported-by: Hao Sun <sunhao.th@gmail.com>
+Reported-by: Jiacheng Xu <stitch@zju.edu.cn>
+Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
+Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
+Cc: Al Viro <viro@zeniv.linux.org.uk>
+Cc: stable@vger.kernel.org
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/inode.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/fs/inode.c b/fs/inode.c
+index ba1de23c13c1ed..b608528efd3a46 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -192,8 +192,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
+ inode->i_wb_frn_history = 0;
+ #endif
+
+- if (security_inode_alloc(inode))
+- goto out;
+ spin_lock_init(&inode->i_lock);
+ lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
+
+@@ -228,11 +226,12 @@ int inode_init_always(struct super_block *sb, struct inode *inode)
+ inode->i_fsnotify_mask = 0;
+ #endif
+ inode->i_flctx = NULL;
++
++ if (unlikely(security_inode_alloc(inode)))
++ return -ENOMEM;
+ this_cpu_inc(nr_inodes);
+
+ return 0;
+-out:
+- return -ENOMEM;
+ }
+ EXPORT_SYMBOL(inode_init_always);
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3543.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3543.patch
new file mode 100644
index 000000000..9d83b59af
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3543.patch
@@ -0,0 +1,97 @@
+From 2f415ad33bc1a729fb1050141921b5a9ec4e062c Mon Sep 17 00:00:00 2001
+From: Kuniyuki Iwashima <kuniyu@amazon.com>
+Date: Thu, 29 Sep 2022 08:52:04 -0700
+Subject: [PATCH] af_unix: Fix memory leaks of the whole sk due to OOB skb.
+
+[ Upstream commit 7a62ed61367b8fd01bae1e18e30602c25060d824 ]
+
+syzbot reported a sequence of memory leaks, and one of them indicated we
+failed to free a whole sk:
+
+ unreferenced object 0xffff8880126e0000 (size 1088):
+ comm "syz-executor419", pid 326, jiffies 4294773607 (age 12.609s)
+ hex dump (first 32 bytes):
+ 00 00 00 00 00 00 00 00 7d 00 00 00 00 00 00 00 ........}.......
+ 01 00 07 40 00 00 00 00 00 00 00 00 00 00 00 00 ...@............
+ backtrace:
+ [<000000006fefe750>] sk_prot_alloc+0x64/0x2a0 net/core/sock.c:1970
+ [<0000000074006db5>] sk_alloc+0x3b/0x800 net/core/sock.c:2029
+ [<00000000728cd434>] unix_create1+0xaf/0x920 net/unix/af_unix.c:928
+ [<00000000a279a139>] unix_create+0x113/0x1d0 net/unix/af_unix.c:997
+ [<0000000068259812>] __sock_create+0x2ab/0x550 net/socket.c:1516
+ [<00000000da1521e1>] sock_create net/socket.c:1566 [inline]
+ [<00000000da1521e1>] __sys_socketpair+0x1a8/0x550 net/socket.c:1698
+ [<000000007ab259e1>] __do_sys_socketpair net/socket.c:1751 [inline]
+ [<000000007ab259e1>] __se_sys_socketpair net/socket.c:1748 [inline]
+ [<000000007ab259e1>] __x64_sys_socketpair+0x97/0x100 net/socket.c:1748
+ [<000000007dedddc1>] do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ [<000000007dedddc1>] do_syscall_64+0x38/0x90 arch/x86/entry/common.c:80
+ [<000000009456679f>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+We can reproduce this issue by creating two AF_UNIX SOCK_STREAM sockets,
+send()ing an OOB skb to each other, and close()ing them without consuming
+the OOB skbs.
+
+ int skpair[2];
+
+ socketpair(AF_UNIX, SOCK_STREAM, 0, skpair);
+
+ send(skpair[0], "x", 1, MSG_OOB);
+ send(skpair[1], "x", 1, MSG_OOB);
+
+ close(skpair[0]);
+ close(skpair[1]);
+
+Currently, we free an OOB skb in unix_sock_destructor() which is called via
+__sk_free(), but it's too late because the receiver's unix_sk(sk)->oob_skb
+is accounted against the sender's sk->sk_wmem_alloc and __sk_free() is
+called only when sk->sk_wmem_alloc is 0.
+
+In the repro sequences, we do not consume the OOB skb, so both two sk's
+sock_put() never reach __sk_free() due to the positive sk->sk_wmem_alloc.
+Then, no one can consume the OOB skb nor call __sk_free(), and we finally
+leak the two whole sk.
+
+Thus, we must free the unconsumed OOB skb earlier when close()ing the
+socket.
+
+Fixes: 314001f0bf92 ("af_unix: Add OOB support")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/af_unix.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index bf338b782fc4c4..d686804119c991 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -569,12 +569,6 @@ static void unix_sock_destructor(struct sock *sk)
+
+ skb_queue_purge(&sk->sk_receive_queue);
+
+-#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
+- if (u->oob_skb) {
+- kfree_skb(u->oob_skb);
+- u->oob_skb = NULL;
+- }
+-#endif
+ WARN_ON(refcount_read(&sk->sk_wmem_alloc));
+ WARN_ON(!sk_unhashed(sk));
+ WARN_ON(sk->sk_socket);
+@@ -620,6 +614,13 @@ static void unix_release_sock(struct sock *sk, int embrion)
+
+ unix_state_unlock(sk);
+
++#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
++ if (u->oob_skb) {
++ kfree_skb(u->oob_skb);
++ u->oob_skb = NULL;
++ }
++#endif
++
+ wake_up_interruptible_all(&u->peer_wait);
+
+ if (skpair != NULL) {
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3623.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3623.patch
new file mode 100644
index 000000000..d44f786de
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-3623.patch
@@ -0,0 +1,175 @@
+From fac35ba763ed07ba93154c95ffc0c4a55023707f Mon Sep 17 00:00:00 2001
+From: Baolin Wang <baolin.wang@linux.alibaba.com>
+Date: Thu, 1 Sep 2022 18:41:31 +0800
+Subject: mm/hugetlb: fix races when looking up a CONT-PTE/PMD size hugetlb
+ page
+
+On some architectures (like ARM64), it can support CONT-PTE/PMD size
+hugetlb, which means it can support not only PMD/PUD size hugetlb (2M and
+1G), but also CONT-PTE/PMD size(64K and 32M) if a 4K page size specified.
+
+So when looking up a CONT-PTE size hugetlb page by follow_page(), it will
+use pte_offset_map_lock() to get the pte entry lock for the CONT-PTE size
+hugetlb in follow_page_pte(). However this pte entry lock is incorrect
+for the CONT-PTE size hugetlb, since we should use huge_pte_lock() to get
+the correct lock, which is mm->page_table_lock.
+
+That means the pte entry of the CONT-PTE size hugetlb under current pte
+lock is unstable in follow_page_pte(), we can continue to migrate or
+poison the pte entry of the CONT-PTE size hugetlb, which can cause some
+potential race issues, even though they are under the 'pte lock'.
+
+For example, suppose thread A is trying to look up a CONT-PTE size hugetlb
+page by move_pages() syscall under the lock, however antoher thread B can
+migrate the CONT-PTE hugetlb page at the same time, which will cause
+thread A to get an incorrect page, if thread A also wants to do page
+migration, then data inconsistency error occurs.
+
+Moreover we have the same issue for CONT-PMD size hugetlb in
+follow_huge_pmd().
+
+To fix above issues, rename the follow_huge_pmd() as follow_huge_pmd_pte()
+to handle PMD and PTE level size hugetlb, which uses huge_pte_lock() to
+get the correct pte entry lock to make the pte entry stable.
+
+Mike said:
+
+Support for CONT_PMD/_PTE was added with bb9dd3df8ee9 ("arm64: hugetlb:
+refactor find_num_contig()"). Patch series "Support for contiguous pte
+hugepages", v4. However, I do not believe these code paths were
+executed until migration support was added with 5480280d3f2d ("arm64/mm:
+enable HugeTLB migration for contiguous bit HugeTLB pages") I would go
+with 5480280d3f2d for the Fixes: targe.
+
+Link: https://lkml.kernel.org/r/635f43bdd85ac2615a58405da82b4d33c6e5eb05.1662017562.git.baolin.wang@linux.alibaba.com
+Fixes: 5480280d3f2d ("arm64/mm: enable HugeTLB migration for contiguous bit HugeTLB pages")
+Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Suggested-by: Mike Kravetz <mike.kravetz@oracle.com>
+Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+---
+ include/linux/hugetlb.h | 8 ++++----
+ mm/gup.c | 14 +++++++++++++-
+ mm/hugetlb.c | 27 +++++++++++++--------------
+ 3 files changed, 30 insertions(+), 19 deletions(-)
+
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index 3ec981a0d8b3a..67c88b82fc32d 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -207,8 +207,8 @@ struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+ struct page *follow_huge_pd(struct vm_area_struct *vma,
+ unsigned long address, hugepd_t hpd,
+ int flags, int pdshift);
+-struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+- pmd_t *pmd, int flags);
++struct page *follow_huge_pmd_pte(struct vm_area_struct *vma, unsigned long address,
++ int flags);
+ struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
+ pud_t *pud, int flags);
+ struct page *follow_huge_pgd(struct mm_struct *mm, unsigned long address,
+@@ -312,8 +312,8 @@ static inline struct page *follow_huge_pd(struct vm_area_struct *vma,
+ return NULL;
+ }
+
+-static inline struct page *follow_huge_pmd(struct mm_struct *mm,
+- unsigned long address, pmd_t *pmd, int flags)
++static inline struct page *follow_huge_pmd_pte(struct vm_area_struct *vma,
++ unsigned long address, int flags)
+ {
+ return NULL;
+ }
+diff --git a/mm/gup.c b/mm/gup.c
+index 00926abb44263..251cb6a10bc0d 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -530,6 +530,18 @@ static struct page *follow_page_pte(struct vm_area_struct *vma,
+ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
+ (FOLL_PIN | FOLL_GET)))
+ return ERR_PTR(-EINVAL);
++
++ /*
++ * Considering PTE level hugetlb, like continuous-PTE hugetlb on
++ * ARM64 architecture.
++ */
++ if (is_vm_hugetlb_page(vma)) {
++ page = follow_huge_pmd_pte(vma, address, flags);
++ if (page)
++ return page;
++ return no_page_table(vma, flags);
++ }
++
+ retry:
+ if (unlikely(pmd_bad(*pmd)))
+ return no_page_table(vma, flags);
+@@ -662,7 +674,7 @@ static struct page *follow_pmd_mask(struct vm_area_struct *vma,
+ if (pmd_none(pmdval))
+ return no_page_table(vma, flags);
+ if (pmd_huge(pmdval) && is_vm_hugetlb_page(vma)) {
+- page = follow_huge_pmd(mm, address, pmd, flags);
++ page = follow_huge_pmd_pte(vma, address, flags);
+ if (page)
+ return page;
+ return no_page_table(vma, flags);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 0bdfc7e1c933f..9564bf817e6a8 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -6946,12 +6946,13 @@ follow_huge_pd(struct vm_area_struct *vma,
+ }
+
+ struct page * __weak
+-follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+- pmd_t *pmd, int flags)
++follow_huge_pmd_pte(struct vm_area_struct *vma, unsigned long address, int flags)
+ {
++ struct hstate *h = hstate_vma(vma);
++ struct mm_struct *mm = vma->vm_mm;
+ struct page *page = NULL;
+ spinlock_t *ptl;
+- pte_t pte;
++ pte_t *ptep, pte;
+
+ /* FOLL_GET and FOLL_PIN are mutually exclusive. */
+ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) ==
+@@ -6961,17 +6962,15 @@ follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ return NULL;
+
+ retry:
+- ptl = pmd_lockptr(mm, pmd);
+- spin_lock(ptl);
+- /*
+- * make sure that the address range covered by this pmd is not
+- * unmapped from other threads.
+- */
+- if (!pmd_huge(*pmd))
+- goto out;
+- pte = huge_ptep_get((pte_t *)pmd);
++ ptep = huge_pte_offset(mm, address, huge_page_size(h));
++ if (!ptep)
++ return NULL;
++
++ ptl = huge_pte_lock(h, mm, ptep);
++ pte = huge_ptep_get(ptep);
+ if (pte_present(pte)) {
+- page = pmd_page(*pmd) + ((address & ~PMD_MASK) >> PAGE_SHIFT);
++ page = pte_page(pte) +
++ ((address & ~huge_page_mask(h)) >> PAGE_SHIFT);
+ /*
+ * try_grab_page() should always succeed here, because: a) we
+ * hold the pmd (ptl) lock, and b) we've just checked that the
+@@ -6987,7 +6986,7 @@ retry:
+ } else {
+ if (is_hugetlb_entry_migration(pte)) {
+ spin_unlock(ptl);
+- __migration_entry_wait(mm, (pte_t *)pmd, ptl);
++ __migration_entry_wait_huge(ptep, ptl);
+ goto retry;
+ }
+ /*
+--
+cgit
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-42703.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-42703.patch
new file mode 100644
index 000000000..059081ce9
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-42703.patch
@@ -0,0 +1,169 @@
+From 2555283eb40df89945557273121e9393ef9b542b Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Wed, 31 Aug 2022 19:06:00 +0200
+Subject: mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse
+
+anon_vma->degree tracks the combined number of child anon_vmas and VMAs
+that use the anon_vma as their ->anon_vma.
+
+anon_vma_clone() then assumes that for any anon_vma attached to
+src->anon_vma_chain other than src->anon_vma, it is impossible for it to
+be a leaf node of the VMA tree, meaning that for such VMAs ->degree is
+elevated by 1 because of a child anon_vma, meaning that if ->degree
+equals 1 there are no VMAs that use the anon_vma as their ->anon_vma.
+
+This assumption is wrong because the ->degree optimization leads to leaf
+nodes being abandoned on anon_vma_clone() - an existing anon_vma is
+reused and no new parent-child relationship is created. So it is
+possible to reuse an anon_vma for one VMA while it is still tied to
+another VMA.
+
+This is an issue because is_mergeable_anon_vma() and its callers assume
+that if two VMAs have the same ->anon_vma, the list of anon_vmas
+attached to the VMAs is guaranteed to be the same. When this assumption
+is violated, vma_merge() can merge pages into a VMA that is not attached
+to the corresponding anon_vma, leading to dangling page->mapping
+pointers that will be dereferenced during rmap walks.
+
+Fix it by separately tracking the number of child anon_vmas and the
+number of VMAs using the anon_vma as their ->anon_vma.
+
+Fixes: 7a3ef208e662 ("mm: prevent endless growth of anon_vma hierarchy")
+Cc: stable@kernel.org
+Acked-by: Michal Hocko <mhocko@suse.com>
+Acked-by: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+ include/linux/rmap.h | 7 +++++--
+ mm/rmap.c | 29 ++++++++++++++++-------------
+ 2 files changed, 21 insertions(+), 15 deletions(-)
+
+diff --git a/include/linux/rmap.h b/include/linux/rmap.h
+index bf80adca980b9..b89b4b86951f8 100644
+--- a/include/linux/rmap.h
++++ b/include/linux/rmap.h
+@@ -41,12 +41,15 @@ struct anon_vma {
+ atomic_t refcount;
+
+ /*
+- * Count of child anon_vmas and VMAs which points to this anon_vma.
++ * Count of child anon_vmas. Equals to the count of all anon_vmas that
++ * have ->parent pointing to this one, including itself.
+ *
+ * This counter is used for making decision about reusing anon_vma
+ * instead of forking new one. See comments in function anon_vma_clone.
+ */
+- unsigned degree;
++ unsigned long num_children;
++ /* Count of VMAs whose ->anon_vma pointer points to this object. */
++ unsigned long num_active_vmas;
+
+ struct anon_vma *parent; /* Parent of this anon_vma */
+
+diff --git a/mm/rmap.c b/mm/rmap.c
+index edc06c52bc82e..93d5a6f793d20 100644
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -93,7 +93,8 @@ static inline struct anon_vma *anon_vma_alloc(void)
+ anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL);
+ if (anon_vma) {
+ atomic_set(&anon_vma->refcount, 1);
+- anon_vma->degree = 1; /* Reference for first vma */
++ anon_vma->num_children = 0;
++ anon_vma->num_active_vmas = 0;
+ anon_vma->parent = anon_vma;
+ /*
+ * Initialise the anon_vma root to point to itself. If called
+@@ -201,6 +202,7 @@ int __anon_vma_prepare(struct vm_area_struct *vma)
+ anon_vma = anon_vma_alloc();
+ if (unlikely(!anon_vma))
+ goto out_enomem_free_avc;
++ anon_vma->num_children++; /* self-parent link for new root */
+ allocated = anon_vma;
+ }
+
+@@ -210,8 +212,7 @@ int __anon_vma_prepare(struct vm_area_struct *vma)
+ if (likely(!vma->anon_vma)) {
+ vma->anon_vma = anon_vma;
+ anon_vma_chain_link(vma, avc, anon_vma);
+- /* vma reference or self-parent link for new root */
+- anon_vma->degree++;
++ anon_vma->num_active_vmas++;
+ allocated = NULL;
+ avc = NULL;
+ }
+@@ -296,19 +297,19 @@ int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src)
+ anon_vma_chain_link(dst, avc, anon_vma);
+
+ /*
+- * Reuse existing anon_vma if its degree lower than two,
+- * that means it has no vma and only one anon_vma child.
++ * Reuse existing anon_vma if it has no vma and only one
++ * anon_vma child.
+ *
+- * Do not chose parent anon_vma, otherwise first child
+- * will always reuse it. Root anon_vma is never reused:
++ * Root anon_vma is never reused:
+ * it has self-parent reference and at least one child.
+ */
+ if (!dst->anon_vma && src->anon_vma &&
+- anon_vma != src->anon_vma && anon_vma->degree < 2)
++ anon_vma->num_children < 2 &&
++ anon_vma->num_active_vmas == 0)
+ dst->anon_vma = anon_vma;
+ }
+ if (dst->anon_vma)
+- dst->anon_vma->degree++;
++ dst->anon_vma->num_active_vmas++;
+ unlock_anon_vma_root(root);
+ return 0;
+
+@@ -358,6 +359,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
+ anon_vma = anon_vma_alloc();
+ if (!anon_vma)
+ goto out_error;
++ anon_vma->num_active_vmas++;
+ avc = anon_vma_chain_alloc(GFP_KERNEL);
+ if (!avc)
+ goto out_error_free_anon_vma;
+@@ -378,7 +380,7 @@ int anon_vma_fork(struct vm_area_struct *vma, struct vm_area_struct *pvma)
+ vma->anon_vma = anon_vma;
+ anon_vma_lock_write(anon_vma);
+ anon_vma_chain_link(vma, avc, anon_vma);
+- anon_vma->parent->degree++;
++ anon_vma->parent->num_children++;
+ anon_vma_unlock_write(anon_vma);
+
+ return 0;
+@@ -410,7 +412,7 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
+ * to free them outside the lock.
+ */
+ if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) {
+- anon_vma->parent->degree--;
++ anon_vma->parent->num_children--;
+ continue;
+ }
+
+@@ -418,7 +420,7 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
+ anon_vma_chain_free(avc);
+ }
+ if (vma->anon_vma) {
+- vma->anon_vma->degree--;
++ vma->anon_vma->num_active_vmas--;
+
+ /*
+ * vma would still be needed after unlink, and anon_vma will be prepared
+@@ -436,7 +438,8 @@ void unlink_anon_vmas(struct vm_area_struct *vma)
+ list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
+ struct anon_vma *anon_vma = avc->anon_vma;
+
+- VM_WARN_ON(anon_vma->degree);
++ VM_WARN_ON(anon_vma->num_children);
++ VM_WARN_ON(anon_vma->num_active_vmas);
+ put_anon_vma(anon_vma);
+
+ list_del(&avc->same_vma);
+--
+cgit
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-1.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-1.patch
new file mode 100644
index 000000000..15fea2b32
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-1.patch
@@ -0,0 +1,107 @@
+From fdf2c95f28bf197bfab421d21e8c697d4f149ea1 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Mon, 5 Dec 2022 12:09:06 -0800
+Subject: [PATCH] proc: proc_skip_spaces() shouldn't think it is working on C
+ strings
+
+commit bce9332220bd677d83b19d21502776ad555a0e73 upstream.
+
+proc_skip_spaces() seems to think it is working on C strings, and ends
+up being just a wrapper around skip_spaces() with a really odd calling
+convention.
+
+Instead of basing it on skip_spaces(), it should have looked more like
+proc_skip_char(), which really is the exact same function (except it
+skips a particular character, rather than whitespace). So use that as
+inspiration, odd coding and all.
+
+Now the calling convention actually makes sense and works for the
+intended purpose.
+
+Reported-and-tested-by: Kyle Zeng <zengyhkyle@gmail.com>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sysctl.c | 25 +++++++++++++------------
+ 1 file changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 25b44424d652cf..e9a3094c52e57a 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -265,13 +265,14 @@ int proc_dostring(struct ctl_table *table, int write,
+ ppos);
+ }
+
+-static size_t proc_skip_spaces(char **buf)
++static void proc_skip_spaces(char **buf, size_t *size)
+ {
+- size_t ret;
+- char *tmp = skip_spaces(*buf);
+- ret = tmp - *buf;
+- *buf = tmp;
+- return ret;
++ while (*size) {
++ if (!isspace(**buf))
++ break;
++ (*size)--;
++ (*buf)++;
++ }
+ }
+
+ static void proc_skip_char(char **buf, size_t *size, const char v)
+@@ -518,7 +519,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
+ bool neg;
+
+ if (write) {
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+
+ if (!left)
+ break;
+@@ -545,7 +546,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table,
+ if (!write && !first && left && !err)
+ proc_put_char(&buffer, &left, '\n');
+ if (write && !err && left)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (write && first)
+ return err ? : -EINVAL;
+ *lenp -= left;
+@@ -587,7 +588,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
+ if (left > PAGE_SIZE - 1)
+ left = PAGE_SIZE - 1;
+
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (!left) {
+ err = -EINVAL;
+ goto out_free;
+@@ -607,7 +608,7 @@ static int do_proc_douintvec_w(unsigned int *tbl_data,
+ }
+
+ if (!err && left)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+
+ out_free:
+ if (err)
+@@ -1072,7 +1073,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
+ if (write) {
+ bool neg;
+
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (!left)
+ break;
+
+@@ -1101,7 +1102,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table,
+ if (!write && !first && left && !err)
+ proc_put_char(&buffer, &left, '\n');
+ if (write && !err)
+- left -= proc_skip_spaces(&p);
++ proc_skip_spaces(&p, &left);
+ if (write && first)
+ return err ? : -EINVAL;
+ *lenp -= left;
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-2.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-2.patch
new file mode 100644
index 000000000..b11e065c8
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-4378-2.patch
@@ -0,0 +1,40 @@
+From e04220518841708f68e7746232e3e54daef464a3 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Mon, 5 Dec 2022 11:33:40 -0800
+Subject: [PATCH] proc: avoid integer type confusion in get_proc_long
+
+commit e6cfaf34be9fcd1a8285a294e18986bfc41a409c upstream.
+
+proc_get_long() is passed a size_t, but then assigns it to an 'int'
+variable for the length. Let's not do that, even if our IO paths are
+limited to MAX_RW_COUNT (exactly because of these kinds of type errors).
+
+So do the proper test in the rigth type.
+
+Reported-by: Kyle Zeng <zengyhkyle@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sysctl.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 205d605cacc5bb..25b44424d652cf 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -340,13 +340,12 @@ static int proc_get_long(char **buf, size_t *size,
+ unsigned long *val, bool *neg,
+ const char *perm_tr, unsigned perm_tr_len, char *tr)
+ {
+- int len;
+ char *p, tmp[TMPBUFLEN];
++ ssize_t len = *size;
+
+- if (!*size)
++ if (len <= 0)
+ return -EINVAL;
+
+- len = *size;
+ if (len > TMPBUFLEN - 1)
+ len = TMPBUFLEN - 1;
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-0394.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-0394.patch
new file mode 100644
index 000000000..25ffd9af5
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-0394.patch
@@ -0,0 +1,43 @@
+From cb3e9864cdbe35ff6378966660edbcbac955fe17 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Tue, 10 Jan 2023 08:59:06 +0800
+Subject: ipv6: raw: Deduct extension header length in
+ rawv6_push_pending_frames
+
+The total cork length created by ip6_append_data includes extension
+headers, so we must exclude them when comparing them against the
+IPV6_CHECKSUM offset which does not include extension headers.
+
+Reported-by: Kyle Zeng <zengyhkyle@gmail.com>
+Fixes: 357b40a18b04 ("[IPV6]: IPV6_CHECKSUM socket option can corrupt kernel memory")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ net/ipv6/raw.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
+index a06a9f847db5c..ada087b50541a 100644
+--- a/net/ipv6/raw.c
++++ b/net/ipv6/raw.c
+@@ -505,6 +505,7 @@ csum_copy_err:
+ static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
+ struct raw6_sock *rp)
+ {
++ struct ipv6_txoptions *opt;
+ struct sk_buff *skb;
+ int err = 0;
+ int offset;
+@@ -522,6 +523,9 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi6 *fl6,
+
+ offset = rp->offset;
+ total_len = inet_sk(sk)->cork.base.length;
++ opt = inet6_sk(sk)->cork.opt;
++ total_len -= opt ? opt->opt_flen : 0;
++
+ if (offset >= total_len - 1) {
+ err = -EINVAL;
+ ip6_flush_pending_frames(sk);
+--
+cgit
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1073.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1073.patch
new file mode 100644
index 000000000..fbad7dd75
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1073.patch
@@ -0,0 +1,34 @@
+From b12fece4c64857e5fab4290bf01b2e0317a88456 Mon Sep 17 00:00:00 2001
+From: Pietro Borrello <borrello@diag.uniroma1.it>
+Date: Mon, 16 Jan 2023 11:11:24 +0000
+Subject: [PATCH] HID: check empty report_list in hid_validate_values()
+
+Add a check for empty report_list in hid_validate_values().
+The missing check causes a type confusion when issuing a list_entry()
+on an empty report_list.
+The problem is caused by the assumption that the device must
+have valid report_list. While this will be true for all normal HID
+devices, a suitably malicious device can violate the assumption.
+
+Fixes: 1b15d2e5b807 ("HID: core: fix validation of report id 0")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+---
+ drivers/hid/hid-core.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index bd47628da6be0d..3e1803592bd4a2 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -993,8 +993,8 @@ struct hid_report *hid_validate_values(struct hid_device *hid,
+ * Validating on id 0 means we should examine the first
+ * report in the list.
+ */
+- report = list_entry(
+- hid->report_enum[type].report_list.next,
++ report = list_first_entry_or_null(
++ &hid->report_enum[type].report_list,
+ struct hid_report, list);
+ } else {
+ report = hid->report_enum[type].report_id_hash[id];
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1077.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1077.patch
new file mode 100644
index 000000000..7bf9fad09
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1077.patch
@@ -0,0 +1,50 @@
+From 71d8dc030a8ebf8401d96872d0ed2d151a4cdbba Mon Sep 17 00:00:00 2001
+From: Anjaliintel-21 <anjali.ray@intel.com>
+Date: Thu, 27 Apr 2023 07:01:53 +0000
+Subject: [PATCH] sched/rt: pick_next_rt_entity(): check list_entry
+
+Commit 326587b84078 ("sched: fix goto retry in pick_next_task_rt()")
+removed any path which could make pick_next_rt_entity() return NULL.
+However, BUG_ON(!rt_se) in _pick_next_task_rt() (the only caller of
+pick_next_rt_entity()) still checks the error condition, which can
+never happen, since list_entry() never returns NULL.
+Remove the BUG_ON check, and instead emit a warning in the only
+possible error condition here: the queue being empty which should
+never happen.
+
+Fixes: 326587b84078 ("sched: fix goto retry in pick_next_task_rt()")
+Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Reviewed-by: Phil Auld <pauld@redhat.com>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Link: https://lore.kernel.org/r/20230128-list-entry-null-check-sched-v3-1-b1a71bd1ac6b@diag.uniroma1.it
+---
+ kernel/sched/rt.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
+index 3daf42a0f462..c70c328bd89a 100644
+--- a/kernel/sched/rt.c
++++ b/kernel/sched/rt.c
+@@ -1607,6 +1607,8 @@ static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq,
+ BUG_ON(idx >= MAX_RT_PRIO);
+
+ queue = array->queue + idx;
++ if (SCHED_WARN_ON(list_empty(queue)))
++ return NULL;
+ next = list_entry(queue->next, struct sched_rt_entity, run_list);
+
+ return next;
+@@ -1619,7 +1621,8 @@ static struct task_struct *_pick_next_task_rt(struct rq *rq)
+
+ do {
+ rt_se = pick_next_rt_entity(rq, rt_rq);
+- BUG_ON(!rt_se);
++ if (unlikely(!rt_se))
++ return NULL;
+ rt_rq = group_rt_rq(rt_se);
+ } while (rt_rq);
+
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1252.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1252.patch
new file mode 100644
index 000000000..89a7f7949
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1252.patch
@@ -0,0 +1,89 @@
+From 9a254403760041528bc8f69fe2f5e1ef86950991 Mon Sep 17 00:00:00 2001
+From: yangerkun <yangerkun@huawei.com>
+Date: Thu, 30 Sep 2021 11:22:28 +0800
+Subject: [PATCH] ovl: fix use after free in struct ovl_aio_req
+
+Example for triggering use after free in a overlay on ext4 setup:
+
+aio_read
+ ovl_read_iter
+ vfs_iter_read
+ ext4_file_read_iter
+ ext4_dio_read_iter
+ iomap_dio_rw -> -EIOCBQUEUED
+ /*
+ * Here IO is completed in a separate thread,
+ * ovl_aio_cleanup_handler() frees aio_req which has iocb embedded
+ */
+ file_accessed(iocb->ki_filp); /**BOOM**/
+
+Fix by introducing a refcount in ovl_aio_req similarly to aio_kiocb. This
+guarantees that iocb is only freed after vfs_read/write_iter() returns on
+underlying fs.
+
+Fixes: 2406a307ac7d ("ovl: implement async IO routines")
+Signed-off-by: yangerkun <yangerkun@huawei.com>
+Link: https://lore.kernel.org/r/20210930032228.3199690-3-yangerkun@huawei.com/
+Cc: <stable@vger.kernel.org> # v5.6
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+---
+ fs/overlayfs/file.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
+index c88ac571593dc1..44fea16751f1db 100644
+--- a/fs/overlayfs/file.c
++++ b/fs/overlayfs/file.c
+@@ -17,6 +17,7 @@
+
+ struct ovl_aio_req {
+ struct kiocb iocb;
++ refcount_t ref;
+ struct kiocb *orig_iocb;
+ struct fd fd;
+ };
+@@ -252,6 +253,14 @@ static rwf_t ovl_iocb_to_rwf(int ifl)
+ return flags;
+ }
+
++static inline void ovl_aio_put(struct ovl_aio_req *aio_req)
++{
++ if (refcount_dec_and_test(&aio_req->ref)) {
++ fdput(aio_req->fd);
++ kmem_cache_free(ovl_aio_request_cachep, aio_req);
++ }
++}
++
+ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)
+ {
+ struct kiocb *iocb = &aio_req->iocb;
+@@ -268,8 +277,7 @@ static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)
+ }
+
+ orig_iocb->ki_pos = iocb->ki_pos;
+- fdput(aio_req->fd);
+- kmem_cache_free(ovl_aio_request_cachep, aio_req);
++ ovl_aio_put(aio_req);
+ }
+
+ static void ovl_aio_rw_complete(struct kiocb *iocb, long res, long res2)
+@@ -319,7 +327,9 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+ aio_req->orig_iocb = iocb;
+ kiocb_clone(&aio_req->iocb, iocb, real.file);
+ aio_req->iocb.ki_complete = ovl_aio_rw_complete;
++ refcount_set(&aio_req->ref, 2);
+ ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter);
++ ovl_aio_put(aio_req);
+ if (ret != -EIOCBQUEUED)
+ ovl_aio_cleanup_handler(aio_req);
+ }
+@@ -390,7 +400,9 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
+ kiocb_clone(&aio_req->iocb, iocb, real.file);
+ aio_req->iocb.ki_flags = ifl;
+ aio_req->iocb.ki_complete = ovl_aio_rw_complete;
++ refcount_set(&aio_req->ref, 2);
+ ret = vfs_iocb_iter_write(real.file, &aio_req->iocb, iter);
++ ovl_aio_put(aio_req);
+ if (ret != -EIOCBQUEUED)
+ ovl_aio_cleanup_handler(aio_req);
+ }
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1582.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1582.patch
new file mode 100644
index 000000000..c38b93c78
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-1582.patch
@@ -0,0 +1,228 @@
+From 24d7275ce2791829953ed4e72f68277ceb2571c6 Mon Sep 17 00:00:00 2001
+From: Yang Shi <shy828301@gmail.com>
+Date: Fri, 11 Feb 2022 16:32:26 -0800
+Subject: [PATCH] fs/proc: task_mmu.c: don't read mapcount for migration entry
+
+The syzbot reported the below BUG:
+
+ kernel BUG at include/linux/page-flags.h:785!
+ invalid opcode: 0000 [#1] PREEMPT SMP KASAN
+ CPU: 1 PID: 4392 Comm: syz-executor560 Not tainted 5.16.0-rc6-syzkaller #0
+ Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+ RIP: 0010:PageDoubleMap include/linux/page-flags.h:785 [inline]
+ RIP: 0010:__page_mapcount+0x2d2/0x350 mm/util.c:744
+ Call Trace:
+ page_mapcount include/linux/mm.h:837 [inline]
+ smaps_account+0x470/0xb10 fs/proc/task_mmu.c:466
+ smaps_pte_entry fs/proc/task_mmu.c:538 [inline]
+ smaps_pte_range+0x611/0x1250 fs/proc/task_mmu.c:601
+ walk_pmd_range mm/pagewalk.c:128 [inline]
+ walk_pud_range mm/pagewalk.c:205 [inline]
+ walk_p4d_range mm/pagewalk.c:240 [inline]
+ walk_pgd_range mm/pagewalk.c:277 [inline]
+ __walk_page_range+0xe23/0x1ea0 mm/pagewalk.c:379
+ walk_page_vma+0x277/0x350 mm/pagewalk.c:530
+ smap_gather_stats.part.0+0x148/0x260 fs/proc/task_mmu.c:768
+ smap_gather_stats fs/proc/task_mmu.c:741 [inline]
+ show_smap+0xc6/0x440 fs/proc/task_mmu.c:822
+ seq_read_iter+0xbb0/0x1240 fs/seq_file.c:272
+ seq_read+0x3e0/0x5b0 fs/seq_file.c:162
+ vfs_read+0x1b5/0x600 fs/read_write.c:479
+ ksys_read+0x12d/0x250 fs/read_write.c:619
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+The reproducer was trying to read /proc/$PID/smaps when calling
+MADV_FREE at the mean time. MADV_FREE may split THPs if it is called
+for partial THP. It may trigger the below race:
+
+ CPU A CPU B
+ ----- -----
+ smaps walk: MADV_FREE:
+ page_mapcount()
+ PageCompound()
+ split_huge_page()
+ page = compound_head(page)
+ PageDoubleMap(page)
+
+When calling PageDoubleMap() this page is not a tail page of THP anymore
+so the BUG is triggered.
+
+This could be fixed by elevated refcount of the page before calling
+mapcount, but that would prevent it from counting migration entries, and
+it seems overkilling because the race just could happen when PMD is
+split so all PTE entries of tail pages are actually migration entries,
+and smaps_account() does treat migration entries as mapcount == 1 as
+Kirill pointed out.
+
+Add a new parameter for smaps_account() to tell this entry is migration
+entry then skip calling page_mapcount(). Don't skip getting mapcount
+for device private entries since they do track references with mapcount.
+
+Pagemap also has the similar issue although it was not reported. Fixed
+it as well.
+
+[shy828301@gmail.com: v4]
+ Link: https://lkml.kernel.org/r/20220203182641.824731-1-shy828301@gmail.com
+[nathan@kernel.org: avoid unused variable warning in pagemap_pmd_range()]
+ Link: https://lkml.kernel.org/r/20220207171049.1102239-1-nathan@kernel.org
+Link: https://lkml.kernel.org/r/20220120202805.3369-1-shy828301@gmail.com
+Fixes: e9b61f19858a ("thp: reintroduce split_huge_page()")
+Signed-off-by: Yang Shi <shy828301@gmail.com>
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reported-by: syzbot+1f52b3a18d5633fa7f82@syzkaller.appspotmail.com
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Cc: Jann Horn <jannh@google.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: Alexey Dobriyan <adobriyan@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+ fs/proc/task_mmu.c | 40 +++++++++++++++++++++++++++++++---------
+ 1 file changed, 31 insertions(+), 9 deletions(-)
+
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index cf25be3e0321..3e68cc9e816c 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -430,7 +430,8 @@ static void smaps_page_accumulate(struct mem_size_stats *mss,
+ }
+
+ static void smaps_account(struct mem_size_stats *mss, struct page *page,
+- bool compound, bool young, bool dirty, bool locked)
++ bool compound, bool young, bool dirty, bool locked,
++ bool migration)
+ {
+ int i, nr = compound ? compound_nr(page) : 1;
+ unsigned long size = nr * PAGE_SIZE;
+@@ -457,8 +458,15 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,
+ * page_count(page) == 1 guarantees the page is mapped exactly once.
+ * If any subpage of the compound page mapped with PTE it would elevate
+ * page_count().
++ *
++ * The page_mapcount() is called to get a snapshot of the mapcount.
++ * Without holding the page lock this snapshot can be slightly wrong as
++ * we cannot always read the mapcount atomically. It is not safe to
++ * call page_mapcount() even with PTL held if the page is not mapped,
++ * especially for migration entries. Treat regular migration entries
++ * as mapcount == 1.
+ */
+- if (page_count(page) == 1) {
++ if ((page_count(page) == 1) || migration) {
+ smaps_page_accumulate(mss, page, size, size << PSS_SHIFT, dirty,
+ locked, true);
+ return;
+@@ -495,6 +503,7 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
+ struct vm_area_struct *vma = walk->vma;
+ bool locked = !!(vma->vm_flags & VM_LOCKED);
+ struct page *page = NULL;
++ bool migration = false;
+
+ if (pte_present(*pte)) {
+ page = vm_normal_page(vma, addr, *pte);
+@@ -514,8 +523,11 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
+ } else {
+ mss->swap_pss += (u64)PAGE_SIZE << PSS_SHIFT;
+ }
+- } else if (is_pfn_swap_entry(swpent))
++ } else if (is_pfn_swap_entry(swpent)){
++ if (is_migration_entry(swpent))
++ migration = true;
+ page = pfn_swap_entry_to_page(swpent);
++ }
+ } else if (unlikely(IS_ENABLED(CONFIG_SHMEM) && mss->check_shmem_swap
+ && pte_none(*pte))) {
+ page = xa_load(&vma->vm_file->f_mapping->i_pages,
+@@ -528,7 +540,8 @@ static void smaps_pte_entry(pte_t *pte, unsigned long addr,
+ if (!page)
+ return;
+
+- smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte), locked);
++ smaps_account(mss, page, false, pte_young(*pte), pte_dirty(*pte),
++ locked, migration);
+ }
+
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+@@ -539,6 +552,7 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
+ struct vm_area_struct *vma = walk->vma;
+ bool locked = !!(vma->vm_flags & VM_LOCKED);
+ struct page *page = NULL;
++ bool migration = false;
+
+ if (pmd_present(*pmd)) {
+ /* FOLL_DUMP will return -EFAULT on huge zero page */
+@@ -546,8 +560,10 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
+ } else if (unlikely(thp_migration_supported() && is_swap_pmd(*pmd))) {
+ swp_entry_t entry = pmd_to_swp_entry(*pmd);
+
+- if (is_migration_entry(entry))
++ if (is_migration_entry(entry)) {
++ migration = true;
+ page = pfn_swap_entry_to_page(entry);
++ }
+ }
+ if (IS_ERR_OR_NULL(page))
+ return;
+@@ -559,7 +575,9 @@ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
+ /* pass */;
+ else
+ mss->file_thp += HPAGE_PMD_SIZE;
+- smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd), locked);
++
++ smaps_account(mss, page, true, pmd_young(*pmd), pmd_dirty(*pmd),
++ locked, migration);
+ }
+ #else
+ static void smaps_pmd_entry(pmd_t *pmd, unsigned long addr,
+@@ -1363,6 +1381,7 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
+ {
+ u64 frame = 0, flags = 0;
+ struct page *page = NULL;
++ bool migration = false;
+
+ if (pte_present(pte)) {
+ if (pm->show_pfn)
+@@ -1384,13 +1403,14 @@ static pagemap_entry_t pte_to_pagemap_entry(struct pagemapread *pm,
+ frame = swp_type(entry) |
+ (swp_offset(entry) << MAX_SWAPFILES_SHIFT);
+ flags |= PM_SWAP;
++ migration = is_migration_entry(entry);
+ if (is_pfn_swap_entry(entry))
+ page = pfn_swap_entry_to_page(entry);
+ }
+
+ if (page && !PageAnon(page))
+ flags |= PM_FILE;
+- if (page && page_mapcount(page) == 1)
++ if (page && !migration && page_mapcount(page) == 1)
+ flags |= PM_MMAP_EXCLUSIVE;
+ if (vma->vm_flags & VM_SOFTDIRTY)
+ flags |= PM_SOFT_DIRTY;
+@@ -1406,8 +1426,9 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
+ spinlock_t *ptl;
+ pte_t *pte, *orig_pte;
+ int err = 0;
+-
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
++ bool migration = false;
++
+ ptl = pmd_trans_huge_lock(pmdp, vma);
+ if (ptl) {
+ u64 flags = 0, frame = 0;
+@@ -1446,11 +1467,12 @@ static int pagemap_pmd_range(pmd_t *pmdp, unsigned long addr, unsigned long end,
+ if (pmd_swp_uffd_wp(pmd))
+ flags |= PM_UFFD_WP;
+ VM_BUG_ON(!is_pmd_migration_entry(pmd));
++ migration = is_migration_entry(entry);
+ page = pfn_swap_entry_to_page(entry);
+ }
+ #endif
+
+- if (page && page_mapcount(page) == 1)
++ if (page && !migration && page_mapcount(page) == 1)
+ flags |= PM_MMAP_EXCLUSIVE;
+
+ for (; addr != end; addr += PAGE_SIZE) {
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2269.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2269.patch
new file mode 100644
index 000000000..538318fe0
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2269.patch
@@ -0,0 +1,56 @@
+From 3d32aaa7e66d5c1479a3c31d6c2c5d45dd0d3b89 Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@kernel.org>
+Date: Mon, 17 Apr 2023 11:59:56 -0400
+Subject: [PATCH] dm ioctl: fix nested locking in table_clear() to remove
+ deadlock concern
+
+syzkaller found the following problematic rwsem locking (with write
+lock already held):
+
+ down_read+0x9d/0x450 kernel/locking/rwsem.c:1509
+ dm_get_inactive_table+0x2b/0xc0 drivers/md/dm-ioctl.c:773
+ __dev_status+0x4fd/0x7c0 drivers/md/dm-ioctl.c:844
+ table_clear+0x197/0x280 drivers/md/dm-ioctl.c:1537
+
+In table_clear, it first acquires a write lock
+https://elixir.bootlin.com/linux/v6.2/source/drivers/md/dm-ioctl.c#L1520
+down_write(&_hash_lock);
+
+Then before the lock is released at L1539, there is a path shown above:
+table_clear -> __dev_status -> dm_get_inactive_table -> down_read
+https://elixir.bootlin.com/linux/v6.2/source/drivers/md/dm-ioctl.c#L773
+down_read(&_hash_lock);
+
+It tries to acquire the same read lock again, resulting in the deadlock
+problem.
+
+Fix this by moving table_clear()'s __dev_status() call to after its
+up_write(&_hash_lock);
+
+Cc: stable@vger.kernel.org
+Reported-by: Zheng Zhang <zheng.zhang@email.ucr.edu>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+---
+ drivers/md/dm-ioctl.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
+index 50a1259294d141..7d5c9c582ed2d6 100644
+--- a/drivers/md/dm-ioctl.c
++++ b/drivers/md/dm-ioctl.c
+@@ -1556,11 +1556,12 @@ static int table_clear(struct file *filp, struct dm_ioctl *param, size_t param_s
+ has_new_map = true;
+ }
+
+- param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
+-
+- __dev_status(hc->md, param);
+ md = hc->md;
+ up_write(&_hash_lock);
++
++ param->flags &= ~DM_INACTIVE_PRESENT_FLAG;
++ __dev_status(md, param);
++
+ if (old_map) {
+ dm_sync_table(md);
+ dm_table_destroy(old_map);
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2513.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2513.patch
new file mode 100644
index 000000000..266fedb1f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-2513.patch
@@ -0,0 +1,120 @@
+From 67d7d8ad99beccd9fe92d585b87f1760dc9018e3 Mon Sep 17 00:00:00 2001
+From: Baokun Li <libaokun1@huawei.com>
+Date: Thu, 16 Jun 2022 10:13:56 +0800
+Subject: [PATCH] ext4: fix use-after-free in ext4_xattr_set_entry
+
+Hulk Robot reported a issue:
+==================================================================
+BUG: KASAN: use-after-free in ext4_xattr_set_entry+0x18ab/0x3500
+Write of size 4105 at addr ffff8881675ef5f4 by task syz-executor.0/7092
+
+CPU: 1 PID: 7092 Comm: syz-executor.0 Not tainted 4.19.90-dirty #17
+Call Trace:
+[...]
+ memcpy+0x34/0x50 mm/kasan/kasan.c:303
+ ext4_xattr_set_entry+0x18ab/0x3500 fs/ext4/xattr.c:1747
+ ext4_xattr_ibody_inline_set+0x86/0x2a0 fs/ext4/xattr.c:2205
+ ext4_xattr_set_handle+0x940/0x1300 fs/ext4/xattr.c:2386
+ ext4_xattr_set+0x1da/0x300 fs/ext4/xattr.c:2498
+ __vfs_setxattr+0x112/0x170 fs/xattr.c:149
+ __vfs_setxattr_noperm+0x11b/0x2a0 fs/xattr.c:180
+ __vfs_setxattr_locked+0x17b/0x250 fs/xattr.c:238
+ vfs_setxattr+0xed/0x270 fs/xattr.c:255
+ setxattr+0x235/0x330 fs/xattr.c:520
+ path_setxattr+0x176/0x190 fs/xattr.c:539
+ __do_sys_lsetxattr fs/xattr.c:561 [inline]
+ __se_sys_lsetxattr fs/xattr.c:557 [inline]
+ __x64_sys_lsetxattr+0xc2/0x160 fs/xattr.c:557
+ do_syscall_64+0xdf/0x530 arch/x86/entry/common.c:298
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+RIP: 0033:0x459fe9
+RSP: 002b:00007fa5e54b4c08 EFLAGS: 00000246 ORIG_RAX: 00000000000000bd
+RAX: ffffffffffffffda RBX: 000000000051bf60 RCX: 0000000000459fe9
+RDX: 00000000200003c0 RSI: 0000000020000180 RDI: 0000000020000140
+RBP: 000000000051bf60 R08: 0000000000000001 R09: 0000000000000000
+R10: 0000000000001009 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007ffc73c93fc0 R14: 000000000051bf60 R15: 00007fa5e54b4d80
+[...]
+==================================================================
+
+Above issue may happen as follows:
+-------------------------------------
+ext4_xattr_set
+ ext4_xattr_set_handle
+ ext4_xattr_ibody_find
+ >> s->end < s->base
+ >> no EXT4_STATE_XATTR
+ >> xattr_check_inode is not executed
+ ext4_xattr_ibody_set
+ ext4_xattr_set_entry
+ >> size_t min_offs = s->end - s->base
+ >> UAF in memcpy
+
+we can easily reproduce this problem with the following commands:
+ mkfs.ext4 -F /dev/sda
+ mount -o debug_want_extra_isize=128 /dev/sda /mnt
+ touch /mnt/file
+ setfattr -n user.cat -v `seq -s z 4096|tr -d '[:digit:]'` /mnt/file
+
+In ext4_xattr_ibody_find, we have the following assignment logic:
+ header = IHDR(inode, raw_inode)
+ = raw_inode + EXT4_GOOD_OLD_INODE_SIZE + i_extra_isize
+ is->s.base = IFIRST(header)
+ = header + sizeof(struct ext4_xattr_ibody_header)
+ is->s.end = raw_inode + s_inode_size
+
+In ext4_xattr_set_entry
+ min_offs = s->end - s->base
+ = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
+ sizeof(struct ext4_xattr_ibody_header)
+ last = s->first
+ free = min_offs - ((void *)last - s->base) - sizeof(__u32)
+ = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize -
+ sizeof(struct ext4_xattr_ibody_header) - sizeof(__u32)
+
+In the calculation formula, all values except s_inode_size and
+i_extra_size are fixed values. When i_extra_size is the maximum value
+s_inode_size - EXT4_GOOD_OLD_INODE_SIZE, min_offs is -4 and free is -8.
+The value overflows. As a result, the preceding issue is triggered when
+memcpy is executed.
+
+Therefore, when finding xattr or setting xattr, check whether
+there is space for storing xattr in the inode to resolve this issue.
+
+Cc: stable@kernel.org
+Reported-by: Hulk Robot <hulkci@huawei.com>
+Signed-off-by: Baokun Li <libaokun1@huawei.com>
+Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20220616021358.2504451-3-libaokun1@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+---
+ fs/ext4/xattr.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+index 564e28a1aa9428..c42b3e0d2d94b4 100644
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -2175,8 +2175,9 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i,
+ struct ext4_inode *raw_inode;
+ int error;
+
+- if (EXT4_I(inode)->i_extra_isize == 0)
++ if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
+ return 0;
++
+ raw_inode = ext4_raw_inode(&is->iloc);
+ header = IHDR(inode, raw_inode);
+ is->s.base = is->s.first = IFIRST(header);
+@@ -2204,8 +2205,9 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode,
+ struct ext4_xattr_search *s = &is->s;
+ int error;
+
+- if (EXT4_I(inode)->i_extra_isize == 0)
++ if (!EXT4_INODE_HAS_XATTR_SPACE(inode))
+ return -ENOSPC;
++
+ error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */);
+ if (error)
+ return error;
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
index 92620086d..b3b22b408 100644
--- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend
@@ -52,7 +52,22 @@ SRC_URI += " \
file://CVE-2022-2663-1.patch\
file://CVE-2022-2663-2.patch\
file://CVE-2022-20158-1.patch\
+ file://0004-soc-aspeed-lpc-mbox-Don-t-allow-partial-reads.patch \
+ file://CVE-2022-3543.patch \
+ file://CVE-2022-42703.patch \
+ file://CVE-2022-4378-1.patch \
+ file://CVE-2022-4378-2.patch \
+ file://CVE-2022-2978.patch \
+ file://CVE-2022-3623.patch \
+ file://CVE-2023-0394.patch \
+ file://CVE-2023-1252.patch\
+ file://CVE-2023-1073.patch\
+ file://CVE-2023-1077.patch\
+ file://CVE-2023-1582.patch \
+ file://CVE-2020-36516.patch \
+ file://0005-ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr-h.patch \
+ file://CVE-2023-2513.patch \
+ file://CVE-2023-2269.patch \
"
-
SRC_URI += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', 'file://1000-128MB-flashmap-for-PFR.patch', '', d)}"
SRC_URI += "${@bb.utils.contains('EXTRA_IMAGE_FEATURES', 'debug-tweaks', 'file://debug.cfg', '', d)}"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/0008-dynamic-threshold-configuration-for-SOLUM-PSU.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/0008-dynamic-threshold-configuration-for-SOLUM-PSU.patch
new file mode 100644
index 000000000..16df1b436
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager/0008-dynamic-threshold-configuration-for-SOLUM-PSU.patch
@@ -0,0 +1,90 @@
+From d7425aa548716339e9c00a45695f93c294613cd4 Mon Sep 17 00:00:00 2001
+From: Vikash Chandola <vikash.chandola@intel.com>
+Date: Fri, 5 Aug 2022 12:57:51 +0000
+Subject: [PATCH] dynamic threshold configuration for SOLUM PSU
+
+PSU output current threshold is different for high line and low line
+input. Using static threshold value doesn't allow thresholds
+to be set based on input voltage. Update SOLUM configurtion file
+to provide sensor label and scale factor to calculate threshold.
+This allows thresholds to get updated on input voltage change.
+
+Tested:
+Successfully able to build and pass through validate-configs.py.
+
+Signed-off-by: Vikash Chandola <vikash.chandola@intel.com>
+Change-Id: I84e425f1e75ce04be96b70b8a91e90f7c796c9e8
+---
+ configurations/PSSF162205A.json | 4 ++++
+ configurations/SOLUM_PSSF162202_PSU.json | 4 ++++
+ schemas/legacy.json | 8 ++++++++
+ 3 files changed, 16 insertions(+)
+
+diff --git a/configurations/PSSF162205A.json b/configurations/PSSF162205A.json
+index d272ef1..7402947 100644
+--- a/configurations/PSSF162205A.json
++++ b/configurations/PSSF162205A.json
+@@ -86,14 +86,18 @@
+ "Direction": "greater than",
+ "Label": "iout1",
+ "Name": "upper critical",
++ "ScaleFactor": 0.001,
+ "Severity": 1,
++ "ThresholdLabel": "iout_oc_warn_limit",
+ "Value": 122
+ },
+ {
+ "Direction": "greater than",
+ "Label": "iout1",
+ "Name": "upper non critical",
++ "ScaleFactor": 0.00091,
+ "Severity": 0,
++ "ThresholdLabel": "iout_oc_warn_limit",
+ "Value": 100
+ },
+ {
+diff --git a/configurations/SOLUM_PSSF162202_PSU.json b/configurations/SOLUM_PSSF162202_PSU.json
+index c3ca25c..176a3d6 100644
+--- a/configurations/SOLUM_PSSF162202_PSU.json
++++ b/configurations/SOLUM_PSSF162202_PSU.json
+@@ -145,14 +145,18 @@
+ "Direction": "greater than",
+ "Label": "iout1",
+ "Name": "upper critical",
++ "ScaleFactor": 0.001,
+ "Severity": 1,
++ "ThresholdLabel": "iout_oc_warn_limit",
+ "Value": 122
+ },
+ {
+ "Direction": "greater than",
+ "Label": "iout1",
+ "Name": "upper non critical",
++ "ScaleFactor": 0.00091,
+ "Severity": 0,
++ "ThresholdLabel": "iout_oc_warn_limit",
+ "Value": 100
+ },
+ {
+diff --git a/schemas/legacy.json b/schemas/legacy.json
+index 47a6c7b..c3339ef 100644
+--- a/schemas/legacy.json
++++ b/schemas/legacy.json
+@@ -698,6 +698,14 @@
+ },
+ "Value": {
+ "type": "number"
++ },
++ "ThresholdLabel": {
++ "enum": [
++ "iout_oc_warn_limit"
++ ]
++ },
++ "ScaleFactor": {
++ "type": "number"
+ }
+ },
+ "required": [
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend
index a8a9f17c5..181497547 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend
@@ -11,5 +11,6 @@ SRC_URI += " file://0001-fru-device-Add-MUX-channel-name-to-FRU-objects.patch \
file://0005-Allow-MUX-idle-state-to-be-configured-as-DISCONNECT.patch \
file://0006-Change-HSBP-FRU-address-and-add-MUX-mode-configurati.patch \
file://0007-Add-HSBP-FRU-details-in-json-configuration.patch \
+ file://0008-dynamic-threshold-configuration-for-SOLUM-PSU.patch \
"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/0001-add-Associations-endpoints-change-delay-timer.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/0001-add-Associations-endpoints-change-delay-timer.patch
new file mode 100644
index 000000000..51afef80f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper/0001-add-Associations-endpoints-change-delay-timer.patch
@@ -0,0 +1,978 @@
+From 48c39d798ce9683c186395272452893e2227d984 Mon Sep 17 00:00:00 2001
+From: "Kallas, Pawel" <pawel.kallas@intel.com>
+Date: Mon, 9 Jan 2023 13:27:45 +0100
+Subject: [PATCH] add Associations endpoints change delay timer
+
+When multiple associations that point to the same interface are
+created, each change (adding or removing one) leads to updating
+"endpoints" property on dbus. This property update is time consuming
+with many endpoints already present, because each update needs to send
+the whole list of current elements plus/minus one. With a lot of
+changes in short time it can cause the service to be unresponsive.
+This change adds timer to delay updating dbus property. This way many
+associations updates can be aggregated into single dbus property
+update.
+
+Tested: Ran on hardware with dbus sensor tester. 4000 created sensors
+with interfaces are processed within 10 seconds. Time before the change
+was above 2 minutes.
+
+Signed-off-by: Kallas, Pawel <pawel.kallas@intel.com>
+Change-Id: I1083c027ab12238249cffc67fb29a8ffef6baf83
+---
+ src/associations.cpp | 156 ++++++++++++++++++++++------------
+ src/associations.hpp | 32 +++++--
+ src/main.cpp | 48 ++++++-----
+ src/processing.cpp | 13 +--
+ src/processing.hpp | 6 +-
+ src/test/associations.cpp | 43 ++++++----
+ src/test/interfaces_added.cpp | 6 +-
+ src/test/name_change.cpp | 10 ++-
+ 8 files changed, 202 insertions(+), 112 deletions(-)
+
+diff --git a/src/associations.cpp b/src/associations.cpp
+index 9fd72ab..7730bbd 100644
+--- a/src/associations.cpp
++++ b/src/associations.cpp
+@@ -1,10 +1,81 @@
+ #include "associations.hpp"
+
+ #include <boost/algorithm/string/predicate.hpp>
++#include <boost/asio/steady_timer.hpp>
+ #include <iostream>
+ #include <sdbusplus/exception.hpp>
+
+-void removeAssociation(const std::string& sourcePath, const std::string& owner,
++void updateEndpointsOnDbus(sdbusplus::asio::object_server& objectServer,
++ const std::string& assocPath,
++ AssociationMaps& assocMaps)
++{
++ auto& iface = assocMaps.ifaces[assocPath];
++ auto& i = std::get<ifacePos>(iface);
++ auto& endpoints = std::get<endpointsPos>(iface);
++
++ // If the interface already exists, only need to update
++ // the property value, otherwise create it
++ if (i)
++ {
++ if (endpoints.empty())
++ {
++ objectServer.remove_interface(i);
++ i = nullptr;
++ }
++ else
++ {
++ i->set_property("endpoints", endpoints);
++ }
++ }
++ else
++ {
++ if (!endpoints.empty())
++ {
++ i = objectServer.add_interface(assocPath,
++ XYZ_ASSOCIATION_INTERFACE);
++ i->register_property("endpoints", endpoints);
++ i->initialize();
++ }
++ }
++}
++
++void scheduleUpdateEndpointsOnDbus(boost::asio::io_context& io,
++ sdbusplus::asio::object_server& objectServer,
++ const std::string& assocPath,
++ AssociationMaps& assocMaps)
++{
++ static std::set<std::string> delayedUpdatePaths;
++
++ if (delayedUpdatePaths.contains(assocPath))
++ {
++ return;
++ }
++
++ auto& iface = assocMaps.ifaces[assocPath];
++ auto& endpoints = std::get<endpointsPos>(iface);
++
++ if (endpoints.size() > endpointsCountTimerThreshold)
++ {
++ delayedUpdatePaths.emplace(assocPath);
++ auto timer = std::make_shared<boost::asio::steady_timer>(
++ io, std::chrono::seconds(endpointUpdateDelaySeconds));
++ timer->async_wait([&objectServer, &assocMaps, timer,
++ assocPath](const boost::system::error_code& ec) {
++ if (!ec)
++ {
++ updateEndpointsOnDbus(objectServer, assocPath, assocMaps);
++ }
++ delayedUpdatePaths.erase(assocPath);
++ });
++ }
++ else
++ {
++ updateEndpointsOnDbus(objectServer, assocPath, assocMaps);
++ }
++}
++
++void removeAssociation(boost::asio::io_context& io,
++ const std::string& sourcePath, const std::string& owner,
+ sdbusplus::asio::object_server& server,
+ AssociationMaps& assocMaps)
+ {
+@@ -34,7 +105,7 @@ void removeAssociation(const std::string& sourcePath, const std::string& owner,
+
+ for (const auto& [assocPath, endpointsToRemove] : assocs->second)
+ {
+- removeAssociationEndpoints(server, assocPath, endpointsToRemove,
++ removeAssociationEndpoints(io, server, assocPath, endpointsToRemove,
+ assocMaps);
+ }
+
+@@ -51,7 +122,8 @@ void removeAssociation(const std::string& sourcePath, const std::string& owner,
+ }
+
+ void removeAssociationEndpoints(
+- sdbusplus::asio::object_server& objectServer, const std::string& assocPath,
++ boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
++ const std::string& assocPath,
+ const boost::container::flat_set<std::string>& endpointsToRemove,
+ AssociationMaps& assocMaps)
+ {
+@@ -74,22 +146,12 @@ void removeAssociationEndpoints(
+ }
+ }
+
+- if (endpointsInDBus.empty())
+- {
+- objectServer.remove_interface(std::get<ifacePos>(assoc->second));
+- std::get<ifacePos>(assoc->second) = nullptr;
+- std::get<endpointsPos>(assoc->second).clear();
+- }
+- else
+- {
+- std::get<ifacePos>(assoc->second)
+- ->set_property("endpoints", endpointsInDBus);
+- }
++ scheduleUpdateEndpointsOnDbus(io, objectServer, assocPath, assocMaps);
+ }
+
+ void checkAssociationEndpointRemoves(
+- const std::string& sourcePath, const std::string& owner,
+- const AssociationPaths& newAssociations,
++ boost::asio::io_context& io, const std::string& sourcePath,
++ const std::string& owner, const AssociationPaths& newAssociations,
+ sdbusplus::asio::object_server& objectServer, AssociationMaps& assocMaps)
+ {
+ // Find the services that have associations on this path.
+@@ -118,7 +180,7 @@ void checkAssociationEndpointRemoves(
+ auto newEndpoints = newAssociations.find(originalAssocPath);
+ if (newEndpoints == newAssociations.end())
+ {
+- removeAssociationEndpoints(objectServer, originalAssocPath,
++ removeAssociationEndpoints(io, objectServer, originalAssocPath,
+ originalEndpoints, assocMaps);
+ }
+ else
+@@ -138,7 +200,7 @@ void checkAssociationEndpointRemoves(
+ }
+ if (!toRemove.empty())
+ {
+- removeAssociationEndpoints(objectServer, originalAssocPath,
++ removeAssociationEndpoints(io, objectServer, originalAssocPath,
+ toRemove, assocMaps);
+ }
+ }
+@@ -146,12 +208,12 @@ void checkAssociationEndpointRemoves(
+ }
+
+ void addEndpointsToAssocIfaces(
+- sdbusplus::asio::object_server& objectServer, const std::string& assocPath,
++ boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
++ const std::string& assocPath,
+ const boost::container::flat_set<std::string>& endpointPaths,
+ AssociationMaps& assocMaps)
+ {
+ auto& iface = assocMaps.ifaces[assocPath];
+- auto& i = std::get<ifacePos>(iface);
+ auto& endpoints = std::get<endpointsPos>(iface);
+
+ // Only add new endpoints
+@@ -162,22 +224,11 @@ void addEndpointsToAssocIfaces(
+ endpoints.push_back(e);
+ }
+ }
+-
+- // If the interface already exists, only need to update
+- // the property value, otherwise create it
+- if (i)
+- {
+- i->set_property("endpoints", endpoints);
+- }
+- else
+- {
+- i = objectServer.add_interface(assocPath, XYZ_ASSOCIATION_INTERFACE);
+- i->register_property("endpoints", endpoints);
+- i->initialize();
+- }
++ scheduleUpdateEndpointsOnDbus(io, objectServer, assocPath, assocMaps);
+ }
+
+-void associationChanged(sdbusplus::asio::object_server& objectServer,
++void associationChanged(boost::asio::io_context& io,
++ sdbusplus::asio::object_server& objectServer,
+ const std::vector<Association>& associations,
+ const std::string& path, const std::string& owner,
+ const interface_map_type& interfaceMap,
+@@ -217,12 +268,12 @@ void associationChanged(sdbusplus::asio::object_server& objectServer,
+ }
+ for (const auto& object : objects)
+ {
+- addEndpointsToAssocIfaces(objectServer, object.first, object.second,
++ addEndpointsToAssocIfaces(io, objectServer, object.first, object.second,
+ assocMaps);
+ }
+
+ // Check for endpoints being removed instead of added
+- checkAssociationEndpointRemoves(path, owner, objects, objectServer,
++ checkAssociationEndpointRemoves(io, path, owner, objects, objectServer,
+ assocMaps);
+
+ if (!objects.empty())
+@@ -312,7 +363,8 @@ void removeFromPendingAssociations(const std::string& endpointPath,
+ }
+ }
+
+-void addSingleAssociation(sdbusplus::asio::object_server& server,
++void addSingleAssociation(boost::asio::io_context& io,
++ sdbusplus::asio::object_server& server,
+ const std::string& assocPath,
+ const std::string& endpoint, const std::string& owner,
+ const std::string& ownerPath,
+@@ -320,7 +372,7 @@ void addSingleAssociation(sdbusplus::asio::object_server& server,
+ {
+ boost::container::flat_set<std::string> endpoints{endpoint};
+
+- addEndpointsToAssocIfaces(server, assocPath, endpoints, assocMaps);
++ addEndpointsToAssocIfaces(io, server, assocPath, endpoints, assocMaps);
+
+ AssociationPaths objects;
+ boost::container::flat_set e{endpoint};
+@@ -355,7 +407,8 @@ void addSingleAssociation(sdbusplus::asio::object_server& server,
+ }
+ }
+
+-void checkIfPendingAssociation(const std::string& objectPath,
++void checkIfPendingAssociation(boost::asio::io_context& io,
++ const std::string& objectPath,
+ const interface_map_type& interfaceMap,
+ AssociationMaps& assocMaps,
+ sdbusplus::asio::object_server& server)
+@@ -399,13 +452,13 @@ void checkIfPendingAssociation(const std::string& objectPath,
+
+ try
+ {
+- addSingleAssociation(server, assocPath, endpointPath, owner,
++ addSingleAssociation(io, server, assocPath, endpointPath, owner,
+ ownerPath, assocMaps);
+
+ // Now the reverse direction (still the same owner and ownerPath)
+ assocPath = endpointPath + '/' + std::get<reverseTypePos>(e);
+ endpointPath = objectPath;
+- addSingleAssociation(server, assocPath, endpointPath, owner,
++ addSingleAssociation(io, server, assocPath, endpointPath, owner,
+ ownerPath, assocMaps);
+ }
+ catch (const sdbusplus::exception::exception& e)
+@@ -495,7 +548,8 @@ void findAssociations(const std::string& endpointPath,
+ * @param[in,out] assocMaps - the association maps
+ * @param[in,out] server - sdbus system object
+ */
+-void removeAssociationIfacesEntry(const std::string& assocPath,
++void removeAssociationIfacesEntry(boost::asio::io_context& io,
++ const std::string& assocPath,
+ const std::string& endpointPath,
+ AssociationMaps& assocMaps,
+ sdbusplus::asio::object_server& server)
+@@ -509,16 +563,7 @@ void removeAssociationIfacesEntry(const std::string& assocPath,
+ {
+ endpoints.erase(e);
+
+- if (endpoints.empty())
+- {
+- server.remove_interface(std::get<ifacePos>(assoc->second));
+- std::get<ifacePos>(assoc->second) = nullptr;
+- }
+- else
+- {
+- std::get<ifacePos>(assoc->second)
+- ->set_property("endpoints", endpoints);
+- }
++ scheduleUpdateEndpointsOnDbus(io, server, assocPath, assocMaps);
+ }
+ }
+ }
+@@ -577,7 +622,8 @@ void removeAssociationOwnersEntry(const std::string& assocPath,
+ }
+ }
+
+-void moveAssociationToPending(const std::string& endpointPath,
++void moveAssociationToPending(boost::asio::io_context& io,
++ const std::string& endpointPath,
+ AssociationMaps& assocMaps,
+ sdbusplus::asio::object_server& server)
+ {
+@@ -599,9 +645,9 @@ void moveAssociationToPending(const std::string& endpointPath,
+ reverseType, owner, assocMaps);
+
+ // Remove both sides of the association from assocMaps.ifaces
+- removeAssociationIfacesEntry(forwardPath + '/' + forwardType,
++ removeAssociationIfacesEntry(io, forwardPath + '/' + forwardType,
+ reversePath, assocMaps, server);
+- removeAssociationIfacesEntry(reversePath + '/' + reverseType,
++ removeAssociationIfacesEntry(io, reversePath + '/' + reverseType,
+ forwardPath, assocMaps, server);
+
+ // Remove both sides of the association from assocMaps.owners
+diff --git a/src/associations.hpp b/src/associations.hpp
+index dd6cbdb..b4ee91b 100644
+--- a/src/associations.hpp
++++ b/src/associations.hpp
+@@ -5,8 +5,12 @@
+ constexpr const char* XYZ_ASSOCIATION_INTERFACE =
+ "xyz.openbmc_project.Association";
+
++constexpr size_t endpointsCountTimerThreshold = 100;
++constexpr int endpointUpdateDelaySeconds = 1;
++
+ /** @brief Remove input association
+ *
++ * @param[in] io - io context
+ * @param[in] sourcePath - Path of the object that contains the
+ * org.openbmc.Associations
+ * @param[in] owner - The Dbus service having its associations
+@@ -16,7 +20,8 @@ constexpr const char* XYZ_ASSOCIATION_INTERFACE =
+ *
+ * @return Void, server, assocMaps updated if needed
+ */
+-void removeAssociation(const std::string& sourcePath, const std::string& owner,
++void removeAssociation(boost::asio::io_context& io,
++ const std::string& sourcePath, const std::string& owner,
+ sdbusplus::asio::object_server& server,
+ AssociationMaps& assocMaps);
+
+@@ -25,6 +30,7 @@ void removeAssociation(const std::string& sourcePath, const std::string& owner,
+ * If the last endpoint was removed, then remove the whole
+ * association object, otherwise just set the property
+ *
++ * @param[in] io - io context
+ * @param[in] objectServer - sdbus system object
+ * @param[in] assocPath - Path of the object that contains the
+ * org.openbmc.Associations
+@@ -34,7 +40,8 @@ void removeAssociation(const std::string& sourcePath, const std::string& owner,
+ * @return Void, objectServer and assocMaps updated if needed
+ */
+ void removeAssociationEndpoints(
+- sdbusplus::asio::object_server& objectServer, const std::string& assocPath,
++ boost::asio::io_context& io, sdbusplus::asio::object_server& objectServer,
++ const std::string& assocPath,
+ const boost::container::flat_set<std::string>& endpointsToRemove,
+ AssociationMaps& assocMaps);
+
+@@ -47,6 +54,7 @@ void removeAssociationEndpoints(
+ * from the endpoints property, remove that whole association object from
+ * D-Bus.
+ *
++ * @param[in] io - io context
+ * @param[in] sourcePath - Path of the object that contains the
+ * org.openbmc.Associations
+ * @param[in] owner - The Dbus service having it's associatons
+@@ -58,8 +66,8 @@ void removeAssociationEndpoints(
+ * @return Void, objectServer and assocMaps updated if needed
+ */
+ void checkAssociationEndpointRemoves(
+- const std::string& sourcePath, const std::string& owner,
+- const AssociationPaths& newAssociations,
++ boost::asio::io_context& io, const std::string& sourcePath,
++ const std::string& owner, const AssociationPaths& newAssociations,
+ sdbusplus::asio::object_server& objectServer, AssociationMaps& assocMaps);
+
+ /** @brief Handle new or changed association interfaces
+@@ -67,6 +75,7 @@ void checkAssociationEndpointRemoves(
+ * Called when either a new org.openbmc.Associations interface was
+ * created, or the associations property on that interface changed
+ *
++ * @param[in] io - io context
+ * @param[in,out] objectServer - sdbus system object
+ * @param[in] associations - New associations to look at for change
+ * @param[in] path - Path of the object that contains the
+@@ -78,7 +87,8 @@ void checkAssociationEndpointRemoves(
+ *
+ * @return Void, objectServer and assocMaps updated if needed
+ */
+-void associationChanged(sdbusplus::asio::object_server& objectServer,
++void associationChanged(boost::asio::io_context& io,
++ sdbusplus::asio::object_server& objectServer,
+ const std::vector<Association>& associations,
+ const std::string& path, const std::string& owner,
+ const interface_map_type& interfaceMap,
+@@ -123,6 +133,7 @@ void removeFromPendingAssociations(const std::string& endpointPath,
+
+ /** @brief Adds a single association D-Bus object (<path>/<type>)
+ *
++ * @param[in] io - io context
+ * @param[in,out] server - sdbus system object
+ * @param[in] assocPath - The association D-Bus path
+ * @param[in] endpoint - The association's D-Bus endpoint path
+@@ -130,7 +141,8 @@ void removeFromPendingAssociations(const std::string& endpointPath,
+ * @param[in] ownerPath - The D-Bus path hosting the Associations property
+ * @param[in,out] assocMaps - The association maps
+ */
+-void addSingleAssociation(sdbusplus::asio::object_server& server,
++void addSingleAssociation(boost::asio::io_context& io,
++ sdbusplus::asio::object_server& server,
+ const std::string& assocPath,
+ const std::string& endpoint, const std::string& owner,
+ const std::string& ownerPath,
+@@ -143,12 +155,14 @@ void addSingleAssociation(sdbusplus::asio::object_server& server,
+ * map, create the 2 real association objects and remove its pending
+ * associations entry. Used when a new path shows up in D-Bus.
+ *
++ * @param[in] io - io context
+ * @param[in] objectPath - the path to check
+ * @param[in] interfaceMap - The master interface map
+ * @param[in,out] assocMaps - The association maps
+ * @param[in,out] server - sdbus system object
+ */
+-void checkIfPendingAssociation(const std::string& objectPath,
++void checkIfPendingAssociation(boost::asio::io_context& io,
++ const std::string& objectPath,
+ const interface_map_type& interfaceMap,
+ AssociationMaps& assocMaps,
+ sdbusplus::asio::object_server& server);
+@@ -172,10 +186,12 @@ void findAssociations(const std::string& endpointPath,
+ * association endpoint (the path that owns the association is still
+ * on D-Bus), then move the association it's involved in to pending.
+ *
++ * @param[in] io - io context
+ * @param[in] endpointPath - the D-Bus endpoint path to check
+ * @param[in,out] assocMaps - The association maps
+ * @param[in,out] server - sdbus system object
+ */
+-void moveAssociationToPending(const std::string& endpointPath,
++void moveAssociationToPending(boost::asio::io_context& io,
++ const std::string& endpointPath,
+ AssociationMaps& assocMaps,
+ sdbusplus::asio::object_server& server);
+diff --git a/src/main.cpp b/src/main.cpp
+index 53b36d5..ee03be7 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -131,7 +131,8 @@ struct InProgressIntrospect
+ #endif
+ };
+
+-void do_associations(sdbusplus::asio::connection* system_bus,
++void do_associations(boost::asio::io_context& io,
++ sdbusplus::asio::connection* system_bus,
+ interface_map_type& interfaceMap,
+ sdbusplus::asio::object_server& objectServer,
+ const std::string& processName, const std::string& path,
+@@ -139,7 +140,7 @@ void do_associations(sdbusplus::asio::connection* system_bus,
+ {
+ constexpr int maxTimeoutRetries = 3;
+ system_bus->async_method_call(
+- [&objectServer, path, processName, &interfaceMap, system_bus,
++ [&io, &objectServer, path, processName, &interfaceMap, system_bus,
+ timeoutRetries](
+ const boost::system::error_code ec,
+ const std::variant<std::vector<Association>>& variantAssociations) {
+@@ -148,7 +149,7 @@ void do_associations(sdbusplus::asio::connection* system_bus,
+ if (ec.value() == boost::system::errc::timed_out &&
+ timeoutRetries < maxTimeoutRetries)
+ {
+- do_associations(system_bus, interfaceMap, objectServer,
++ do_associations(io, system_bus, interfaceMap, objectServer,
+ processName, path, timeoutRetries + 1);
+ return;
+ }
+@@ -156,14 +157,15 @@ void do_associations(sdbusplus::asio::connection* system_bus,
+ }
+ std::vector<Association> associations =
+ std::get<std::vector<Association>>(variantAssociations);
+- associationChanged(objectServer, associations, path, processName,
+- interfaceMap, associationMaps);
++ associationChanged(io, objectServer, associations, path,
++ processName, interfaceMap, associationMaps);
+ },
+ processName, path, "org.freedesktop.DBus.Properties", "Get",
+ assocDefsInterface, assocDefsProperty);
+ }
+
+-void do_introspect(sdbusplus::asio::connection* system_bus,
++void do_introspect(boost::asio::io_context& io,
++ sdbusplus::asio::connection* system_bus,
+ std::shared_ptr<InProgressIntrospect> transaction,
+ interface_map_type& interface_map,
+ sdbusplus::asio::object_server& objectServer,
+@@ -171,7 +173,7 @@ void do_introspect(sdbusplus::asio::connection* system_bus,
+ {
+ constexpr int maxTimeoutRetries = 3;
+ system_bus->async_method_call(
+- [&interface_map, &objectServer, transaction, path, system_bus,
++ [&io, &interface_map, &objectServer, transaction, path, system_bus,
+ timeoutRetries](const boost::system::error_code ec,
+ const std::string& introspect_xml) {
+ if (ec)
+@@ -179,7 +181,7 @@ void do_introspect(sdbusplus::asio::connection* system_bus,
+ if (ec.value() == boost::system::errc::timed_out &&
+ timeoutRetries < maxTimeoutRetries)
+ {
+- do_introspect(system_bus, transaction, interface_map,
++ do_introspect(io, system_bus, transaction, interface_map,
+ objectServer, path, timeoutRetries + 1);
+ return;
+ }
+@@ -220,7 +222,7 @@ void do_introspect(sdbusplus::asio::connection* system_bus,
+
+ if (std::strcmp(iface_name, assocDefsInterface) == 0)
+ {
+- do_associations(system_bus, interface_map, objectServer,
++ do_associations(io, system_bus, interface_map, objectServer,
+ transaction->process_name, path);
+ }
+
+@@ -229,7 +231,7 @@ void do_introspect(sdbusplus::asio::connection* system_bus,
+
+ // Check if this new path has a pending association that can
+ // now be completed.
+- checkIfPendingAssociation(path, interface_map,
++ checkIfPendingAssociation(io, path, interface_map,
+ transaction->assocMaps, objectServer);
+
+ pElement = pRoot->FirstChildElement("node");
+@@ -244,7 +246,7 @@ void do_introspect(sdbusplus::asio::connection* system_bus,
+ parent_path.clear();
+ }
+
+- do_introspect(system_bus, transaction, interface_map,
++ do_introspect(io, system_bus, transaction, interface_map,
+ objectServer, parent_path + "/" + child_path);
+ }
+ pElement = pElement->NextSiblingElement("node");
+@@ -275,7 +277,7 @@ void start_new_introspect(
+ #endif
+ );
+
+- do_introspect(system_bus, transaction, interface_map, objectServer,
++ do_introspect(io, system_bus, transaction, interface_map, objectServer,
+ "/");
+ }
+ }
+@@ -684,7 +686,7 @@ int main(int argc, char** argv)
+
+ if (!old_owner.empty())
+ {
+- processNameChangeDelete(name_owners, name, old_owner,
++ processNameChangeDelete(io, name_owners, name, old_owner,
+ interface_map, associationMaps, server);
+ }
+
+@@ -715,7 +717,7 @@ int main(int argc, char** argv)
+ sdbusplus::bus::match::rules::nameOwnerChanged(), nameChangeHandler);
+
+ std::function<void(sdbusplus::message::message & message)>
+- interfacesAddedHandler = [&interface_map, &name_owners, &server](
++ interfacesAddedHandler = [&io, &interface_map, &name_owners, &server](
+ sdbusplus::message::message& message) {
+ sdbusplus::message::object_path obj_path;
+ InterfacesAdded interfaces_added;
+@@ -728,8 +730,9 @@ int main(int argc, char** argv)
+ if (needToIntrospect(well_known, service_whitelist,
+ service_blacklist))
+ {
+- processInterfaceAdded(interface_map, obj_path, interfaces_added,
+- well_known, associationMaps, server);
++ processInterfaceAdded(io, interface_map, obj_path,
++ interfaces_added, well_known,
++ associationMaps, server);
+ }
+ };
+
+@@ -739,7 +742,7 @@ int main(int argc, char** argv)
+ interfacesAddedHandler);
+
+ std::function<void(sdbusplus::message::message & message)>
+- interfacesRemovedHandler = [&interface_map, &name_owners, &server](
++ interfacesRemovedHandler = [&io, &interface_map, &name_owners, &server](
+ sdbusplus::message::message& message) {
+ sdbusplus::message::object_path obj_path;
+ std::vector<std::string> interfaces_removed;
+@@ -765,7 +768,7 @@ int main(int argc, char** argv)
+
+ if (interface == assocDefsInterface)
+ {
+- removeAssociation(obj_path.str, sender, server,
++ removeAssociation(io, obj_path.str, sender, server,
+ associationMaps);
+ }
+
+@@ -788,8 +791,8 @@ int main(int argc, char** argv)
+ {
+ // Remove the 2 association D-Bus paths and move the
+ // association to pending.
+- moveAssociationToPending(obj_path.str, associationMaps,
+- server);
++ moveAssociationToPending(io, obj_path.str,
++ associationMaps, server);
+ }
+ }
+ }
+@@ -809,7 +812,8 @@ int main(int argc, char** argv)
+ interfacesRemovedHandler);
+
+ std::function<void(sdbusplus::message::message & message)>
+- associationChangedHandler = [&server, &name_owners, &interface_map](
++ associationChangedHandler = [&io, &server, &name_owners,
++ &interface_map](
+ sdbusplus::message::message& message) {
+ std::string objectName;
+ boost::container::flat_map<std::string,
+@@ -828,7 +832,7 @@ int main(int argc, char** argv)
+ {
+ return;
+ }
+- associationChanged(server, associations, message.get_path(),
++ associationChanged(io, server, associations, message.get_path(),
+ well_known, interface_map, associationMaps);
+ }
+ };
+diff --git a/src/processing.cpp b/src/processing.cpp
+index f144b77..5e61fbc 100644
+--- a/src/processing.cpp
++++ b/src/processing.cpp
+@@ -40,6 +40,7 @@ bool needToIntrospect(const std::string& processName,
+ }
+
+ void processNameChangeDelete(
++ boost::asio::io_context& io,
+ boost::container::flat_map<std::string, std::string>& nameOwners,
+ const std::string& wellKnown, const std::string& oldOwner,
+ interface_map_type& interfaceMap, AssociationMaps& assocMaps,
+@@ -67,7 +68,8 @@ void processNameChangeDelete(
+ assocDefsInterface);
+ if (assoc != ifaces->second.end())
+ {
+- removeAssociation(pathIt->first, wellKnown, server, assocMaps);
++ removeAssociation(io, pathIt->first, wellKnown, server,
++ assocMaps);
+ }
+
+ // Instead of checking if every single path is the endpoint of an
+@@ -80,7 +82,7 @@ void processNameChangeDelete(
+ {
+ // Remove the 2 association D-Bus paths and move the
+ // association to pending.
+- moveAssociationToPending(pathIt->first, assocMaps, server);
++ moveAssociationToPending(io, pathIt->first, assocMaps, server);
+ }
+ }
+ pathIt->second.erase(wellKnown);
+@@ -95,7 +97,8 @@ void processNameChangeDelete(
+ }
+ }
+
+-void processInterfaceAdded(interface_map_type& interfaceMap,
++void processInterfaceAdded(boost::asio::io_context& io,
++ interface_map_type& interfaceMap,
+ const sdbusplus::message::object_path& objPath,
+ const InterfacesAdded& intfAdded,
+ const std::string& wellKnown,
+@@ -127,7 +130,7 @@ void processInterfaceAdded(interface_map_type& interfaceMap,
+ }
+ std::vector<Association> associations =
+ std::get<std::vector<Association>>(*variantAssociations);
+- associationChanged(server, associations, objPath.str, wellKnown,
++ associationChanged(io, server, associations, objPath.str, wellKnown,
+ interfaceMap, assocMaps);
+ }
+ }
+@@ -178,5 +181,5 @@ void processInterfaceAdded(interface_map_type& interfaceMap,
+ }
+
+ // The new interface might have an association pending
+- checkIfPendingAssociation(objPath.str, interfaceMap, assocMaps, server);
++ checkIfPendingAssociation(io, objPath.str, interfaceMap, assocMaps, server);
+ }
+diff --git a/src/processing.hpp b/src/processing.hpp
+index 114b502..98be262 100644
+--- a/src/processing.hpp
++++ b/src/processing.hpp
+@@ -60,6 +60,7 @@ bool needToIntrospect(const std::string& processName,
+
+ /** @brief Handle the removal of an existing name in objmgr data structures
+ *
++ * @param[in] io - io context
+ * @param[in,out] nameOwners - Map of unique name to well known name
+ * @param[in] wellKnown - Well known name that has new owner
+ * @param[in] oldOwner - Old unique name
+@@ -69,6 +70,7 @@ bool needToIntrospect(const std::string& processName,
+ *
+ */
+ void processNameChangeDelete(
++ boost::asio::io_context& io,
+ boost::container::flat_map<std::string, std::string>& nameOwners,
+ const std::string& wellKnown, const std::string& oldOwner,
+ interface_map_type& interfaceMap, AssociationMaps& assocMaps,
+@@ -76,6 +78,7 @@ void processNameChangeDelete(
+
+ /** @brief Handle an interfaces added signal
+ *
++ * @param[in] io - io context
+ * @param[in,out] interfaceMap - Global map of interfaces
+ * @param[in] objPath - New path to process
+ * @param[in] interfacesAdded - New interfaces to process
+@@ -84,7 +87,8 @@ void processNameChangeDelete(
+ * @param[in,out] server - sdbus system object
+ *
+ */
+-void processInterfaceAdded(interface_map_type& interfaceMap,
++void processInterfaceAdded(boost::asio::io_context& io,
++ interface_map_type& interfaceMap,
+ const sdbusplus::message::object_path& objPath,
+ const InterfacesAdded& intfAdded,
+ const std::string& wellKnown,
+diff --git a/src/test/associations.cpp b/src/test/associations.cpp
+index 73c36ed..f019a76 100644
+--- a/src/test/associations.cpp
++++ b/src/test/associations.cpp
+@@ -11,6 +11,12 @@
+
+ class TestAssociations : public AsioServerClassTest
+ {
++ public:
++ boost::asio::io_context io;
++ virtual void SetUp()
++ {
++ io.run();
++ }
+ };
+ sdbusplus::asio::object_server* TestAssociations::AsioServerClassTest::server =
+ nullptr;
+@@ -22,7 +28,7 @@ TEST_F(TestAssociations, SourcePathNotInAssociations)
+ std::string sourcePath = "/xyz/openbmc_project/no/association";
+ AssociationMaps assocMaps;
+
+- removeAssociation(sourcePath, DEFAULT_DBUS_SVC, *server, assocMaps);
++ removeAssociation(io, sourcePath, DEFAULT_DBUS_SVC, *server, assocMaps);
+ }
+
+ // Verify call when owner is not in associated owners
+@@ -31,7 +37,7 @@ TEST_F(TestAssociations, OwnerNotInAssociations)
+ AssociationMaps assocMaps;
+ assocMaps.owners = createDefaultOwnerAssociation();
+
+- removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
++ removeAssociation(io, DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
+ assocMaps);
+ }
+
+@@ -42,7 +48,7 @@ TEST_F(TestAssociations, PathNotInAssocInterfaces)
+
+ assocMaps.owners = createDefaultOwnerAssociation();
+
+- removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
++ removeAssociation(io, DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
+ assocMaps);
+
+ EXPECT_TRUE(assocMaps.owners.empty());
+@@ -57,7 +63,7 @@ TEST_F(TestAssociations, PathIsInAssociatedInterfaces)
+ assocMaps.owners = createDefaultOwnerAssociation();
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+- removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
++ removeAssociation(io, DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
+ assocMaps);
+
+ // Verify owner association was deleted
+@@ -83,7 +89,7 @@ TEST_F(TestAssociations, PathIsInAssociatedInterfacesExtraEndpoints)
+ // Add another endpoint to the assoc interfaces
+ addEndpointToInterfaceAssociation(assocMaps.ifaces);
+
+- removeAssociation(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
++ removeAssociation(io, DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, *server,
+ assocMaps);
+
+ // Verify owner association was deleted
+@@ -109,7 +115,7 @@ TEST_F(TestAssociations, checkAssociationEndpointRemovesNoEpRemove)
+ assocMaps.owners = createDefaultOwnerAssociation();
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+- checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
++ checkAssociationEndpointRemoves(io, DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
+ newAssocPaths, *server, assocMaps);
+
+ // Verify endpoints were not deleted because they matche with what was
+@@ -130,7 +136,7 @@ TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveApDiff)
+ assocMaps.owners = createDefaultOwnerAssociation();
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+- checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
++ checkAssociationEndpointRemoves(io, DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
+ newAssocPaths, *server, assocMaps);
+
+ // Verify initial endpoints were deleted because the new path
+@@ -152,7 +158,7 @@ TEST_F(TestAssociations, checkAssociationEndpointRemovesEpRemoveEpChanged)
+ assocMaps.owners = createDefaultOwnerAssociation();
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+- checkAssociationEndpointRemoves(DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
++ checkAssociationEndpointRemoves(io, DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC,
+ newAssocPaths, *server, assocMaps);
+
+ // Verify initial endpoints were deleted because of different endpoints
+@@ -175,7 +181,7 @@ TEST_F(TestAssociations, associationChangedEmptyEndpoint)
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+ // Empty endpoint will result in deletion of corresponding assocInterface
+- associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
++ associationChanged(io, *server, associations, DEFAULT_SOURCE_PATH,
+ DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
+
+ // Both of these should be 0 since we have an invalid endpoint
+@@ -203,7 +209,7 @@ TEST_F(TestAssociations, associationChangedAddNewAssoc)
+ {"/new/source/path", {{DEFAULT_DBUS_SVC, {"a"}}}},
+ {"/xyz/openbmc_project/new/endpoint", {{DEFAULT_DBUS_SVC, {"a"}}}}};
+
+- associationChanged(*server, associations, "/new/source/path",
++ associationChanged(io, *server, associations, "/new/source/path",
+ DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
+
+ // Two source paths
+@@ -237,7 +243,7 @@ TEST_F(TestAssociations, associationChangedAddNewAssocEmptyObj)
+ // Make it look like the assoc endpoints are on D-Bus
+ interface_map_type interfaceMap = createDefaultInterfaceMap();
+
+- associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
++ associationChanged(io, *server, associations, DEFAULT_SOURCE_PATH,
+ DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
+
+ // New associations so ensure it now contains a single entry
+@@ -273,7 +279,7 @@ TEST_F(TestAssociations, associationChangedAddNewAssocNewOwner)
+ assocMaps.owners = createDefaultOwnerAssociation();
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+- associationChanged(*server, associations, DEFAULT_SOURCE_PATH, newOwner,
++ associationChanged(io, *server, associations, DEFAULT_SOURCE_PATH, newOwner,
+ interfaceMap, assocMaps);
+
+ // New endpoint so assocOwners should be same size
+@@ -306,7 +312,7 @@ TEST_F(TestAssociations, associationChangedAddNewAssocSameInterface)
+ assocMaps.owners = createDefaultOwnerAssociation();
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+- associationChanged(*server, associations, DEFAULT_SOURCE_PATH,
++ associationChanged(io, *server, associations, DEFAULT_SOURCE_PATH,
+ DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
+
+ // Should have 3 entries in AssociationInterfaces, one is just missing an
+@@ -406,7 +412,7 @@ TEST_F(TestAssociations, associationChangedPending)
+ AssociationMaps assocMaps;
+ interface_map_type interfaceMap;
+
+- associationChanged(*server, associations, "/new/source/path",
++ associationChanged(io, *server, associations, "/new/source/path",
+ DEFAULT_DBUS_SVC, interfaceMap, assocMaps);
+
+ // No associations were actually added
+@@ -460,7 +466,7 @@ TEST_F(TestAssociations, checkIfPending)
+ EXPECT_EQ(assocMaps.pending.size(), 1);
+
+ // Move the pending association to a real association
+- checkIfPendingAssociation(DEFAULT_SOURCE_PATH, interfaceMap, assocMaps,
++ checkIfPendingAssociation(io, DEFAULT_SOURCE_PATH, interfaceMap, assocMaps,
+ *server);
+
+ EXPECT_TRUE(assocMaps.pending.empty());
+@@ -468,7 +474,8 @@ TEST_F(TestAssociations, checkIfPending)
+ EXPECT_EQ(assocMaps.ifaces.size(), 2);
+
+ // This shouldn't do anything, since /new/path isn't pending
+- checkIfPendingAssociation("/new/path", interfaceMap, assocMaps, *server);
++ checkIfPendingAssociation(io, "/new/path", interfaceMap, assocMaps,
++ *server);
+ EXPECT_TRUE(assocMaps.pending.empty());
+ EXPECT_EQ(assocMaps.owners.size(), 1);
+ EXPECT_EQ(assocMaps.ifaces.size(), 2);
+@@ -525,7 +532,7 @@ TEST_F(TestAssociations, moveAssocToPendingNoOp)
+ AssociationMaps assocMaps;
+
+ // Not an association, so it shouldn't do anything
+- moveAssociationToPending(DEFAULT_ENDPOINT, assocMaps, *server);
++ moveAssociationToPending(io, DEFAULT_ENDPOINT, assocMaps, *server);
+
+ EXPECT_TRUE(assocMaps.pending.empty());
+ EXPECT_TRUE(assocMaps.owners.empty());
+@@ -538,7 +545,7 @@ TEST_F(TestAssociations, moveAssocToPending)
+ assocMaps.owners = createDefaultOwnerAssociation();
+ assocMaps.ifaces = createDefaultInterfaceAssociation(server);
+
+- moveAssociationToPending(DEFAULT_ENDPOINT, assocMaps, *server);
++ moveAssociationToPending(io, DEFAULT_ENDPOINT, assocMaps, *server);
+
+ // Check it's now pending
+ EXPECT_EQ(assocMaps.pending.size(), 1);
+diff --git a/src/test/interfaces_added.cpp b/src/test/interfaces_added.cpp
+index ee0e438..14cdc85 100644
+--- a/src/test/interfaces_added.cpp
++++ b/src/test/interfaces_added.cpp
+@@ -38,9 +38,13 @@ TEST_F(TestInterfacesAdded, InterfacesAddedGoodPath)
+ auto intfAdded =
+ createInterfacesAdded(assocDefsInterface, assocDefsProperty);
+
+- processInterfaceAdded(interfaceMap, DEFAULT_SOURCE_PATH, intfAdded,
++ boost::asio::io_context io;
++
++ processInterfaceAdded(io, interfaceMap, DEFAULT_SOURCE_PATH, intfAdded,
+ DEFAULT_DBUS_SVC, assocMaps, *server);
+
++ io.run();
++
+ // Interface map will get the following:
+ // /logging/entry/1 /logging/entry /logging/ / system/chassis
+ // dump_InterfaceMapType(interfaceMap);
+diff --git a/src/test/name_change.cpp b/src/test/name_change.cpp
+index 95d02af..3ac4e41 100644
+--- a/src/test/name_change.cpp
++++ b/src/test/name_change.cpp
+@@ -6,6 +6,12 @@
+
+ class TestNameChange : public AsioServerClassTest
+ {
++ public:
++ boost::asio::io_context io;
++ virtual void SetUp()
++ {
++ io.run();
++ }
+ };
+ sdbusplus::asio::object_server* TestNameChange::AsioServerClassTest::server =
+ nullptr;
+@@ -20,7 +26,7 @@ TEST_F(TestNameChange, UniqueNameNoInterfaces)
+ interface_map_type interfaceMap;
+ AssociationMaps assocMaps;
+
+- processNameChangeDelete(nameOwners, wellKnown, oldOwner, interfaceMap,
++ processNameChangeDelete(io, nameOwners, wellKnown, oldOwner, interfaceMap,
+ assocMaps, *server);
+ EXPECT_EQ(nameOwners.size(), 0);
+ }
+@@ -42,7 +48,7 @@ TEST_F(TestNameChange, UniqueNameAssociationsAndInterface)
+ auto interfaceMap = createInterfaceMap(
+ DEFAULT_SOURCE_PATH, DEFAULT_DBUS_SVC, assocInterfacesSet);
+
+- processNameChangeDelete(nameOwners, DEFAULT_DBUS_SVC, oldOwner,
++ processNameChangeDelete(io, nameOwners, DEFAULT_DBUS_SVC, oldOwner,
+ interfaceMap, assocMaps, *server);
+ EXPECT_EQ(nameOwners.size(), 0);
+
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend
index 4fc41d058..05e9fec1b 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-mapper_%.bbappend
@@ -1 +1,3 @@
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "file://0001-add-Associations-endpoints-change-delay-timer.patch"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd/0001-Avoid-negated-postcode-write-to-D-Bus.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd/0001-Avoid-negated-postcode-write-to-D-Bus.patch
new file mode 100644
index 000000000..47afc4568
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd/0001-Avoid-negated-postcode-write-to-D-Bus.patch
@@ -0,0 +1,58 @@
+From 3311e449da0c7431f5512138aa61212af3d769a1 Mon Sep 17 00:00:00 2001
+From: Zhikui Ren <zhikui.ren@intel.com>
+Date: Mon, 14 Nov 2022 14:14:33 -0800
+Subject: [PATCH] Avoid negated postcode write to D-Bus
+
+This commit removes the code which writes the negated
+postcode value to D-Bus object. This has some side effects
+when bombarded data pushed to port 80.
+
+With this change, if same post code is written on LPC channel
+it will be set but D-Bus will not emit the 'PropertiesChanged'
+signal. Actually there is no need to emit the signal if actual
+property value(postcode) is not changed.
+
+So if post code changes, D-Bus will emit the signal as usual
+with this code. Any client applications depends on this, still
+can register for signal for knowing postcode change.
+
+Renamed bbappend file for generic notation.
+
+Tested:
+ - Manually verified by setting different post code,
+ emits the signal.
+
+ busctl set-property xyz.openbmc_project.State.Boot.Raw
+ /xyz/openbmc_project/state/boot/raw0 xyz.openbmc_project.State.Boot.Raw
+ Value t 00
+
+ dbus-monitor --system "type='signal',member='PropertiesChanged',
+ interface='org.freedesktop.DBus.Properties',
+ path_namespace=/xyz/openbmc_project/state/boot/raw0,
+ arg0=xyz.openbmc_project.State.Boot.Raw"
+
+ - Verified functionality with real post code changes.
+
+Change-Id: I13e7879a19ada593891821df3702613cc8e84572
+Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
+Signed-off-by: Zhikui Ren <zhikui.ren@intel.com>
+---
+ main.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/main.cpp b/main.cpp
+index 3a3b4ce..764c855 100644
+--- a/main.cpp
++++ b/main.cpp
+@@ -66,7 +66,7 @@ void PostCodeEventHandler(sdeventplus::source::IO& s, int postFd, uint32_t,
+ // HACK: Always send property changed signal even for the same code
+ // since we are single threaded, external users will never see the
+ // first value.
+- reporter->value(std::make_tuple(~code, secondary_post_code_t{}), true);
++ // reporter->value(std::make_tuple(~code, secondary_post_code_t{}), true);
+ reporter->value(std::make_tuple(code, secondary_post_code_t{}));
+
+ // read depends on old data being cleared since it doens't always read
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_%.bbappend
new file mode 100644
index 000000000..893f410e8
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_%.bbappend
@@ -0,0 +1,9 @@
+FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
+PROJECT_SRC_DIR := "${THISDIR}/${PN}"
+
+DEPENDS += " gtest"
+
+#SRC_URI = "git://github.com/openbmc/phosphor-host-postd.git"
+SRCREV = "6a5e0a1cba979c3c793e794c41481221da9a4e33"
+
+SRC_URI += "file://0001-Avoid-negated-postcode-write-to-D-Bus.patch"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_git.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_git.bbappend
deleted file mode 100644
index 21ff75f73..000000000
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/host/phosphor-host-postd_git.bbappend
+++ /dev/null
@@ -1,4 +0,0 @@
-DEPENDS += " gtest"
-
-#SRC_URI = "git://github.com/openbmc/phosphor-host-postd.git"
-SRCREV = "6a5e0a1cba979c3c793e794c41481221da9a4e33"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0009-virtual_media-Fix-for-bmcweb-crash.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0009-virtual_media-Fix-for-bmcweb-crash.patch
new file mode 100644
index 000000000..a2a120c22
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/vm/0009-virtual_media-Fix-for-bmcweb-crash.patch
@@ -0,0 +1,47 @@
+From 348186f045f23d59405ac0011e983aea8334598a Mon Sep 17 00:00:00 2001
+From: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
+Date: Thu, 4 May 2023 13:56:27 +0000
+Subject: [PATCH] virtual_media: Fix for bmcweb crash
+
+This is ported from main line.
+https://gerrit.openbmc.org/c/openbmc/bmcweb/+/62593
+
+bmcweb crashes when user not providing userName or password while
+posting ISO form Redfish.
+
+This fix provides to avoid bmcweb crash when user try to post ISO images
+from Redfish without providing username or password.
+
+Tested:
+Redfish validator passed with this change.
+Verified by Posting ISO from Redfish.
+
+Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com>
+---
+ redfish-core/lib/virtual_media.hpp | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp
+index 6dfc726b..838a08b1 100644
+--- a/redfish-core/lib/virtual_media.hpp
++++ b/redfish-core/lib/virtual_media.hpp
+@@ -1069,6 +1069,16 @@ inline void requestNBDVirtualMediaRoutes(App& app)
+ return true;
+ }
+
++ if (!actionParams.userName)
++ {
++ actionParams.userName = "";
++ }
++
++ if (!actionParams.password)
++ {
++ actionParams.password = "";
++ }
++
+ // manager is irrelevant for
+ // VirtualMedia dbus calls
+ doMountVmLegacy(asyncResp, service, resName,
+--
+2.17.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
index d5e7a6dd2..e3bed9eb0 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend
@@ -55,6 +55,7 @@ SRC_URI += " \
file://vm/0006-Bmcweb-handle-permission-denied-exception.patch \
file://vm/0007-Fix-unmounting-image-in-proxy-mode.patch \
file://vm/0008-Return-404-for-POST-on-Proxy-InsertMedia.patch \
+ file://vm/0009-virtual_media-Fix-for-bmcweb-crash.patch \
"
# EventService: Temporary pulled to downstream. See eventservice\README for details
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb
index bdc85913f..5ddca8730 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/pmci/mctpd.bb
@@ -5,7 +5,7 @@ LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e"
SRC_URI = "git://git@github.com/Intel-BMC/mctpd.git;protocol=ssh;branch=1-release"
-SRCREV = "4aa697fba21a2d0d0770358a8c9493bf5d8d5741"
+SRCREV = "1741334eb0972de547d053e97d0a5b93892b070e"
S = "${WORKDIR}/git"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0017-psusensor-Determine-PSU-threshold-dynamically.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0017-psusensor-Determine-PSU-threshold-dynamically.patch
new file mode 100644
index 000000000..1823e96a5
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0017-psusensor-Determine-PSU-threshold-dynamically.patch
@@ -0,0 +1,160 @@
+From 654fef4afba55c4f84f664b43d8a1fecc1224e7b Mon Sep 17 00:00:00 2001
+From: Vikash Chandola <vikash.chandola@intel.com>
+Date: Wed, 27 Jul 2022 10:07:25 +0000
+Subject: [PATCH] psusensor: Determine PSU threshold dynamically
+
+PSU output current range(rated, max etc) are dependent on input
+voltage. A power supply can deliver higher output on high line input
+compared to low line input. Existing implementation uses static
+thresholds which causes thresholds to get hit too early for high line
+input. This change allows threshold to be set dynamically.
+
+"ThresholdLabel" and "ScaleFactor" are added in SOLUM's entity-manager
+configuration file. These parameters provide pmbus register name and
+scaling factor to be used for threshold calculation. psusensor fetches
+"ThresholdLabel" and multiplies it with "ScaleFactor" to determine
+threshold value. "ScaleFactor" allows threshold to be set in ratio to
+a value. Example create a threshold that gets triggered at 0.8 times
+max permissible current value.
+
+"ThresholdLabel" and "ScaleFactor" can be used for the cases where
+threshold need to be determined on the basis on another parameter's
+value.
+
+Tested:
+Tested by running system on High line and low line input. In both
+cases critical and warning thresholds were updated as per
+"ThresholdLabel" and "ScaleFactor". If configuration file doesn't
+contain "ThresholdLabel" and "ScaleFactor" then "Value" was used.
+
+Signed-off-by: Vikash Chandola <vikash.chandola@intel.com>
+Change-Id: Ia588ee0971e3d4e79a9827ffd6f39398725a4273
+---
+ include/Thresholds.hpp | 3 +-
+ src/PSUSensorMain.cpp | 2 +-
+ src/Thresholds.cpp | 64 +++++++++++++++++++++++++++++++++++++-----
+ 3 files changed, 60 insertions(+), 9 deletions(-)
+
+diff --git a/include/Thresholds.hpp b/include/Thresholds.hpp
+index 640fdb4..7373507 100644
+--- a/include/Thresholds.hpp
++++ b/include/Thresholds.hpp
+@@ -111,7 +111,8 @@ struct ThresholdTimer
+ bool parseThresholdsFromConfig(
+ const SensorData& sensorData,
+ std::vector<thresholds::Threshold>& thresholdVector,
+- const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr);
++ const std::string* matchLabel = nullptr, const int* sensorIndex = nullptr,
++ const std::string* sensorPathStr = nullptr);
+
+ bool parseThresholdsFromAttr(std::vector<thresholds::Threshold>& thresholds,
+ const std::string& inputPath,
+diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
+index ae7afc3..5847863 100644
+--- a/src/PSUSensorMain.cpp
++++ b/src/PSUSensorMain.cpp
+@@ -846,7 +846,7 @@ static void createSensorsCallback(
+
+ std::vector<thresholds::Threshold> sensorThresholds;
+ if (!parseThresholdsFromConfig(*sensorData, sensorThresholds,
+- &labelHead))
++ &labelHead ,nullptr, &sensorPathStr))
+ {
+ std::cerr << "error populating thresholds for "
+ << sensorNameSubStr << "\n";
+diff --git a/src/Thresholds.cpp b/src/Thresholds.cpp
+index aef084e..cddfa2b 100644
+--- a/src/Thresholds.cpp
++++ b/src/Thresholds.cpp
+@@ -56,11 +56,48 @@ std::string toBusValue(const Direction& direction)
+ }
+ }
+ }
++static const std::unordered_map<std::string, std::string> labelToHwmonSuffix = {
++ {"iout_oc_warn_limit", "max"},
++};
++
++static std::optional<double>
++ parseThresholdFromLabel(const std::string* sensorPathStr,
++ const SensorBaseConfigMap& sensorData)
++{
++ if (sensorPathStr == nullptr)
++ {
++ return std::nullopt;
++ }
++ auto thresholdLabelFind = sensorData.find("ThresholdLabel");
++ auto scaleFactorFind = sensorData.find("ScaleFactor");
++ if (thresholdLabelFind == sensorData.end() ||
++ scaleFactorFind == sensorData.end())
++ {
++ return std::nullopt;
++ }
++ auto hwmonFileSuffix = labelToHwmonSuffix.find(
++ std::visit(VariantToStringVisitor(), thresholdLabelFind->second));
++ if (hwmonFileSuffix == labelToHwmonSuffix.end())
++ {
++ return std::nullopt;
++ }
++ auto fileParts = splitFileName(*sensorPathStr);
++ if (!fileParts.has_value())
++ {
++ return std::nullopt;
++ }
++ auto& [type, nr, item] = fileParts.value();
++ auto attrPath =
++ boost::replace_all_copy(*sensorPathStr, item, hwmonFileSuffix->second);
++ return readFile(attrPath, (1.0 / std::visit(VariantToDoubleVisitor(),
++ scaleFactorFind->second)));
++}
+
+ bool parseThresholdsFromConfig(
+ const SensorData& sensorData,
+ std::vector<thresholds::Threshold>& thresholdVector,
+- const std::string* matchLabel, const int* sensorIndex)
++ const std::string* matchLabel, const int* sensorIndex,
++ const std::string* sensorPathStr)
+ {
+ for (const auto& item : sensorData)
+ {
+@@ -110,10 +147,7 @@ bool parseThresholdsFromConfig(
+
+ auto directionFind = item.second.find("Direction");
+ auto severityFind = item.second.find("Severity");
+- auto valueFind = item.second.find("Value");
+- if (valueFind == item.second.end() ||
+- severityFind == item.second.end() ||
+- directionFind == item.second.end())
++ if (severityFind == item.second.end() || directionFind == item.second.end())
+ {
+ std::cerr << "Malformed threshold on configuration interface "
+ << item.first << "\n";
+@@ -139,8 +173,24 @@ bool parseThresholdsFromConfig(
+ {
+ direction = Direction::HIGH;
+ }
+- double val = std::visit(VariantToDoubleVisitor(), valueFind->second);
+-
++ double val = 0;
++ auto valueFind = item.second.find("Value");
++ auto labelValueOption = parseThresholdFromLabel(sensorPathStr, item.second);
++ if (labelValueOption.has_value())
++ {
++ val = labelValueOption.value();
++ }
++ else if (valueFind != item.second.end())
++ {
++ val = std::visit(VariantToDoubleVisitor(), valueFind->second);
++ }
++ else
++ {
++ std::cerr << "Failed to parse threshold value configuration for "
++ "interface "
++ << item.first << "\n";
++ return false;
++ }
+ thresholdVector.emplace_back(level, direction, val, hysteresis);
+ }
+ return true;
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend
index a9d4a7627..7e3356e9a 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend
@@ -22,6 +22,7 @@ SRC_URI += "\
file://0014-Treat-zero-temperatures-readings-as-errors-in-IpmbSe.patch \
file://0015-Fix-for-PSU2-Power-lost-RedFish-events.patch \
file://0016-Ignore-VR-sensor-readings-if-content-is-0xFF.patch \
+ file://0017-psusensor-Determine-PSU-threshold-dynamically.patch \
"
DEPENDS:append = " libgpiod libmctp"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0001-Change-to-pam_faillock-and-pam-pwquality.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0001-Change-to-pam_faillock-and-pam-pwquality.patch
new file mode 100644
index 000000000..e050d9493
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager/0001-Change-to-pam_faillock-and-pam-pwquality.patch
@@ -0,0 +1,492 @@
+From 0636e9177c718cd46023c454fb36825e1d000a4f Mon Sep 17 00:00:00 2001
+From: "Jason M. Bills" <jason.m.bills@intel.com>
+Date: Tue, 28 Mar 2023 15:32:45 -0700
+Subject: [PATCH] Change to pam_faillock and pam pwquality
+
+pam_tally2 is being replaced by pam_faillock. The parameters in
+common-auth have moved to faillock.conf, so this commit adds a new
+method to modify paramters in a given configuration file.
+
+The output from the 'faillock' command differs from 'pam_tally2', so
+this commit adds a new function to parse the output from 'faillock' to
+determine if the user is currently locked.
+
+pam_cracklib is being replaced by pam_pwquality. The parameters in
+common-password have moved to pwquality.conf.
+
+I referenced the work done by Joseph Reynolds in this commit [1] to know
+what changes were required.
+
+[1]: https://gerrit.openbmc.org/c/openbmc/phosphor-user-manager/+/39853
+
+Tested:
+Confirmed that the AccountLockoutDuration and AccountLockoutThreshold
+parameters under /redfish/v1/AccountService both return the correct
+value from common-auth.
+
+Set deny to 10 and unlock_time to 30 seconds and confirmed that a user
+account will correctly show as locked after 10 failed login attempts,
+and that user will show as unlocked 30 seconds later.
+
+Used Redfish to PATCH both AccountLockoutDuration and
+AccountLockoutThreshold and confirmed that the updated values are
+correctly reported in Redfish and that the correct lines in
+faillock.conf are modified.
+
+Confirmed that the MinPasswordLength parameter under
+/redfish/v1/AccountService returns the correct value from
+common-password.
+
+Set minlen to 9 and confirmed that a user password could not be set with
+a length of 8.
+
+Used Redfish to PATCH MinPasswordLength and confirmed that the updated
+value is correctly reported in Redfish and that the correct line in
+pwquality.conf is modified.
+
+Change-Id: I0701e4148c0b8333c6b8889d4695e61ce7f5366d
+Signed-off-by: Jason M. Bills <jason.m.bills@intel.com>
+---
+ user_mgr.cpp | 257 +++++++++++++++++++++++++++++++++++++--------------
+ user_mgr.hpp | 37 ++++++++
+ 2 files changed, 224 insertions(+), 70 deletions(-)
+
+diff --git a/user_mgr.cpp b/user_mgr.cpp
+index c49fbef..68ca0ff 100644
+--- a/user_mgr.cpp
++++ b/user_mgr.cpp
+@@ -51,15 +51,15 @@ static constexpr int success = 0;
+ static constexpr int failure = -1;
+
+ // pam modules related
+-static constexpr const char* pamTally2 = "pam_tally2.so";
+-static constexpr const char* pamCrackLib = "pam_cracklib.so";
+ static constexpr const char* pamPWHistory = "pam_pwhistory.so";
+ static constexpr const char* minPasswdLenProp = "minlen";
+ static constexpr const char* remOldPasswdCount = "remember";
+ static constexpr const char* maxFailedAttempt = "deny";
+ static constexpr const char* unlockTimeout = "unlock_time";
+ static constexpr const char* pamPasswdConfigFile = "/etc/pam.d/common-password";
+-static constexpr const char* pamAuthConfigFile = "/etc/pam.d/common-auth";
++static constexpr const char* faillockConfigFile = "/etc/security/faillock.conf";
++static constexpr const char* pwQualityConfigFile =
++ "/etc/security/pwquality.conf";
+
+ // Object Manager related
+ static constexpr const char* ldapMgrObjBasePath =
+@@ -320,8 +320,8 @@ uint8_t UserMgr::minPasswordLength(uint8_t value)
+ {
+ return value;
+ }
+- if (setPamModuleArgValue(pamCrackLib, minPasswdLenProp,
+- std::to_string(value)) != success)
++ if (setPamModuleConfValue(pwQualityConfigFile, minPasswdLenProp,
++ std::to_string(value)) != success)
+ {
+ log<level::ERR>("Unable to set minPasswordLength");
+ elog<InternalFailure>();
+@@ -350,8 +350,8 @@ uint16_t UserMgr::maxLoginAttemptBeforeLockout(uint16_t value)
+ {
+ return value;
+ }
+- if (setPamModuleArgValue(pamTally2, maxFailedAttempt,
+- std::to_string(value)) != success)
++ if (setPamModuleConfValue(faillockConfigFile, maxFailedAttempt,
++ std::to_string(value)) != success)
+ {
+ log<level::ERR>("Unable to set maxLoginAttemptBeforeLockout");
+ elog<InternalFailure>();
+@@ -365,8 +365,8 @@ uint32_t UserMgr::accountUnlockTimeout(uint32_t value)
+ {
+ return value;
+ }
+- if (setPamModuleArgValue(pamTally2, unlockTimeout, std::to_string(value)) !=
+- success)
++ if (setPamModuleConfValue(faillockConfigFile, unlockTimeout,
++ std::to_string(value)) != success)
+ {
+ log<level::ERR>("Unable to set accountUnlockTimeout");
+ elog<InternalFailure>();
+@@ -378,15 +378,7 @@ int UserMgr::getPamModuleArgValue(const std::string& moduleName,
+ const std::string& argName,
+ std::string& argValue)
+ {
+- std::string fileName;
+- if (moduleName == pamTally2)
+- {
+- fileName = pamAuthConfigFile;
+- }
+- else
+- {
+- fileName = pamPasswdConfigFile;
+- }
++ std::string fileName = pamPasswdConfigFile;
+ std::ifstream fileToRead(fileName, std::ios::in);
+ if (!fileToRead.is_open())
+ {
+@@ -427,19 +419,52 @@ int UserMgr::getPamModuleArgValue(const std::string& moduleName,
+ return failure;
+ }
+
+-int UserMgr::setPamModuleArgValue(const std::string& moduleName,
+- const std::string& argName,
+- const std::string& argValue)
++int UserMgr::getPamModuleConfValue(const std::string& confFile,
++ const std::string& argName,
++ std::string& argValue)
+ {
+- std::string fileName;
+- if (moduleName == pamTally2)
++ std::ifstream fileToRead(confFile, std::ios::in);
++ if (!fileToRead.is_open())
+ {
+- fileName = pamAuthConfigFile;
++ log<level::ERR>("Failed to open pam configuration file",
++ entry("FILE_NAME=%s", confFile.c_str()));
++ return failure;
+ }
+- else
++ std::string line;
++ auto argSearch = argName + "=";
++ size_t startPos = 0;
++ size_t endPos = 0;
++ while (getline(fileToRead, line))
+ {
+- fileName = pamPasswdConfigFile;
++ // skip comments section starting with #
++ if ((startPos = line.find('#')) != std::string::npos)
++ {
++ if (startPos == 0)
++ {
++ continue;
++ }
++ // skip comments after meaningful section and process those
++ line = line.substr(0, startPos);
++ }
++ if ((startPos = line.find(argSearch)) != std::string::npos)
++ {
++ if ((endPos = line.find(' ', startPos)) == std::string::npos)
++ {
++ endPos = line.size();
++ }
++ startPos += argSearch.size();
++ argValue = line.substr(startPos, endPos - startPos);
++ return success;
++ }
+ }
++ return failure;
++}
++
++int UserMgr::setPamModuleArgValue(const std::string& moduleName,
++ const std::string& argName,
++ const std::string& argValue)
++{
++ std::string fileName = pamPasswdConfigFile;
+ std::string tmpFileName = fileName + "_tmp";
+ std::ifstream fileToRead(fileName, std::ios::in);
+ std::ofstream fileToWrite(tmpFileName, std::ios::out);
+@@ -497,6 +522,64 @@ int UserMgr::setPamModuleArgValue(const std::string& moduleName,
+ return failure;
+ }
+
++int UserMgr::setPamModuleConfValue(const std::string& confFile,
++ const std::string& argName,
++ const std::string& argValue)
++{
++ std::string tmpConfFile = confFile + "_tmp";
++ std::ifstream fileToRead(confFile, std::ios::in);
++ std::ofstream fileToWrite(tmpConfFile, std::ios::out);
++ if (!fileToRead.is_open() || !fileToWrite.is_open())
++ {
++ log<level::ERR>("Failed to open pam configuration /tmp file",
++ entry("FILE_NAME=%s", confFile.c_str()));
++ return failure;
++ }
++ std::string line;
++ auto argSearch = argName + "=";
++ size_t startPos = 0;
++ size_t endPos = 0;
++ bool found = false;
++ while (getline(fileToRead, line))
++ {
++ // skip comments section starting with #
++ if ((startPos = line.find('#')) != std::string::npos)
++ {
++ if (startPos == 0)
++ {
++ fileToWrite << line << std::endl;
++ continue;
++ }
++ // skip comments after meaningful section and process those
++ line = line.substr(0, startPos);
++ }
++ if ((startPos = line.find(argSearch)) != std::string::npos)
++ {
++ if ((endPos = line.find(' ', startPos)) == std::string::npos)
++ {
++ endPos = line.size();
++ }
++ startPos += argSearch.size();
++ fileToWrite << line.substr(0, startPos) << argValue
++ << line.substr(endPos, line.size() - endPos)
++ << std::endl;
++ found = true;
++ continue;
++ }
++ fileToWrite << line << std::endl;
++ }
++ fileToWrite.close();
++ fileToRead.close();
++ if (found)
++ {
++ if (std::rename(tmpConfFile.c_str(), confFile.c_str()) == 0)
++ {
++ return success;
++ }
++ }
++ return failure;
++}
++
+ void UserMgr::userEnable(const std::string& userName, bool enabled)
+ {
+ throwForUserDoesNotExist(userName);
+@@ -510,51 +593,87 @@ void UserMgr::userEnable(const std::string& userName, bool enabled)
+ }
+
+ /**
+- * pam_tally2 app will provide the user failure count and failure status
+- * in second line of output with words position [0] - user name,
+- * [1] - failure count, [2] - latest timestamp, [3] - failure timestamp
+- * [4] - failure app
++ * faillock app will provide the user failed login list with when the attempt
++ * was made, the type, the source, and if it's valid.
++ *
++ * Valid in this case means that the attempt was made within the fail_interval
++ * time. So, we can check this list for the number of valid entries (lines
++ * ending with 'V') compared to the maximum allowed to determine if the user is
++ * locked out.
++ *
++ * This data is only refreshed when an attempt is made, so if the user appears
++ * to be locked out, we must also check if the most recent attempt was older
++ * than the unlock_time to know if the user has since been unlocked.
+ **/
+-
+-static constexpr size_t t2UserIdx = 0;
+-static constexpr size_t t2FailCntIdx = 1;
+-static constexpr size_t t2OutputIndex = 1;
+-
+-bool UserMgr::userLockedForFailedAttempt(const std::string& userName)
++bool UserMgr::parseFaillockForLockout(
++ const std::vector<std::string>& faillockOutput)
+ {
+- // All user management lock has to be based on /etc/shadow
+- // TODO phosphor-user-manager#10 phosphor::user::shadow::Lock lock{};
+- std::vector<std::string> output;
+-
+- output = executeCmd("/usr/sbin/pam_tally2", "-u", userName.c_str());
++ uint16_t failAttempts = 0;
++ time_t lastFailedAttempt{};
++ for (const std::string& line : faillockOutput)
++ {
++ if (!boost::ends_with(line, "V"))
++ {
++ continue;
++ }
+
+- std::vector<std::string> splitWords;
+- boost::algorithm::split(splitWords, output[t2OutputIndex],
+- boost::algorithm::is_any_of("\t "),
+- boost::token_compress_on);
++ // Count this failed attempt
++ failAttempts++;
+
+- try
+- {
+- unsigned long tmp = std::stoul(splitWords[t2FailCntIdx], nullptr);
+- uint16_t value16 = 0;
+- if (tmp > std::numeric_limits<decltype(value16)>::max())
++ // Update the last attempt time
++ // First get the "when" which is the first two words (date and time)
++ size_t pos = line.find(" ");
++ if (pos == std::string::npos)
++ {
++ continue;
++ }
++ pos = line.find(" ", pos + 1);
++ if (pos == std::string::npos)
+ {
+- throw std::out_of_range("Out of range");
++ continue;
+ }
+- value16 = static_cast<decltype(value16)>(tmp);
+- if (AccountPolicyIface::maxLoginAttemptBeforeLockout() != 0 &&
+- value16 >= AccountPolicyIface::maxLoginAttemptBeforeLockout())
++ std::string failDateTime = line.substr(0, pos);
++
++ // NOTE: Cannot use std::get_time() here as the implementation of %y in
++ // libstdc++ does not match POSIX strptime() before gcc 12.1.0
++ // https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=a8d3c98746098e2784be7144c1ccc9fcc34a0888
++ std::tm tmStruct = {};
++ if (!strptime(failDateTime.c_str(), "%F %T", &tmStruct))
+ {
+- return true; // User account is locked out
++ // log<level::ERR>("Failed to parse latest failure date/time");
++ // elog<InternalFailure>();
+ }
+- return false; // User account is un-locked
++
++ time_t failTimestamp = std::mktime(&tmStruct);
++ lastFailedAttempt = std::max(failTimestamp, lastFailedAttempt);
++ }
++
++ if (failAttempts < AccountPolicyIface::maxLoginAttemptBeforeLockout())
++ {
++ return false;
+ }
+- catch (const std::exception& e)
++
++ if (lastFailedAttempt +
++ static_cast<time_t>(AccountPolicyIface::accountUnlockTimeout()) <=
++ std::time(NULL))
+ {
+- log<level::ERR>("Exception for userLockedForFailedAttempt",
+- entry("WHAT=%s", e.what()));
+- throw;
++ return false;
+ }
++
++ return true;
++}
++
++bool UserMgr::userLockedForFailedAttempt(const std::string& userName)
++{
++ // All user management lock has to be based on /etc/shadow
++ // TODO phosphor-user-manager#10 phosphor::user::shadow::Lock lock{};
++
++ std::vector<std::string> output;
++
++ output =
++ executeCmd("/usr/sbin/faillock", "--user", userName.c_str(), "--reset");
++
++ return parseFaillockForLockout(output);
+ }
+
+ bool UserMgr::userLockedForFailedAttempt(const std::string& userName,
+@@ -567,12 +686,8 @@ bool UserMgr::userLockedForFailedAttempt(const std::string& userName,
+ {
+ return userLockedForFailedAttempt(userName);
+ }
+- output = executeCmd("/usr/sbin/pam_tally2", "-u", userName.c_str(), "-r");
+-
+- std::vector<std::string> splitWords;
+- boost::algorithm::split(splitWords, output[t2OutputIndex],
+- boost::algorithm::is_any_of("\t "),
+- boost::token_compress_on);
++ output =
++ executeCmd("/usr/sbin/faillock", "--user", userName.c_str(), "--reset");
+
+ return userLockedForFailedAttempt(userName);
+ }
+@@ -940,8 +1055,8 @@ UserMgr::UserMgr(sdbusplus::bus::bus& bus, const char* path,
+ std::string valueStr;
+ auto value = minPasswdLength;
+ unsigned long tmp = 0;
+- if (getPamModuleArgValue(pamCrackLib, minPasswdLenProp, valueStr) !=
+- success)
++ if (getPamModuleConfValue(pwQualityConfigFile, minPasswdLenProp,
++ valueStr) != success)
+ {
+ AccountPolicyIface::minPasswordLength(minPasswdLength);
+ }
+@@ -991,7 +1106,8 @@ UserMgr::UserMgr(sdbusplus::bus::bus& bus, const char* path,
+ AccountPolicyIface::rememberOldPasswordTimes(value);
+ }
+ valueStr.clear();
+- if (getPamModuleArgValue(pamTally2, maxFailedAttempt, valueStr) != success)
++ if (getPamModuleConfValue(faillockConfigFile, maxFailedAttempt, valueStr) !=
++ success)
+ {
+ AccountPolicyIface::maxLoginAttemptBeforeLockout(0);
+ }
+@@ -1016,7 +1132,8 @@ UserMgr::UserMgr(sdbusplus::bus::bus& bus, const char* path,
+ AccountPolicyIface::maxLoginAttemptBeforeLockout(value16);
+ }
+ valueStr.clear();
+- if (getPamModuleArgValue(pamTally2, unlockTimeout, valueStr) != success)
++ if (getPamModuleConfValue(faillockConfigFile, unlockTimeout, valueStr) !=
++ success)
+ {
+ AccountPolicyIface::accountUnlockTimeout(0);
+ }
+diff --git a/user_mgr.hpp b/user_mgr.hpp
+index 5d5ca99..92a265b 100644
+--- a/user_mgr.hpp
++++ b/user_mgr.hpp
+@@ -155,6 +155,14 @@ class UserMgr : public Ifaces
+ */
+ uint32_t accountUnlockTimeout(uint32_t val) override;
+
++ /** @brief parses the faillock output for locked user status
++ *
++ * @param[in] - output from faillock for the user
++ * @return - true / false indicating user locked / un-locked
++ **/
++ bool
++ parseFaillockForLockout(const std::vector<std::string>& faillockOutput);
++
+ /** @brief lists user locked state for failed attempt
+ *
+ * @param[in] - user name
+@@ -311,6 +319,20 @@ class UserMgr : public Ifaces
+ int getPamModuleArgValue(const std::string& moduleName,
+ const std::string& argName, std::string& argValue);
+
++ /** @brief get pam argument value
++ * method to get argument value from pam configuration
++ *
++ * @param[in] confFile - path of the module config file from where arg has
++ * to be read
++ * @param[in] argName - argument name
++ * @param[out] argValue - argument value
++ *
++ * @return 0 - success state of the function
++ */
++ int getPamModuleConfValue(const std::string& confFile,
++ const std::string& argName,
++ std::string& argValue);
++
+ /** @brief set pam argument value
+ * method to set argument value in pam configuration
+ *
+@@ -325,6 +347,20 @@ class UserMgr : public Ifaces
+ const std::string& argName,
+ const std::string& argValue);
+
++ /** @brief set pam argument value
++ * method to set argument value in pam configuration
++ *
++ * @param[in] confFile - path of the module config file in which argument
++ * value has to be set
++ * @param[in] argName - argument name
++ * @param[out] argValue - argument value
++ *
++ * @return 0 - success state of the function
++ */
++ int setPamModuleConfValue(const std::string& confFile,
++ const std::string& argName,
++ const std::string& argValue);
++
+ /** @brief get service name
+ * method to get dbus service name
+ *
+@@ -351,6 +387,7 @@ class UserMgr : public Ifaces
+ virtual DbusUserObj getPrivilegeMapperObject(void);
+
+ friend class TestUserMgr;
++
+ };
+
+ } // namespace user
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
index 0bf528eb4..88a2b0f2d 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/users/phosphor-user-manager_%.bbappend
@@ -6,6 +6,7 @@ SRCREV = "b01e2fe760eb04ae9d0d13716a127056949e2601"
EXTRA_OECONF += "${@bb.utils.contains_any("IMAGE_FEATURES", [ 'debug-tweaks', 'allow-root-login' ], '', '--disable-root_user_mgmt', d)}"
SRC_URI += " \
+ file://0001-Change-to-pam_faillock-and-pam-pwquality.patch \
file://0005-Added-suport-for-multiple-user-manager-services.patch \
file://0006-Use-groupmems-instead-of-getgrnam_r-due-to-overlay.patch \
"
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue/0001-Old-password-input-in-change-password-screen.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue/0001-Old-password-input-in-change-password-screen.patch
new file mode 100644
index 000000000..313ba9387
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue/0001-Old-password-input-in-change-password-screen.patch
@@ -0,0 +1,135 @@
+From 9da7bafdcee1bd022b7e47eecf704eb799b389e8 Mon Sep 17 00:00:00 2001
+From: Yaswanth Reddy M <yaswanthx.reddy.munukuru@intel.com>
+Date: Wed, 17 May 2023 10:47:56 +0000
+Subject: [PATCH] Old password input in change password screen
+
+When the user changed their password in profile settings, to prevent
+XSS attacks, I added the current password input field to authenticate
+the user.
+
+Once the authentication had success with the current password, then
+allowing the update was possible. After the password is changed
+successfully, all the sessions of the user who changed the password
+will be disconnected, including the current session. and the current
+session will navigate to the login page.
+
+Signed-off-by: Yaswanth Reddy M <yaswanthx.reddy.munukuru@intel.com>
+---
+ src/locales/en-US.json | 4 +-
+ src/views/ProfileSettings/ProfileSettings.vue | 54 +++++++++++++++++--
+ 2 files changed, 53 insertions(+), 5 deletions(-)
+
+diff --git a/src/locales/en-US.json b/src/locales/en-US.json
+index 637f052..8d98abb 100644
+--- a/src/locales/en-US.json
++++ b/src/locales/en-US.json
+@@ -617,6 +617,7 @@
+ "confirmPassword": "Confirm new password",
+ "defaultUTC": "Default (UTC)",
+ "newPassword": "New password",
++ "currentPassword": "Current password",
+ "newPassLabelTextInfo": "Password must be between %{min} - %{max} characters",
+ "passwordsDoNotMatch": "Passwords do not match",
+ "profileInfoTitle": "Profile information",
+@@ -625,7 +626,8 @@
+ "timezoneDisplayDesc": "Select how time is displayed throughout the application",
+ "username": "Username",
+ "toast": {
+- "successSaveSettings": "Successfully saved account settings."
++ "successSaveSettings": "Successfully saved account settings.",
++ "wrongCredentials": "Wrong credentials"
+ }
+ },
+ "pageNetwork": {
+diff --git a/src/views/ProfileSettings/ProfileSettings.vue b/src/views/ProfileSettings/ProfileSettings.vue
+index 35fc800..330fd4a 100644
+--- a/src/views/ProfileSettings/ProfileSettings.vue
++++ b/src/views/ProfileSettings/ProfileSettings.vue
+@@ -23,6 +23,21 @@
+ <page-section
+ :section-title="$t('pageProfileSettings.changePassword')"
+ >
++ <b-form-group
++ id="input-group-0"
++ :label="$t('pageProfileSettings.currentPassword')"
++ label-for="input-0"
++ >
++ <input-password-toggle>
++ <b-form-input
++ id="old-password"
++ v-model="form.currentPassword"
++ type="password"
++ data-test-id="profileSettings-input-ocurrentPassword"
++ class="form-control-with-button"
++ />
++ </input-password-toggle>
++ </b-form-group>
+ <b-form-group
+ id="input-group-1"
+ :label="$t('pageProfileSettings.newPassword')"
+@@ -151,6 +166,7 @@ export default {
+ form: {
+ newPassword: '',
+ confirmPassword: '',
++ currentPassword: '',
+ isUtcDisplay: this.$store.getters['global/isUtcDisplay'],
+ },
+ };
+@@ -198,9 +214,12 @@ export default {
+ this.$store
+ .dispatch('userManagement/updateUser', userData)
+ .then((message) => {
+- (this.form.newPassword = ''), (this.form.confirmPassword = '');
++ (this.form.newPassword = ''),
++ (this.form.confirmPassword = ''),
++ (this.form.currentPassword = '');
+ this.$v.$reset();
+ this.successToast(message);
++ this.$store.dispatch('authentication/logout');
+ })
+ .catch(({ message }) => this.errorToast(message));
+ },
+@@ -212,10 +231,37 @@ export default {
+ );
+ },
+ submitForm() {
+- if (this.form.confirmPassword || this.form.newPassword) {
+- this.saveNewPasswordInputData();
++ if (
++ this.form.confirmPassword &&
++ this.form.newPassword &&
++ this.form.currentPassword
++ ) {
++ this.confirmAuthenticate();
+ }
+- this.saveTimeZonePrefrenceData();
++ if (
++ this.$store.getters['global/isUtcDisplay'] != this.form.isUtcDisplay
++ ) {
++ this.saveTimeZonePrefrenceData();
++ }
++ },
++ confirmAuthenticate() {
++ this.$v.form.newPassword.$touch();
++ if (this.$v.$invalid) return;
++
++ const username = this.username;
++ const password = this.form.currentPassword;
++
++ this.$store
++ .dispatch('authentication/login', { username, password })
++ .then(() => {
++ this.saveNewPasswordInputData();
++ })
++ .catch(() => {
++ this.$v.$reset();
++ this.errorToast(
++ this.$t('pageProfileSettings.toast.wrongCredentials')
++ );
++ });
+ },
+ },
+ };
+--
+2.25.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue_%.bbappend
index bdd6a3bad..412e88501 100644
--- a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue_%.bbappend
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/webui-vue_%.bbappend
@@ -6,6 +6,7 @@ FILESEXTRAPATHS:append := "${THISDIR}/${PN}:"
SRC_URI += " \
file://login-company-logo.svg \
file://logo-header.svg \
+ file://0001-Old-password-input-in-change-password-screen.patch \
"
do_compile:prepend() {
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/0001-replace-krb5-config-with-pkg-config.patch b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/0001-replace-krb5-config-with-pkg-config.patch
deleted file mode 100644
index a7db1b3c9..000000000
--- a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/0001-replace-krb5-config-with-pkg-config.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From ed70f0623708b8a6c1f58a5d243d87c5ff45b24d Mon Sep 17 00:00:00 2001
-From: Roy Li <rongqing.li@windriver.com>
-Date: Tue, 26 Apr 2016 13:13:01 +0800
-Subject: [PATCH] replace krb5-config with pkg-config
-
-Upstream-Status: Pending
-
-Signed-off-by: Roy Li <rongqing.li@windriver.com>
-
----
- configure.ac | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 5569a26..56b0380 100755
---- a/configure.ac
-+++ b/configure.ac
-@@ -1290,7 +1290,7 @@ AC_ARG_WITH(gssapi,
- fi
- ])
-
--: ${KRB5CONFIG:="$GSSAPI_ROOT/bin/krb5-config"}
-+KRB5CONFIG=`which pkg-config`
-
- save_CPPFLAGS="$CPPFLAGS"
- AC_MSG_CHECKING([if GSS-API support is requested])
-@@ -1301,7 +1301,7 @@ if test x"$want_gss" = xyes; then
- if test -n "$host_alias" -a -f "$GSSAPI_ROOT/bin/$host_alias-krb5-config"; then
- GSSAPI_INCS=`$GSSAPI_ROOT/bin/$host_alias-krb5-config --cflags gssapi`
- elif test -f "$KRB5CONFIG"; then
-- GSSAPI_INCS=`$KRB5CONFIG --cflags gssapi`
-+ GSSAPI_INCS=`$KRB5CONFIG --cflags mit-krb5-gssapi`
- elif test "$GSSAPI_ROOT" != "yes"; then
- GSSAPI_INCS="-I$GSSAPI_ROOT/include"
- fi
-@@ -1394,7 +1394,7 @@ if test x"$want_gss" = xyes; then
- elif test -f "$KRB5CONFIG"; then
- dnl krb5-config doesn't have --libs-only-L or similar, put everything
- dnl into LIBS
-- gss_libs=`$KRB5CONFIG --libs gssapi`
-+ gss_libs=`$KRB5CONFIG --libs mit-krb5-gssapi`
- LIBS="$gss_libs $LIBS"
- else
- case $host in
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32205-cookie-apply-limits.patch b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32205-cookie-apply-limits.patch
deleted file mode 100644
index dc7b59f7f..000000000
--- a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32205-cookie-apply-limits.patch
+++ /dev/null
@@ -1,171 +0,0 @@
-From 48d7064a49148f03942380967da739dcde1cdc24 Mon Sep 17 00:00:00 2001
-From: Daniel Stenberg <daniel@haxx.se>
-Date: Sun, 26 Jun 2022 11:00:48 +0200
-Subject: [PATCH] cookie: apply limits
-
-- Send no more than 150 cookies per request
-- Cap the max length used for a cookie: header to 8K
-- Cap the max number of received Set-Cookie: headers to 50
-
-Bug: https://curl.se/docs/CVE-2022-32205.html
-CVE-2022-32205
-Reported-by: Harry Sintonen
-Closes #9048
----
- lib/cookie.c | 14 ++++++++++++--
- lib/cookie.h | 21 +++++++++++++++++++--
- lib/http.c | 13 +++++++++++--
- lib/urldata.h | 1 +
- 4 files changed, 43 insertions(+), 6 deletions(-)
-
-diff --git a/lib/cookie.c b/lib/cookie.c
-index a308346a777bc..a1ab89532033b 100644
---- a/lib/cookie.c
-+++ b/lib/cookie.c
-@@ -482,6 +482,10 @@ Curl_cookie_add(struct Curl_easy *data,
- (void)data;
- #endif
-
-+ DEBUGASSERT(MAX_SET_COOKIE_AMOUNT <= 255); /* counter is an unsigned char */
-+ if(data->req.setcookies >= MAX_SET_COOKIE_AMOUNT)
-+ return NULL;
-+
- /* First, alloc and init a new struct for it */
- co = calloc(1, sizeof(struct Cookie));
- if(!co)
-@@ -821,7 +825,7 @@ Curl_cookie_add(struct Curl_easy *data,
- freecookie(co);
- return NULL;
- }
--
-+ data->req.setcookies++;
- }
- else {
- /*
-@@ -1375,7 +1379,8 @@ static struct Cookie *dup_cookie(struct Cookie *src)
- *
- * It shall only return cookies that haven't expired.
- */
--struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
-+struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
-+ struct CookieInfo *c,
- const char *host, const char *path,
- bool secure)
- {
-@@ -1430,6 +1435,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
- mainco = newco;
-
- matches++;
-+ if(matches >= MAX_COOKIE_SEND_AMOUNT) {
-+ infof(data, "Included max number of cookies (%u) in request!",
-+ matches);
-+ break;
-+ }
- }
- else
- goto fail;
-diff --git a/lib/cookie.h b/lib/cookie.h
-index 453dfced8a342..abc0a2e8a01ad 100644
---- a/lib/cookie.h
-+++ b/lib/cookie.h
-@@ -83,10 +83,26 @@ struct CookieInfo {
- */
- #define MAX_COOKIE_LINE 5000
-
--/* This is the maximum length of a cookie name or content we deal with: */
-+/* Maximum length of an incoming cookie name or content we deal with. Longer
-+ cookies are ignored. */
- #define MAX_NAME 4096
- #define MAX_NAME_TXT "4095"
-
-+/* Maximum size for an outgoing cookie line libcurl will use in an http
-+ request. This is the default maximum length used in some versions of Apache
-+ httpd. */
-+#define MAX_COOKIE_HEADER_LEN 8190
-+
-+/* Maximum number of cookies libcurl will send in a single request, even if
-+ there might be more cookies that match. One reason to cap the number is to
-+ keep the maximum HTTP request within the maximum allowed size. */
-+#define MAX_COOKIE_SEND_AMOUNT 150
-+
-+/* Maximum number of Set-Cookie: lines accepted in a single response. If more
-+ such header lines are received, they are ignored. This value must be less
-+ than 256 since an unsigned char is used to count. */
-+#define MAX_SET_COOKIE_AMOUNT 50
-+
- struct Curl_easy;
- /*
- * Add a cookie to the internal list of cookies. The domain and path arguments
-@@ -99,7 +115,8 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
- const char *domain, const char *path,
- bool secure);
-
--struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, const char *host,
-+struct Cookie *Curl_cookie_getlist(struct Curl_easy *data,
-+ struct CookieInfo *c, const char *host,
- const char *path, bool secure);
- void Curl_cookie_freelist(struct Cookie *cookies);
- void Curl_cookie_clearall(struct CookieInfo *cookies);
-diff --git a/lib/http.c b/lib/http.c
-index 5284475ba92c4..258722a602e40 100644
---- a/lib/http.c
-+++ b/lib/http.c
-@@ -2711,12 +2711,14 @@ CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
- }
-
- #if !defined(CURL_DISABLE_COOKIES)
-+
- CURLcode Curl_http_cookies(struct Curl_easy *data,
- struct connectdata *conn,
- struct dynbuf *r)
- {
- CURLcode result = CURLE_OK;
- char *addcookies = NULL;
-+ bool linecap = FALSE;
- if(data->set.str[STRING_COOKIE] &&
- !Curl_checkheaders(data, STRCONST("Cookie")))
- addcookies = data->set.str[STRING_COOKIE];
-@@ -2734,7 +2736,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
- !strcmp(host, "127.0.0.1") ||
- !strcmp(host, "[::1]") ? TRUE : FALSE;
- Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
-- co = Curl_cookie_getlist(data->cookies, host, data->state.up.path,
-+ co = Curl_cookie_getlist(data, data->cookies, host, data->state.up.path,
- secure_context);
- Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
- }
-@@ -2748,6 +2750,13 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
- if(result)
- break;
- }
-+ if((Curl_dyn_len(r) + strlen(co->name) + strlen(co->value) + 1) >=
-+ MAX_COOKIE_HEADER_LEN) {
-+ infof(data, "Restricted outgoing cookies due to header size, "
-+ "'%s' not sent", co->name);
-+ linecap = TRUE;
-+ break;
-+ }
- result = Curl_dyn_addf(r, "%s%s=%s", count?"; ":"",
- co->name, co->value);
- if(result)
-@@ -2758,7 +2767,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
- }
- Curl_cookie_freelist(store);
- }
-- if(addcookies && !result) {
-+ if(addcookies && !result && !linecap) {
- if(!count)
- result = Curl_dyn_addn(r, STRCONST("Cookie: "));
- if(!result) {
-diff --git a/lib/urldata.h b/lib/urldata.h
-index 17fe25720be33..bcb4d460c2fe6 100644
---- a/lib/urldata.h
-+++ b/lib/urldata.h
-@@ -698,6 +698,7 @@ struct SingleRequest {
- #ifndef CURL_DISABLE_DOH
- struct dohdata *doh; /* DoH specific data for this request */
- #endif
-+ unsigned char setcookies;
- BIT(header); /* incoming data has HTTP header */
- BIT(content_range); /* set TRUE if Content-Range: was found */
- BIT(upload_done); /* set to TRUE when doing chunked transfer-encoding
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32206-return-error-on-too-many-compression-steps.patch b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32206-return-error-on-too-many-compression-steps.patch
deleted file mode 100644
index bdf3ba35e..000000000
--- a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32206-return-error-on-too-many-compression-steps.patch
+++ /dev/null
@@ -1,48 +0,0 @@
-From 3a09fbb7f264c67c438d01a30669ce325aa508e2 Mon Sep 17 00:00:00 2001
-From: Daniel Stenberg <daniel@haxx.se>
-Date: Mon, 16 May 2022 16:28:13 +0200
-Subject: [PATCH] content_encoding: return error on too many compression steps
-
-The max allowed steps is arbitrarily set to 5.
-
-Bug: https://curl.se/docs/CVE-2022-32206.html
-CVE-2022-32206
-Reported-by: Harry Sintonen
-Closes #9049
----
- lib/content_encoding.c | 9 +++++++++
- 1 file changed, 9 insertions(+)
-
-diff --git a/lib/content_encoding.c b/lib/content_encoding.c
-index c5591ca48ac78..95ba48a2dd563 100644
---- a/lib/content_encoding.c
-+++ b/lib/content_encoding.c
-@@ -1028,12 +1028,16 @@ static const struct content_encoding *find_encoding(const char *name,
- return NULL;
- }
-
-+/* allow no more than 5 "chained" compression steps */
-+#define MAX_ENCODE_STACK 5
-+
- /* Set-up the unencoding stack from the Content-Encoding header value.
- * See RFC 7231 section 3.1.2.2. */
- CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
- const char *enclist, int maybechunked)
- {
- struct SingleRequest *k = &data->req;
-+ int counter = 0;
-
- do {
- const char *name;
-@@ -1068,6 +1072,11 @@ CURLcode Curl_build_unencoding_stack(struct Curl_easy *data,
- if(!encoding)
- encoding = &error_encoding; /* Defer error at stack use. */
-
-+ if(++counter >= MAX_ENCODE_STACK) {
-+ failf(data, "Reject response due to %u content encodings",
-+ counter);
-+ return CURLE_BAD_CONTENT_ENCODING;
-+ }
- /* Stack the unencoding stage. */
- writer = new_unencoding_writer(data, encoding, k->writer_stack);
- if(!writer)
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32207-fopen-add-Curl_fopen-for-better-overwriting-of-fi.patch b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32207-fopen-add-Curl_fopen-for-better-overwriting-of-fi.patch
deleted file mode 100644
index 9b4c128d9..000000000
--- a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32207-fopen-add-Curl_fopen-for-better-overwriting-of-fi.patch
+++ /dev/null
@@ -1,280 +0,0 @@
-From 20f9dd6bae50b7223171b17ba7798946e74f877f Mon Sep 17 00:00:00 2001
-From: Daniel Stenberg <daniel@haxx.se>
-Date: Wed, 25 May 2022 10:09:53 +0200
-Subject: [PATCH] fopen: add Curl_fopen() for better overwriting of files
-
-Bug: https://curl.se/docs/CVE-2022-32207.html
-CVE-2022-32207
-Reported-by: Harry Sintonen
-Closes #9050
----
- CMakeLists.txt | 1 +
- configure.ac | 1 +
- lib/Makefile.inc | 2 +
- lib/cookie.c | 19 ++-----
- lib/curl_config.h.cmake | 3 ++
- lib/fopen.c | 113 ++++++++++++++++++++++++++++++++++++++++
- lib/fopen.h | 30 +++++++++++
- 7 files changed, 154 insertions(+), 15 deletions(-)
- create mode 100644 lib/fopen.c
- create mode 100644 lib/fopen.h
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 45d763d5a9c1d..ad20777f3d688 100644
---- a/CMakeLists.txt
-+++ b/CMakeLists.txt
-@@ -1067,6 +1067,7 @@ elseif(HAVE_LIBSOCKET)
- set(CMAKE_REQUIRED_LIBRARIES socket)
- endif()
-
-+check_symbol_exists(fchmod "${CURL_INCLUDES}" HAVE_FCHMOD)
- check_symbol_exists(basename "${CURL_INCLUDES}" HAVE_BASENAME)
- check_symbol_exists(socket "${CURL_INCLUDES}" HAVE_SOCKET)
- check_symbol_exists(select "${CURL_INCLUDES}" HAVE_SELECT)
-diff --git a/configure.ac b/configure.ac
-index b0245b99a669f..de2dee5a484ed 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -3438,6 +3438,7 @@ AC_CHECK_DECLS([getpwuid_r], [], [AC_DEFINE(HAVE_DECL_GETPWUID_R_MISSING, 1, "Se
-
-
- AC_CHECK_FUNCS([fnmatch \
-+ fchmod \
- geteuid \
- getpass_r \
- getppid \
-diff --git a/lib/Makefile.inc b/lib/Makefile.inc
-index 533e16df97020..9bd8e324bd1c1 100644
---- a/lib/Makefile.inc
-+++ b/lib/Makefile.inc
-@@ -137,6 +137,7 @@ LIB_CFILES = \
- escape.c \
- file.c \
- fileinfo.c \
-+ fopen.c \
- formdata.c \
- ftp.c \
- ftplistparser.c \
-@@ -270,6 +271,7 @@ LIB_HFILES = \
- escape.h \
- file.h \
- fileinfo.h \
-+ fopen.h \
- formdata.h \
- ftp.h \
- ftplistparser.h \
-diff --git a/lib/cookie.c b/lib/cookie.c
-index a1ab89532033b..cb57b86387191 100644
---- a/lib/cookie.c
-+++ b/lib/cookie.c
-@@ -99,8 +99,8 @@ Example set of cookies:
- #include "curl_get_line.h"
- #include "curl_memrchr.h"
- #include "parsedate.h"
--#include "rand.h"
- #include "rename.h"
-+#include "fopen.h"
-
- /* The last 3 #include files should be in this order */
- #include "curl_printf.h"
-@@ -1641,20 +1641,9 @@ static CURLcode cookie_output(struct Curl_easy *data,
- use_stdout = TRUE;
- }
- else {
-- unsigned char randsuffix[9];
--
-- if(Curl_rand_hex(data, randsuffix, sizeof(randsuffix)))
-- return 2;
--
-- tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
-- if(!tempstore)
-- return CURLE_OUT_OF_MEMORY;
--
-- out = fopen(tempstore, FOPEN_WRITETEXT);
-- if(!out) {
-- error = CURLE_WRITE_ERROR;
-+ error = Curl_fopen(data, filename, &out, &tempstore);
-+ if(error)
- goto error;
-- }
- }
-
- fputs("# Netscape HTTP Cookie File\n"
-@@ -1701,7 +1690,7 @@ static CURLcode cookie_output(struct Curl_easy *data,
- if(!use_stdout) {
- fclose(out);
- out = NULL;
-- if(Curl_rename(tempstore, filename)) {
-+ if(tempstore && Curl_rename(tempstore, filename)) {
- unlink(tempstore);
- error = CURLE_WRITE_ERROR;
- goto error;
-diff --git a/lib/curl_config.h.cmake b/lib/curl_config.h.cmake
-index cd4b568d89948..eb2c62b971453 100644
---- a/lib/curl_config.h.cmake
-+++ b/lib/curl_config.h.cmake
-@@ -159,6 +159,9 @@
- /* Define to 1 if you have the <assert.h> header file. */
- #cmakedefine HAVE_ASSERT_H 1
-
-+/* Define to 1 if you have the `fchmod' function. */
-+#cmakedefine HAVE_FCHMOD 1
-+
- /* Define to 1 if you have the `basename' function. */
- #cmakedefine HAVE_BASENAME 1
-
-diff --git a/lib/fopen.c b/lib/fopen.c
-new file mode 100644
-index 0000000000000..ad3691ba9d158
---- /dev/null
-+++ b/lib/fopen.c
-@@ -0,0 +1,113 @@
-+/***************************************************************************
-+ * _ _ ____ _
-+ * Project ___| | | | _ \| |
-+ * / __| | | | |_) | |
-+ * | (__| |_| | _ <| |___
-+ * \___|\___/|_| \_\_____|
-+ *
-+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
-+ *
-+ * This software is licensed as described in the file COPYING, which
-+ * you should have received as part of this distribution. The terms
-+ * are also available at https://curl.se/docs/copyright.html.
-+ *
-+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
-+ * copies of the Software, and permit persons to whom the Software is
-+ * furnished to do so, under the terms of the COPYING file.
-+ *
-+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-+ * KIND, either express or implied.
-+ *
-+ * SPDX-License-Identifier: curl
-+ *
-+ ***************************************************************************/
-+
-+#include "curl_setup.h"
-+
-+#if !defined(CURL_DISABLE_COOKIES) || !defined(CURL_DISABLE_ALTSVC) || \
-+ !defined(CURL_DISABLE_HSTS)
-+
-+#ifdef HAVE_FCNTL_H
-+#include <fcntl.h>
-+#endif
-+
-+#include "urldata.h"
-+#include "rand.h"
-+#include "fopen.h"
-+/* The last 3 #include files should be in this order */
-+#include "curl_printf.h"
-+#include "curl_memory.h"
-+#include "memdebug.h"
-+
-+/*
-+ * Curl_fopen() opens a file for writing with a temp name, to be renamed
-+ * to the final name when completed. If there is an existing file using this
-+ * name at the time of the open, this function will clone the mode from that
-+ * file. if 'tempname' is non-NULL, it needs a rename after the file is
-+ * written.
-+ */
-+CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
-+ FILE **fh, char **tempname)
-+{
-+ CURLcode result = CURLE_WRITE_ERROR;
-+ unsigned char randsuffix[9];
-+ char *tempstore = NULL;
-+ struct_stat sb;
-+ int fd = -1;
-+ *tempname = NULL;
-+
-+ if(stat(filename, &sb) == -1 || !S_ISREG(sb.st_mode)) {
-+ /* a non-regular file, fallback to direct fopen() */
-+ *fh = fopen(filename, FOPEN_WRITETEXT);
-+ if(*fh)
-+ return CURLE_OK;
-+ goto fail;
-+ }
-+
-+ result = Curl_rand_hex(data, randsuffix, sizeof(randsuffix));
-+ if(result)
-+ goto fail;
-+
-+ tempstore = aprintf("%s.%s.tmp", filename, randsuffix);
-+ if(!tempstore) {
-+ result = CURLE_OUT_OF_MEMORY;
-+ goto fail;
-+ }
-+
-+ result = CURLE_WRITE_ERROR;
-+ fd = open(tempstore, O_WRONLY | O_CREAT | O_EXCL, 0600);
-+ if(fd == -1)
-+ goto fail;
-+
-+#ifdef HAVE_FCHMOD
-+ {
-+ struct_stat nsb;
-+ if((fstat(fd, &nsb) != -1) &&
-+ (nsb.st_uid == sb.st_uid) && (nsb.st_gid == sb.st_gid)) {
-+ /* if the user and group are the same, clone the original mode */
-+ if(fchmod(fd, sb.st_mode) == -1)
-+ goto fail;
-+ }
-+ }
-+#endif
-+
-+ *fh = fdopen(fd, FOPEN_WRITETEXT);
-+ if(!*fh)
-+ goto fail;
-+
-+ *tempname = tempstore;
-+ return CURLE_OK;
-+
-+fail:
-+ if(fd != -1) {
-+ close(fd);
-+ unlink(tempstore);
-+ }
-+
-+ free(tempstore);
-+
-+ *tempname = NULL;
-+ return result;
-+}
-+
-+#endif /* ! disabled */
-diff --git a/lib/fopen.h b/lib/fopen.h
-new file mode 100644
-index 0000000000000..289e55f2afd24
---- /dev/null
-+++ b/lib/fopen.h
-@@ -0,0 +1,30 @@
-+#ifndef HEADER_CURL_FOPEN_H
-+#define HEADER_CURL_FOPEN_H
-+/***************************************************************************
-+ * _ _ ____ _
-+ * Project ___| | | | _ \| |
-+ * / __| | | | |_) | |
-+ * | (__| |_| | _ <| |___
-+ * \___|\___/|_| \_\_____|
-+ *
-+ * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
-+ *
-+ * This software is licensed as described in the file COPYING, which
-+ * you should have received as part of this distribution. The terms
-+ * are also available at https://curl.se/docs/copyright.html.
-+ *
-+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
-+ * copies of the Software, and permit persons to whom the Software is
-+ * furnished to do so, under the terms of the COPYING file.
-+ *
-+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
-+ * KIND, either express or implied.
-+ *
-+ * SPDX-License-Identifier: curl
-+ *
-+ ***************************************************************************/
-+
-+CURLcode Curl_fopen(struct Curl_easy *data, const char *filename,
-+ FILE **fh, char **tempname);
-+
-+#endif
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32208-krb5-return-error-properly-on-decode-errors.patch b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32208-krb5-return-error-properly-on-decode-errors.patch
deleted file mode 100644
index be9f52d86..000000000
--- a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/CVE-2022-32208-krb5-return-error-properly-on-decode-errors.patch
+++ /dev/null
@@ -1,64 +0,0 @@
-From 6ecdf5136b52af747e7bda08db9a748256b1cd09 Mon Sep 17 00:00:00 2001
-From: Daniel Stenberg <daniel@haxx.se>
-Date: Thu, 9 Jun 2022 09:27:24 +0200
-Subject: [PATCH] krb5: return error properly on decode errors
-
-Bug: https://curl.se/docs/CVE-2022-32208.html
-CVE-2022-32208
-Reported-by: Harry Sintonen
-Closes #9051
----
- lib/krb5.c | 18 +++++++++++-------
- 1 file changed, 11 insertions(+), 7 deletions(-)
-
-diff --git a/lib/krb5.c b/lib/krb5.c
-index e289595c9e1dd..517491c4658bf 100644
---- a/lib/krb5.c
-+++ b/lib/krb5.c
-@@ -142,11 +142,8 @@ krb5_decode(void *app_data, void *buf, int len,
- enc.value = buf;
- enc.length = len;
- maj = gss_unwrap(&min, *context, &enc, &dec, NULL, NULL);
-- if(maj != GSS_S_COMPLETE) {
-- if(len >= 4)
-- strcpy(buf, "599 ");
-+ if(maj != GSS_S_COMPLETE)
- return -1;
-- }
-
- memcpy(buf, dec.value, dec.length);
- len = curlx_uztosi(dec.length);
-@@ -508,6 +505,7 @@ static CURLcode read_data(struct connectdata *conn,
- {
- int len;
- CURLcode result;
-+ int nread;
-
- result = socket_read(fd, &len, sizeof(len));
- if(result)
-@@ -516,7 +514,10 @@ static CURLcode read_data(struct connectdata *conn,
- if(len) {
- /* only realloc if there was a length */
- len = ntohl(len);
-- buf->data = Curl_saferealloc(buf->data, len);
-+ if(len > CURL_MAX_INPUT_LENGTH)
-+ len = 0;
-+ else
-+ buf->data = Curl_saferealloc(buf->data, len);
- }
- if(!len || !buf->data)
- return CURLE_OUT_OF_MEMORY;
-@@ -524,8 +525,11 @@ static CURLcode read_data(struct connectdata *conn,
- result = socket_read(fd, buf->data, len);
- if(result)
- return result;
-- buf->size = conn->mech->decode(conn->app_data, buf->data, len,
-- conn->data_prot, conn);
-+ nread = conn->mech->decode(conn->app_data, buf->data, len,
-+ conn->data_prot, conn);
-+ if(nread < 0)
-+ return CURLE_RECV_ERROR;
-+ buf->size = (size_t)nread;
- buf->index = 0;
- return CURLE_OK;
- }
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/disable-tests b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/disable-tests
new file mode 100644
index 000000000..92056bd8c
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/disable-tests
@@ -0,0 +1,28 @@
+# These CRL test (alt-avc) are failing
+356
+412
+413
+# These CRL tests are scanning docs
+971
+1119
+1132
+1135
+# These CRL tests are scnning headers
+1167
+# These CRL tests are scanning man pages
+1139
+1140
+1173
+1177
+# This CRL test is looking for m4 files
+1165
+# This CRL test is looking for src files
+1185
+# These CRL tests need --libcurl option to be enabled
+1400
+1401
+1402
+1403
+1404
+1405
+1465
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl/run-ptest b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/run-ptest
new file mode 100644
index 000000000..614e82292
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-support/curl/curl/run-ptest
@@ -0,0 +1,6 @@
+#!/bin/sh
+cd tests
+./runtests.pl -a -n -s | sed \
+ -e 's|\([^ ]* *\) \([^ ]* *\)...OK|PASS: \1 \2|' \
+ -e 's|\([^ ]* *\) \([^ ]* *\)...FAILED|FAIL: \1 \2|' \
+ -e 's/Warning: test[0-9]\+ not present in tests\/data\/Makefile.inc//'
diff --git a/meta-openbmc-mods/meta-common/recipes-support/curl/curl_7.83.1.bb b/meta-openbmc-mods/meta-common/recipes-support/curl/curl_8.1.0.bb
index d20b3194c..0efd0de5c 100644
--- a/meta-openbmc-mods/meta-common/recipes-support/curl/curl_7.83.1.bb
+++ b/meta-openbmc-mods/meta-common/recipes-support/curl/curl_8.1.0.bb
@@ -3,62 +3,66 @@ DESCRIPTION = "It uses URL syntax to transfer data to and from servers. \
curl is a widely used because of its ability to be flexible and complete \
complex tasks. For example, you can use curl for things like user authentication, \
HTTP post, SSL connections, proxy support, FTP uploads, and more!"
-HOMEPAGE = "http://curl.haxx.se/"
-BUGTRACKER = "http://curl.haxx.se/mail/list.cgi?list=curl-tracker"
+HOMEPAGE = "https://curl.se/"
+BUGTRACKER = "https://github.com/curl/curl/issues"
SECTION = "console/network"
-LICENSE = "MIT"
-LIC_FILES_CHKSUM = "file://COPYING;md5=190c514872597083303371684954f238"
-
-SRC_URI = "https://curl.haxx.se/download/curl-${PV}.tar.bz2 \
- file://0001-replace-krb5-config-with-pkg-config.patch \
- file://CVE-2022-32205-cookie-apply-limits.patch \
- file://CVE-2022-32206-return-error-on-too-many-compression-steps.patch \
- file://CVE-2022-32207-fopen-add-Curl_fopen-for-better-overwriting-of-fi.patch \
- file://CVE-2022-32208-krb5-return-error-properly-on-decode-errors.patch \
-"
+LICENSE = "curl"
+LIC_FILES_CHKSUM = "file://COPYING;md5=db8448a1e43eb2125f7740fc397db1f6"
-SRC_URI[sha256sum] = "f539a36fb44a8260ec5d977e4e0dbdd2eee29ed90fcedaa9bc3c9f78a113bff0"
+SRC_URI = " \
+ https://curl.se/download/${BP}.tar.xz \
+ file://run-ptest \
+ file://disable-tests \
+"
+SRC_URI[sha256sum] = "6bd80ad4f07187015911216ee7185b90d285ac5162aed1bded144f9f93232a3c"
# Curl has used many names over the years...
CVE_PRODUCT = "haxx:curl haxx:libcurl curl:curl curl:libcurl libcurl:libcurl daniel_stenberg:curl"
-inherit autotools pkgconfig binconfig multilib_header
+inherit autotools pkgconfig binconfig multilib_header ptest
-PACKAGECONFIG ??= "${@bb.utils.filter('DISTRO_FEATURES', 'ipv6', d)} ssl libidn proxy threaded-resolver verbose zlib"
-PACKAGECONFIG_class-native = "ipv6 proxy ssl threaded-resolver verbose zlib"
-PACKAGECONFIG_class-nativesdk = "ipv6 proxy ssl threaded-resolver verbose zlib"
+# Entropy source for random PACKAGECONFIG option
+RANDOM ?= "/dev/urandom"
+
+PACKAGECONFIG ??= "${@bb.utils.filter('DISTRO_FEATURES', 'ipv6', d)} libidn openssl proxy random threaded-resolver verbose zlib"
+PACKAGECONFIG:class-native = "ipv6 openssl proxy random threaded-resolver verbose zlib"
+PACKAGECONFIG:class-nativesdk = "ipv6 openssl proxy random threaded-resolver verbose zlib"
# 'ares' and 'threaded-resolver' are mutually exclusive
PACKAGECONFIG[ares] = "--enable-ares,--disable-ares,c-ares,,,threaded-resolver"
PACKAGECONFIG[brotli] = "--with-brotli,--without-brotli,brotli"
PACKAGECONFIG[builtinmanual] = "--enable-manual,--disable-manual"
+# Don't use this in production
+PACKAGECONFIG[debug] = "--enable-debug,--disable-debug"
PACKAGECONFIG[dict] = "--enable-dict,--disable-dict,"
PACKAGECONFIG[gnutls] = "--with-gnutls,--without-gnutls,gnutls"
PACKAGECONFIG[gopher] = "--enable-gopher,--disable-gopher,"
PACKAGECONFIG[imap] = "--enable-imap,--disable-imap,"
PACKAGECONFIG[ipv6] = "--enable-ipv6,--disable-ipv6,"
PACKAGECONFIG[krb5] = "--with-gssapi,--without-gssapi,krb5"
-PACKAGECONFIG[ldap] = "--enable-ldap,--disable-ldap,"
-PACKAGECONFIG[ldaps] = "--enable-ldaps,--disable-ldaps,"
+PACKAGECONFIG[ldap] = "--enable-ldap,--disable-ldap,openldap"
+PACKAGECONFIG[ldaps] = "--enable-ldaps,--disable-ldaps,openldap"
PACKAGECONFIG[libgsasl] = "--with-libgsasl,--without-libgsasl,libgsasl"
PACKAGECONFIG[libidn] = "--with-libidn2,--without-libidn2,libidn2"
PACKAGECONFIG[libssh2] = "--with-libssh2,--without-libssh2,libssh2"
PACKAGECONFIG[mbedtls] = "--with-mbedtls=${STAGING_DIR_TARGET},--without-mbedtls,mbedtls"
PACKAGECONFIG[mqtt] = "--enable-mqtt,--disable-mqtt,"
PACKAGECONFIG[nghttp2] = "--with-nghttp2,--without-nghttp2,nghttp2"
+PACKAGECONFIG[openssl] = "--with-openssl,--without-openssl,openssl"
PACKAGECONFIG[pop3] = "--enable-pop3,--disable-pop3,"
PACKAGECONFIG[proxy] = "--enable-proxy,--disable-proxy,"
+PACKAGECONFIG[random] = "--with-random=${RANDOM},--without-random"
PACKAGECONFIG[rtmpdump] = "--with-librtmp,--without-librtmp,rtmpdump"
PACKAGECONFIG[rtsp] = "--enable-rtsp,--disable-rtsp,"
PACKAGECONFIG[smb] = "--enable-smb,--disable-smb,"
PACKAGECONFIG[smtp] = "--enable-smtp,--disable-smtp,"
-PACKAGECONFIG[ssl] = "--with-ssl --with-random=/dev/urandom,--without-ssl,openssl"
PACKAGECONFIG[nss] = "--with-nss,--without-nss,nss"
PACKAGECONFIG[telnet] = "--enable-telnet,--disable-telnet,"
PACKAGECONFIG[tftp] = "--enable-tftp,--disable-tftp,"
PACKAGECONFIG[threaded-resolver] = "--enable-threaded-resolver,--disable-threaded-resolver,,,,ares"
PACKAGECONFIG[verbose] = "--enable-verbose,--disable-verbose"
PACKAGECONFIG[zlib] = "--with-zlib=${STAGING_LIBDIR}/../,--without-zlib,zlib"
+PACKAGECONFIG[zstd] = "--with-zstd,--without-zstd,zstd"
EXTRA_OECONF = " \
--disable-libcurl-option \
@@ -66,9 +70,8 @@ EXTRA_OECONF = " \
--enable-crypto-auth \
--with-ca-bundle=${sysconfdir}/ssl/certs/ca-certificates.crt \
--without-libpsl \
- --enable-debug \
--enable-optimize \
- --disable-curldebug \
+ ${@'--without-ssl' if (bb.utils.filter('PACKAGECONFIG', 'gnutls mbedtls nss openssl', d) == '') else ''} \
"
do_install:append:class-target() {
@@ -77,15 +80,35 @@ do_install:append:class-target() {
-e 's,--sysroot=${STAGING_DIR_TARGET},,g' \
-e 's,--with-libtool-sysroot=${STAGING_DIR_TARGET},,g' \
-e 's|${DEBUG_PREFIX_MAP}||g' \
+ -e 's|${@" ".join(d.getVar("DEBUG_PREFIX_MAP").split())}||g' \
${D}${bindir}/curl-config
}
+do_compile_ptest() {
+ oe_runmake test
+ oe_runmake -C ${B}/tests/server
+}
+
+do_install_ptest() {
+ cat ${WORKDIR}/disable-tests >> ${S}/tests/data/DISABLED
+ rm -f ${B}/tests/configurehelp.pm
+ cp -rf ${B}/tests ${D}${PTEST_PATH}
+ cp -rf ${S}/tests ${D}${PTEST_PATH}
+ find ${D}${PTEST_PATH}/ -type f -name Makefile.am -o -name Makefile.in -o -name Makefile -delete
+ install -d ${D}${PTEST_PATH}/src
+ ln -sf ${bindir}/curl ${D}${PTEST_PATH}/src/curl
+ cp -rf ${D}${bindir}/curl-config ${D}${PTEST_PATH}
+}
+
+RDEPENDS:${PN}-ptest += "bash perl-modules perl-module-time-hires perl-module-digest-md5 \
+ perl-module-digest perl-module-ipc-open2"
+
PACKAGES =+ "lib${BPN}"
-FILES_lib${BPN} = "${libdir}/lib*.so.*"
-RRECOMMENDS_lib${BPN} += "ca-certificates"
+FILES:lib${BPN} = "${libdir}/lib*.so.*"
+RRECOMMENDS:lib${BPN} += "ca-certificates"
-FILES_${PN} += "${datadir}/zsh"
+FILES:${PN} += "${datadir}/zsh"
inherit multilib_script
MULTILIB_SCRIPTS = "${PN}-dev:${bindir}/curl-config"
diff --git a/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-ensure-the-XATTR_NAME_CAPS-is-defined-when-it-is-use.patch b/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-ensure-the-XATTR_NAME_CAPS-is-defined-when-it-is-use.patch
new file mode 100644
index 000000000..05c771ac1
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-ensure-the-XATTR_NAME_CAPS-is-defined-when-it-is-use.patch
@@ -0,0 +1,32 @@
+Ensure the XATTR_NAME_CAPS is defined when it is used
+
+Upstream-Status: Pending
+
+VFS_CAP_U32 can not ensure that XATTR_NAME_CAPS is defined, and failed to build
+libcap-native in old release, like CentOS release 6.7 (Final), with the blow
+error:
+ cap_file.c: In function ‘cap_get_fd’:
+ cap_file.c:199: error: ‘XATTR_NAME_CAPS’ undeclared (first use in this function)
+ cap_file.c:199: error: (Each undeclared identifier is reported only once
+
+Signed-off-by: Roy Li <rongqing.li@windriver.com>
+---
+ libcap/cap_file.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libcap/cap_file.c b/libcap/cap_file.c
+index 40756ea..e27ca80 100644
+--- a/libcap/cap_file.c
++++ b/libcap/cap_file.c
+@@ -25,7 +25,7 @@ extern int fremovexattr(int, const char *);
+
+ #include "libcap.h"
+
+-#ifdef VFS_CAP_U32
++#if defined (VFS_CAP_U32) && defined (XATTR_NAME_CAPS)
+
+ #if VFS_CAP_U32 != __CAP_BLKS
+ # error VFS representation of capabilities is not the same size as kernel
+--
+2.8.1
+
diff --git a/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-nativesdk-libcap-Raise-the-size-of-arrays-containing.patch b/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-nativesdk-libcap-Raise-the-size-of-arrays-containing.patch
new file mode 100644
index 000000000..2ac1e6e56
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0001-nativesdk-libcap-Raise-the-size-of-arrays-containing.patch
@@ -0,0 +1,34 @@
+From 709aa8e156415215b0bb034d05b2aa2f44be044e Mon Sep 17 00:00:00 2001
+From: Hongxu Jia <hongxu.jia@windriver.com>
+Date: Thu, 14 Oct 2021 15:57:36 +0800
+Subject: [PATCH] nativesdk-libcap: Raise the size of arrays containing dl
+ paths
+
+This patch puts the dynamic loader path in the binaries, SYSTEM_DIRS strings
+and lengths as well as ld.so.cache path in the dynamic loader to specific
+sections in memory. The sections that contain paths have been allocated a 4096
+byte section, which is the maximum path length in linux. This will allow the
+relocating script to parse the ELF binary, detect the section and easily replace
+the strings in a certain path.
+
+Upstream-Status: Inappropriate [SDK specific]
+
+Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
+
+---
+ libcap/execable.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libcap/execable.h b/libcap/execable.h
+index fee17b4..5bb0c55 100644
+--- a/libcap/execable.h
++++ b/libcap/execable.h
+@@ -23,7 +23,7 @@
+ #endif
+ #define __EXECABLE_H
+
+-const char __execable_dl_loader[] __attribute((section(".interp"))) =
++const char __execable_dl_loader[4096] __attribute((section(".interp"))) =
+ SHARED_LOADER ;
+
+ static void __execable_parse_args(int *argc_p, char ***argv_p)
diff --git a/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0002-tests-do-not-run-target-executables.patch b/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0002-tests-do-not-run-target-executables.patch
new file mode 100644
index 000000000..20346cf2f
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-support/libcap/files/0002-tests-do-not-run-target-executables.patch
@@ -0,0 +1,30 @@
+From 10212b6d4e8843feffbeab5336342d97f3a46bb2 Mon Sep 17 00:00:00 2001
+From: Alexander Kanavin <alex.kanavin@gmail.com>
+Date: Fri, 20 Dec 2019 16:54:05 +0100
+Subject: [PATCH] tests: do not run target executables
+
+Upstream-Status: Inappropriate [oe-core specific]
+Signed-off-by: Alexander Kanavin <alex.kanavin@gmail.com>
+
+---
+ tests/Makefile | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/tests/Makefile b/tests/Makefile
+index ecb7d1b..8950c73 100644
+--- a/tests/Makefile
++++ b/tests/Makefile
+@@ -61,13 +61,11 @@ endif
+
+ # unprivileged
+ run_psx_test: psx_test
+- ./psx_test
+
+ psx_test: psx_test.c $(DEPS)
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LINKEXTRA) $(LIBPSXLIB)
+
+ run_libcap_psx_test: libcap_psx_test
+- ./libcap_psx_test
+
+ libcap_psx_test: libcap_psx_test.c $(DEPS)
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $< -o $@ $(LINKEXTRA) $(LIBCAPLIB) $(LIBPSXLIB)
diff --git a/meta-openbmc-mods/meta-common/recipes-support/libcap/libcap_2.69.bb b/meta-openbmc-mods/meta-common/recipes-support/libcap/libcap_2.69.bb
new file mode 100644
index 000000000..92fa766d3
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-support/libcap/libcap_2.69.bb
@@ -0,0 +1,79 @@
+SUMMARY = "Library for getting/setting POSIX.1e capabilities"
+DESCRIPTION = "A library providing the API to access POSIX capabilities. \
+These allow giving various kinds of specific privileges to individual \
+users, without giving them full root permissions."
+HOMEPAGE = "http://sites.google.com/site/fullycapable/"
+# no specific GPL version required
+LICENSE = "BSD-3-Clause | GPL-2.0-only"
+LIC_FILES_CHKSUM_PAM = "file://pam_cap/License;md5=905326f41d3d1f8df21943f9a4ed6b50"
+LIC_FILES_CHKSUM = "file://License;md5=2965a646645b72ecee859b43c592dcaa \
+ ${@bb.utils.contains('PACKAGECONFIG', 'pam', '${LIC_FILES_CHKSUM_PAM}', '', d)} \
+ "
+
+DEPENDS = "hostperl-runtime-native gperf-native"
+
+SRC_URI = "${KERNELORG_MIRROR}/linux/libs/security/linux-privs/${BPN}2/${BPN}-${PV}.tar.xz \
+ file://0001-ensure-the-XATTR_NAME_CAPS-is-defined-when-it-is-use.patch \
+ file://0002-tests-do-not-run-target-executables.patch \
+ "
+SRC_URI:append:class-nativesdk = " \
+ file://0001-nativesdk-libcap-Raise-the-size-of-arrays-containing.patch \
+ "
+SRC_URI[sha256sum] = "f311f8f3dad84699d0566d1d6f7ec943a9298b28f714cae3c931dfd57492d7eb"
+
+UPSTREAM_CHECK_URI = "https://www.kernel.org/pub/linux/libs/security/linux-privs/${BPN}2/"
+
+inherit lib_package
+
+PACKAGECONFIG ??= "${@bb.utils.filter('DISTRO_FEATURES', 'pam', d)}"
+PACKAGECONFIG:class-native ??= ""
+
+PACKAGECONFIG[pam] = "PAM_CAP=yes,PAM_CAP=no,libpam"
+
+EXTRA_OEMAKE = " \
+ INDENT= \
+ lib='${baselib}' \
+ RAISE_SETFCAP=no \
+ DYNAMIC=yes \
+ USE_GPERF=yes \
+"
+
+EXTRA_OEMAKE:append:class-target = " SYSTEM_HEADERS=${STAGING_INCDIR}"
+
+do_compile() {
+ unset CFLAGS BUILD_CFLAGS
+ oe_runmake \
+ ${PACKAGECONFIG_CONFARGS} \
+ AR="${AR}" \
+ CC="${CC}" \
+ RANLIB="${RANLIB}" \
+ OBJCOPY="${OBJCOPY}" \
+ COPTS="${CFLAGS}" \
+ BUILD_COPTS="${BUILD_CFLAGS}"
+}
+
+do_install() {
+ oe_runmake install \
+ ${PACKAGECONFIG_CONFARGS} \
+ DESTDIR="${D}" \
+ prefix="${prefix}" \
+ SBINDIR="${sbindir}"
+}
+
+do_install:append() {
+ # Move the library to base_libdir
+ install -d ${D}${base_libdir}
+ if [ ! ${D}${libdir} -ef ${D}${base_libdir} ]; then
+ mv ${D}${libdir}/libcap* ${D}${base_libdir}
+ if [ -d ${D}${libdir}/security ]; then
+ mv ${D}${libdir}/security ${D}${base_libdir}
+ fi
+ fi
+}
+
+FILES:${PN}-dev += "${base_libdir}/*.so"
+
+# pam files
+FILES:${PN} += "${base_libdir}/security/*.so"
+
+BBCLASSEXTEND = "native nativesdk"