Skip to content

Commit 69c86dc

Browse files
author
John W. Linville
committed
cxl/region: Avoid null pointer dereference in region lookup
JIRA: https://issues.redhat.com/browse/RHEL-51656 CVE: CVE-2024-41084 cxl_dpa_to_region() looks up a region based on a memdev and DPA. It wrongly assumes an endpoint found mapping the DPA is also of a fully assembled region. When not true it leads to a null pointer dereference looking up the region name. This appears during testing of region lookup after a failure to assemble a BIOS defined region or if the lookup raced with the assembly of the BIOS defined region. Failure to clean up BIOS defined regions that fail assembly is an issue in itself and a fix to that problem will alleviate some of the impact. It will not alleviate the race condition so let's harden this path. The behavior change is that the kernel oops due to a null pointer dereference is replaced with a dev_dbg() message noting that an endpoint was mapped. Additional comments are added so that future users of this function can more clearly understand what it provides. Fixes: 0a105ab ("cxl/memdev: Warn of poison inject or clear to a mapped region") Signed-off-by: Alison Schofield <alison.schofield@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Link: https://patch.msgid.link/20240604003609.202682-1-alison.schofield@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com> (cherry picked from commit 285f2a0) Conflicts: (RHEL9 function in drivers/cxl/core/memdev.c) drivers/cxl/core/region.c Signed-off-by: John W. Linville <linville@redhat.com>
1 parent ffa09cd commit 69c86dc

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

drivers/cxl/core/memdev.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,22 +260,33 @@ static int __cxl_dpa_to_region(struct device *dev, void *arg)
260260
{
261261
struct cxl_dpa_to_region_context *ctx = arg;
262262
struct cxl_endpoint_decoder *cxled;
263+
struct cxl_region *cxlr;
263264
u64 dpa = ctx->dpa;
264265

265266
if (!is_endpoint_decoder(dev))
266267
return 0;
267268

268269
cxled = to_cxl_endpoint_decoder(dev);
269-
if (!cxled->dpa_res || !resource_size(cxled->dpa_res))
270+
if (!cxled || !cxled->dpa_res || !resource_size(cxled->dpa_res))
270271
return 0;
271272

272273
if (dpa > cxled->dpa_res->end || dpa < cxled->dpa_res->start)
273274
return 0;
274275

275-
dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa,
276-
dev_name(&cxled->cxld.region->dev));
276+
/*
277+
* Stop the region search (return 1) when an endpoint mapping is
278+
* found. The region may not be fully constructed so offering
279+
* the cxlr in the context structure is not guaranteed.
280+
*/
281+
cxlr = cxled->cxld.region;
282+
if (cxlr)
283+
dev_dbg(dev, "dpa:0x%llx mapped in region:%s\n", dpa,
284+
dev_name(&cxlr->dev));
285+
else
286+
dev_dbg(dev, "dpa:0x%llx mapped in endpoint:%s\n", dpa,
287+
dev_name(dev));
277288

278-
ctx->cxlr = cxled->cxld.region;
289+
ctx->cxlr = cxlr;
279290

280291
return 1;
281292
}

0 commit comments

Comments
 (0)