From: sashiko-bot@kernel.org
To: "Yihan Ding" <dingyihan@uniontech.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf v2 1/2] bpf: allow UTF-8 literals in bpf_bprintf_prepare()
Date: Wed, 15 Apr 2026 03:48:00 +0000 [thread overview]
Message-ID: <20260415034800.89F7EC2BCB4@smtp.kernel.org> (raw)
In-Reply-To: <20260415032126.1096299-2-dingyihan@uniontech.com>
Sashiko AI review found 2 potential issue(s):
- [Critical] Misuse of `snprintf` return value causes `tmp_buf` to advance out-of-bounds, leading to buffer overflow and memory corruption.
- [High] Truncated strings in `%s` specifiers lack a null terminator, causing `bstr_printf` to perform an out-of-bounds read and leak kernel memory.
--
commit 5e148b2d150df2934403df59a01d44e2a86c360d
Author: Yihan Ding <dingyihan@uniontech.com>
bpf: allow UTF-8 literals in bpf_bprintf_prepare()
bpf_bprintf_prepare() only needs ASCII parsing for conversion
specifiers. Plain text can safely carry bytes >= 0x80, so allow
UTF-8 literals outside '%' sequences while keeping ASCII control
bytes rejected and format specifiers ASCII-only.
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index bb95e287b0dc8..b40add1cfa2c4 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
[ ... ]
> @@ -867,6 +873,14 @@ int bpf_bprintf_prepare(const char *fmt, u32 fmt_size, const u64 *raw_args,
> * always access fmt[i + 1], in the worst case it will be a 0
> */
> i++;
> + /*
> + * The format parser below only understands ASCII conversion
> + * specifiers and modifiers, so reject non-ASCII after '%'.
> + */
> + if (!isascii((unsigned char)fmt[i])) {
> + err = -EINVAL;
> + goto out;
> + }
>
> /* skip optional "[0 +-][num]" width formatting field */
> while (fmt[i] == '0' || fmt[i] == '+' || fmt[i] == '-' ||
This regression wasn't introduced by this patch, but there appears to be an
issue in how the return value of snprintf() is used later in this function.
When parsing %pB or %pI specifiers, the code formats the argument into the
bin_args buffer:
kernel/bpf/helpers.c:bpf_bprintf_prepare() {
...
if (fmt[i + 1] == 'B') {
if (tmp_buf) {
err = snprintf(tmp_buf,
(tmp_buf_end - tmp_buf),
"%pB",
(void *)(long)raw_args[num_spec]);
tmp_buf += (err + 1);
}
...
}
Does this code advance tmp_buf out-of-bounds if the remaining space is too
small?
The kernel's snprintf() returns the number of characters that would have
been written. If truncation occurs, it returns the un-truncated length.
Since the code unconditionally executes tmp_buf += (err + 1), truncation
would cause tmp_buf to advance past tmp_buf_end.
On the next loop iteration, the bounds check evaluates
(tmp_buf_end - tmp_buf < sizeof_cur_arg).
Since tmp_buf > tmp_buf_end, the left side evaluates to a negative ptrdiff_t.
This is compared to sizeof_cur_arg (a size_t), causing the negative value
to be promoted to a large unsigned integer.
Could this bypass the bounds check and allow out-of-bounds writes into
adjacent per-CPU memory?
There is another regression not introduced by this patch related to string
truncation.
When formatting %s, the code uses bpf_trace_copy_string() which internally
uses strncpy_from_kernel_nofault():
kernel/bpf/helpers.c:bpf_bprintf_prepare() {
...
} else if (fmt[i] == 's') {
...
unsafe_ptr = (char *)(long)raw_args[num_spec];
err = bpf_trace_copy_string(tmp_buf, unsafe_ptr,
fmt_ptype,
tmp_buf_end - tmp_buf);
if (err < 0) {
tmp_buf[0] = '\0';
err = 1;
}
tmp_buf += err;
num_spec++;
...
}
Does this code lack a null terminator if the string is truncated?
If the source string length meets or exceeds the remaining space, exactly
tmp_buf_end - tmp_buf characters are copied without appending a null byte.
The code advances tmp_buf += err but fails to manually append a null
terminator.
Later, bstr_printf() unconditionally calls strlen(str_arg) for %s.
Because the string is not null-terminated, could strlen() scan past the end
of the bin_args buffer and leak potentially sensitive kernel data?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260415032126.1096299-1-dingyihan@uniontech.com?part=1
next prev parent reply other threads:[~2026-04-15 3:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-15 3:21 [PATCH bpf v2 0/2] bpf: allow UTF-8 literals in bpf_bprintf_prepare() Yihan Ding
2026-04-15 3:21 ` [PATCH bpf v2 1/2] " Yihan Ding
2026-04-15 3:48 ` sashiko-bot [this message]
2026-04-15 10:44 ` Paul Chaignon
2026-04-15 10:49 ` Paul Chaignon
2026-04-15 3:21 ` [PATCH bpf v2 2/2] selftests/bpf: cover UTF-8 trace_printk output Yihan Ding
2026-04-15 10:46 ` Paul Chaignon
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=20260415034800.89F7EC2BCB4@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=dingyihan@uniontech.com \
--cc=sashiko@lists.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox