Re: [PATCH 1/2] Compiler Attributes: Add __counted_by_ptr macro
From: Bill Wendling
Date: Thu Jan 15 2026 - 19:59:46 EST
On Wed, Jan 14, 2026 at 8:00 PM Kees Cook <kees@xxxxxxxxxx> wrote:
>
> On Wed, Jan 14, 2026 at 07:36:47PM +0000, Bill Wendling wrote:
> > 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.
> >
> > Note that Clang's support for "void *" members will be in version 22.
> > So, when using Clang, you'll need to wait until its release before using
> > the feature with "void *". No such restriction applies to GCC's version
> > 16.
>
> I think to keep operational parity, we should limit counted_ptr on Clang
> to version 22 then, otherwise we'll have problems using it on void *.
>
> > This is a reworking of Kees' previous patch [1].
>
> Thanks for this!
>
> >
> > Link: https://lore.kernel.org/all/20251020220118.1226740-1-kees@xxxxxxxxxx/ [1]
> > Co-developed-by: Kees Cook <kees@xxxxxxxxxx>
>
> This needs to be followed by my S-o-b, I think? checkpatch.pl ought to
> check this.
>
> > Signed-off-by: Bill Wendling <morbo@xxxxxxxxxx>
> > ---
> > Cc: Kees Cook <kees@xxxxxxxxxx>
> > Cc: "Gustavo A. R. Silva" <gustavoars@xxxxxxxxxx>
> > Cc: Nathan Chancellor <nathan@xxxxxxxxxx>
> > Cc: Nick Desaulniers <nick.desaulniers+lkml@xxxxxxxxx>
> > Cc: Justin Stitt <justinstitt@xxxxxxxxxx>
> > Cc: Miguel Ojeda <ojeda@xxxxxxxxxx>
> > Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
> > Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
> > Cc: Heiko Carstens <hca@xxxxxxxxxxxxx>
> > Cc: Marc Herbert <Marc.Herbert@xxxxxxxxxxxxxxx>
> > Cc: Uros Bizjak <ubizjak@xxxxxxxxx>
> > Cc: Tejun Heo <tj@xxxxxxxxxx>
> > Cc: Jeff Xu <jeffxu@xxxxxxxxxxxx>
> > Cc: "Michal Koutný" <mkoutny@xxxxxxxx>
> > Cc: Shakeel Butt <shakeel.butt@xxxxxxxxx>
> > Cc: "Thomas Weißschuh" <thomas.weissschuh@xxxxxxxxxxxxx>
> > Cc: John Stultz <jstultz@xxxxxxxxxx>
> > Cc: Christian Brauner <brauner@xxxxxxxxxx>
> > Cc: Randy Dunlap <rdunlap@xxxxxxxxxxxxx>
> > Cc: Brian Gerst <brgerst@xxxxxxxxx>
> > Cc: Masahiro Yamada <masahiroy@xxxxxxxxxx>
> > Cc: linux-kernel@xxxxxxxxxxxxxxx
> > Cc: linux-hardening@xxxxxxxxxxxxxxx
> > Cc: llvm@xxxxxxxxxxxxxxx
> > ---
> > v3 - Replace the previous code with a modified version of Kees' previous patch
> > [1].
> > - The question about the naming of the macro was considered, but we decided
> > to keep the original naming (__counted_by_ptr), because it mirrors the current
> > macros like "__counted_by_{le,be}".
> > v2 - Add support for GCC.
> > ---
> > Makefile | 6 ++++++
> > include/linux/compiler_types.h | 18 +++++++++++++++++-
> > include/uapi/linux/stddef.h | 4 ++++
> > init/Kconfig | 7 +++++++
> > 4 files changed, 34 insertions(+), 1 deletion(-)
> >
> > diff --git a/Makefile b/Makefile
> > index 9d38125263fb..6b029f694bc2 100644
> > --- 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)
> >
> > diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
> > index d3318a3c2577..e597c814d60b 100644
> > --- a/include/linux/compiler_types.h
> > +++ b/include/linux/compiler_types.h
> > @@ -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 >= 21.1
>
> As I mention above, let's make this 22
>
> > + *
> > + * gcc: https://gcc.gnu.org/pipermail/gcc-patches/2025-April/681727.html
> > + * clang: https://github.com/llvm/llvm-project/pull/137250
>
> Oh, hm, did the docs for
> https://clang.llvm.org/docs/AttributeReference.html#counted-by-counted-by-or-null-sized-by-sized-by-or-null
> not get updated by the above PR? Docs should get added to LLVM for this
> so we can link to the same AttributeReference.html as above.
>
> And, actually, same question for GCC, now that I'm looking at this...
>
>
> > + */
> > +#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
> > diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h
> > index 9a28f7d9a334..111b097ec00b 100644
> > --- a/include/uapi/linux/stddef.h
> > +++ b/include/uapi/linux/stddef.h
> > @@ -72,6 +72,10 @@
> > #define __counted_by_be(m)
> > #endif
> >
> > +#ifndef __counted_by_ptr
> > +#define __counted_by_ptr(m)
> > +#endif
> > +
> > #ifdef __KERNEL__
> > #define __kernel_nonstring __nonstring
> > #else
> > diff --git a/init/Kconfig b/init/Kconfig
> > index fa79feb8fe57..dc27b998d111 100644
> > --- a/init/Kconfig
> > +++ b/init/Kconfig
> > @@ -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 21.1.0
> > + default y if CC_IS_CLANG && CLANG_VERSION >= 210100
>
> Let's do 22
>
> > + # 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)
> >
> > --
> > 2.52.0.457.g6b5491de43-goog
> >
>
> Great! Once this is fixed up, I'll snag the other 2 patches from my
> original series too.
>
Should be corrected now. PTAL.
-bw