On Fri, Sep 23, 2022 at 01:28:07PM -0700, Kees Cook wrote:
The __malloc attribute should not be applied to "realloc" functions, as the returned pointer may alias the storage of the prior pointer. Instead of splitting __malloc from __alloc_size, which would be a huge amount of churn, just create __realloc_size for the few cases where it is needed.
Additionally removes the conditional test for __alloc_size__, which is always defined now.
Cc: Christoph Lameter cl@linux.com Cc: Pekka Enberg penberg@kernel.org Cc: David Rientjes rientjes@google.com Cc: Joonsoo Kim iamjoonsoo.kim@lge.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Vlastimil Babka vbabka@suse.cz Cc: Roman Gushchin roman.gushchin@linux.dev Cc: Hyeonggon Yoo 42.hyeyoo@gmail.com Cc: Marco Elver elver@google.com Cc: linux-mm@kvack.org Signed-off-by: Kees Cook keescook@chromium.org
include/linux/compiler_types.h | 13 +++++-------- include/linux/slab.h | 12 ++++++------ mm/slab_common.c | 4 ++-- 3 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index 4f2a819fd60a..f141a6f6b9f6 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -271,15 +271,12 @@ struct ftrace_likely_data { /*
- Any place that could be marked with the "alloc_size" attribute is also
- a place to be marked with the "malloc" attribute. Do this as part of the
- __alloc_size macro to avoid redundant attributes and to avoid missing a
- __malloc marking.
- a place to be marked with the "malloc" attribute, except those that may
- be performing a _reallocation_, as that may alias the existing pointer.
*/
- For these, use __realloc_size().
-#ifdef __alloc_size__ -# define __alloc_size(x, ...) __alloc_size__(x, ## __VA_ARGS__) __malloc -#else -# define __alloc_size(x, ...) __malloc -#endif +#define __alloc_size(x, ...) __alloc_size__(x, ## __VA_ARGS__) __malloc +#define __realloc_size(x, ...) __alloc_size__(x, ## __VA_ARGS__) #ifndef asm_volatile_goto #define asm_volatile_goto(x...) asm goto(x) diff --git a/include/linux/slab.h b/include/linux/slab.h index 0fefdf528e0d..41bd036e7551 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -184,7 +184,7 @@ int kmem_cache_shrink(struct kmem_cache *s); /*
- Common kmalloc functions provided by all allocators
*/ -void * __must_check krealloc(const void *objp, size_t new_size, gfp_t flags) __alloc_size(2); +void * __must_check krealloc(const void *objp, size_t new_size, gfp_t flags) __realloc_size(2); void kfree(const void *objp); void kfree_sensitive(const void *objp); size_t __ksize(const void *objp); @@ -647,10 +647,10 @@ static inline __alloc_size(1, 2) void *kmalloc_array(size_t n, size_t size, gfp_
- @new_size: new size of a single member of the array
- @flags: the type of memory to allocate (see kmalloc)
*/ -static inline __alloc_size(2, 3) void * __must_check krealloc_array(void *p,
size_t new_n,
size_t new_size,
gfp_t flags)
+static inline __realloc_size(2, 3) void * __must_check krealloc_array(void *p,
size_t new_n,
size_t new_size,
gfp_t flags)
{ size_t bytes; @@ -774,7 +774,7 @@ static inline __alloc_size(1, 2) void *kvcalloc(size_t n, size_t size, gfp_t fla } extern void *kvrealloc(const void *p, size_t oldsize, size_t newsize, gfp_t flags)
__alloc_size(3);
__realloc_size(3);
extern void kvfree(const void *addr); extern void kvfree_sensitive(const void *addr, size_t len); diff --git a/mm/slab_common.c b/mm/slab_common.c index 17996649cfe3..457671ace7eb 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -1134,8 +1134,8 @@ module_init(slab_proc_init); #endif /* CONFIG_SLAB || CONFIG_SLUB_DEBUG */ -static __always_inline void *__do_krealloc(const void *p, size_t new_size,
gfp_t flags)
+static __always_inline __realloc_size(2) void * +__do_krealloc(const void *p, size_t new_size, gfp_t flags) { void *ret; size_t ks; -- 2.34.1
This is now squashed with later one. (so undefined __alloc_size__ issues are fixed) for the latest version of this patch:
Looks good to me, Acked-by: Hyeonggon Yoo 42.hyeyoo@gmail.com