FAILED: patch "[PATCH] cxl/ras: Fix cxl_rch_get_aer_info() out-of-bounds AER" failed to apply to 6.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 29458e62d0829cbc99435f3e44fd560f9bbf1da7
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090316-wildfowl-boasting-efe0@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 29458e62d0829cbc99435f3e44fd560f9bbf1da7 Mon Sep 17 00:00:00 2001
From: Terry Bowman <[email protected]>
Date: Mon, 3 Aug 2026 17:17:57 -0500
Subject: [PATCH] cxl/ras: Fix cxl_rch_get_aer_info() out-of-bounds AER
register read
cxl_rch_get_aer_info() copies the RCH Downstream Port AER capability from the RCRB MMIO block using a readl() loop bounded by sizeof(struct aer_capability_regs). This struct is a software layout and its embedded struct pcie_tlp_log is larger than the on-wire AER capability. As a result the loop reads past the mapped AER register block.
The over-read also populates the software-only tail fields including header_log.header_len. An out-of-range header_len passed to pcie_print_tlp_log() can then loop past the header log buffer and cause a second out-of-bounds read.
The read was correct when introduced, but struct pcie_tlp_log has since grown (Header Log and TLP Prefix Log sizes, header_len and flit fields), so sizeof(struct aer_capability_regs) no longer matches the physical AER capability.
Bound the read to the physical AER registers, header through the 16 byte Header Log. Zero the destination first so the software-only fields are deterministic.
drivers/cxl/core/ras_rch.c +16 -1
@@ -58,13 +58,28 @@ void cxl_disable_rch_root_ints(struct cxl_dport *dport)static bool cxl_rch_get_aer_info (void __iomem *aer_base,struct aer_capability_regs *aer_regs) { -int read_cnt =sizeof (struct aer_capability_regs ) /sizeof (u32); +/* +* Bound the copy to the physically-defined AER registers (header +* through the 16-byte Header Log). struct aer_capability_regs is a +* software layout whose embedded struct pcie_tlp_log is larger than +* the on-wire AER capability; copying sizeof(*aer_regs) would +* over-read the RCRB-mapped MMIO block. +*/ +int read_cnt = (PCI_ERR_HEADER_LOG +16 ) /sizeof (u32);u32 *aer_regs_buf = (u32 *)aer_regs;int n;if (!aer_base)return false; +/* +* Zero the destination so the software-only tail fields +* (e.g. header_log.header_len) are deterministic rather than +* left as uninitialized stack, which could drive a bogus loop +* length in pcie_print_tlp_log(). +*/ +memset (aer_regs,0 ,sizeof (*aer_regs)); +/* Use readl() to guarantee 32-bit accesses */ for (n =0 ; n < read_cnt; n++) aer_regs_buf[n] =readl (aer_base + n *sizeof (u32));
Sasha Levin
maintainerPATCH 1/2 cxl/pci: Move CXL driver's RCH error handling into core/ras_rch.c
From: Terry Bowman <[email protected]>
[ Upstream commit 0ff60f2ec3e4043a442e805f80f8a2445113ec8f ]
Restricted CXL Host (RCH) protocol error handling uses a procedure distinct from the CXL Virtual Hierarchy (VH) handling. This is because of the differences in the RCH and VH topologies. Improve the maintainability and add ability to enable/disable RCH handling.
Move and combine the RCH handling code into a single block conditionally compiled with the CONFIG_CXL_RCH_RAS kernel config.
Stable-dep-of: 29458e62d082 ("cxl/ras: Fix cxl_rch_get_aer_info() out-of-bounds AER register read")
--- drivers/cxl/core/Makefile | 1 + drivers/cxl/core/core.h | 11 +--- drivers/cxl/core/pci.c | 115 ----------------------------------- drivers/cxl/core/ras_rch.c | 121 +++++++++++++++++++++++++++++++++++++ tools/testing/cxl/Kbuild | 1 + 5 files changed, 126 insertions(+), 123 deletions(-) create mode 100644 drivers/cxl/core/ras_rch.c
drivers/cxl/core/Makefile +1 -0
@@ -20,3 +20,4 @@ cxl_core-$(CONFIG_CXL_MCE) += mce.o cxl_core-$(CONFIG_CXL_FEATURES) += features.o cxl_core-$(CONFIG_CXL_EDAC_MEM_FEATURES) += edac.o cxl_core-$(CONFIG_CXL_RAS) += ras.o +cxl_core-$(CONFIG_CXL_RAS) += ras_rch.o
drivers/cxl/core/core.h +3 -8
@@ -149,6 +149,9 @@ int cxl_ras_init(void);void cxl_ras_exit (void );bool cxl_handle_ras (struct cxl_dev_state *cxlds,void __iomem *ras_base);void cxl_handle_cor_ras (struct cxl_dev_state *cxlds,void __iomem *ras_base); +void cxl_dport_map_rch_aer (struct cxl_dport *dport); +void cxl_disable_rch_root_ints (struct cxl_dport *dport); +void cxl_handle_rdport_errors (struct cxl_dev_state *cxlds);#else static inline int cxl_ras_init (void ) {
@@ -164,14 +167,6 @@ static inline bool cxl_handle_ras(struct cxl_dev_state *cxlds, void __iomem *rasreturn false; }static inline void cxl_handle_cor_ras (struct cxl_dev_state *cxlds,void __iomem *ras_base) { } -#endif /* CONFIG_CXL_RAS */ - -/* Restricted CXL Host specific RAS functions */ -#ifdef CONFIG_CXL_RAS -void cxl_dport_map_rch_aer (struct cxl_dport *dport); -void cxl_disable_rch_root_ints (struct cxl_dport *dport); -void cxl_handle_rdport_errors (struct cxl_dev_state *cxlds); -#else static inline void cxl_dport_map_rch_aer (struct cxl_dport *dport) { }static inline void cxl_disable_rch_root_ints (struct cxl_dport *dport) { }static inline void cxl_handle_rdport_errors (struct cxl_dev_state *cxlds) { }
drivers/cxl/core/pci.c +0 -115
121 lines not on this page · raw message
drivers/cxl/core/ras_rch.c new file +121 -0
121 lines not on this page · raw message
tools/testing/cxl/Kbuild +1 -0
@@ -64,6 +64,7 @@ cxl_core-$(CONFIG_CXL_MCE) += $(CXL_CORE_SRC)/mce.o cxl_core-$(CONFIG_CXL_FEATURES) += $(CXL_CORE_SRC)/features.o cxl_core-$(CONFIG_CXL_EDAC_MEM_FEATURES) += $(CXL_CORE_SRC)/edac.o cxl_core-$(CONFIG_CXL_RAS) += $(CXL_CORE_SRC)/ras.o +cxl_core-$(CONFIG_CXL_RAS) += $(CXL_CORE_SRC)/ras_rch.o cxl_core-y += config_check.o cxl_core-y += cxl_core_test.o cxl_core-y += cxl_core_exports.o
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 cxl/ras: Fix cxl_rch_get_aer_info() out-of-bounds AER register read
From: Terry Bowman <[email protected]>
[ Upstream commit 29458e62d0829cbc99435f3e44fd560f9bbf1da7 ]
cxl_rch_get_aer_info() copies the RCH Downstream Port AER capability from the RCRB MMIO block using a readl() loop bounded by sizeof(struct aer_capability_regs). This struct is a software layout and its embedded struct pcie_tlp_log is larger than the on-wire AER capability. As a result the loop reads past the mapped AER register block.
The over-read also populates the software-only tail fields including header_log.header_len. An out-of-range header_len passed to pcie_print_tlp_log() can then loop past the header log buffer and cause a second out-of-bounds read.
The read was correct when introduced, but struct pcie_tlp_log has since grown (Header Log and TLP Prefix Log sizes, header_len and flit fields), so sizeof(struct aer_capability_regs) no longer matches the physical AER capability.
Bound the read to the physical AER registers, header through the 16 byte Header Log. Zero the destination first so the software-only fields are deterministic.
--- drivers/cxl/core/ras_rch.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
drivers/cxl/core/ras_rch.c +16 -1
@@ -58,13 +58,28 @@ void cxl_disable_rch_root_ints(struct cxl_dport *dport)static bool cxl_rch_get_aer_info (void __iomem *aer_base,struct aer_capability_regs *aer_regs) { -int read_cnt =sizeof (struct aer_capability_regs ) /sizeof (u32); +/* +* Bound the copy to the physically-defined AER registers (header +* through the 16-byte Header Log). struct aer_capability_regs is a +* software layout whose embedded struct pcie_tlp_log is larger than +* the on-wire AER capability; copying sizeof(*aer_regs) would +* over-read the RCRB-mapped MMIO block. +*/ +int read_cnt = (PCI_ERR_HEADER_LOG +16 ) /sizeof (u32);u32 *aer_regs_buf = (u32 *)aer_regs;int n;if (!aer_base)return false; +/* +* Zero the destination so the software-only tail fields +* (e.g. header_log.header_len) are deterministic rather than +* left as uninitialized stack, which could drive a bogus loop +* length in pcie_print_tlp_log(). +*/ +memset (aer_regs,0 ,sizeof (*aer_regs)); +/* Use readl() to guarantee 32-bit accesses */ for (n =0 ; n < read_cnt; n++) aer_regs_buf[n] =readl (aer_base + n *sizeof (u32));
Signature · 1 line
2.53.0