summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 08:49:43 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-19 08:49:43 -0700
commite8bf40d154020dd323596933ffaebda7111828fa (patch)
treeb2c80654528fbe8d338111c18c128267d2c69263
parentc36a4991e231242c04141536718d47255ec80887 (diff)
parenta58a57a1076f8c5dae0327e3710899478c3be901 (diff)
Merge tag 'chrome-platform-firmware-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linuxHEADmaster
Pull chrome platform firmware updates from Tzung-Bi Shih: "Fixes: - Don't map no-map memory regions for CBMEM entries - Check bound of coreboot table entries Cleanups: - Fix typo in docs" * tag 'chrome-platform-firmware-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux: firmware: coreboot: Validate table bounds firmware: coreboot: Skip no-map CBMEM entries docs: ABI: testing: Fix typo
-rw-r--r--Documentation/ABI/testing/sysfs-firmware-gsmi2
-rw-r--r--drivers/firmware/google/coreboot_table.c43
2 files changed, 37 insertions, 8 deletions
diff --git a/Documentation/ABI/testing/sysfs-firmware-gsmi b/Documentation/ABI/testing/sysfs-firmware-gsmi
index 7a558354c1ee..3b3c3ae6f458 100644
--- a/Documentation/ABI/testing/sysfs-firmware-gsmi
+++ b/Documentation/ABI/testing/sysfs-firmware-gsmi
@@ -19,7 +19,7 @@ Description:
/sys/firmware/gsmi/vars:
This directory has the same layout (and
- underlying implementation as /sys/firmware/efi/vars.
+ underlying implementation) as /sys/firmware/efi/vars.
See `Documentation/ABI/*/sysfs-firmware-efi-vars`
for more information on how to interact with
this structure.
diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index e63933ff6747..25ee8cf53429 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -13,8 +13,10 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/device-id/coreboot.h>
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -123,7 +125,7 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_
ptr_end = ptr + len;
ptr_entry = ptr + header->header_bytes;
- for (i = 0; i < header->table_entries; i++) {
+ for (i = 0; i < header->table_entries; i++, ptr_entry += entry->size) {
if (ptr_entry + sizeof(*entry) > ptr_end)
return -EINVAL;
entry = ptr_entry;
@@ -147,6 +149,26 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_
switch (device->entry.tag) {
case LB_TAG_CBMEM_ENTRY:
+ /*
+ * Skip entries that are not exclusively System RAM or
+ * Reserved memory.
+ * On ARM64, no-map regions are filtered out as they are
+ * IORESOURCE_MEM (see request_standard_resources() in
+ * arch/arm64/kernel/setup.c).
+ * On x86, CBMEM often resides in standard reserved regions
+ * (IORES_DESC_RESERVED).
+ */
+ if (region_intersects(device->cbmem_entry.address,
+ device->cbmem_entry.entry_size,
+ IORESOURCE_SYSTEM_RAM,
+ IORES_DESC_NONE) != REGION_INTERSECTS &&
+ region_intersects(device->cbmem_entry.address,
+ device->cbmem_entry.entry_size,
+ IORESOURCE_MEM,
+ IORES_DESC_RESERVED) != REGION_INTERSECTS) {
+ kfree(device);
+ continue;
+ }
dev_set_name(&device->dev, "cbmem-%08x",
device->cbmem_entry.id);
break;
@@ -155,8 +177,6 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_
break;
}
- ptr_entry += entry->size;
-
ret = device_register(&device->dev);
if (ret) {
dev_warn(dev, "failed to register coreboot device: %d\n", ret);
@@ -170,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;
@@ -181,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 */
@@ -189,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);