]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
compiler_types.h: Attributes: Add __counted_by_ptr macro
authorBill Wendling <morbo@google.com>
Fri, 16 Jan 2026 00:57:57 +0000 (00:57 +0000)
committerKees Cook <kees@kernel.org>
Sat, 17 Jan 2026 19:00:28 +0000 (11:00 -0800)
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/
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>
Makefile
include/linux/compiler_types.h
include/uapi/linux/stddef.h
init/Kconfig

index 3cd00b62cde99c5ca1afaebb4463ffbd732557d8..c0751976cdee8678a9628337ffdb94322c9698b7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -952,6 +952,12 @@ KBUILD_CFLAGS      += $(CC_AUTO_VAR_INIT_ZERO_ENABLER)
 endif
 endif
 
+ifdef CONFIG_CC_IS_CLANG
+ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
+KBUILD_CFLAGS  += -fexperimental-late-parse-attributes
+endif
+endif
+
 # Explicitly clear padding bits during variable initialization
 KBUILD_CFLAGS += $(call cc-option,-fzero-init-padding-bits=all)
 
index d3318a3c257775d4f44e8f2eb7911ac52eefecc5..d095beb904ea323504b00c135f0ff17417663fac 100644 (file)
@@ -369,7 +369,7 @@ struct ftrace_likely_data {
  * Optional: only supported since clang >= 18
  *
  *   gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
- * clang: https://github.com/llvm/llvm-project/pull/76348
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#counted-by-counted-by-or-null-sized-by-sized-by-or-null
  *
  * __bdos on clang < 19.1.2 can erroneously return 0:
  * https://github.com/llvm/llvm-project/pull/110497
@@ -383,6 +383,22 @@ struct ftrace_likely_data {
 # define __counted_by(member)
 #endif
 
+/*
+ * Runtime track number of objects pointed to by a pointer member for use by
+ * CONFIG_FORTIFY_SOURCE and CONFIG_UBSAN_BOUNDS.
+ *
+ * Optional: only supported since gcc >= 16
+ * Optional: only supported since clang >= 22
+ *
+ *   gcc: https://gcc.gnu.org/pipermail/gcc-patches/2025-April/681727.html
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#counted-by-counted-by-or-null-sized-by-sized-by-or-null
+ */
+#ifdef CONFIG_CC_HAS_COUNTED_BY_PTR
+#define __counted_by_ptr(member)       __attribute__((__counted_by__(member)))
+#else
+#define __counted_by_ptr(member)
+#endif
+
 /*
  * Optional: only supported since gcc >= 15
  * Optional: not supported by Clang
index 9a28f7d9a3342d04f2e6b7a2b70f13311557d9b6..111b097ec00b0a3b53b1f2b3de6ef432042dc107 100644 (file)
 #define __counted_by_be(m)
 #endif
 
+#ifndef __counted_by_ptr
+#define __counted_by_ptr(m)
+#endif
+
 #ifdef __KERNEL__
 #define __kernel_nonstring     __nonstring
 #else
index fa79feb8fe57bb01d8ce8f35e33535709b57d452..96b7cd481eaaab92d3903255e02310e2d01d074c 100644 (file)
@@ -143,6 +143,13 @@ config CC_HAS_COUNTED_BY
        # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
        default y if CC_IS_GCC && GCC_VERSION >= 150100
 
+config CC_HAS_COUNTED_BY_PTR
+       bool
+       # supported since clang 22
+       default y if CC_IS_CLANG && CLANG_VERSION >= 220000
+       # supported since gcc 16.0.0
+       default y if CC_IS_GCC && GCC_VERSION >= 160000
+
 config CC_HAS_MULTIDIMENSIONAL_NONSTRING
        def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)