All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Rong Tao" <rtoax@foxmail.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v4 2/2] selftests/bpf: Test bpf_strcat,bpf_strncat kfuncs
Date: Mon, 20 Jul 2026 08:51:13 +0000	[thread overview]
Message-ID: <20260720085114.072751F000E9@smtp.kernel.org> (raw)
In-Reply-To: <tencent_1A540D31C1E052E8262BE0324005E7756D05@qq.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [Critical] `__bpf_strncat` contains a critical out-of-bounds read and potential kernel panic when `dst` is not null-terminated.
- [High] The new failure tests passing scalar or invalid pointers to `bpf_strcat` and `bpf_strncat` will be rejected by the verifier, breaking the selftest suite.
- [High] The `test_strncat_success` test asserts an incorrect return value and checks against the wrong string, guaranteeing runtime failure.
- [High] The `src` argument in `bpf_strcat` and `bpf_strncat` lacks a string or size suffix, causing the verifier to only enforce a 1-byte size, leading to kernel memory disclosure.
- [High] `run_too_long_tests` asserts `-E2BIG` but `__bpf_strncat` returns `-EINVAL`, breaking the test suite.
--

--- Patch [2]: [PATCH bpf-next v4 2/2] selftests/bpf: Test bpf_strcat,bpf_strncat kfuncs ---
commit 08f044c5d96948cad08013caa519f6e718db089c
Author: Rong Tao <rongtao@cestc.cn>

selftests/bpf: Test bpf_strcat,bpf_strncat kfuncs

This patch adds selftests for the newly introduced bpf_strcat() and
bpf_strncat() kfuncs. It extends existing string kfunc failure and success
test suites to validate these operations. It also cleans up some extra
whitespace in string_kfuncs_failure1.c.

> diff --git a/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c b/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c
> index 300032a194451..460567ef622a5 100644
> --- a/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c
> +++ b/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c
> @@ -24,6 +24,8 @@ static const char * const test_cases[] = {
>  	"strcasestr",
>  	"strnstr",
>  	"strncasestr",
> +	"strcat",
> +	"strncat",
>  };

[Severity: High]
Will run_too_long_tests() fail for these new test cases due to a mismatched
error code?

The run_too_long_tests() loop expects all over-long string tests to return
-E2BIG. However, looking at __bpf_strncat() in kernel/bpf/helpers.c, if the
destination buffer is full because it lacks a null terminator within dsz
bounds:

    if (dlen >= dsz || sz == 0 || dsz == 0)
        return -EINVAL;

Since the test string is completely filled without a null terminator, wouldn't
it return -EINVAL instead of -E2BIG, causing the ASSERT_EQ to fail?

> diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c b/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c
> index bddc4e8579d24..d432d4990f802 100644
> --- a/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c
> +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c
[ ... ]
> @@ -30,29 +31,31 @@ char *invalid_kern_ptr = (char *)-1;
>  
>  /* Passing NULL to string kfuncs (treated as a userspace ptr) */
[ ... ]
> +SEC("syscall") __retval(USER_PTR_ERR)int test_strcat_null1(void *ctx) { return bpf_strcat(kern_buf, sizeof(kern_buf), NULL); }
> +SEC("syscall") __retval(USER_PTR_ERR)int test_strncat_null1(void *ctx) { return bpf_strncat(kern_buf, sizeof(kern_buf), NULL, 2); }
>  
>  /* Passing userspace ptr to string kfuncs */
[ ... ]
> +SEC("syscall") __retval(USER_PTR_ERR) int test_strcat_user_ptr1(void *ctx) { return bpf_strcat(user_ptr, 1, kern_buf); }

[Severity: High]
Will these tests fail to load during verification rather than failing at
runtime?

Because the dst and src parameters in bpf_strcat() lack the __ign or
__nullable suffix in their kernel definitions, the verifier treats them as
strictly typed KF_ARG_PTR_TO_MEM.

If we pass a scalar like user_ptr or NULL, won't the verifier reject the
program during the load phase, breaking the test suite when the skeleton is
loaded?

> diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c b/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c
> index 412c53b87b182..2dbd1349689ea 100644
> --- a/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c
> +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c
[ ... ]
> @@ -23,5 +24,7 @@ SEC("syscall") int test_strstr_too_long(void *ctx) { return bpf_strstr(long_str,
>  SEC("syscall") int test_strcasestr_too_long(void *ctx) { return bpf_strcasestr(long_str, "hello"); }
>  SEC("syscall") int test_strnstr_too_long(void *ctx) { return bpf_strnstr(long_str, "hello", sizeof(long_str)); }
>  SEC("syscall") int test_strncasestr_too_long(void *ctx) { return bpf_strncasestr(long_str, "hello", sizeof(long_str)); }
> +SEC("syscall") int test_strcat_too_long(void *ctx) { return bpf_strcat(long_str, sizeof(long_str), str); }

[Severity: Critical]
Could this test trigger an out-of-bounds read and kernel panic?

Looking at __bpf_strncat() in kernel/bpf/helpers.c, when calculating dlen
there is no bounds check against dsz:

    while (dst[dlen] != '\0')
        dlen++;

If test_strcat_too_long() passes a completely filled long_str without a null
terminator, won't this loop read past the end of the BPF-provided buffer into
adjacent kernel memory?

> diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_success.c b/tools/testing/selftests/bpf/progs/string_kfuncs_success.c
> index f65b1226a81a3..71fbbe97b4c50 100644
> --- a/tools/testing/selftests/bpf/progs/string_kfuncs_success.c
> +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_success.c
[ ... ]
> +__test(0) int test_strcat_success(void *ctx) {
> +	char buf[32] = "hello";
> +	bpf_strcat(buf, sizeof(buf), str);
> +	return bpf_strcmp(buf, "hellohello world");
> +}

[Severity: High]
Does the signature of bpf_strcat() allow arbitrary kernel memory disclosure?

The src parameter in bpf_strcat() is annotated simply as const char *src,
lacking a __str suffix or a paired size argument in kernel/bpf/helpers.c:

    __bpf_kfunc int bpf_strcat(char *dst, u32 dst__sz, const char *src)

This causes the verifier to check only the size of the base type (1 byte).
If a BPF program passes a valid 1-byte memory region, could
strncpy_from_kernel_nofault() safely copy past the 1-byte verified region,
exposing adjacent kernel memory into dst?

> +__test(8) int test_strncat_success(void *ctx) {
> +	char buf[32] = "hello";
> +	bpf_strncat(buf, sizeof(buf), str, 3);
> +	return bpf_strcmp(buf, "hellohe");
> +}

[Severity: High]
Is the expected return value correct here?

The test uses __test(8), expecting the program to return 8. However,
bpf_strcmp() evaluates to 0 on a successful match. Wouldn't the program
return 0 instead of 8, causing this test to fail reliably?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1784536164.git.rtoax@foxmail.com?part=2

  reply	other threads:[~2026-07-20  8:51 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1784536164.git.rtoax@foxmail.com>
2026-07-20  8:34 ` [PATCH bpf-next v4 1/2] bpf: add bpf_strcat,bpf_strncat kfunc Rong Tao
2026-07-20  8:51   ` sashiko-bot
2026-07-20  8:34 ` [PATCH bpf-next v4 2/2] selftests/bpf: Test bpf_strcat,bpf_strncat kfuncs Rong Tao
2026-07-20  8:51   ` sashiko-bot [this message]
2026-07-20  9:31   ` bot+bpf-ci

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=20260720085114.072751F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=rtoax@foxmail.com \
    --cc=sashiko-reviews@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 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.