This is an effort to get rid of all multiplications from allocation functions in order to prevent integer overflows [1][2]. As the "cmd_buf" variable is a pointer to "struct at76_command" and this structure ends in a flexible array: struct at76_command { [...] u8 data[]; } __packed; the preferred way in the kernel is to use the struct_size() helper to do the arithmetic instead of the calculation "size + count" in the kmalloc() function. Also, declare a new variable (total_size) since the return value of the struct_size() helper is used several times. At the same time, prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). In this case, it is important to note that the attribute used is "__counted_by_le" since the counter type is "__le16". This way, the code is more readable and safer. Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [1] Link: https://github.com/KSPP/linux/issues/160 [2] Signed-off-by: Erick Archer <erick.archer@xxxxxxxxxxx> --- drivers/net/wireless/atmel/at76c50x-usb.c | 12 ++++++------ drivers/net/wireless/atmel/at76c50x-usb.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c index 0ca2f629683d..baa53cfefe48 100644 --- a/drivers/net/wireless/atmel/at76c50x-usb.c +++ b/drivers/net/wireless/atmel/at76c50x-usb.c @@ -721,9 +721,11 @@ static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf, int buf_size) { int ret; - struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) + - buf_size, GFP_KERNEL); + size_t total_size; + struct at76_command *cmd_buf; + total_size = struct_size(cmd_buf, data, buf_size); + cmd_buf = kmalloc(total_size, GFP_KERNEL); if (!cmd_buf) return -ENOMEM; @@ -732,15 +734,13 @@ static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf, cmd_buf->size = cpu_to_le16(buf_size); memcpy(cmd_buf->data, buf, buf_size); - at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size, + at76_dbg_dump(DBG_CMD, cmd_buf, total_size, "issuing command %s (0x%02x)", at76_get_cmd_string(cmd), cmd); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE, - 0, 0, cmd_buf, - sizeof(struct at76_command) + buf_size, - USB_CTRL_GET_TIMEOUT); + 0, 0, cmd_buf, total_size, USB_CTRL_GET_TIMEOUT); kfree(cmd_buf); return ret; } diff --git a/drivers/net/wireless/atmel/at76c50x-usb.h b/drivers/net/wireless/atmel/at76c50x-usb.h index 746e64dfd8aa..843146a0de64 100644 --- a/drivers/net/wireless/atmel/at76c50x-usb.h +++ b/drivers/net/wireless/atmel/at76c50x-usb.h @@ -151,7 +151,7 @@ struct at76_command { u8 cmd; u8 reserved; __le16 size; - u8 data[]; + u8 data[] __counted_by_le(size); } __packed; /* Length of Atmel-specific Rx header before 802.11 frame */ -- 2.25.1