Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

compiler_types.h: Attributes: Add __counted_by_ptr macro

Introduce __counted_by_ptr(), which works like __counted_by(), but for
pointer struct members.

struct foo {
int a, b, c;
char *buffer __counted_by_ptr(bytes);
short nr_bars;
struct bar *bars __counted_by_ptr(nr_bars);
size_t bytes;
};

Because "counted_by" can only be applied to pointer members in very
recent compiler versions, its application ends up needing to be distinct
from flexibe array "counted_by" annotations, hence a separate macro.

This is a reworking of Kees' previous patch [1].

Link: https://lore.kernel.org/all/20251020220118.1226740-1-kees@kernel.org/ [1]
Co-developed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Bill Wendling <morbo@google.com>
Link: https://patch.msgid.link/20260116005838.2419118-1-morbo@google.com
Signed-off-by: Kees Cook <kees@kernel.org>

authored by

Bill Wendling and committed by
Kees Cook
150a04d8 9f54ab83

+34 -1
+6
Makefile
··· 952 952 endif 953 953 endif 954 954 955 + ifdef CONFIG_CC_IS_CLANG 956 + ifdef CONFIG_CC_HAS_COUNTED_BY_PTR 957 + KBUILD_CFLAGS += -fexperimental-late-parse-attributes 958 + endif 959 + endif 960 + 955 961 # Explicitly clear padding bits during variable initialization 956 962 KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all) 957 963
+17 -1
include/linux/compiler_types.h
··· 369 369 * Optional: only supported since clang >= 18 370 370 * 371 371 * gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 372 - * clang: https://github.com/llvm/llvm-project/pull/76348 372 + * clang: https://clang.llvm.org/docs/AttributeReference.html#counted-by-counted-by-or-null-sized-by-sized-by-or-null 373 373 * 374 374 * __bdos on clang < 19.1.2 can erroneously return 0: 375 375 * https://github.com/llvm/llvm-project/pull/110497 ··· 381 381 # define __counted_by(member) __attribute__((__counted_by__(member))) 382 382 #else 383 383 # define __counted_by(member) 384 + #endif 385 + 386 + /* 387 + * Runtime track number of objects pointed to by a pointer member for use by 388 + * CONFIG_FORTIFY_SOURCE and CONFIG_UBSAN_BOUNDS. 389 + * 390 + * Optional: only supported since gcc >= 16 391 + * Optional: only supported since clang >= 22 392 + * 393 + * gcc: https://gcc.gnu.org/pipermail/gcc-patches/2025-April/681727.html 394 + * clang: https://clang.llvm.org/docs/AttributeReference.html#counted-by-counted-by-or-null-sized-by-sized-by-or-null 395 + */ 396 + #ifdef CONFIG_CC_HAS_COUNTED_BY_PTR 397 + #define __counted_by_ptr(member) __attribute__((__counted_by__(member))) 398 + #else 399 + #define __counted_by_ptr(member) 384 400 #endif 385 401 386 402 /*
+4
include/uapi/linux/stddef.h
··· 72 72 #define __counted_by_be(m) 73 73 #endif 74 74 75 + #ifndef __counted_by_ptr 76 + #define __counted_by_ptr(m) 77 + #endif 78 + 75 79 #ifdef __KERNEL__ 76 80 #define __kernel_nonstring __nonstring 77 81 #else
+7
init/Kconfig
··· 143 143 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896 144 144 default y if CC_IS_GCC && GCC_VERSION >= 150100 145 145 146 + config CC_HAS_COUNTED_BY_PTR 147 + bool 148 + # supported since clang 22 149 + default y if CC_IS_CLANG && CLANG_VERSION >= 220000 150 + # supported since gcc 16.0.0 151 + default y if CC_IS_GCC && GCC_VERSION >= 160000 152 + 146 153 config CC_HAS_MULTIDIMENSIONAL_NONSTRING 147 154 def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror) 148 155