All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kees Cook <kees@kernel.org>
To: Bill Wendling <morbo@google.com>
Cc: "Kees Cook" <kees@kernel.org>,
	"Matthew Wilcox (Oracle)" <willy@infradead.org>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
	"David Gow" <david@davidgow.net>,
	"Petr Mladek" <pmladek@suse.com>,
	"Shuvam Pandey" <shuvampandey1@gmail.com>,
	"Steven Rostedt" <rostedt@goodmis.org>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Sergey Senozhatsky" <senozhatsky@chromium.org>,
	"Günther Noack" <gnoack@google.com>,
	"Mickaël Salaün" <mic@digikod.net>,
	"Masami Hiramatsu" <mhiramat@kernel.org>,
	"Mathieu Desnoyers" <mathieu.desnoyers@efficios.com>,
	"Jiri Kosina" <jikos@kernel.org>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"Andrii Nakryiko" <andrii@kernel.org>,
	"Eduard Zingerman" <eddyz87@gmail.com>,
	"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
	"Martin KaFai Lau" <martin.lau@linux.dev>,
	"Song Liu" <song@kernel.org>,
	"Yonghong Song" <yonghong.song@linux.dev>,
	"Jiri Olsa" <jolsa@kernel.org>,
	"Emil Tsalapatis" <emil@etsalapatis.com>,
	"Ihor Solodrai" <ihor.solodrai@linux.dev>,
	"Christophe Leroy (CS GROUP)" <chleroy@kernel.org>,
	"Uwe Kleine-König" <u.kleine-koenig@baylibre.com>,
	"Madhavan Srinivasan" <maddy@linux.ibm.com>,
	"Michael Ellerman" <mpe@ellerman.id.au>,
	"Nicholas Piggin" <npiggin@gmail.com>,
	"Shivaprasad G Bhat" <sbhat@linux.ibm.com>,
	"Thorsten Blum" <blum@kernel.org>,
	"Alison Schofield" <alison.schofield@intel.com>,
	"Dave Jiang" <dave.jiang@intel.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Guangshuo Li" <lgs201920130244@gmail.com>,
	"Ira Weiny" <iweiny@kernel.org>,
	"Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>,
	"Vishal Verma" <vishal.l.verma@intel.com>,
	"Randy Dunlap" <rdunlap@infradead.org>,
	"Shuah Khan" <skhan@linuxfoundation.org>,
	linux-kernel@vger.kernel.org, bpf@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	linux-trace-kernel@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org, nvdimm@lists.linux.dev,
	linux-doc@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: [PATCH v4 08/11] seq_buf: Add seq_buf_init_append()
Date: Fri,  2 Oct 2026 20:59:13 -0700	[thread overview]
Message-ID: <20261003035921.1918874-8-kees@kernel.org> (raw)
In-Reply-To: <20261003035906.too.263-kees@kernel.org>

From: Bill Wendling <morbo@google.com>

Several strlcat() call sites being converted to seq_buf need behavior
seq_buf doesn't currently provide. The normal seq_buf_init() always
sets the new buffer size to 0 via seq_buf_clear(). Code migrating from
strlcat(buf, ...), which appends to whatever buf already contains,
can't use seq_buf_init() without discarding that existing content. Add
seq_buf_init_append(), which preserves the existing contents and positions
the seq_buf to append after it. A buffer with no NUL within its size
starts out overflowed, as strlcat() treats it as already truncated.
Add KUnit tests for behavior coverage.

Tests passed under qemu on ARCH=x86_64 with GCC 16.2.0 and CONFIG_KASAN=y,
and on big-endian ARCH=s390 with GCC s390x-linux-gnu 16.2.0.

Assisted-by: LLM
Signed-off-by: Bill Wendling <morbo@google.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Co-developed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Kees Cook <kees@kernel.org>
---
 include/linux/seq_buf.h   | 25 +++++++++++++++
 lib/tests/seq_buf_kunit.c | 67 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)

diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h
index 195e612a212a..50b1e78eeea6 100644
--- a/include/linux/seq_buf.h
+++ b/include/linux/seq_buf.h
@@ -71,6 +71,31 @@ seq_buf_set_overflow(struct seq_buf *s)
 	s->len = s->size + 1;
 }
 
+/**
+ * seq_buf_init_append - initialize a seq_buf over a buffer that may
+ *			 already hold NUL-terminated content
+ * @s: the seq_buf handle
+ * @buf: pointer to the (possibly non-empty) buffer
+ * @size: total size of @buf
+ *
+ * Unlike seq_buf_init(), which always starts @buf at len=0, this
+ * preserves whatever NUL-terminated content @buf already holds and
+ * positions @s to append after it. Useful for converting code that used
+ * to append to an existing buffer with strlcat()/scnprintf() and friends.
+ *
+ * If @buf holds no NUL within @size, @s starts out overflowed, as
+ * strlcat() treats such a buffer as already truncated.
+ */
+static inline void
+seq_buf_init_append(struct seq_buf *s, char *buf, unsigned int size)
+{
+	s->buffer = buf;
+	s->size = size;
+	s->len = strnlen(buf, size);
+	if (s->len == size)
+		seq_buf_set_overflow(s);
+}
+
 /*
  * How much buffer is left on the seq_buf?
  */
diff --git a/lib/tests/seq_buf_kunit.c b/lib/tests/seq_buf_kunit.c
index b6fc7b784859..170524146892 100644
--- a/lib/tests/seq_buf_kunit.c
+++ b/lib/tests/seq_buf_kunit.c
@@ -29,6 +29,72 @@ static void seq_buf_init_test(struct kunit *test)
 	KUNIT_EXPECT_EQ(test, seq_buf_strlen(&s), 0);
 }
 
+static void seq_buf_init_append_test(struct kunit *test)
+{
+	char buf[32] = "hello";
+	struct seq_buf s;
+
+	/* Initial string contents match. */
+	seq_buf_init_append(&s, buf, sizeof(buf));
+	KUNIT_EXPECT_EQ(test, s.size, 32);
+	KUNIT_EXPECT_EQ(test, s.len, 5);
+	KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
+	KUNIT_EXPECT_EQ(test, seq_buf_buffer_left(&s), 32 - 5);
+	KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 5);
+	KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello");
+	KUNIT_EXPECT_EQ(test, seq_buf_strlen(&s), 5);
+
+	/* Appending with space works. */
+	seq_buf_puts(&s, " world");
+	KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
+	KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
+	KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
+	KUNIT_EXPECT_EQ(test, seq_buf_strlen(&s), 11);
+
+	/* No truncation when space for NUL is present. */
+	seq_buf_init_append(&s, buf, 12);
+	KUNIT_EXPECT_EQ(test, s.size, 12);
+	KUNIT_EXPECT_EQ(test, s.len, 11);
+	KUNIT_EXPECT_FALSE(test, seq_buf_has_overflowed(&s));
+	KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
+	KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello world");
+	KUNIT_EXPECT_EQ(test, seq_buf_strlen(&s), 11);
+
+	/*
+	 * No NUL within the size: the content is already truncated, as
+	 * strlcat() would see it, so @s starts out overflowed. The content
+	 * stays, and appending adds nothing.
+	 */
+	seq_buf_init_append(&s, buf, 11);
+	KUNIT_EXPECT_EQ(test, s.size, 11);
+	KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
+	KUNIT_EXPECT_EQ(test, seq_buf_buffer_left(&s), 0);
+	KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 11);
+	KUNIT_EXPECT_MEMEQ(test, buf, "hello world", 11);
+	seq_buf_puts(&s, "!");
+	KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
+	KUNIT_EXPECT_MEMEQ(test, buf, "hello world", 11);
+	KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hello worl");
+	KUNIT_EXPECT_EQ(test, seq_buf_strlen(&s), 10);
+
+	/*
+	 * The size bounds the scan: the string runs past it, so there is
+	 * no NUL within the size either.
+	 */
+	seq_buf_init_append(&s, buf, 5);
+	KUNIT_EXPECT_EQ(test, s.size, 5);
+	KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
+	KUNIT_EXPECT_EQ(test, seq_buf_buffer_left(&s), 0);
+	KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "hell");
+
+	/* With no room even for a NUL, @s is overflowed and @buf untouched. */
+	seq_buf_init_append(&s, buf, 0);
+	KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
+	KUNIT_EXPECT_EQ(test, seq_buf_used(&s), 0);
+	KUNIT_EXPECT_STREQ(test, seq_buf_str(&s), "");
+	KUNIT_EXPECT_EQ(test, buf[0], 'h');
+}
+
 static void seq_buf_declare_test(struct kunit *test)
 {
 	DECLARE_SEQ_BUF(s, 24);
@@ -662,6 +728,7 @@ static void seq_buf_terminate_test(struct kunit *test)
 
 static struct kunit_case seq_buf_test_cases[] = {
 	KUNIT_CASE(seq_buf_init_test),
+	KUNIT_CASE(seq_buf_init_append_test),
 	KUNIT_CASE(seq_buf_declare_test),
 	KUNIT_CASE(seq_buf_clear_test),
 	KUNIT_CASE(seq_buf_puts_test),
-- 
2.55.0


  parent reply	other threads:[~2026-10-03  3:59 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-03  3:59 [PATCH v4 00/11] seq_buf: Add seq_buf_strlen() Kees Cook
2026-10-03  3:59 ` [PATCH v4 01/11] seq_buf: Do not print an empty line from an overflowed seq_buf_do_printk() Kees Cook
2026-10-03  4:07   ` sashiko-bot
2026-10-03  4:50   ` bot+bpf-ci
2026-10-03  4:50     ` bot+bpf-ci
2026-10-05 10:05     ` Kees Cook
2026-10-03  3:59 ` [PATCH v4 02/11] seq_buf: Do not pop from an overflowed seq_buf Kees Cook
2026-10-03  4:05   ` sashiko-bot
2026-10-03  3:59 ` [PATCH v4 03/11] seq_buf: Copy what fits when seq_buf_puts() and seq_buf_putmem() overflow Kees Cook
2026-10-03  4:07   ` sashiko-bot
2026-10-03  4:50   ` bot+bpf-ci
2026-10-03  4:50     ` bot+bpf-ci
2026-10-05 10:06     ` Kees Cook
2026-10-03  3:59 ` [PATCH v4 04/11] seq_buf: Clear what a writer did not claim when a seq_buf overflows Kees Cook
2026-10-03  4:07   ` sashiko-bot
2026-10-03  4:50   ` bot+bpf-ci
2026-10-03  4:50     ` bot+bpf-ci
2026-10-03  3:59 ` [PATCH v4 05/11] seq_buf: Add seq_buf_strlen() Kees Cook
2026-10-03  4:04   ` sashiko-bot
2026-10-03 15:36   ` Andy Shevchenko
2026-10-04  7:26     ` Kees Cook
2026-10-04  8:34       ` Andy Shevchenko
2026-10-05 11:22         ` Kees Cook
2026-10-05 11:34           ` Alejandro Colomar
2026-10-05 15:58             ` Kees Cook
2026-10-05 16:43               ` Alejandro Colomar
2026-10-03  3:59 ` [PATCH v4 06/11] seq_buf: Add seq_buf_terminate() Kees Cook
2026-10-03  4:05   ` sashiko-bot
2026-10-03  3:59 ` [PATCH v4 07/11] bpf: Remove dead newline stripping from format_disasm_line() Kees Cook
2026-10-03  4:05   ` sashiko-bot
2026-10-03  3:59 ` Kees Cook [this message]
2026-10-03  4:05   ` [PATCH v4 08/11] seq_buf: Add seq_buf_init_append() sashiko-bot
2026-10-03  4:33   ` bot+bpf-ci
2026-10-03  4:33     ` bot+bpf-ci
2026-10-03 10:31     ` Kees Cook
2026-10-03  3:59 ` [PATCH v4 09/11] powerpc/papr_scm: Return the string length from the sysfs show functions Kees Cook
2026-10-03  4:06   ` sashiko-bot
2026-10-03  3:59 ` [PATCH v4 10/11] nvdimm: ndtest: Return the string length from flags_show() Kees Cook
2026-10-03  4:08   ` sashiko-bot
2026-10-03  3:59 ` [PATCH v4 11/11] docs: core-api: Document the seq_buf API Kees Cook
2026-10-03  4:03   ` sashiko-bot
2026-10-03  6:32 ` [PATCH v4 00/11] seq_buf: Add seq_buf_strlen() Alexei Starovoitov

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=20261003035921.1918874-8-kees@kernel.org \
    --to=kees@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=alison.schofield@intel.com \
    --cc=andrii@kernel.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=ast@kernel.org \
    --cc=blum@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=chleroy@kernel.org \
    --cc=corbet@lwn.net \
    --cc=daniel@iogearbox.net \
    --cc=dave.jiang@intel.com \
    --cc=david@davidgow.net \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=gnoack@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=ihor.solodrai@linux.dev \
    --cc=iweiny@kernel.org \
    --cc=jikos@kernel.org \
    --cc=jolsa@kernel.org \
    --cc=lgs201920130244@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-trace-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=maddy@linux.ibm.com \
    --cc=martin.lau@linux.dev \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=memxor@gmail.com \
    --cc=mhiramat@kernel.org \
    --cc=mic@digikod.net \
    --cc=morbo@google.com \
    --cc=mpe@ellerman.id.au \
    --cc=npiggin@gmail.com \
    --cc=nvdimm@lists.linux.dev \
    --cc=pmladek@suse.com \
    --cc=rdunlap@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=sbhat@linux.ibm.com \
    --cc=senozhatsky@chromium.org \
    --cc=shuvampandey1@gmail.com \
    --cc=skhan@linuxfoundation.org \
    --cc=song@kernel.org \
    --cc=u.kleine-koenig@baylibre.com \
    --cc=u.kleine-koenig@pengutronix.de \
    --cc=vishal.l.verma@intel.com \
    --cc=willy@infradead.org \
    --cc=yonghong.song@linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.