firmware: coreboot: Check size of table entry and split memcpy
PATCH v3 1/1 firmware: coreboot: Check size of table entry and split memcpy
The memcpy() of the data following a coreboot_table_entry couldn't be evaluated by the compiler under CONFIG_FORTIFY_SOURCE. To make it easier to reason about, add an explicit flexible array member to struct coreboot_device so the entire entry can be copied at once. Additionally, validate the sizes before copying. Avoids this run-time false positive warning:
memcpy: detected field-spanning write (size 168) of single field "&device->entry" at drivers/firmware/google/coreboot_table.c:103 (size 8)
---
v3: leave memcpy source as ptr_entry (jwerner)
v2: https://lore.kernel.org/lkml/[email protected]
v1: https://lore.kernel.org/lkml/[email protected]
--- drivers/firmware/google/coreboot_table.c | 9 +++++++-- drivers/firmware/google/coreboot_table.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-)
drivers/firmware/google/coreboot_table.c +7 -2
@@ -93,14 +93,19 @@ static int coreboot_table_populate(struct device *dev, void *ptr)for (i =0 ; i < header->table_entries; i++) { entry = ptr_entry; - device =kzalloc (sizeof (struct device ) + entry->size,GFP_KERNEL ); +if (entry->size <sizeof (*entry)) { +dev_warn (dev,"coreboot table entry too small!\n" ); +return -EINVAL ; + } + + device =kzalloc (sizeof (device->dev) + entry->size,GFP_KERNEL );if (!device)return -ENOMEM ; device->dev.parent = dev; device->dev.bus = &coreboot_bus_type; device->dev.release = coreboot_device_release; -memcpy (&device->entry, ptr_entry, entry->size); +memcpy (device->raw, ptr_entry, entry->size);switch (device->entry.tag) {case LB_TAG_CBMEM_ENTRY :
drivers/firmware/google/coreboot_table.h +1 -0
@@ -79,6 +79,7 @@ struct coreboot_device {struct lb_cbmem_ref cbmem_ref;struct lb_cbmem_entry cbmem_entry;struct lb_framebuffer framebuffer; +DECLARE_FLEX_ARRAY (u8, raw); }; };
Signature · 1 line
2.34.1
Quoting Kees Cook (2023-01-12 15:03:16)
Quoted 21 lines
The
memcpy()of the data following acoreboot_table_entrycouldn't be evaluated by the compiler underCONFIG_FORTIFY_SOURCE. To make it easier to reason about, add an explicit flexible array member to structcoreboot_deviceso the entire entry can be copied at once. Additionally, validate the sizes before copying. Avoids this run-time false positive warning:memcpy: detected field-spanning write (size 168) of single field "
&device->entry" atdrivers/firmware/google/coreboot_table.c:103(size 8)Reported-by Paul Menzel <[email protected]>Cc Jack Rosenthal <[email protected]>Cc Guenter Roeck <[email protected]>Cc Julius Werner <[email protected]>Cc Brian Norris <[email protected]>Cc Stephen Boyd <[email protected]>Cc Greg Kroah-Hartman <[email protected]>Signed-off-by Kees Cook <[email protected]>Reviewed-by Julius Werner <[email protected]>Reviewed-by Guenter Roeck <[email protected]>
Quoted 1 line
---
Quoted 21 lines · Kees Cook
The
memcpy()of the data following acoreboot_table_entrycouldn't be evaluated by the compiler underCONFIG_FORTIFY_SOURCE. To make it easier to reason about, add an explicit flexible array member to structcoreboot_deviceso the entire entry can be copied at once. Additionally, validate the sizes before copying. Avoids this run-time false positive warning:memcpy: detected field-spanning write (size 168) of single field "
&device->entry" atdrivers/firmware/google/coreboot_table.c:103(size 8)Reported-by Paul Menzel <[email protected]>Cc Jack Rosenthal <[email protected]>Cc Guenter Roeck <[email protected]>Cc Julius Werner <[email protected]>Cc Brian Norris <[email protected]>Cc Stephen Boyd <[email protected]>Cc Greg Kroah-Hartman <[email protected]>Signed-off-by Kees Cook <[email protected]>Reviewed-by Julius Werner <[email protected]>Reviewed-by Guenter Roeck <[email protected]>
Quoted 1 line
---