mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: linux-mm@kvack.org, linux-hardening@vger.kernel.org
Cc: Alejandro Colomar <alx@kernel.org>, Kees Cook <kees@kernel.org>,
	 Christopher Bazley <chris.bazley.wg14@gmail.com>,
	shadow <~hallyn/shadow@lists.sr.ht>,
	 linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	 kasan-dev@googlegroups.com, Dmitry Vyukov <dvyukov@google.com>,
	 Alexander Potapenko <glider@google.com>,
	Marco Elver <elver@google.com>, Christoph Lameter <cl@linux.com>,
	 David Rientjes <rientjes@google.com>,
	Vlastimil Babka <vbabka@suse.cz>,
	 Roman Gushchin <roman.gushchin@linux.dev>,
	Harry Yoo <harry.yoo@oracle.com>,
	 Andrew Clayton <andrew@digital-domain.net>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>,
	 Michal Hocko <mhocko@suse.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	 Al Viro <viro@zeniv.linux.org.uk>,
	Martin Uecker <uecker@tugraz.at>, Sam James <sam@gentoo.org>,
	 Andrew Pinski <pinskia@gmail.com>
Subject: [RFC v4 0/7] Add and use sprintf_end() instead of less ergonomic APIs
Date: Thu, 10 Jul 2025 04:47:33 +0200	[thread overview]
Message-ID: <cover.1752113247.git.alx@kernel.org> (raw)
In-Reply-To: <cover.1751823326.git.alx@kernel.org>

Hi,

Changes in v4:

-  Added to global CC everyone who participated in the discussion so
   far.
-  Rename seprintf() => sprintf_end().
-  Implement SPRINTF_END().
-  Drop stprintf().  We don't need it as an intermediate helper.
-  Link to the draft of a standards proposal (which I'll paste as a
   reply to this mail again).
-  Minor fixes or updates to commit messages.
-  Added Marco Elver's Acked-by: tag in commit 5/7.
-  In stack_depot_sprint_end(), do sprintf_end(p, end, "") when
   nr_entries is 0, to guarantee that the string is valid if this is the
   first s*printf() call in a row.
-  Document sprintf_end() as 'string end-delimited print formatted'.
   This spells the letters in seprintf() for their meaning, in case
   anyone thinks the letters are randomly chosen.  :)
-  Remove comment about vsnprintf(3) not failing in the kernel, after
   Rasmus commented this is QoI guaranteed by the kernel.

Remaining questions:

-  There are only 3 remaining calls to snprintf(3) under mm/.  They are
   just fine for now, which is why I didn't replace them.  If anyone
   wants to replace them, to get rid of all snprintf(3), we could that.
   I think for now we can leave them, to minimize the churn.

	$ grep -rnI snprintf mm/
	mm/hugetlb_cgroup.c:674:		snprintf(buf, size, "%luGB", hsize / SZ_1G);
	mm/hugetlb_cgroup.c:676:		snprintf(buf, size, "%luMB", hsize / SZ_1M);
	mm/hugetlb_cgroup.c:678:		snprintf(buf, size, "%luKB", hsize / SZ_1K);

-  There are only 2 remaining calls to the kernel's scnprintf().  This
   one I would really like to get rid of.  Also, those calls are quite
   suspicious of not being what we want.  Please do have a look at them
   and confirm what's the appropriate behavior in the 2 cases when the
   string is truncated or not copied at all.  That code is very scary
   for me to try to guess.

	$ grep -rnI scnprintf mm/
	mm/kfence/report.c:75:		int len = scnprintf(buf, sizeof(buf), "%ps", (void *)stack_entries[skipnr]);
	mm/kfence/kfence_test.mod.c:22:	{ 0x96848186, "scnprintf" },
	mm/kmsan/report.c:42:		len = scnprintf(buf, sizeof(buf), "%ps",

   Apart from two calls, I see a string literal with that name.  Please
   let me know if I should do anything about it.  I don't know what that
   is.

-  I think we should remove one error handling check in
   "mm/page_owner.c" (marked with an XXX comment), but I'm not 100%
   sure.  Please confirm.

Other comments:

-  This is still not complying to coding style.  I'll keep it like that
   while questions remain open.
-  I've tested the tests under CONFIG_KFENCE_KUNIT_TEST=y, and this has
   no regressions at all.
-  With the current style of the sprintf_end() prototyope, this triggers
   a diagnostic due to a GCC bug:
   <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108036>
   It would be interesting to ask GCC to fix that bug.  (Added relevant
   GCC maintainers and contributors to CC in this cover letter.)


Have a lovely night!
Alex


Alejandro Colomar (7):
  vsprintf: Add [v]sprintf_end()
  stacktrace, stackdepot: Add sprintf_end()-like variants of functions
  mm: Use sprintf_end() instead of less ergonomic APIs
  array_size.h: Add ENDOF()
  mm: Fix benign off-by-one bugs
  sprintf: Add [V]SPRINTF_END()
  mm: Use [V]SPRINTF_END() to avoid specifying the array size

 include/linux/array_size.h |  6 ++++
 include/linux/sprintf.h    |  6 ++++
 include/linux/stackdepot.h | 13 +++++++++
 include/linux/stacktrace.h |  3 ++
 kernel/stacktrace.c        | 28 ++++++++++++++++++
 lib/stackdepot.c           | 13 +++++++++
 lib/vsprintf.c             | 59 ++++++++++++++++++++++++++++++++++++++
 mm/backing-dev.c           |  2 +-
 mm/cma.c                   |  4 +--
 mm/cma_debug.c             |  2 +-
 mm/hugetlb.c               |  3 +-
 mm/hugetlb_cgroup.c        |  2 +-
 mm/hugetlb_cma.c           |  2 +-
 mm/kasan/report.c          |  3 +-
 mm/kfence/kfence_test.c    | 28 +++++++++---------
 mm/kmsan/kmsan_test.c      |  6 ++--
 mm/memblock.c              |  4 +--
 mm/mempolicy.c             | 18 ++++++------
 mm/page_owner.c            | 32 +++++++++++----------
 mm/percpu.c                |  2 +-
 mm/shrinker_debug.c        |  2 +-
 mm/slub.c                  |  5 ++--
 mm/zswap.c                 |  2 +-
 23 files changed, 187 insertions(+), 58 deletions(-)

Range-diff against v3:
1:  64334f0b94d6 ! 1:  2c4f793de0b8 vsprintf: Add [v]seprintf(), [v]stprintf()
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    vsprintf: Add [v]seprintf(), [v]stprintf()
    +    vsprintf: Add [v]sprintf_end()
     
    -    seprintf()
    -    ==========
    -
    -    seprintf() is a function similar to stpcpy(3) in the sense that it
    +    sprintf_end() is a function similar to stpcpy(3) in the sense that it
         returns a pointer that is suitable for chaining to other copy
         operations.
     
    @@ Commit message
     
         It also makes error handling much easier, by reporting truncation with
         a null pointer, which is accepted and transparently passed down by
    -    subsequent seprintf() calls.  This results in only needing to report
    -    errors once after a chain of seprintf() calls, unlike snprintf(3), which
    -    requires checking after every call.
    +    subsequent sprintf_end() calls.  This results in only needing to report
    +    errors once after a chain of sprintf_end() calls, unlike snprintf(3),
    +    which requires checking after every call.
     
                 p = buf;
                 e = buf + countof(buf);
    -            p = seprintf(p, e, foo);
    -            p = seprintf(p, e, bar);
    +            p = sprintf_end(p, e, foo);
    +            p = sprintf_end(p, e, bar);
                 if (p == NULL)
                         goto trunc;
     
    @@ Commit message
                 size = countof(buf);
                 len += scnprintf(buf + len, size - len, foo);
                 len += scnprintf(buf + len, size - len, bar);
    -            if (len >= size)
    -                    goto trunc;
    +            // No ability to check.
     
         It seems aparent that it's a more elegant approach to string catenation.
     
    -    stprintf()
    -    ==========
    -
    -    stprintf() is a helper that is needed for implementing seprintf()
    -    --although it could be open-coded within vseprintf(), of course--, but
    -    it's also useful by itself.  It has the same interface properties as
    -    strscpy(): that is, it copies with truncation, and reports truncation
    -    with -E2BIG.  It would be useful to replace some calls to snprintf(3)
    -    and scnprintf() which don't need chaining, and where it's simpler to
    -    pass a size.
    -
    -    It is better than plain snprintf(3), because it results in simpler error
    -    detection (it doesn't need a check >=countof(buf), but rather <0).
    +    These functions will soon be proposed for standardization as
    +    [v]seprintf() into C2y, and they exist in Plan9 as seprint(2) --but the
    +    Plan9 implementation has important bugs--.
     
    +    Link: <https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0049.git/tree/alx-0049.txt>
         Cc: Kees Cook <kees@kernel.org>
         Cc: Christopher Bazley <chris.bazley.wg14@gmail.com>
    +    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    +    Cc: Marco Elver <elver@google.com>
    +    Cc: Michal Hocko <mhocko@suse.com>
    +    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    +    Cc: Al Viro <viro@zeniv.linux.org.uk>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## include/linux/sprintf.h ##
    -@@ include/linux/sprintf.h: __printf(2, 3) int sprintf(char *buf, const char * fmt, ...);
    - __printf(2, 0) int vsprintf(char *buf, const char *, va_list);
    - __printf(3, 4) int snprintf(char *buf, size_t size, const char *fmt, ...);
    +@@ include/linux/sprintf.h: __printf(3, 4) int snprintf(char *buf, size_t size, const char *fmt, ...);
      __printf(3, 0) int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
    -+__printf(3, 4) int stprintf(char *buf, size_t size, const char *fmt, ...);
    -+__printf(3, 0) int vstprintf(char *buf, size_t size, const char *fmt, va_list args);
      __printf(3, 4) int scnprintf(char *buf, size_t size, const char *fmt, ...);
      __printf(3, 0) int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
    -+__printf(3, 4) char *seprintf(char *p, const char end[0], const char *fmt, ...);
    -+__printf(3, 0) char *vseprintf(char *p, const char end[0], const char *fmt, va_list args);
    ++__printf(3, 4) char *sprintf_end(char *p, const char end[0], const char *fmt, ...);
    ++__printf(3, 0) char *vsprintf_end(char *p, const char end[0], const char *fmt, va_list args);
      __printf(2, 3) __malloc char *kasprintf(gfp_t gfp, const char *fmt, ...);
      __printf(2, 0) __malloc char *kvasprintf(gfp_t gfp, const char *fmt, va_list args);
      __printf(2, 0) const char *kvasprintf_const(gfp_t gfp, const char *fmt, va_list args);
     
      ## lib/vsprintf.c ##
    -@@ lib/vsprintf.c: int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
    - }
    - EXPORT_SYMBOL(vsnprintf);
    - 
    -+/**
    -+ * vstprintf - Format a string and place it in a buffer
    -+ * @buf: The buffer to place the result into
    -+ * @size: The size of the buffer, including the trailing null space
    -+ * @fmt: The format string to use
    -+ * @args: Arguments for the format string
    -+ *
    -+ * The return value is the length of the new string.
    -+ * If the string is truncated, the function returns -E2BIG.
    -+ *
    -+ * If you're not already dealing with a va_list consider using stprintf().
    -+ *
    -+ * See the vsnprintf() documentation for format string extensions over C99.
    -+ */
    -+int vstprintf(char *buf, size_t size, const char *fmt, va_list args)
    -+{
    -+	int len;
    -+
    -+	len = vsnprintf(buf, size, fmt, args);
    -+
    -+	// It seems the kernel's vsnprintf() doesn't fail?
    -+	//if (unlikely(len < 0))
    -+	//	return -E2BIG;
    -+
    -+	if (unlikely(len >= size))
    -+		return -E2BIG;
    -+
    -+	return len;
    -+}
    -+EXPORT_SYMBOL(vstprintf);
    -+
    - /**
    -  * vscnprintf - Format a string and place it in a buffer
    -  * @buf: The buffer to place the result into
     @@ lib/vsprintf.c: int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
      }
      EXPORT_SYMBOL(vscnprintf);
      
     +/**
    -+ * vseprintf - Format a string and place it in a buffer
    ++ * vsprintf_end - va_list string end-delimited print formatted
     + * @p: The buffer to place the result into
     + * @end: A pointer to one past the last character in the buffer
     + * @fmt: The format string to use
    @@ lib/vsprintf.c: int vscnprintf(char *buf, size_t size, const char *fmt, va_list
     + * The return value is a pointer to the trailing '\0'.
     + * If @p is NULL, the function returns NULL.
     + * If the string is truncated, the function returns NULL.
    -+ *
    -+ * If you're not already dealing with a va_list consider using seprintf().
    ++ * If @end <= @p, the function returns NULL.
     + *
     + * See the vsnprintf() documentation for format string extensions over C99.
     + */
    -+char *vseprintf(char *p, const char end[0], const char *fmt, va_list args)
    ++char *vsprintf_end(char *p, const char end[0], const char *fmt, va_list args)
     +{
     +	int len;
    ++	size_t size;
     +
     +	if (unlikely(p == NULL))
     +		return NULL;
     +
    -+	len = vstprintf(p, end - p, fmt, args);
    -+	if (unlikely(len < 0))
    ++	size = end - p;
    ++	if (WARN_ON_ONCE(size == 0 || size > INT_MAX))
    ++		return NULL;
    ++
    ++	len = vsnprintf(p, size, fmt, args);
    ++	if (unlikely(len >= size))
     +		return NULL;
     +
     +	return p + len;
     +}
    -+EXPORT_SYMBOL(vseprintf);
    ++EXPORT_SYMBOL(vsprintf_end);
     +
      /**
       * snprintf - Format a string and place it in a buffer
       * @buf: The buffer to place the result into
    -@@ lib/vsprintf.c: int snprintf(char *buf, size_t size, const char *fmt, ...)
    - }
    - EXPORT_SYMBOL(snprintf);
    - 
    -+/**
    -+ * stprintf - Format a string and place it in a buffer
    -+ * @buf: The buffer to place the result into
    -+ * @size: The size of the buffer, including the trailing null space
    -+ * @fmt: The format string to use
    -+ * @...: Arguments for the format string
    -+ *
    -+ * The return value is the length of the new string.
    -+ * If the string is truncated, the function returns -E2BIG.
    -+ */
    -+
    -+int stprintf(char *buf, size_t size, const char *fmt, ...)
    -+{
    -+	va_list args;
    -+	int len;
    -+
    -+	va_start(args, fmt);
    -+	len = vstprintf(buf, size, fmt, args);
    -+	va_end(args);
    -+
    -+	return len;
    -+}
    -+EXPORT_SYMBOL(stprintf);
    -+
    - /**
    -  * scnprintf - Format a string and place it in a buffer
    -  * @buf: The buffer to place the result into
     @@ lib/vsprintf.c: int scnprintf(char *buf, size_t size, const char *fmt, ...)
      }
      EXPORT_SYMBOL(scnprintf);
      
     +/**
    -+ * seprintf - Format a string and place it in a buffer
    ++ * sprintf_end - string end-delimited print formatted
     + * @p: The buffer to place the result into
     + * @end: A pointer to one past the last character in the buffer
     + * @fmt: The format string to use
    @@ lib/vsprintf.c: int scnprintf(char *buf, size_t size, const char *fmt, ...)
     + * The return value is a pointer to the trailing '\0'.
     + * If @buf is NULL, the function returns NULL.
     + * If the string is truncated, the function returns NULL.
    ++ * If @end <= @p, the function returns NULL.
     + */
     +
    -+char *seprintf(char *p, const char end[0], const char *fmt, ...)
    ++char *sprintf_end(char *p, const char end[0], const char *fmt, ...)
     +{
     +	va_list args;
     +
     +	va_start(args, fmt);
    -+	p = vseprintf(p, end, fmt, args);
    ++	p = vsprintf_end(p, end, fmt, args);
     +	va_end(args);
     +
     +	return p;
     +}
    -+EXPORT_SYMBOL(seprintf);
    ++EXPORT_SYMBOL(sprintf_end);
     +
      /**
       * vsprintf - Format a string and place it in a buffer
2:  9c140de9842d ! 2:  894d02b08056 stacktrace, stackdepot: Add seprintf()-like variants of functions
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    stacktrace, stackdepot: Add seprintf()-like variants of functions
    -
    -    I think there's an anomaly in stack_depot_s*print().  If we have zero
    -    entries, we don't copy anything, which means the string is still not a
    -    string.  Normally, this function is called surrounded by other calls to
    -    s*printf(), which guarantee that there's a '\0', but maybe we should
    -    make sure to write a '\0' here?
    +    stacktrace, stackdepot: Add sprintf_end()-like variants of functions
     
         Cc: Kees Cook <kees@kernel.org>
         Cc: Christopher Bazley <chris.bazley.wg14@gmail.com>
    +    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    +    Cc: Marco Elver <elver@google.com>
    +    Cc: Michal Hocko <mhocko@suse.com>
    +    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    +    Cc: Al Viro <viro@zeniv.linux.org.uk>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## include/linux/stackdepot.h ##
    @@ include/linux/stackdepot.h: void stack_depot_print(depot_stack_handle_t stack);
      		       int spaces);
      
     +/**
    -+ * stack_depot_seprint - Print a stack trace from stack depot into a buffer
    ++ * stack_depot_sprint_end - Print a stack trace from stack depot into a buffer
     + *
     + * @handle:	Stack depot handle returned from stack_depot_save()
     + * @p:		Pointer to the print buffer
    @@ include/linux/stackdepot.h: void stack_depot_print(depot_stack_handle_t stack);
     + *
     + * Return:	Pointer to trailing '\0'; or NULL on truncation
     + */
    -+char *stack_depot_seprint(depot_stack_handle_t handle, char *p,
    -+                          const char end[0], int spaces);
    ++char *stack_depot_sprint_end(depot_stack_handle_t handle, char *p,
    ++                             const char end[0], int spaces);
     +
      /**
       * stack_depot_put - Drop a reference to a stack trace from stack depot
    @@ include/linux/stacktrace.h: void stack_trace_print(const unsigned long *trace, u
      		       int spaces);
      int stack_trace_snprint(char *buf, size_t size, const unsigned long *entries,
      			unsigned int nr_entries, int spaces);
    -+char *stack_trace_seprint(char *p, const char end[0],
    -+			  const unsigned long *entries, unsigned int nr_entries,
    -+			  int spaces);
    ++char *stack_trace_sprint_end(char *p, const char end[0],
    ++			     const unsigned long *entries,
    ++			     unsigned int nr_entries, int spaces);
      unsigned int stack_trace_save(unsigned long *store, unsigned int size,
      			      unsigned int skipnr);
      unsigned int stack_trace_save_tsk(struct task_struct *task,
    @@ kernel/stacktrace.c: int stack_trace_snprint(char *buf, size_t size, const unsig
      EXPORT_SYMBOL_GPL(stack_trace_snprint);
      
     +/**
    -+ * stack_trace_seprint - Print the entries in the stack trace into a buffer
    ++ * stack_trace_sprint_end - Print the entries in the stack trace into a buffer
     + * @p:		Pointer to the print buffer
     + * @end:	Pointer to one past the last element in the buffer
     + * @entries:	Pointer to storage array
    @@ kernel/stacktrace.c: int stack_trace_snprint(char *buf, size_t size, const unsig
     + *
     + * Return: Pointer to the trailing '\0'; or NULL on truncation.
     + */
    -+char *stack_trace_seprint(char *p, const char end[0],
    ++char *stack_trace_sprint_end(char *p, const char end[0],
     +			  const unsigned long *entries, unsigned int nr_entries,
     +			  int spaces)
     +{
    @@ kernel/stacktrace.c: int stack_trace_snprint(char *buf, size_t size, const unsig
     +		return 0;
     +
     +	for (i = 0; i < nr_entries; i++) {
    -+		p = seprintf(p, end, "%*c%pS\n", 1 + spaces, ' ',
    ++		p = sprintf_end(p, end, "%*c%pS\n", 1 + spaces, ' ',
     +			     (void *)entries[i]);
     +	}
     +
     +	return p;
     +}
    -+EXPORT_SYMBOL_GPL(stack_trace_seprint);
    ++EXPORT_SYMBOL_GPL(stack_trace_sprint_end);
     +
      #ifdef CONFIG_ARCH_STACKWALK
      
    @@ lib/stackdepot.c: int stack_depot_snprint(depot_stack_handle_t handle, char *buf
      }
      EXPORT_SYMBOL_GPL(stack_depot_snprint);
      
    -+char *stack_depot_seprint(depot_stack_handle_t handle, char *p,
    -+			  const char end[0], int spaces)
    ++char *stack_depot_sprint_end(depot_stack_handle_t handle, char *p,
    ++			     const char end[0], int spaces)
     +{
     +	unsigned long *entries;
     +	unsigned int nr_entries;
     +
     +	nr_entries = stack_depot_fetch(handle, &entries);
    -+	return nr_entries ? stack_trace_seprint(p, end, entries, nr_entries,
    -+						spaces) : p;
    ++	return nr_entries ?
    ++		stack_trace_sprint_end(p, end, entries, nr_entries, spaces)
    ++		: sprintf_end(p, end, "");
     +}
    -+EXPORT_SYMBOL_GPL(stack_depot_seprint);
    ++EXPORT_SYMBOL_GPL(stack_depot_sprint_end);
     +
      depot_stack_handle_t __must_check stack_depot_set_extra_bits(
      			depot_stack_handle_t handle, unsigned int extra_bits)
3:  033bf00f1fcf ! 3:  690ed4d22f57 mm: Use seprintf() instead of less ergonomic APIs
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    mm: Use seprintf() instead of less ergonomic APIs
    +    mm: Use sprintf_end() instead of less ergonomic APIs
     
         While doing this, I detected some anomalies in the existing code:
     
    @@ Commit message
     
                 This file uses the 'p += snprintf()' anti-pattern.  That will
                 overflow the pointer on truncation, which has undefined
    -            behavior.  Using seprintf(), this bug is fixed.
    +            behavior.  Using sprintf_end(), this bug is fixed.
     
                 As in the previous file, here there was also dead code in the
                 last scnprintf() call, by incrementing a pointer that is not
    @@ Commit message
                 a good reason (i.e., we may want to avoid calling
                 print_page_owner_memcg() if we truncated before).  Please review
                 if this amount of error handling is the right one, or if we want
    -            to add or remove some.  For seprintf(), a single test for null
    -            after the last call is enough to detect truncation.
    +            to add or remove some.  For sprintf_end(), a single test for
    +            null after the last call is enough to detect truncation.
     
         mm/slub.c:
     
                 Again, the 'p += snprintf()' anti-pattern.  This is UB, and by
    -            using seprintf() we've fixed the bug.
    +            using sprintf_end() we've fixed the bug.
     
    -    Fixes: f99e12b21b84 (2021-07-30; "kfence: add function to mask address bits")
    -    [alx: that commit introduced dead code]
    -    Fixes: af649773fb25 (2024-07-17; "mm/numa_balancing: teach mpol_to_str about the balancing mode")
    -    [alx: that commit added p+=snprintf() calls, which are UB]
    -    Fixes: 2291990ab36b (2008-04-28; "mempolicy: clean-up mpol-to-str() mempolicy formatting")
    -    [alx: that commit changed p+=sprintf() into p+=snprintf(), which is still UB]
    -    Fixes: 948927ee9e4f (2013-11-13; "mm, mempolicy: make mpol_to_str robust and always succeed")
    -    [alx: that commit changes old code into p+=snprintf(), which is still UB]
    -    [alx: that commit also produced dead code by leaving the last 'p+=...']
    -    Fixes: d65360f22406 (2022-09-26; "mm/slub: clean up create_unique_id()")
    -    [alx: that commit changed p+=sprintf() into p+=snprintf(), which is still UB]
         Cc: Kees Cook <kees@kernel.org>
         Cc: Christopher Bazley <chris.bazley.wg14@gmail.com>
         Cc: Sven Schnelle <svens@linux.ibm.com>
         Cc: Marco Elver <elver@google.com>
         Cc: Heiko Carstens <hca@linux.ibm.com>
         Cc: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
    -    Cc: "Huang, Ying" <ying.huang@intel.com>
         Cc: Andrew Morton <akpm@linux-foundation.org>
    -    Cc: Lee Schermerhorn <lee.schermerhorn@hp.com>
         Cc: Linus Torvalds <torvalds@linux-foundation.org>
         Cc: David Rientjes <rientjes@google.com>
         Cc: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
         Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com>
         Cc: Chao Yu <chao.yu@oppo.com>
         Cc: Vlastimil Babka <vbabka@suse.cz>
    +    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    +    Cc: Michal Hocko <mhocko@suse.com>
    +    Cc: Al Viro <viro@zeniv.linux.org.uk>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## mm/kfence/kfence_test.c ##
    @@ mm/kfence/kfence_test.c: static bool report_matches(const struct expect_report *
      	switch (r->type) {
      	case KFENCE_ERROR_OOB:
     -		cur += scnprintf(cur, end - cur, "BUG: KFENCE: out-of-bounds %s",
    -+		cur = seprintf(cur, end, "BUG: KFENCE: out-of-bounds %s",
    ++		cur = sprintf_end(cur, end, "BUG: KFENCE: out-of-bounds %s",
      				 get_access_type(r));
      		break;
      	case KFENCE_ERROR_UAF:
     -		cur += scnprintf(cur, end - cur, "BUG: KFENCE: use-after-free %s",
    -+		cur = seprintf(cur, end, "BUG: KFENCE: use-after-free %s",
    ++		cur = sprintf_end(cur, end, "BUG: KFENCE: use-after-free %s",
      				 get_access_type(r));
      		break;
      	case KFENCE_ERROR_CORRUPTION:
     -		cur += scnprintf(cur, end - cur, "BUG: KFENCE: memory corruption");
    -+		cur = seprintf(cur, end, "BUG: KFENCE: memory corruption");
    ++		cur = sprintf_end(cur, end, "BUG: KFENCE: memory corruption");
      		break;
      	case KFENCE_ERROR_INVALID:
     -		cur += scnprintf(cur, end - cur, "BUG: KFENCE: invalid %s",
    -+		cur = seprintf(cur, end, "BUG: KFENCE: invalid %s",
    ++		cur = sprintf_end(cur, end, "BUG: KFENCE: invalid %s",
      				 get_access_type(r));
      		break;
      	case KFENCE_ERROR_INVALID_FREE:
     -		cur += scnprintf(cur, end - cur, "BUG: KFENCE: invalid free");
    -+		cur = seprintf(cur, end, "BUG: KFENCE: invalid free");
    ++		cur = sprintf_end(cur, end, "BUG: KFENCE: invalid free");
      		break;
      	}
      
     -	scnprintf(cur, end - cur, " in %pS", r->fn);
    -+	seprintf(cur, end, " in %pS", r->fn);
    ++	sprintf_end(cur, end, " in %pS", r->fn);
      	/* The exact offset won't match, remove it; also strip module name. */
      	cur = strchr(expect[0], '+');
      	if (cur)
    @@ mm/kfence/kfence_test.c: static bool report_matches(const struct expect_report *
      	switch (r->type) {
      	case KFENCE_ERROR_OOB:
     -		cur += scnprintf(cur, end - cur, "Out-of-bounds %s at", get_access_type(r));
    -+		cur = seprintf(cur, end, "Out-of-bounds %s at", get_access_type(r));
    ++		cur = sprintf_end(cur, end, "Out-of-bounds %s at", get_access_type(r));
      		addr = arch_kfence_test_address(addr);
      		break;
      	case KFENCE_ERROR_UAF:
     -		cur += scnprintf(cur, end - cur, "Use-after-free %s at", get_access_type(r));
    -+		cur = seprintf(cur, end, "Use-after-free %s at", get_access_type(r));
    ++		cur = sprintf_end(cur, end, "Use-after-free %s at", get_access_type(r));
      		addr = arch_kfence_test_address(addr);
      		break;
      	case KFENCE_ERROR_CORRUPTION:
     -		cur += scnprintf(cur, end - cur, "Corrupted memory at");
    -+		cur = seprintf(cur, end, "Corrupted memory at");
    ++		cur = sprintf_end(cur, end, "Corrupted memory at");
      		break;
      	case KFENCE_ERROR_INVALID:
     -		cur += scnprintf(cur, end - cur, "Invalid %s at", get_access_type(r));
    -+		cur = seprintf(cur, end, "Invalid %s at", get_access_type(r));
    ++		cur = sprintf_end(cur, end, "Invalid %s at", get_access_type(r));
      		addr = arch_kfence_test_address(addr);
      		break;
      	case KFENCE_ERROR_INVALID_FREE:
     -		cur += scnprintf(cur, end - cur, "Invalid free of");
    -+		cur = seprintf(cur, end, "Invalid free of");
    ++		cur = sprintf_end(cur, end, "Invalid free of");
      		break;
      	}
      
     -	cur += scnprintf(cur, end - cur, " 0x%p", (void *)addr);
    -+	seprintf(cur, end, " 0x%p", (void *)addr);
    ++	sprintf_end(cur, end, " 0x%p", (void *)addr);
      
      	spin_lock_irqsave(&observed.lock, flags);
      	if (!report_available())
    @@ mm/kmsan/kmsan_test.c: static bool report_matches(const struct expect_report *r)
      	end = &expected_header[sizeof(expected_header) - 1];
      
     -	cur += scnprintf(cur, end - cur, "BUG: KMSAN: %s", r->error_type);
    -+	cur = seprintf(cur, end, "BUG: KMSAN: %s", r->error_type);
    ++	cur = sprintf_end(cur, end, "BUG: KMSAN: %s", r->error_type);
      
     -	scnprintf(cur, end - cur, " in %s", r->symbol);
    -+	seprintf(cur, end, " in %s", r->symbol);
    ++	sprintf_end(cur, end, " in %s", r->symbol);
      	/* The exact offset won't match, remove it; also strip module name. */
      	cur = strchr(expected_header, '+');
      	if (cur)
    @@ mm/mempolicy.c: void mpol_to_str(char *buffer, int maxlen, struct mempolicy *pol
      	default:
      		WARN_ON_ONCE(1);
     -		snprintf(p, maxlen, "unknown");
    -+		seprintf(p, e, "unknown");
    ++		sprintf_end(p, e, "unknown");
      		return;
      	}
      
     -	p += snprintf(p, maxlen, "%s", policy_modes[mode]);
    -+	p = seprintf(p, e, "%s", policy_modes[mode]);
    ++	p = sprintf_end(p, e, "%s", policy_modes[mode]);
      
      	if (flags & MPOL_MODE_FLAGS) {
     -		p += snprintf(p, buffer + maxlen - p, "=");
    -+		p = seprintf(p, e, "=");
    ++		p = sprintf_end(p, e, "=");
      
      		/*
      		 * Static and relative are mutually exclusive.
      		 */
      		if (flags & MPOL_F_STATIC_NODES)
     -			p += snprintf(p, buffer + maxlen - p, "static");
    -+			p = seprintf(p, e, "static");
    ++			p = sprintf_end(p, e, "static");
      		else if (flags & MPOL_F_RELATIVE_NODES)
     -			p += snprintf(p, buffer + maxlen - p, "relative");
    -+			p = seprintf(p, e, "relative");
    ++			p = sprintf_end(p, e, "relative");
      
      		if (flags & MPOL_F_NUMA_BALANCING) {
      			if (!is_power_of_2(flags & MPOL_MODE_FLAGS))
     -				p += snprintf(p, buffer + maxlen - p, "|");
     -			p += snprintf(p, buffer + maxlen - p, "balancing");
    -+				p = seprintf(p, e, "|");
    -+			p = seprintf(p, e, "balancing");
    ++				p = sprintf_end(p, e, "|");
    ++			p = sprintf_end(p, e, "balancing");
      		}
      	}
      
      	if (!nodes_empty(nodes))
     -		p += scnprintf(p, buffer + maxlen - p, ":%*pbl",
     -			       nodemask_pr_args(&nodes));
    -+		seprintf(p, e, ":%*pbl", nodemask_pr_args(&nodes));
    ++		sprintf_end(p, e, ":%*pbl", nodemask_pr_args(&nodes));
      }
      
      #ifdef CONFIG_SYSFS
    @@ mm/page_owner.c: static inline int print_page_owner_memcg(char *kbuf, size_t cou
      	if (memcg_data & MEMCG_DATA_OBJEXTS)
     -		ret += scnprintf(kbuf + ret, count - ret,
     -				"Slab cache page\n");
    -+		p = seprintf(p, end, "Slab cache page\n");
    ++		p = sprintf_end(p, end, "Slab cache page\n");
      
      	memcg = page_memcg_check(page);
      	if (!memcg)
    @@ mm/page_owner.c: static inline int print_page_owner_memcg(char *kbuf, size_t cou
      	online = (memcg->css.flags & CSS_ONLINE);
      	cgroup_name(memcg->css.cgroup, name, sizeof(name));
     -	ret += scnprintf(kbuf + ret, count - ret,
    -+	p = seprintf(p, end,
    ++	p = sprintf_end(p, end,
      			"Charged %sto %smemcg %s\n",
      			PageMemcgKmem(page) ? "(via objcg) " : "",
      			online ? "" : "offline ",
    @@ mm/page_owner.c: print_page_owner(char __user *buf, size_t count, unsigned long
     -	ret = scnprintf(kbuf, count,
     +	p = kbuf;
     +	e = kbuf + count;
    -+	p = seprintf(p, e,
    ++	p = sprintf_end(p, e,
      			"Page allocated via order %u, mask %#x(%pGg), pid %d, tgid %d (%s), ts %llu ns\n",
      			page_owner->order, page_owner->gfp_mask,
      			&page_owner->gfp_mask, page_owner->pid,
    @@ mm/page_owner.c: print_page_owner(char __user *buf, size_t count, unsigned long
      	pageblock_mt = get_pageblock_migratetype(page);
      	page_mt  = gfp_migratetype(page_owner->gfp_mask);
     -	ret += scnprintf(kbuf + ret, count - ret,
    -+	p = seprintf(p, e,
    ++	p = sprintf_end(p, e,
      			"PFN 0x%lx type %s Block %lu type %s Flags %pGp\n",
      			pfn,
      			migratetype_names[page_mt],
    @@ mm/page_owner.c: print_page_owner(char __user *buf, size_t count, unsigned long
     -	ret += stack_depot_snprint(handle, kbuf + ret, count - ret, 0);
     -	if (ret >= count)
     -		goto err;
    -+	p = stack_depot_seprint(handle, p, e, 0);
    ++	p = stack_depot_sprint_end(handle, p, e, 0);
     +	if (p == NULL)
     +		goto err;  // XXX: Should we remove this error handling?
      
      	if (page_owner->last_migrate_reason != -1) {
     -		ret += scnprintf(kbuf + ret, count - ret,
    -+		p = seprintf(p, e,
    ++		p = sprintf_end(p, e,
      			"Page has been migrated, last migrate reason: %s\n",
      			migrate_reason_names[page_owner->last_migrate_reason]);
      	}
    @@ mm/page_owner.c: print_page_owner(char __user *buf, size_t count, unsigned long
      
     -	ret += snprintf(kbuf + ret, count - ret, "\n");
     -	if (ret >= count)
    -+	p = seprintf(p, e, "\n");
    ++	p = sprintf_end(p, e, "\n");
     +	if (p == NULL)
      		goto err;
      
    @@ mm/slub.c: static char *create_unique_id(struct kmem_cache *s)
      	if (p != name + 1)
      		*p++ = '-';
     -	p += snprintf(p, ID_STR_LENGTH - (p - name), "%07u", s->size);
    -+	p = seprintf(p, e, "%07u", s->size);
    ++	p = sprintf_end(p, e, "%07u", s->size);
      
     -	if (WARN_ON(p > name + ID_STR_LENGTH - 1)) {
     +	if (WARN_ON(p == NULL)) {
4:  d8bd0e1d308b ! 4:  e05c5afabb3c array_size.h: Add ENDOF()
    @@ Metadata
      ## Commit message ##
         array_size.h: Add ENDOF()
     
    -    This macro is useful to calculate the second argument to seprintf(),
    +    This macro is useful to calculate the second argument to sprintf_end(),
         avoiding off-by-one bugs.
     
         Cc: Kees Cook <kees@kernel.org>
         Cc: Christopher Bazley <chris.bazley.wg14@gmail.com>
    +    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    +    Cc: Marco Elver <elver@google.com>
    +    Cc: Michal Hocko <mhocko@suse.com>
    +    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    +    Cc: Al Viro <viro@zeniv.linux.org.uk>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## include/linux/array_size.h ##
5:  740755c1a888 ! 5:  44a5cfc82acf mm: Fix benign off-by-one bugs
    @@ Commit message
         'end' --that is, at most the terminating null byte will be written at
         'end-1'--.
     
    -    Fixes: bc8fbc5f305a (2021-02-26; "kfence: add test suite")
    -    Fixes: 8ed691b02ade (2022-10-03; "kmsan: add tests for KMSAN")
    +    Acked-by: Marco Elver <elver@google.com>
         Cc: Kees Cook <kees@kernel.org>
         Cc: Christopher Bazley <chris.bazley.wg14@gmail.com>
         Cc: Alexander Potapenko <glider@google.com>
    -    Cc: Marco Elver <elver@google.com>
         Cc: Dmitry Vyukov <dvyukov@google.com>
         Cc: Alexander Potapenko <glider@google.com>
         Cc: Jann Horn <jannh@google.com>
         Cc: Andrew Morton <akpm@linux-foundation.org>
         Cc: Linus Torvalds <torvalds@linux-foundation.org>
    +    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    +    Cc: Marco Elver <elver@google.com>
    +    Cc: Michal Hocko <mhocko@suse.com>
    +    Cc: Al Viro <viro@zeniv.linux.org.uk>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## mm/kfence/kfence_test.c ##
    @@ mm/kfence/kfence_test.c: static bool report_matches(const struct expect_report *
     +	end = ENDOF(expect[0]);
      	switch (r->type) {
      	case KFENCE_ERROR_OOB:
    - 		cur = seprintf(cur, end, "BUG: KFENCE: out-of-bounds %s",
    + 		cur = sprintf_end(cur, end, "BUG: KFENCE: out-of-bounds %s",
     @@ mm/kfence/kfence_test.c: static bool report_matches(const struct expect_report *r)
      
      	/* Access information */
    @@ mm/kmsan/kmsan_test.c: static bool report_matches(const struct expect_report *r)
     -	end = &expected_header[sizeof(expected_header) - 1];
     +	end = ENDOF(expected_header);
      
    - 	cur = seprintf(cur, end, "BUG: KMSAN: %s", r->error_type);
    + 	cur = sprintf_end(cur, end, "BUG: KMSAN: %s", r->error_type);
      
6:  44d05559398c ! 6:  0314948eb225 sprintf: Add [V]STPRINTF()
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    sprintf: Add [V]STPRINTF()
    +    sprintf: Add [V]SPRINTF_END()
     
    -    These macros take the array size argument implicitly to avoid programmer
    -    mistakes.  This guarantees that the input is an array, unlike the common
    -    call
    +    These macros take the end of the array argument implicitly to avoid
    +    programmer mistakes.  This guarantees that the input is an array, unlike
     
                 snprintf(buf, sizeof(buf), ...);
     
    -    which is dangerous if the programmer passes a pointer.
    +    which is dangerous if the programmer passes a pointer instead of an
    +    array.
     
         These macros are essentially the same as the 2-argument version of
    -    strscpy(), but with a formatted string.
    +    strscpy(), but with a formatted string, and returning a pointer to the
    +    terminating '\0' (or NULL, on error).
     
    +    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    +    Cc: Marco Elver <elver@google.com>
    +    Cc: Michal Hocko <mhocko@suse.com>
    +    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    +    Cc: Al Viro <viro@zeniv.linux.org.uk>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## include/linux/sprintf.h ##
    @@ include/linux/sprintf.h
      #include <linux/types.h>
     +#include <linux/array_size.h>
     +
    -+#define STPRINTF(a, fmt, ...)  stprintf(a, ARRAY_SIZE(a), fmt, ##__VA_ARGS__)
    -+#define VSTPRINTF(a, fmt, ap)  vstprintf(a, ARRAY_SIZE(a), fmt, ap)
    ++#define SPRINTF_END(a, fmt, ...)  sprintf_end(a, ENDOF(a), fmt, ##__VA_ARGS__)
    ++#define VSPRINTF_END(a, fmt, ap)  vsprintf_end(a, ENDOF(a), fmt, ap)
      
      int num_to_str(char *buf, int size, unsigned long long num, unsigned int width);
      
7:  d0e95db3c80a ! 7:  f99632f42eee mm: Use [V]STPRINTF() to avoid specifying the array size
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    mm: Use [V]STPRINTF() to avoid specifying the array size
    +    mm: Use [V]SPRINTF_END() to avoid specifying the array size
     
    +    Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
    +    Cc: Marco Elver <elver@google.com>
    +    Cc: Michal Hocko <mhocko@suse.com>
    +    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    +    Cc: Al Viro <viro@zeniv.linux.org.uk>
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
     
      ## mm/backing-dev.c ##
    @@ mm/backing-dev.c: int bdi_register_va(struct backing_dev_info *bdi, const char *
      		return 0;
      
     -	vsnprintf(bdi->dev_name, sizeof(bdi->dev_name), fmt, args);
    -+	VSTPRINTF(bdi->dev_name, fmt, args);
    ++	VSPRINTF_END(bdi->dev_name, fmt, args);
      	dev = device_create(&bdi_class, NULL, MKDEV(0, 0), bdi, bdi->dev_name);
      	if (IS_ERR(dev))
      		return PTR_ERR(dev);
    @@ mm/cma.c: static int __init cma_new_area(const char *name, phys_addr_t size,
      
      	if (name)
     -		snprintf(cma->name, CMA_MAX_NAME, "%s", name);
    -+		STPRINTF(cma->name, "%s", name);
    ++		SPRINTF_END(cma->name, "%s", name);
      	else
     -		snprintf(cma->name, CMA_MAX_NAME,  "cma%d\n", cma_area_count);
    -+		STPRINTF(cma->name, "cma%d\n", cma_area_count);
    ++		SPRINTF_END(cma->name, "cma%d\n", cma_area_count);
      
      	cma->available_count = cma->count = size >> PAGE_SHIFT;
      	cma->order_per_bit = order_per_bit;
    @@ mm/cma_debug.c: static void cma_debugfs_add_one(struct cma *cma, struct dentry *
      	for (r = 0; r < cma->nranges; r++) {
      		cmr = &cma->ranges[r];
     -		snprintf(rdirname, sizeof(rdirname), "%d", r);
    -+		STPRINTF(rdirname, "%d", r);
    ++		SPRINTF_END(rdirname, "%d", r);
      		dir = debugfs_create_dir(rdirname, rangedir);
      		debugfs_create_file("base_pfn", 0444, dir,
      			    &cmr->base_pfn, &cma_debugfs_fops);
    @@ mm/hugetlb.c: void __init hugetlb_add_hstate(unsigned int order)
      	INIT_LIST_HEAD(&h->hugepage_activelist);
     -	snprintf(h->name, HSTATE_NAME_LEN, "hugepages-%lukB",
     -					huge_page_size(h)/SZ_1K);
    -+	STPRINTF(h->name, "hugepages-%lukB", huge_page_size(h)/SZ_1K);
    ++	SPRINTF_END(h->name, "hugepages-%lukB", huge_page_size(h)/SZ_1K);
      
      	parsed_hstate = h;
      }
    @@ mm/hugetlb_cgroup.c: hugetlb_cgroup_cfttypes_init(struct hstate *h, struct cftyp
      		*cft = *tmpl;
      		/* rebuild the name */
     -		snprintf(cft->name, MAX_CFTYPE_NAME, "%s.%s", buf, tmpl->name);
    -+		STPRINTF(cft->name, "%s.%s", buf, tmpl->name);
    ++		SPRINTF_END(cft->name, "%s.%s", buf, tmpl->name);
      		/* rebuild the private */
      		cft->private = MEMFILE_PRIVATE(idx, tmpl->private);
      		/* rebuild the file_offset */
    @@ mm/hugetlb_cma.c: void __init hugetlb_cma_reserve(int order)
      		size = round_up(size, PAGE_SIZE << order);
      
     -		snprintf(name, sizeof(name), "hugetlb%d", nid);
    -+		STPRINTF(name, "hugetlb%d", nid);
    ++		SPRINTF_END(name, "hugetlb%d", nid);
      		/*
      		 * Note that 'order per bit' is based on smallest size that
      		 * may be returned to CMA allocator in the case of
    @@ mm/kasan/report.c: static void print_memory_metadata(const void *addr)
      
     -		snprintf(buffer, sizeof(buffer),
     -				(i == 0) ? ">%px: " : " %px: ", row);
    -+		STPRINTF(buffer, (i == 0) ? ">%px: " : " %px: ", row);
    ++		SPRINTF_END(buffer, (i == 0) ? ">%px: " : " %px: ", row);
      
      		/*
      		 * We should not pass a shadow pointer to generic
    @@ mm/memblock.c: static void __init_memblock memblock_dump(struct memblock_type *t
      #ifdef CONFIG_NUMA
      		if (numa_valid_node(memblock_get_region_node(rgn)))
     -			snprintf(nid_buf, sizeof(nid_buf), " on node %d",
    -+			STPRINTF(nid_buf, " on node %d",
    ++			SPRINTF_END(nid_buf, " on node %d",
      				 memblock_get_region_node(rgn));
      #endif
      		pr_info(" %s[%#x]\t[%pa-%pa], %pa bytes%s flags: %#x\n",
    @@ mm/memblock.c: int reserve_mem_release_by_name(const char *name)
      	start = phys_to_virt(map->start);
      	end = start + map->size - 1;
     -	snprintf(buf, sizeof(buf), "reserve_mem:%s", name);
    -+	STPRINTF(buf, "reserve_mem:%s", name);
    ++	SPRINTF_END(buf, "reserve_mem:%s", name);
      	free_reserved_area(start, end, 0, buf);
      	map->size = 0;
      
    @@ mm/percpu.c: int __init pcpu_page_first_chunk(size_t reserved_size, pcpu_fc_cpu_
      	int nr_g0_units;
      
     -	snprintf(psize_str, sizeof(psize_str), "%luK", PAGE_SIZE >> 10);
    -+	STPRINTF(psize_str, "%luK", PAGE_SIZE >> 10);
    ++	SPRINTF_END(psize_str, "%luK", PAGE_SIZE >> 10);
      
      	ai = pcpu_build_alloc_info(reserved_size, 0, PAGE_SIZE, NULL);
      	if (IS_ERR(ai))
    @@ mm/shrinker_debug.c: int shrinker_debugfs_add(struct shrinker *shrinker)
      	shrinker->debugfs_id = id;
      
     -	snprintf(buf, sizeof(buf), "%s-%d", shrinker->name, id);
    -+	STPRINTF(buf, "%s-%d", shrinker->name, id);
    ++	SPRINTF_END(buf, "%s-%d", shrinker->name, id);
      
      	/* create debugfs entry */
      	entry = debugfs_create_dir(buf, shrinker_debugfs_root);
    @@ mm/zswap.c: static struct zswap_pool *zswap_pool_create(char *type, char *compre
      
      	/* unique name for each pool specifically required by zsmalloc */
     -	snprintf(name, 38, "zswap%x", atomic_inc_return(&zswap_pools_count));
    -+	STPRINTF(name, "zswap%x", atomic_inc_return(&zswap_pools_count));
    ++	SPRINTF_END(name, "zswap%x", atomic_inc_return(&zswap_pools_count));
      	pool->zpool = zpool_create_pool(type, name, gfp);
      	if (!pool->zpool) {
      		pr_err("%s zpool not available\n", type);
-- 
2.50.0


  parent reply	other threads:[~2025-07-10  2:47 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-05 20:33 [RFC v1 0/3] Add and use seprintf() " Alejandro Colomar
2025-07-05 20:33 ` [RFC v1 1/3] vsprintf: Add [v]seprintf(), [v]stprintf() Alejandro Colomar
2025-07-05 20:40   ` Alejandro Colomar
2025-07-07  9:47   ` Alexander Potapenko
2025-07-07 14:59     ` Alejandro Colomar
2025-07-05 20:33 ` [RFC v1 2/3] stacktrace, stackdepot: Add seprintf()-like variants of functions Alejandro Colomar
2025-07-05 20:33 ` [RFC v1 3/3] mm: Use seprintf() instead of less ergonomic APIs Alejandro Colomar
2025-07-05 21:54   ` Alejandro Colomar
2025-07-06 17:37 ` [RFC v2 0/5] Add and use " Alejandro Colomar
2025-07-06 17:37   ` [RFC v2 1/5] vsprintf: Add [v]seprintf(), [v]stprintf() Alejandro Colomar
2025-07-06 17:37   ` [RFC v2 2/5] stacktrace, stackdepot: Add seprintf()-like variants of functions Alejandro Colomar
2025-07-06 17:37   ` [RFC v2 3/5] mm: Use seprintf() instead of less ergonomic APIs Alejandro Colomar
2025-07-06 17:37   ` [RFC v2 4/5] array_size.h: Add ENDOF() Alejandro Colomar
2025-07-06 17:37   ` [RFC v2 5/5] mm: Fix benign off-by-one bugs Alejandro Colomar
2025-07-07  5:06   ` [RFC v3 0/7] Add and use seprintf() instead of less ergonomic APIs Alejandro Colomar
2025-07-07  5:06     ` [RFC v3 1/7] vsprintf: Add [v]seprintf(), [v]stprintf() Alejandro Colomar
2025-07-07  5:06     ` [RFC v3 2/7] stacktrace, stackdepot: Add seprintf()-like variants of functions Alejandro Colomar
2025-07-07  5:06     ` [RFC v3 3/7] mm: Use seprintf() instead of less ergonomic APIs Alejandro Colomar
2025-07-07  7:44       ` Marco Elver
2025-07-07 14:39         ` Alejandro Colomar
2025-07-07 14:58           ` Marco Elver
2025-07-07 18:51             ` Alejandro Colomar
2025-07-07 19:08               ` Marco Elver
2025-07-07 20:53                 ` Alejandro Colomar
2025-07-07 19:17       ` Linus Torvalds
2025-07-07 19:35         ` Al Viro
2025-07-07 20:46           ` Linus Torvalds
2025-07-07 20:29         ` Alejandro Colomar
2025-07-07 20:49           ` Linus Torvalds
2025-07-07 21:05             ` Alejandro Colomar
2025-07-07 21:26               ` Alejandro Colomar
2025-07-07 22:17                 ` Linus Torvalds
2025-07-08  2:20                   ` Alejandro Colomar
2025-07-12 20:58         ` Christopher Bazley
2025-07-14  7:57           ` Christopher Bazley
2025-07-07  5:06     ` [RFC v3 4/7] array_size.h: Add ENDOF() Alejandro Colomar
2025-07-07  5:06     ` [RFC v3 5/7] mm: Fix benign off-by-one bugs Alejandro Colomar
2025-07-07  7:46       ` Marco Elver
2025-07-07  7:53         ` Michal Hocko
2025-07-07 14:42           ` Alejandro Colomar
2025-07-07 15:12             ` Michal Hocko
2025-07-07 15:29               ` Alejandro Colomar
2025-07-07  5:06     ` [RFC v3 6/7] sprintf: Add [V]STPRINTF() Alejandro Colomar
2025-07-07  5:06     ` [RFC v3 7/7] mm: Use [V]STPRINTF() to avoid specifying the array size Alejandro Colomar
2025-07-07  5:11     ` [RFC v3 0/7] Add and use seprintf() instead of less ergonomic APIs Alejandro Colomar
2025-07-10  2:47   ` Alejandro Colomar [this message]
2025-07-10  2:47     ` alx-0049r2 - add seprintf() Alejandro Colomar
2025-07-10  2:48     ` [RFC v4 1/7] vsprintf: Add [v]sprintf_end() Alejandro Colomar
2025-07-10  2:48     ` [RFC v4 2/7] stacktrace, stackdepot: Add sprintf_end()-like variants of functions Alejandro Colomar
2025-07-10  2:48     ` [RFC v4 3/7] mm: Use sprintf_end() instead of less ergonomic APIs Alejandro Colomar
2025-07-10  2:48     ` [RFC v4 4/7] array_size.h: Add ENDOF() Alejandro Colomar
2025-07-10  2:48     ` [RFC v4 5/7] mm: Fix benign off-by-one bugs Alejandro Colomar
2025-07-10  2:48     ` [RFC v4 6/7] sprintf: Add [V]SPRINTF_END() Alejandro Colomar
2025-07-10 15:52       ` Linus Torvalds
2025-07-10 18:30         ` Alejandro Colomar
2025-07-10 21:21           ` Alejandro Colomar
2025-07-10 22:08             ` Linus Torvalds
2025-07-10  2:49     ` [RFC v4 7/7] mm: Use [V]SPRINTF_END() to avoid specifying the array size Alejandro Colomar
2025-07-10 21:30   ` [RFC v5 0/7] Add and use sprintf_{end,array}() instead of less ergonomic APIs Alejandro Colomar
2025-07-10 21:30     ` [RFC v5 1/7] vsprintf: Add [v]sprintf_end() Alejandro Colomar
2025-07-10 21:30     ` [RFC v5 2/7] stacktrace, stackdepot: Add sprintf_end()-like variants of functions Alejandro Colomar
2025-07-10 21:30     ` [RFC v5 3/7] mm: Use sprintf_end() instead of less ergonomic APIs Alejandro Colomar
2025-07-10 21:31     ` [RFC v5 4/7] array_size.h: Add ENDOF() Alejandro Colomar
2025-07-10 21:31     ` [RFC v5 5/7] mm: Fix benign off-by-one bugs Alejandro Colomar
2025-07-10 21:31     ` [RFC v5 6/7] sprintf: Add [v]sprintf_array() Alejandro Colomar
2025-07-10 21:58       ` Linus Torvalds
2025-07-10 23:23         ` Alejandro Colomar
2025-07-10 23:24           ` Alejandro Colomar
2025-07-11  0:19           ` Alejandro Colomar
2025-07-11 17:43           ` David Laight
2025-07-11 19:17             ` Alejandro Colomar
2025-07-11 19:21               ` Alejandro Colomar
2025-07-11  6:05         ` Martin Uecker
2025-07-11  6:19           ` Martin Uecker
2025-07-11 17:45           ` David Laight
2025-07-11 17:58             ` Linus Torvalds
2025-07-11 19:24               ` Matthew Wilcox
2025-07-15  5:19               ` Kees Cook
2025-07-15  6:24                 ` Martin Uecker
2025-07-17 23:44                   ` Kees Cook
2025-07-15  7:08                 ` Alejandro Colomar
2025-07-17 23:47                   ` Kees Cook
2025-07-18  0:56                     ` Alejandro Colomar
2025-07-11 18:01             ` Martin Uecker
2025-07-10 21:31     ` [RFC v5 7/7] mm: Use [v]sprintf_array() to avoid specifying the array size Alejandro Colomar
2025-07-11  1:56   ` [RFC v6 0/8] Add and use sprintf_{end,trunc,array}() instead of less ergonomic APIs Alejandro Colomar
2025-07-11  1:56     ` [RFC v6 1/8] vsprintf: Add [v]sprintf_trunc() Alejandro Colomar
2025-07-11  1:56     ` [RFC v6 2/8] vsprintf: Add [v]sprintf_end() Alejandro Colomar
2025-07-11  1:56     ` [RFC v6 3/8] sprintf: Add [v]sprintf_array() Alejandro Colomar
2025-07-11  1:56     ` [RFC v6 4/8] stacktrace, stackdepot: Add sprintf_end()-like variants of functions Alejandro Colomar
2025-07-11  1:57     ` [RFC v6 5/8] mm: Use sprintf_end() instead of less ergonomic APIs Alejandro Colomar
2025-07-11  1:57     ` [RFC v6 6/8] array_size.h: Add ENDOF() Alejandro Colomar
2025-07-11  1:57     ` [RFC v6 7/8] mm: Fix benign off-by-one bugs Alejandro Colomar
2025-07-11  1:57     ` [RFC v6 8/8] mm: Use [v]sprintf_array() to avoid specifying the array size Alejandro Colomar
2025-07-08  6:43 ` [RFC v1 0/3] Add and use seprintf() instead of less ergonomic APIs Rasmus Villemoes
2025-07-08 11:36   ` Alejandro Colomar
2025-07-08 13:51     ` Rasmus Villemoes
2025-07-08 16:14       ` Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=cover.1752113247.git.alx@kernel.org \
    --to=alx@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=andrew@digital-domain.net \
    --cc=chris.bazley.wg14@gmail.com \
    --cc=cl@linux.com \
    --cc=dvyukov@google.com \
    --cc=elver@google.com \
    --cc=glider@google.com \
    --cc=harry.yoo@oracle.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=kees@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux@rasmusvillemoes.dk \
    --cc=mhocko@suse.com \
    --cc=pinskia@gmail.com \
    --cc=rientjes@google.com \
    --cc=roman.gushchin@linux.dev \
    --cc=sam@gentoo.org \
    --cc=torvalds@linux-foundation.org \
    --cc=uecker@tugraz.at \
    --cc=vbabka@suse.cz \
    --cc=viro@zeniv.linux.org.uk \
    --cc=~hallyn/shadow@lists.sr.ht \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®