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>,
	"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>,
	"Steven Rostedt" <rostedt@goodmis.org>,
	"Masami Hiramatsu" <mhiramat@kernel.org>,
	"Mathieu Desnoyers" <mathieu.desnoyers@efficios.com>,
	"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>,
	"Petr Mladek" <pmladek@suse.com>,
	"Matthew Wilcox (Oracle)" <willy@infradead.org>,
	"Shuvam Pandey" <shuvampandey1@gmail.com>,
	"David Gow" <david@davidgow.net>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	bpf@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Sergey Senozhatsky" <senozhatsky@chromium.org>,
	"Günther Noack" <gnoack@google.com>,
	"Mickaël Salaün" <mic@digikod.net>,
	"Jiri Kosina" <jikos@kernel.org>,
	"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,
	linux-security-module@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 06/11] seq_buf: Add seq_buf_terminate()
Date: Fri,  2 Oct 2026 20:59:11 -0700	[thread overview]
Message-ID: <20261003035921.1918874-6-kees@kernel.org> (raw)
In-Reply-To: <20261003035906.too.263-kees@kernel.org>

Seven callers call seq_buf_str() only to NUL-terminate the buffer,
discarding the returned pointer. Two of them need a comment to say so.

Add seq_buf_terminate(), wrapping the __seq_buf_terminate() helper that
seq_buf_str() and seq_buf_strlen() already use, and convert those
callers. It returns void: returning the offset would just be
seq_buf_strlen() under another name. A zero-sized seq_buf is left
untouched, as in the other accessors.

Add tests for the three cases: room for the NUL after the data, an
overflowed buffer where it lands in the last byte, and a zero-sized
buffer that must not be written to.

Build tested ARCH=x86_64 defconfig with GCC 16.2.0, plus
CONFIG_HIST_TRIGGERS=y and CONFIG_BPF_SYSCALL=y to reach the converted
call sites in kernel/trace/trace_events_hist.c and
kernel/bpf/diagnostics.c. Tests run 24/24 passing on ARCH=um.

Assisted-by: LLM
Signed-off-by: Kees Cook <kees@kernel.org>
---
 include/linux/seq_buf.h          | 23 +++++++++++++++++++++++
 kernel/bpf/diagnostics.c         |  6 +++---
 kernel/trace/trace_events.c      |  4 ++--
 kernel/trace/trace_events_hist.c |  6 ++----
 lib/tests/seq_buf_kunit.c        | 28 ++++++++++++++++++++++++++++
 5 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h
index 87ccc62f1c62..195e612a212a 100644
--- a/include/linux/seq_buf.h
+++ b/include/linux/seq_buf.h
@@ -171,6 +171,29 @@ static inline size_t seq_buf_strlen(struct seq_buf *s)
 	return __seq_buf_terminate(s);
 }
 
+/**
+ * seq_buf_terminate - NUL-terminate the string in a seq_buf
+ * @s: the seq_buf handle
+ *
+ * Terminate @s->buffer exactly as seq_buf_str() and seq_buf_strlen() do,
+ * for callers that want neither the pointer nor the length and only need
+ * the buffer to be safe to read as a C string. A zero-sized seq_buf has
+ * nowhere to put a NUL and is left untouched.
+ *
+ * Nothing is returned on purpose: a caller that wants the length should
+ * use seq_buf_strlen(), which says so.
+ *
+ * After this function is called, s->buffer is safe to use
+ * in string operations.
+ */
+static inline void seq_buf_terminate(struct seq_buf *s)
+{
+	if (s->size == 0)
+		return;
+
+	__seq_buf_terminate(s);
+}
+
 /**
  * seq_buf_get_buf - get buffer to write arbitrary data to
  * @s: the seq_buf handle
diff --git a/kernel/bpf/diagnostics.c b/kernel/bpf/diagnostics.c
index 0abbbe177e31..594cf3c8b74c 100644
--- a/kernel/bpf/diagnostics.c
+++ b/kernel/bpf/diagnostics.c
@@ -351,7 +351,7 @@ static void diag_fmt_restore(struct bpf_verifier_env *env, struct diag_fmt_mark
 
 	if (mark.chunk) {
 		mark.chunk->seq.len = mark.len;
-		seq_buf_str(&mark.chunk->seq);
+		seq_buf_terminate(&mark.chunk->seq);
 	}
 }
 
@@ -631,11 +631,11 @@ static void format_disasm_line(struct bpf_verifier_env *env, int insn_idx,
 		return;
 
 	print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
-	seq_buf_str(&ctx.seq);
+	seq_buf_terminate(&ctx.seq);
 	ctx.seq.len = strnlen(line->text, sizeof(line->text));
 	while (ctx.seq.len && line->text[ctx.seq.len - 1] == '\n')
 		seq_buf_pop(&ctx.seq);
-	seq_buf_str(&ctx.seq);
+	seq_buf_terminate(&ctx.seq);
 
 	line->valid = true;
 }
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 9dbc2441763b..39bb391546de 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -4906,7 +4906,7 @@ static __init int event_trace_enable(void)
 	 */
 	__trace_early_add_events(tr);
 
-	seq_buf_str(&bootup_event_seq);
+	seq_buf_terminate(&bootup_event_seq);
 	early_enable_events(tr, bootup_event_buf, false);
 
 	trace_printk_start_comm();
@@ -4935,7 +4935,7 @@ static __init int event_trace_enable_again(void)
 	if (!tr)
 		return -ENODEV;
 
-	seq_buf_str(&bootup_event_seq);
+	seq_buf_terminate(&bootup_event_seq);
 	early_enable_events(tr, bootup_event_buf, true);
 
 	return 0;
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 963e0d6b61fd..57bd1cd5c657 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -2988,8 +2988,7 @@ find_synthetic_field_var(struct hist_trigger_data *target_hist_data,
 	seq_buf_init(&s, synthetic_name, MAX_FILTER_STR_VAL);
 	seq_buf_printf(&s, "synthetic_%s", field_name);
 
-	/* Terminate synthetic_name with a NUL. */
-	seq_buf_str(&s);
+	seq_buf_terminate(&s);
 
 	if (seq_buf_has_overflowed(&s)) {
 		kfree(synthetic_name);
@@ -3106,8 +3105,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data,
 	if (saved_filter)
 		seq_buf_printf(&s, " if %s", saved_filter);
 
-	/* Terminate cmd with a NUL. */
-	seq_buf_str(&s);
+	seq_buf_terminate(&s);
 
 	if (seq_buf_has_overflowed(&s)) {
 		kfree(cmd);
diff --git a/lib/tests/seq_buf_kunit.c b/lib/tests/seq_buf_kunit.c
index 569ab3d96f10..b6fc7b784859 100644
--- a/lib/tests/seq_buf_kunit.c
+++ b/lib/tests/seq_buf_kunit.c
@@ -633,6 +633,33 @@ static void seq_buf_strlen_zero_size_test(struct kunit *test)
 	KUNIT_EXPECT_STREQ(test, buf, "untouched");
 }
 
+static void seq_buf_terminate_test(struct kunit *test)
+{
+	char buf[16];
+	struct seq_buf s;
+
+	/* Terminates directly after the data when there is room. */
+	memset(buf, 'z', sizeof(buf));
+	seq_buf_init(&s, buf, sizeof(buf));
+	seq_buf_puts(&s, "ab");
+	seq_buf_terminate(&s);
+	KUNIT_EXPECT_STREQ(test, buf, "ab");
+
+	/* Terminates in the last byte once the buffer has overflowed. */
+	memset(buf, 'z', sizeof(buf));
+	seq_buf_init(&s, buf, 4);
+	seq_buf_puts(&s, "abcdef");
+	KUNIT_EXPECT_TRUE(test, seq_buf_has_overflowed(&s));
+	seq_buf_terminate(&s);
+	KUNIT_EXPECT_STREQ(test, buf, "abc");
+
+	/* A zero-sized seq_buf is left alone. */
+	strscpy(buf, "untouched", sizeof(buf));
+	seq_buf_init(&s, buf, 0);
+	seq_buf_terminate(&s);
+	KUNIT_EXPECT_STREQ(test, buf, "untouched");
+}
+
 static struct kunit_case seq_buf_test_cases[] = {
 	KUNIT_CASE(seq_buf_init_test),
 	KUNIT_CASE(seq_buf_declare_test),
@@ -656,6 +683,7 @@ static struct kunit_case seq_buf_test_cases[] = {
 	KUNIT_CASE(seq_buf_strlen_puts_overflow_test),
 	KUNIT_CASE(seq_buf_strlen_embedded_nul_test),
 	KUNIT_CASE(seq_buf_strlen_zero_size_test),
+	KUNIT_CASE(seq_buf_terminate_test),
 	KUNIT_CASE(seq_buf_do_printk_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 ` Kees Cook [this message]
2026-10-03  4:05   ` [PATCH v4 06/11] seq_buf: Add seq_buf_terminate() 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 ` [PATCH v4 08/11] seq_buf: Add seq_buf_init_append() Kees Cook
2026-10-03  4:05   ` 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-6-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.