From 2fac0c6418a9f07451d806a29154429fca7cbee6 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 24 Aug 2021 10:00:17 +1000 Subject: [PATCH] Compiler Attributes: add __alloc_size() for better bounds checking Patch series "Add __alloc_size() for better bounds checking", v2. GCC and Clang both use the "alloc_size" attribute to assist with bounds checking around the use of allocation functions. Add the attribute, adjust the Makefile to silence needless warnings, and add the hints to the allocators where possible. These changes have been in use for a while now in GrapheneOS. This patch (of 2): GCC and Clang can use the "alloc_size" attribute to better inform the results of __builtin_object_size() (for compile-time constant values). Clang can additionally use alloc_size to inform the results of __builtin_dynamic_object_size() (for run-time values). Because GCC sees the frequent use of struct_size() as an allocator size argument, and notices it can return SIZE_MAX (the overflow indication), it complains about these call sites may overflow (since SIZE_MAX is greater than the default -Walloc-size-larger-than=PTRDIFF_MAX). This isn't helpful since we already know a SIZE_MAX will be caught at run-time (this was an intentional design). Instead, just disable this check as it is both a false positive and redundant. (Clang does not have this warning option.) Link: https://lkml.kernel.org/r/20210818214021.2476230-1-keescook@chromium.org Link: https://lkml.kernel.org/r/20210818214021.2476230-2-keescook@chromium.org Signed-off-by: Kees Cook Reviewed-by: Miguel Ojeda Reviewed-by: Nathan Chancellor Cc: Nick Desaulniers Cc: Andy Whitcroft Cc: Christoph Lameter Cc: Daniel Micay Cc: David Rientjes Cc: Dennis Zhou Cc: Dwaipayan Ray Cc: Joe Perches Cc: Joonsoo Kim Cc: Lukas Bulwahn Cc: Pekka Enberg Cc: Tejun Heo Cc: Vlastimil Babka Signed-off-by: Andrew Morton Signed-off-by: Stephen Rothwell --- Makefile | 6 ++++++ include/linux/compiler_attributes.h | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/Makefile b/Makefile index 476e3fb9feb3..56151c396958 100644 --- a/Makefile +++ b/Makefile @@ -1097,6 +1097,12 @@ ifdef CONFIG_CC_IS_GCC KBUILD_CFLAGS += -Wno-maybe-uninitialized endif +ifdef CONFIG_CC_IS_GCC +# The allocators already balk at large sizes, so silence the compiler +# warnings for bounds checks involving those possible values. +KBUILD_CFLAGS += -Wno-alloc-size-larger-than +endif + # disable invalid "can't wrap" optimizations for signed / pointers KBUILD_CFLAGS += -fno-strict-overflow diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index 67c5667f8042..203b0ac62d15 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -54,6 +54,12 @@ #define __aligned(x) __attribute__((__aligned__(x))) #define __aligned_largest __attribute__((__aligned__)) +/* + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute + * clang: https://clang.llvm.org/docs/AttributeReference.html#alloc-size + */ +#define __alloc_size(x, ...) __attribute__((__alloc_size__(x, ## __VA_ARGS__))) + /* * Note: users of __always_inline currently do not write "inline" themselves, * which seems to be required by gcc to apply the attribute according -- 2.50.1