diff options
author | Kees Cook <keescook@chromium.org> | 2018-05-08 15:52:32 -0400 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2018-06-05 15:16:51 -0400 |
commit | 49b7f8983aa78581bfd511a26891b26cd734e293 (patch) | |
tree | e897c47ee7eacb557d129287451e736cb345ae8d | |
parent | ca90800a91ba723d78ded634d037c1d2df8b54d6 (diff) |
mm: Use overflow helpers in kmalloc_array*()
Instead of open-coded multiplication and bounds checking, use the new
overflow helper.
Suggested-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r-- | include/linux/slab.h | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/include/linux/slab.h b/include/linux/slab.h index 81ebd71f8c03..4d759e1ddc33 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #define _LINUX_SLAB_H | 13 | #define _LINUX_SLAB_H |
14 | 14 | ||
15 | #include <linux/gfp.h> | 15 | #include <linux/gfp.h> |
16 | #include <linux/overflow.h> | ||
16 | #include <linux/types.h> | 17 | #include <linux/types.h> |
17 | #include <linux/workqueue.h> | 18 | #include <linux/workqueue.h> |
18 | 19 | ||
@@ -624,11 +625,13 @@ int memcg_update_all_caches(int num_memcgs); | |||
624 | */ | 625 | */ |
625 | static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) | 626 | static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) |
626 | { | 627 | { |
627 | if (size != 0 && n > SIZE_MAX / size) | 628 | size_t bytes; |
629 | |||
630 | if (unlikely(check_mul_overflow(n, size, &bytes))) | ||
628 | return NULL; | 631 | return NULL; |
629 | if (__builtin_constant_p(n) && __builtin_constant_p(size)) | 632 | if (__builtin_constant_p(n) && __builtin_constant_p(size)) |
630 | return kmalloc(n * size, flags); | 633 | return kmalloc(bytes, flags); |
631 | return __kmalloc(n * size, flags); | 634 | return __kmalloc(bytes, flags); |
632 | } | 635 | } |
633 | 636 | ||
634 | /** | 637 | /** |
@@ -657,11 +660,13 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long); | |||
657 | static inline void *kmalloc_array_node(size_t n, size_t size, gfp_t flags, | 660 | static inline void *kmalloc_array_node(size_t n, size_t size, gfp_t flags, |
658 | int node) | 661 | int node) |
659 | { | 662 | { |
660 | if (size != 0 && n > SIZE_MAX / size) | 663 | size_t bytes; |
664 | |||
665 | if (unlikely(check_mul_overflow(n, size, &bytes))) | ||
661 | return NULL; | 666 | return NULL; |
662 | if (__builtin_constant_p(n) && __builtin_constant_p(size)) | 667 | if (__builtin_constant_p(n) && __builtin_constant_p(size)) |
663 | return kmalloc_node(n * size, flags, node); | 668 | return kmalloc_node(bytes, flags, node); |
664 | return __kmalloc_node(n * size, flags, node); | 669 | return __kmalloc_node(bytes, flags, node); |
665 | } | 670 | } |
666 | 671 | ||
667 | static inline void *kcalloc_node(size_t n, size_t size, gfp_t flags, int node) | 672 | static inline void *kcalloc_node(size_t n, size_t size, gfp_t flags, int node) |