firmware: coreboot: Validate table bounds

The existing coreboot_table_populate() bounds checks limit individual
entries to the mapped length.  However, coreboot_table_probe() replaces
the platform resource length with header and table sizes supplied by
firmware before mapping the full table.

A malformed table can overflow the 32-bit size addition or advertise an
extent beyond the resource, causing the driver to map and parse memory
outside the resource.  A resource shorter than the fixed header is also
mapped as though it contained a complete header.

Reject resources shorter than the fixed header.  After validating the
signature, require a complete header, calculate the advertised extent
with overflow checking, and reject extents beyond the resource before
remapping the table.

Fixes: d384d6f43d ("firmware: google memconsole: Add coreboot support")
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Link: https://lore.kernel.org/r/20260801165651.42172-1-acharyalaxman8848@gmail.com
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
This commit is contained in:
Laxman Acharya Padhya
2026-08-03 03:00:21 +00:00
committed by Tzung-Bi Shih
parent e31ecda9e3
commit a58a57a107
+13 -4
View File
@@ -190,6 +190,7 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_
static int coreboot_table_probe(struct platform_device *pdev)
{
resource_size_t len;
resource_size_t table_span;
struct coreboot_table_header *header;
struct resource *res;
struct device *dev = &pdev->dev;
@@ -201,7 +202,7 @@ static int coreboot_table_probe(struct platform_device *pdev)
return -EINVAL;
len = resource_size(res);
if (!res->start || !len)
if (!res->start || len < sizeof(*header))
return -EINVAL;
/* Check just the header first to make sure things are sane */
@@ -209,19 +210,27 @@ static int coreboot_table_probe(struct platform_device *pdev)
if (!header)
return -ENOMEM;
len = header->header_bytes + header->table_bytes;
ret = strncmp(header->signature, "LBIO", sizeof(header->signature));
if (!ret &&
(header->header_bytes < sizeof(*header) ||
check_add_overflow((resource_size_t)header->header_bytes,
(resource_size_t)header->table_bytes,
&table_span) ||
table_span > len))
ret = -EINVAL;
memunmap(header);
if (ret) {
dev_warn(dev, "coreboot table missing or corrupt!\n");
return -ENODEV;
}
ptr = memremap(res->start, len, MEMREMAP_WB);
ptr = memremap(res->start, table_span, MEMREMAP_WB);
if (!ptr)
return -ENOMEM;
ret = coreboot_table_populate(dev, ptr, len);
ret = coreboot_table_populate(dev, ptr, table_span);
memunmap(ptr);