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/[email protected]/ 
> [1]
> Co-developed-by: Kees Cook <[email protected]>

This needs to be followed by my S-o-b, I think? checkpatch.pl ought to
check this.

> Signed-off-by: Bill Wendling <[email protected]>
> ---
> Cc: Kees Cook <[email protected]>
> Cc: "Gustavo A. R. Silva" <[email protected]>
> Cc: Nathan Chancellor <[email protected]>
> Cc: Nick Desaulniers <[email protected]>
> Cc: Justin Stitt <[email protected]>
> Cc: Miguel Ojeda <[email protected]>
> Cc: Peter Zijlstra <[email protected]>
> Cc: Andrew Morton <[email protected]>
> Cc: Heiko Carstens <[email protected]>
> Cc: Marc Herbert <[email protected]>
> Cc: Uros Bizjak <[email protected]>
> Cc: Tejun Heo <[email protected]>
> Cc: Jeff Xu <[email protected]>
> Cc: "Michal Koutný" <[email protected]>
> Cc: Shakeel Butt <[email protected]>
> Cc: "Thomas Weißschuh" <[email protected]>
> Cc: John Stultz <[email protected]>
> Cc: Christian Brauner <[email protected]>
> Cc: Randy Dunlap <[email protected]>
> Cc: Brian Gerst <[email protected]>
> Cc: Masahiro Yamada <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
> 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.

Thanks!

-Kees

-- 
Kees Cook

Reply via email to