From: Ahmad Fatoum <ahmad@xxxxxx> We already use __alloc_size and __realloc_size in <malloc.h>, so GCC can warn about some types of memory safety issues at build-time. Let's have the same for xfuncs.h as well and additionally specify __returns_nonnull, so the compiler could provide better diagnostics. Signed-off-by: Ahmad Fatoum <ahmad@xxxxxx> --- v1 -> v2: - spell attribute the same in __has_attribute and __attribute__ - drop __returns_nonnull from strdup style functions that return NULL if the argument is NULL --- include/linux/compiler_types.h | 9 +++++++++ include/xfuncs.h | 17 +++++++++-------- scripts/include/linux/compiler.h | 9 +++++++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index d925b3da296d..a713459f6e47 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -157,6 +157,12 @@ struct ftrace_likely_data { # define __no_stack_protector #endif +#if __has_attribute(__returns_nonnull__) +#define __returns_nonnull __attribute__((__returns_nonnull__)) +#else +#define __returns_nonnull +#endif + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ @@ -212,6 +218,9 @@ struct ftrace_likely_data { # define __realloc_size(x, ...) #endif +# define __xalloc_size(args...) __returns_nonnull __alloc_size(args) +# define __xrealloc_size(args...) __returns_nonnull __realloc_size(args) + /* Are two types/vars the same type (ignoring qualifiers)? */ #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) diff --git a/include/xfuncs.h b/include/xfuncs.h index a9132d378722..60ec220bd9b8 100644 --- a/include/xfuncs.h +++ b/include/xfuncs.h @@ -3,18 +3,19 @@ #define __XFUNCS_H #include <linux/types.h> +#include <linux/compiler.h> #include <stdarg.h> #include <wchar.h> -void *xmalloc(size_t size); -void *xrealloc(void *ptr, size_t size); -void *xzalloc(size_t size); +void *xmalloc(size_t size) __xalloc_size(1); +void *xrealloc(void *ptr, size_t size) __xrealloc_size(2); +void *xzalloc(size_t size) __xalloc_size(1); char *xstrdup(const char *s); -char *xstrndup(const char *s, size_t size); -void* xmemalign(size_t alignment, size_t bytes); -void* xmemdup(const void *orig, size_t size); -char *xasprintf(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2))); -char *xvasprintf(const char *fmt, va_list ap); +char *xstrndup(const char *s, size_t size) __returns_nonnull; +void* xmemalign(size_t alignment, size_t bytes) __xalloc_size(2); +void* xmemdup(const void *orig, size_t size) __returns_nonnull; +char *xasprintf(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2))) __returns_nonnull; +char *xvasprintf(const char *fmt, va_list ap) __returns_nonnull; wchar_t *xstrdup_wchar(const wchar_t *src); wchar_t *xstrdup_char_to_wchar(const char *src); diff --git a/scripts/include/linux/compiler.h b/scripts/include/linux/compiler.h index fa7208a32d76..780ccec21a3c 100644 --- a/scripts/include/linux/compiler.h +++ b/scripts/include/linux/compiler.h @@ -39,6 +39,15 @@ # define unlikely(x) __builtin_expect(!!(x), 0) #endif +#ifndef __returns_nonnull +# define __returns_nonnull +#endif + +# define __alloc_size(x, ...) +# define __realloc_size(x, ...) +# define __xalloc_size(args...) __returns_nonnull __alloc_size(args) +# define __xrealloc_size(args...) __returns_nonnull __realloc_size(args) + #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) #include <linux/types.h> -- 2.39.2