Hi Kees, On Fri, Sep 23, 2022 at 10:35 PM Kees Cook <keescook@xxxxxxxxxxxx> 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@xxxxxxxxx> > Cc: Pekka Enberg <penberg@xxxxxxxxxx> > Cc: David Rientjes <rientjes@xxxxxxxxxx> > Cc: Joonsoo Kim <iamjoonsoo.kim@xxxxxxx> > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> > Cc: Vlastimil Babka <vbabka@xxxxxxx> > Cc: Roman Gushchin <roman.gushchin@xxxxxxxxx> > Cc: Hyeonggon Yoo <42.hyeyoo@xxxxxxxxx> > Cc: Marco Elver <elver@xxxxxxxxxx> > Cc: linux-mm@xxxxxxxxx > Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> Thanks for your patch, which is now commit 63caa04ec60583b1 ("slab: Remove __malloc attribute from realloc functions") in next-20220927. Noreply@xxxxxxxxxxxxxx reported all gcc8-based builds to fail (e.g. [1], more at [2]): In file included from <command-line>: ./include/linux/percpu.h: In function ‘__alloc_reserved_percpu’: ././include/linux/compiler_types.h:279:30: error: expected declaration specifiers before ‘__alloc_size__’ #define __alloc_size(x, ...) __alloc_size__(x, ## __VA_ARGS__) __malloc ^~~~~~~~~~~~~~ ./include/linux/percpu.h:120:74: note: in expansion of macro ‘__alloc_size’ [...] It's building fine with e.g. gcc-9 (which is my usual m68k cross-compiler). Reverting this commit on next-20220927 fixes the issue. [1] http://kisskb.ellerman.id.au/kisskb/buildresult/14803908/ [2] http://kisskb.ellerman.id.au/kisskb/head/1bd8b75fe6adeaa89d02968bdd811ffe708cf839/ > --- > 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 > -- Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds