Hi,
Add the __counted_by_ptr() macro for annotating pointer struct members with the "counted_by" attribute. Add LKDTM test, and a first user.
-Kees
Kees Cook (3): compiler_types: Introduce __counted_by_ptr() lkdtm/bugs: Add __counted_by_ptr() test PTR_BOUNDS coredump: Use __counted_by_ptr for struct core_name::corename
init/Kconfig | 11 +++ Makefile | 4 ++ include/linux/compiler_types.h | 21 +++++- include/uapi/linux/stddef.h | 4 ++ drivers/misc/lkdtm/bugs.c | 90 ++++++++++++++++++++++--- fs/coredump.c | 8 +-- tools/testing/selftests/lkdtm/tests.txt | 2 + 7 files changed, 127 insertions(+), 13 deletions(-)
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; };
Since "counted_by" can only be applied to pointer members in very recent compiler versions, its application ends up needing to be distinct from flexible array "counted_by" annotations, hence a separate macro.
Unfortunately, this annotation cannot be used for "void *" members (since such a member is considered a pointer to an incomplete type, and neither Clang nor GCC developers could be convinced otherwise[1], even in the face of the GNU extension that "void *" has size "1 byte" for pointer arithmetic). For "void *" members, we must use the coming "sized_by" attribute.
Link: https://gcc.gnu.org/pipermail/gcc-patches/2025-May/683136.html [1] Signed-off-by: Kees Cook kees@kernel.org --- Cc: Miguel Ojeda ojeda@kernel.org Cc: Nathan Chancellor nathan@kernel.org Cc: Nick Desaulniers nick.desaulniers+lkml@gmail.com Cc: Bill Wendling morbo@google.com Cc: Justin Stitt justinstitt@google.com Cc: Peter Zijlstra peterz@infradead.org Cc: Marco Elver elver@google.com Cc: Przemek Kitszel przemyslaw.kitszel@intel.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Masahiro Yamada masahiroy@kernel.org Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Johannes Weiner hannes@cmpxchg.org Cc: llvm@lists.linux.dev --- init/Kconfig | 11 +++++++++++ Makefile | 4 ++++ include/linux/compiler_types.h | 21 ++++++++++++++++++++- include/uapi/linux/stddef.h | 4 ++++ 4 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/init/Kconfig b/init/Kconfig index cab3ad28ca49..54691b086bc6 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -139,6 +139,17 @@ 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_BARE + def_bool $(success,echo 'struct foo { int *ptr __attribute__((__counted_by__(count))); int count; };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror) + +config CC_HAS_COUNTED_BY_PTR_EXP + def_bool $(success,echo 'struct foo { int *ptr __attribute__((__counted_by__(count))); int count; };' | $(CC) $(CLANG_FLAGS) -fexperimental-late-parse-attributes -x c - -c -o /dev/null -Werror) + depends on !CC_HAS_COUNTED_BY_PTR_BARE + +config CC_HAS_COUNTED_BY_PTR + def_bool y + depends on CC_HAS_COUNTED_BY_PTR_BARE || CC_HAS_COUNTED_BY_PTR_EXP + config CC_HAS_MULTIDIMENSIONAL_NONSTRING def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
diff --git a/Makefile b/Makefile index d14824792227..1b297dcbb0df 100644 --- a/Makefile +++ b/Makefile @@ -933,6 +933,10 @@ KBUILD_CFLAGS += $(CC_AUTO_VAR_INIT_ZERO_ENABLER) endif endif
+ifdef CONFIG_CC_HAS_COUNTED_BY_PTR_EXP +KBUILD_CFLAGS += -fexperimental-late-parse-attributes +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 59288a2c1ad2..f197ea03b593 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -353,11 +353,14 @@ struct ftrace_likely_data { #endif
/* + * Runtime track number of flexible array member elements for use by + * CONFIG_FORTIFY_SOURCE and CONFIG_UBSAN_BOUNDS. + * * Optional: only supported since gcc >= 15 * 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... * * __bdos on clang < 19.1.2 can erroneously return 0: * https://github.com/llvm/llvm-project/pull/110497 @@ -371,6 +374,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 >= 20 + * + * gcc: https://gcc.gnu.org/pipermail/gcc-patches/2025-April/681727.html + * clang: ... + */ +#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
On Tue, 21 Oct 2025 at 00:01, Kees Cook kees@kernel.org 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; };
Since "counted_by" can only be applied to pointer members in very recent compiler versions, its application ends up needing to be distinct from flexible array "counted_by" annotations, hence a separate macro.
Unfortunately, this annotation cannot be used for "void *" members (since such a member is considered a pointer to an incomplete type, and neither Clang nor GCC developers could be convinced otherwise[1], even in the face of the GNU extension that "void *" has size "1 byte" for pointer arithmetic). For "void *" members, we must use the coming "sized_by" attribute.
Link: https://gcc.gnu.org/pipermail/gcc-patches/2025-May/683136.html [1] Signed-off-by: Kees Cook kees@kernel.org
Cc: Miguel Ojeda ojeda@kernel.org Cc: Nathan Chancellor nathan@kernel.org Cc: Nick Desaulniers nick.desaulniers+lkml@gmail.com Cc: Bill Wendling morbo@google.com Cc: Justin Stitt justinstitt@google.com Cc: Peter Zijlstra peterz@infradead.org Cc: Marco Elver elver@google.com Cc: Przemek Kitszel przemyslaw.kitszel@intel.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Masahiro Yamada masahiroy@kernel.org Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Johannes Weiner hannes@cmpxchg.org Cc: llvm@lists.linux.dev
init/Kconfig | 11 +++++++++++ Makefile | 4 ++++ include/linux/compiler_types.h | 21 ++++++++++++++++++++- include/uapi/linux/stddef.h | 4 ++++ 4 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/init/Kconfig b/init/Kconfig index cab3ad28ca49..54691b086bc6 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -139,6 +139,17 @@ 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_BARE
def_bool $(success,echo 'struct foo { int *ptr __attribute__((__counted_by__(count))); int count; };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
+config CC_HAS_COUNTED_BY_PTR_EXP
def_bool $(success,echo 'struct foo { int *ptr __attribute__((__counted_by__(count))); int count; };' | $(CC) $(CLANG_FLAGS) -fexperimental-late-parse-attributes -x c - -c -o /dev/null -Werror)
depends on !CC_HAS_COUNTED_BY_PTR_BARE
Do these still require an unreleased Clang version? Otherwise a version check will be faster.
+config CC_HAS_COUNTED_BY_PTR
def_bool y
depends on CC_HAS_COUNTED_BY_PTR_BARE || CC_HAS_COUNTED_BY_PTR_EXP
config CC_HAS_MULTIDIMENSIONAL_NONSTRING def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
diff --git a/Makefile b/Makefile index d14824792227..1b297dcbb0df 100644 --- a/Makefile +++ b/Makefile @@ -933,6 +933,10 @@ KBUILD_CFLAGS += $(CC_AUTO_VAR_INIT_ZERO_ENABLER) endif endif
+ifdef CONFIG_CC_HAS_COUNTED_BY_PTR_EXP +KBUILD_CFLAGS += -fexperimental-late-parse-attributes +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 59288a2c1ad2..f197ea03b593 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -353,11 +353,14 @@ struct ftrace_likely_data { #endif
/*
- Runtime track number of flexible array member elements for use by
- CONFIG_FORTIFY_SOURCE and CONFIG_UBSAN_BOUNDS.
- Optional: only supported since gcc >= 15
- Optional: only supported since clang >= 18
- gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
- clang: https://clang.llvm.org/docs/AttributeReference.html#counted-by-counted-by-or...
- __bdos on clang < 19.1.2 can erroneously return 0:
- https://github.com/llvm/llvm-project/pull/110497
@@ -371,6 +374,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 >= 20
- clang: ...
- */
+#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
2.34.1
On Mon, Oct 20, 2025 at 3:01 PM Kees Cook kees@kernel.org 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; };
Since "counted_by" can only be applied to pointer members in very recent compiler versions, its application ends up needing to be distinct from flexible array "counted_by" annotations, hence a separate macro.
Unfortunately, this annotation cannot be used for "void *" members (since such a member is considered a pointer to an incomplete type, and neither Clang nor GCC developers could be convinced otherwise[1], even in the face of the GNU extension that "void *" has size "1 byte" for pointer arithmetic). For "void *" members, we must use the coming "sized_by" attribute.
I'm pretty sure that "sized_by" is available in Clang right now.
-bw
Link: https://gcc.gnu.org/pipermail/gcc-patches/2025-May/683136.html [1] Signed-off-by: Kees Cook kees@kernel.org
Cc: Miguel Ojeda ojeda@kernel.org Cc: Nathan Chancellor nathan@kernel.org Cc: Nick Desaulniers nick.desaulniers+lkml@gmail.com Cc: Bill Wendling morbo@google.com Cc: Justin Stitt justinstitt@google.com Cc: Peter Zijlstra peterz@infradead.org Cc: Marco Elver elver@google.com Cc: Przemek Kitszel przemyslaw.kitszel@intel.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Masahiro Yamada masahiroy@kernel.org Cc: Christophe Leroy christophe.leroy@csgroup.eu Cc: Johannes Weiner hannes@cmpxchg.org Cc: llvm@lists.linux.dev
init/Kconfig | 11 +++++++++++ Makefile | 4 ++++ include/linux/compiler_types.h | 21 ++++++++++++++++++++- include/uapi/linux/stddef.h | 4 ++++ 4 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/init/Kconfig b/init/Kconfig index cab3ad28ca49..54691b086bc6 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -139,6 +139,17 @@ 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_BARE
def_bool $(success,echo 'struct foo { int *ptr __attribute__((__counted_by__(count))); int count; };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
+config CC_HAS_COUNTED_BY_PTR_EXP
def_bool $(success,echo 'struct foo { int *ptr __attribute__((__counted_by__(count))); int count; };' | $(CC) $(CLANG_FLAGS) -fexperimental-late-parse-attributes -x c - -c -o /dev/null -Werror)
depends on !CC_HAS_COUNTED_BY_PTR_BARE
+config CC_HAS_COUNTED_BY_PTR
def_bool y
depends on CC_HAS_COUNTED_BY_PTR_BARE || CC_HAS_COUNTED_BY_PTR_EXP
config CC_HAS_MULTIDIMENSIONAL_NONSTRING def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror)
diff --git a/Makefile b/Makefile index d14824792227..1b297dcbb0df 100644 --- a/Makefile +++ b/Makefile @@ -933,6 +933,10 @@ KBUILD_CFLAGS += $(CC_AUTO_VAR_INIT_ZERO_ENABLER) endif endif
+ifdef CONFIG_CC_HAS_COUNTED_BY_PTR_EXP +KBUILD_CFLAGS += -fexperimental-late-parse-attributes +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 59288a2c1ad2..f197ea03b593 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -353,11 +353,14 @@ struct ftrace_likely_data { #endif
/*
- Runtime track number of flexible array member elements for use by
- CONFIG_FORTIFY_SOURCE and CONFIG_UBSAN_BOUNDS.
- Optional: only supported since gcc >= 15
- Optional: only supported since clang >= 18
- gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
- clang: https://clang.llvm.org/docs/AttributeReference.html#counted-by-counted-by-or...
- __bdos on clang < 19.1.2 can erroneously return 0:
- https://github.com/llvm/llvm-project/pull/110497
@@ -371,6 +374,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 >= 20
- clang: ...
- */
+#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
2.34.1
Provide run-time validation of the __counted_by_ptr() annotation via newly added PTR_BOUNDS LKDTM test.
Signed-off-by: Kees Cook kees@kernel.org --- Cc: Arnd Bergmann arnd@arndb.de Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/lkdtm/bugs.c | 90 ++++++++++++++++++++++--- tools/testing/selftests/lkdtm/tests.txt | 2 + 2 files changed, 84 insertions(+), 8 deletions(-)
diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index 376047beea3d..a069a7d686fc 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -414,32 +414,32 @@ static void lkdtm_ARRAY_BOUNDS(void) pr_expected_config(CONFIG_UBSAN_BOUNDS); }
-struct lkdtm_annotated { +struct lkdtm_cb_fam { unsigned long flags; int count; int array[] __counted_by(count); };
-static volatile int fam_count = 4; +static volatile int element_count = 4;
static void lkdtm_FAM_BOUNDS(void) { - struct lkdtm_annotated *inst; + struct lkdtm_cb_fam *inst;
- inst = kzalloc(struct_size(inst, array, fam_count + 1), GFP_KERNEL); + inst = kzalloc(struct_size(inst, array, element_count + 1), GFP_KERNEL); if (!inst) { pr_err("FAIL: could not allocate test struct!\n"); return; }
- inst->count = fam_count; + inst->count = element_count; pr_info("Array access within bounds ...\n"); - inst->array[1] = fam_count; + inst->array[1] = element_count; ignored = inst->array[1];
pr_info("Array access beyond bounds ...\n"); - inst->array[fam_count] = fam_count; - ignored = inst->array[fam_count]; + inst->array[element_count] = element_count; + ignored = inst->array[element_count];
kfree(inst);
@@ -454,6 +454,79 @@ static void lkdtm_FAM_BOUNDS(void) pr_expected_config(CONFIG_UBSAN_BOUNDS); }
+struct lkdtm_extra { + short a, b; + u16 sixteen; + u32 bigger; + u64 biggest; +}; + +struct lkdtm_cb_ptr { + int a, b, c; + int nr_extra; + char *buf __counted_by_ptr(len); + size_t len; + struct lkdtm_extra *extra __counted_by_ptr(nr_extra); +}; + +static noinline void check_ptr_len(struct lkdtm_cb_ptr *p, size_t len) +{ + if (__member_size(p->buf) != len) + pr_err("FAIL: could not determine size of inst->buf: %zu\n", + __member_size(p->buf)); + else + pr_info("good: inst->buf length is %zu\n", len); +} + +static void lkdtm_PTR_BOUNDS(void) +{ + struct lkdtm_cb_ptr *inst; + + inst = kzalloc(sizeof(*inst), GFP_KERNEL); + if (!inst) { + pr_err("FAIL: could not allocate struct lkdtm_cb_ptr!\n"); + return; + } + + inst->buf = kzalloc(element_count, GFP_KERNEL); + if (!inst->buf) { + pr_err("FAIL: could not allocate inst->buf!\n"); + return; + } + inst->len = element_count; + + /* Double element_count */ + inst->extra = kcalloc(element_count * 2, sizeof(*inst->extra), GFP_KERNEL); + inst->nr_extra = element_count * 2; + + pr_info("Pointer access within bounds ...\n"); + check_ptr_len(inst, 4); + /* All 4 bytes */ + inst->buf[0] = 'A'; + inst->buf[1] = 'B'; + inst->buf[2] = 'C'; + inst->buf[3] = 'D'; + /* Halfway into the array */ + inst->extra[element_count].biggest = 0x1000; + + pr_info("Pointer access beyond bounds ...\n"); + ignored = inst->extra[inst->nr_extra].b; + + kfree(inst->extra); + kfree(inst->buf); + kfree(inst); + + pr_err("FAIL: survived access of invalid pointer member offset!\n"); + + if (!IS_ENABLED(CONFIG_CC_HAS_COUNTED_BY_PTR)) + pr_warn("This is expected since this %s was built with a compiler that does not support __counted_by_ptr\n", + lkdtm_kernel_info); + else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS)) + pr_expected_config(CONFIG_UBSAN_TRAP); + else + pr_expected_config(CONFIG_UBSAN_BOUNDS); +} + static void lkdtm_CORRUPT_LIST_ADD(void) { /* @@ -716,6 +789,7 @@ static struct crashtype crashtypes[] = { CRASHTYPE(OVERFLOW_UNSIGNED), CRASHTYPE(ARRAY_BOUNDS), CRASHTYPE(FAM_BOUNDS), + CRASHTYPE(PTR_BOUNDS), CRASHTYPE(CORRUPT_LIST_ADD), CRASHTYPE(CORRUPT_LIST_DEL), CRASHTYPE(STACK_GUARD_PAGE_LEADING), diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt index cff124c1eddd..204d4a669632 100644 --- a/tools/testing/selftests/lkdtm/tests.txt +++ b/tools/testing/selftests/lkdtm/tests.txt @@ -9,6 +9,8 @@ EXCEPTION #CORRUPT_STACK Crashes entire system on success #CORRUPT_STACK_STRONG Crashes entire system on success ARRAY_BOUNDS call trace:|UBSAN: array-index-out-of-bounds +FAM_BOUNDS call trace:|UBSAN: array-index-out-of-bounds +PTR_BOUNDS call trace:|UBSAN: array-index-out-of-bounds CORRUPT_LIST_ADD list_add corruption CORRUPT_LIST_DEL list_del corruption STACK_GUARD_PAGE_LEADING
Use the __counted_by annotation now available for struct pointer members, __counted_by_ptr(). Move assignments to immediately after allocation.
Signed-off-by: Kees Cook kees@kernel.org --- Cc: Al Viro viro@zeniv.linux.org.uk Cc: Christian Brauner brauner@kernel.org Cc: Jan Kara jack@suse.cz Cc: linux-fsdevel@vger.kernel.org --- fs/coredump.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/coredump.c b/fs/coredump.c index 5c1c381ee380..876f1cdb756f 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -92,7 +92,7 @@ enum coredump_type_t { };
struct core_name { - char *corename; + char *corename __counted_by_ptr(size); int used, size; unsigned int core_pipe_limit; bool core_dumped; @@ -106,15 +106,15 @@ static int expand_corename(struct core_name *cn, int size)
size = kmalloc_size_roundup(size); corename = krealloc(cn->corename, size, GFP_KERNEL); - if (!corename) return -ENOMEM;
+ cn->corename = corename; + cn->size = size; + if (size > core_name_size) /* racy but harmless */ core_name_size = size;
- cn->size = size; - cn->corename = corename; return 0; }
linux-kselftest-mirror@lists.linaro.org