linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] firmware: coreboot: Check size of table entry and split memcpy
@ 2023-01-07  3:14 Kees Cook
  2023-01-07  4:39 ` Guenter Roeck
  2023-01-09 15:02 ` Julius Werner
  0 siblings, 2 replies; 4+ messages in thread
From: Kees Cook @ 2023-01-07  3:14 UTC (permalink / raw)
  To: Jack Rosenthal
  Cc: Kees Cook, Paul Menzel, Guenter Roeck, Julius Werner,
	Brian Norris, Stephen Boyd, Greg Kroah-Hartman, linux-kernel,
	linux-hardening

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)

Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
Link: https://lore.kernel.org/all/03ae2704-8c30-f9f0-215b-7cdf4ad35a9a@molgen.mpg.de/
Cc: Jack Rosenthal <jrosenth@chromium.org>
Cc: Guenter Roeck <groeck@chromium.org>
Cc: Julius Werner <jwerner@chromium.org>
Cc: Brian Norris <briannorris@chromium.org>
Cc: Stephen Boyd <swboyd@chromium.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
---
v2: move flex array to struct coreboot_device (julius)
v1: https://lore.kernel.org/lkml/20230106045327.never.413-kees@kernel.org
---
 drivers/firmware/google/coreboot_table.c | 9 +++++++--
 drivers/firmware/google/coreboot_table.h | 1 +
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
index 2652c396c423..564a3c908838 100644
--- a/drivers/firmware/google/coreboot_table.c
+++ b/drivers/firmware/google/coreboot_table.c
@@ -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, entry, entry->size);
 
 		switch (device->entry.tag) {
 		case LB_TAG_CBMEM_ENTRY:
diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h
index 37f4d335a606..d814dca33a08 100644
--- a/drivers/firmware/google/coreboot_table.h
+++ b/drivers/firmware/google/coreboot_table.h
@@ -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);
 	};
 };
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] firmware: coreboot: Check size of table entry and split memcpy
  2023-01-07  3:14 [PATCH v2] firmware: coreboot: Check size of table entry and split memcpy Kees Cook
@ 2023-01-07  4:39 ` Guenter Roeck
  2023-01-09 15:02 ` Julius Werner
  1 sibling, 0 replies; 4+ messages in thread
From: Guenter Roeck @ 2023-01-07  4:39 UTC (permalink / raw)
  To: Kees Cook
  Cc: Jack Rosenthal, Paul Menzel, Guenter Roeck, Julius Werner,
	Brian Norris, Stephen Boyd, Greg Kroah-Hartman, linux-kernel,
	linux-hardening

On Fri, Jan 6, 2023 at 7:14 PM Kees Cook <keescook@chromium.org> wrote:
>
> 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)
>
> Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
> Link: https://lore.kernel.org/all/03ae2704-8c30-f9f0-215b-7cdf4ad35a9a@molgen.mpg.de/
> Cc: Jack Rosenthal <jrosenth@chromium.org>
> Cc: Guenter Roeck <groeck@chromium.org>
> Cc: Julius Werner <jwerner@chromium.org>
> Cc: Brian Norris <briannorris@chromium.org>
> Cc: Stephen Boyd <swboyd@chromium.org>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Signed-off-by: Kees Cook <keescook@chromium.org>

Reviewed-by: Guenter Roeck <groeck@chromium.org>

> ---
> v2: move flex array to struct coreboot_device (julius)
> v1: https://lore.kernel.org/lkml/20230106045327.never.413-kees@kernel.org
> ---
>  drivers/firmware/google/coreboot_table.c | 9 +++++++--
>  drivers/firmware/google/coreboot_table.h | 1 +
>  2 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c
> index 2652c396c423..564a3c908838 100644
> --- a/drivers/firmware/google/coreboot_table.c
> +++ b/drivers/firmware/google/coreboot_table.c
> @@ -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, entry, entry->size);
>
>                 switch (device->entry.tag) {
>                 case LB_TAG_CBMEM_ENTRY:
> diff --git a/drivers/firmware/google/coreboot_table.h b/drivers/firmware/google/coreboot_table.h
> index 37f4d335a606..d814dca33a08 100644
> --- a/drivers/firmware/google/coreboot_table.h
> +++ b/drivers/firmware/google/coreboot_table.h
> @@ -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);
>         };
>  };
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] firmware: coreboot: Check size of table entry and split memcpy
  2023-01-07  3:14 [PATCH v2] firmware: coreboot: Check size of table entry and split memcpy Kees Cook
  2023-01-07  4:39 ` Guenter Roeck
@ 2023-01-09 15:02 ` Julius Werner
  2023-01-12 23:00   ` Kees Cook
  1 sibling, 1 reply; 4+ messages in thread
From: Julius Werner @ 2023-01-09 15:02 UTC (permalink / raw)
  To: Kees Cook
  Cc: Jack Rosenthal, Paul Menzel, Guenter Roeck, Julius Werner,
	Brian Norris, Stephen Boyd, Greg Kroah-Hartman, linux-kernel,
	linux-hardening

Reviewed-by: Julius Werner <jwerner@chromium.org>

> -               memcpy(&device->entry, ptr_entry, entry->size);
> +               memcpy(device->raw, entry, entry->size);

nit: It's a bit odd to change the source pointer from ptr_entry to
entry here. Technically the static analyzer would be within its rights
to give you a warning for that as well, because you're now
"overrunning" the source struct instead of the destination one.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] firmware: coreboot: Check size of table entry and split memcpy
  2023-01-09 15:02 ` Julius Werner
@ 2023-01-12 23:00   ` Kees Cook
  0 siblings, 0 replies; 4+ messages in thread
From: Kees Cook @ 2023-01-12 23:00 UTC (permalink / raw)
  To: Julius Werner
  Cc: Jack Rosenthal, Paul Menzel, Guenter Roeck, Brian Norris,
	Stephen Boyd, Greg Kroah-Hartman, linux-kernel, linux-hardening

On Mon, Jan 09, 2023 at 04:02:26PM +0100, Julius Werner wrote:
> Reviewed-by: Julius Werner <jwerner@chromium.org>
> 
> > -               memcpy(&device->entry, ptr_entry, entry->size);
> > +               memcpy(device->raw, entry, entry->size);
> 
> nit: It's a bit odd to change the source pointer from ptr_entry to
> entry here. Technically the static analyzer would be within its rights
> to give you a warning for that as well, because you're now
> "overrunning" the source struct instead of the destination one.

True. We've been focused on write overflows, but yeah, since the
location of the flex array changed, I'll switch this back to ptr_entry.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-01-12 23:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-07  3:14 [PATCH v2] firmware: coreboot: Check size of table entry and split memcpy Kees Cook
2023-01-07  4:39 ` Guenter Roeck
2023-01-09 15:02 ` Julius Werner
2023-01-12 23:00   ` Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).