Commit b1cd1b65 authored by Brooke Basile's avatar Brooke Basile Committed by Greg Kroah-Hartman

USB: gadget: u_f: add overflow checks to VLA macros

size can potentially hold an overflowed value if its assigned expression
is left unchecked, leading to a smaller than needed allocation when
vla_group_size() is used by callers to allocate memory.
To fix this, add a test for saturation before declaring variables and an
overflow check to (n) * sizeof(type).
If the expression results in overflow, vla_group_size() will return SIZE_MAX.
Reported-by: default avatarIlja Van Sprundel <ivansprundel@ioactive.com>
Suggested-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarBrooke Basile <brookebasile@gmail.com>
Acked-by: default avatarFelipe Balbi <balbi@kernel.org>
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent f1ec7ae6
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#define __U_F_H__ #define __U_F_H__
#include <linux/usb/gadget.h> #include <linux/usb/gadget.h>
#include <linux/overflow.h>
/* Variable Length Array Macros **********************************************/ /* Variable Length Array Macros **********************************************/
#define vla_group(groupname) size_t groupname##__next = 0 #define vla_group(groupname) size_t groupname##__next = 0
...@@ -21,20 +22,35 @@ ...@@ -21,20 +22,35 @@
#define vla_item(groupname, type, name, n) \ #define vla_item(groupname, type, name, n) \
size_t groupname##_##name##__offset = ({ \ size_t groupname##_##name##__offset = ({ \
size_t offset = 0; \
if (groupname##__next != SIZE_MAX) { \
size_t align_mask = __alignof__(type) - 1; \ size_t align_mask = __alignof__(type) - 1; \
size_t offset = (groupname##__next + align_mask) & ~align_mask;\ size_t offset = (groupname##__next + align_mask) \
size_t size = (n) * sizeof(type); \ & ~align_mask; \
groupname##__next = offset + size; \ size_t size = array_size(n, sizeof(type)); \
if (check_add_overflow(offset, size, \
&groupname##__next)) { \
groupname##__next = SIZE_MAX; \
offset = 0; \
} \
} \
offset; \ offset; \
}) })
#define vla_item_with_sz(groupname, type, name, n) \ #define vla_item_with_sz(groupname, type, name, n) \
size_t groupname##_##name##__sz = (n) * sizeof(type); \ size_t groupname##_##name##__sz = array_size(n, sizeof(type)); \
size_t groupname##_##name##__offset = ({ \ size_t groupname##_##name##__offset = ({ \
size_t offset = 0; \
if (groupname##__next != SIZE_MAX) { \
size_t align_mask = __alignof__(type) - 1; \ size_t align_mask = __alignof__(type) - 1; \
size_t offset = (groupname##__next + align_mask) & ~align_mask;\ size_t offset = (groupname##__next + align_mask) \
size_t size = groupname##_##name##__sz; \ & ~align_mask; \
groupname##__next = offset + size; \ if (check_add_overflow(offset, groupname##_##name##__sz,\
&groupname##__next)) { \
groupname##__next = SIZE_MAX; \
offset = 0; \
} \
} \
offset; \ offset; \
}) })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment