forked from Minki/linux
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: Ilja Van Sprundel <ivansprundel@ioactive.com> Suggested-by: Kees Cook <keescook@chromium.org> Signed-off-by: Brooke Basile <brookebasile@gmail.com> Acked-by: Felipe Balbi <balbi@kernel.org> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
f1ec7ae6c9
commit
b1cd1b65af
@ -14,6 +14,7 @@
|
||||
#define __U_F_H__
|
||||
|
||||
#include <linux/usb/gadget.h>
|
||||
#include <linux/overflow.h>
|
||||
|
||||
/* Variable Length Array Macros **********************************************/
|
||||
#define vla_group(groupname) size_t groupname##__next = 0
|
||||
@ -21,21 +22,36 @@
|
||||
|
||||
#define vla_item(groupname, type, name, n) \
|
||||
size_t groupname##_##name##__offset = ({ \
|
||||
size_t align_mask = __alignof__(type) - 1; \
|
||||
size_t offset = (groupname##__next + align_mask) & ~align_mask;\
|
||||
size_t size = (n) * sizeof(type); \
|
||||
groupname##__next = offset + size; \
|
||||
size_t offset = 0; \
|
||||
if (groupname##__next != SIZE_MAX) { \
|
||||
size_t align_mask = __alignof__(type) - 1; \
|
||||
size_t offset = (groupname##__next + align_mask) \
|
||||
& ~align_mask; \
|
||||
size_t size = array_size(n, sizeof(type)); \
|
||||
if (check_add_overflow(offset, size, \
|
||||
&groupname##__next)) { \
|
||||
groupname##__next = SIZE_MAX; \
|
||||
offset = 0; \
|
||||
} \
|
||||
} \
|
||||
offset; \
|
||||
})
|
||||
|
||||
#define vla_item_with_sz(groupname, type, name, n) \
|
||||
size_t groupname##_##name##__sz = (n) * sizeof(type); \
|
||||
size_t groupname##_##name##__offset = ({ \
|
||||
size_t align_mask = __alignof__(type) - 1; \
|
||||
size_t offset = (groupname##__next + align_mask) & ~align_mask;\
|
||||
size_t size = groupname##_##name##__sz; \
|
||||
groupname##__next = offset + size; \
|
||||
offset; \
|
||||
size_t groupname##_##name##__sz = array_size(n, sizeof(type)); \
|
||||
size_t groupname##_##name##__offset = ({ \
|
||||
size_t offset = 0; \
|
||||
if (groupname##__next != SIZE_MAX) { \
|
||||
size_t align_mask = __alignof__(type) - 1; \
|
||||
size_t offset = (groupname##__next + align_mask) \
|
||||
& ~align_mask; \
|
||||
if (check_add_overflow(offset, groupname##_##name##__sz,\
|
||||
&groupname##__next)) { \
|
||||
groupname##__next = SIZE_MAX; \
|
||||
offset = 0; \
|
||||
} \
|
||||
} \
|
||||
offset; \
|
||||
})
|
||||
|
||||
#define vla_ptr(ptr, groupname, name) \
|
||||
|
Loading…
Reference in New Issue
Block a user