[PATCH 6/8] cxl/cdat: Fix uninitialized stack use in endpoint bandwidth gathering

Guixin Liu <[email protected]>
Newsgroups org.kernel.vger.linux-cxl
Message-ID <[email protected]>
cxl_endpoint_gather_bandwidth() combines the endpoint's upstream link
bandwidth with the bandwidth from the endpoint CDAT into an uninitialized
on-stack array:

	struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX];
	...
	cxl_coordinates_combine(ep_coord, pci_coord, perf->cdat_coord);

__cxl_coordinates_combine() only assigns the output bandwidth when both
inputs are non-zero:

	if (c1->write_bandwidth && c2->write_bandwidth)
		out->write_bandwidth = min(...);

That form is intended for the chained 'out == c1' calls that follow, but on
this first call @out is fresh stack. A device whose CDAT DSLBIS does not
report a bandwidth for an access class leaves the corresponding ep_coord
entry untouched, and cxl_bandwidth_add() then accumulates that stack
residue into the region coordinates that are published through the region's
sysfs access coordinate attributes.

pci_coord and sw_coord are less severe but still wrong. Their producers,
cxl_pci_get_bandwidth() and cxl_port_get_switch_dport_bandwidth(), only
fill in the read/write bandwidth fields, so the latency terms are read
uninitialized by the unconditional read_latency and write_latency sums in
the same helper. cxl_bandwidth_add() propagates only bandwidth, so those
sums are discarded rather than published, but the reads themselves are
still undefined behaviour.

Zero initialize all three, which also makes an unreported bandwidth read
back as 0, the value the rest of the CXL performance code already uses to
mean "unknown".

Fixes: a5ab0de0ebaa ("cxl: Calculate region bandwidth of targets with shared upstream link")
Signed-off-by: Guixin Liu <[email protected]>
---
 drivers/cxl/core/cdat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
index 5c9f07262513..3c6a1537f89b 100644
--- a/drivers/cxl/core/cdat.c
+++ b/drivers/cxl/core/cdat.c
@@ -633,9 +633,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr,
 	struct cxl_port *endpoint = to_cxl_port(cxled->cxld.dev.parent);
 	struct cxl_port *parent_port = to_cxl_port(endpoint->dev.parent);
 	struct cxl_port *gp_port = to_cxl_port(parent_port->dev.parent);
-	struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX];
-	struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX];
-	struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX];
+	struct access_coordinate pci_coord[ACCESS_COORDINATE_MAX] = { };
+	struct access_coordinate sw_coord[ACCESS_COORDINATE_MAX] = { };
+	struct access_coordinate ep_coord[ACCESS_COORDINATE_MAX] = { };
 	struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
 	struct cxl_dev_state *cxlds = cxlmd->cxlds;
 	struct pci_dev *pdev = to_pci_dev(cxlds->dev);
-- 
2.43.7
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.