Skip to content

Commit

Permalink
USB: gadget: u_f: add overflow checks to VLA macros
Browse files Browse the repository at this point in the history
commit b1cd1b6 upstream.

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>
  • Loading branch information
brookebasile authored and gregkh committed Sep 3, 2020
1 parent ec5c266 commit 480e178
Showing 1 changed file with 27 additions and 11 deletions.
38 changes: 27 additions & 11 deletions drivers/usb/gadget/u_f.h
Expand Up @@ -14,28 +14,44 @@
#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
#define vla_group_size(groupname) groupname##__next

#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) \
Expand Down

0 comments on commit 480e178

Please sign in to comment.