diff options
Diffstat (limited to 'include/linux/slab.h')
| -rw-r--r-- | include/linux/slab.h | 18 | 
1 files changed, 12 insertions, 6 deletions
diff --git a/include/linux/slab.h b/include/linux/slab.h index 81ebd71f8c03..14e3fe4bd6a1 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -13,6 +13,7 @@  #define	_LINUX_SLAB_H  #include <linux/gfp.h> +#include <linux/overflow.h>  #include <linux/types.h>  #include <linux/workqueue.h> @@ -599,6 +600,7 @@ struct memcg_cache_params {  			struct memcg_cache_array __rcu *memcg_caches;  			struct list_head __root_caches_node;  			struct list_head children; +			bool dying;  		};  		struct {  			struct mem_cgroup *memcg; @@ -624,11 +626,13 @@ int memcg_update_all_caches(int num_memcgs);   */  static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)  { -	if (size != 0 && n > SIZE_MAX / size) +	size_t bytes; + +	if (unlikely(check_mul_overflow(n, size, &bytes)))  		return NULL;  	if (__builtin_constant_p(n) && __builtin_constant_p(size)) -		return kmalloc(n * size, flags); -	return __kmalloc(n * size, flags); +		return kmalloc(bytes, flags); +	return __kmalloc(bytes, flags);  }  /** @@ -657,11 +661,13 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long);  static inline void *kmalloc_array_node(size_t n, size_t size, gfp_t flags,  				       int node)  { -	if (size != 0 && n > SIZE_MAX / size) +	size_t bytes; + +	if (unlikely(check_mul_overflow(n, size, &bytes)))  		return NULL;  	if (__builtin_constant_p(n) && __builtin_constant_p(size)) -		return kmalloc_node(n * size, flags, node); -	return __kmalloc_node(n * size, flags, node); +		return kmalloc_node(bytes, flags, node); +	return __kmalloc_node(bytes, flags, node);  }  static inline void *kcalloc_node(size_t n, size_t size, gfp_t flags, int node)  |