[PATCH 18/32] firewire: Use __mem_to_flex_dup() with struct iso_interrupt_event

Kees Cook
2022-05-04T01:56:14Z

As part of the work to perform bounds checking on all memcpy() uses,
replace the open-coded a deserialization of bytes out of memory into a
trailing flexible array by using a flex_array.h helper to perform the
allocation, bounds checking, and copying.

Cc: Stefan Richter <stefanr@s5r6.in-berlin.de>
Cc: linux1394-devel@lists.sourceforge.net
Signed-off-by: Kees Cook <keescook@chromium.org>
---
drivers/firewire/core-cdev.c | 7 ++-----
include/uapi/linux/firewire-cdev.h | 4 ++--
2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index c9fe5903725a..7e884c61e12e 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -913,17 +913,14 @@ static void iso_callback(struct fw_iso_context *context, u32 cycle,
size_t header_length, void *header, void *data)
{
struct client *client = data;
- struct iso_interrupt_event *e;
+ struct iso_interrupt_event *e = NULL;

- e = kmalloc(sizeof(*e) + header_length, GFP_ATOMIC);
- if (e == NULL)
+ if (__mem_to_flex_dup(&e, .interrupt, header, header_length, GFP_ATOMIC))
return;

e->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
e->interrupt.closure = client->iso_closure;
e->interrupt.cycle = cycle;
- e->interrupt.header_length = header_length;
- memcpy(e->interrupt.header, header, header_length);
queue_event(client, &e->event, &e->interrupt,
sizeof(e->interrupt) + header_length, NULL, 0);
}
diff --git a/include/uapi/linux/firewire-cdev.h b/include/uapi/linux/firewire-cdev.h
index 5effa9832802..22c5f59e9dfa 100644
--- a/include/uapi/linux/firewire-cdev.h
+++ b/include/uapi/linux/firewire-cdev.h
@@ -264,8 +264,8 @@ struct fw_cdev_event_iso_interrupt {
__u64 closure;
__u32 type;
__u32 cycle;
- __u32 header_length;
- __u32 header[0];
+ __DECLARE_FLEX_ARRAY_ELEMENTS_COUNT(__u32, header_length);
+ __DECLARE_FLEX_ARRAY_ELEMENTS(__u32, header);
};

/**
--
2.32.0