* [PATCH bpf-next v3 0/2] bpf: Add kfunc bpf_strncasecmp() @ 2026-01-20 7:03 Yuzuki Ishiyama 2026-01-20 7:03 ` [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc Yuzuki Ishiyama 2026-01-20 7:03 ` [PATCH bpf-next v3 2/2] selftests/bpf: Test kfunc bpf_strncasecmp Yuzuki Ishiyama 0 siblings, 2 replies; 9+ messages in thread From: Yuzuki Ishiyama @ 2026-01-20 7:03 UTC (permalink / raw) To: bpf Cc: mykyta.yatsenko5, vmalik, andrii, ast, daniel, martin.lau, Yuzuki Ishiyama This patchset introduces bpf_strncasecmp to allow case-insensitive and limited-length string comparison. This is useful for parsing protocol headers like HTTP. --- Changes in v3: - Use ternary operator to maintain style consistency - Reverted unnecessary doc comment about XATTR_SIZE_MAX Changes in v2: - Compute max_sz upfront and remove len check from the loop body - Document that @len is limited by XATTR_SIZE_MAX Yuzuki Ishiyama (2): bpf: add bpf_strncasecmp kfunc selftests/bpf: Test kfunc bpf_strncasecmp kernel/bpf/helpers.c | 34 +++++++++++++++---- .../selftests/bpf/prog_tests/string_kfuncs.c | 1 + .../bpf/progs/string_kfuncs_failure1.c | 6 ++++ .../bpf/progs/string_kfuncs_failure2.c | 1 + .../bpf/progs/string_kfuncs_success.c | 7 ++++ 5 files changed, 43 insertions(+), 6 deletions(-) -- 2.52.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc 2026-01-20 7:03 [PATCH bpf-next v3 0/2] bpf: Add kfunc bpf_strncasecmp() Yuzuki Ishiyama @ 2026-01-20 7:03 ` Yuzuki Ishiyama 2026-01-20 7:21 ` bot+bpf-ci 2026-01-20 7:03 ` [PATCH bpf-next v3 2/2] selftests/bpf: Test kfunc bpf_strncasecmp Yuzuki Ishiyama 1 sibling, 1 reply; 9+ messages in thread From: Yuzuki Ishiyama @ 2026-01-20 7:03 UTC (permalink / raw) To: bpf Cc: mykyta.yatsenko5, vmalik, andrii, ast, daniel, martin.lau, Yuzuki Ishiyama bpf_strncasecmp() function performs same like bpf_strcasecmp() except limiting the comparison to a specific length. Signed-off-by: Yuzuki Ishiyama <ishiyama@hpc.is.uec.ac.jp> --- kernel/bpf/helpers.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 9eaa4185e0a7..753753f039ff 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -3406,18 +3406,20 @@ __bpf_kfunc void __bpf_trap(void) * __get_kernel_nofault instead of plain dereference to make them safe. */ -static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) +static int __bpf_strncasecmp(const char *s1, const char *s2, bool ignore_case, size_t len) { char c1, c2; - int i; + int i, max_sz; if (!copy_from_kernel_nofault_allowed(s1, 1) || !copy_from_kernel_nofault_allowed(s2, 1)) { return -ERANGE; } + max_sz = min_t(int, len, XATTR_SIZE_MAX); + guard(pagefault)(); - for (i = 0; i < XATTR_SIZE_MAX; i++) { + for (i = 0; i < max_sz; i++) { __get_kernel_nofault(&c1, s1, char, err_out); __get_kernel_nofault(&c2, s2, char, err_out); if (ignore_case) { @@ -3431,7 +3433,7 @@ static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) s1++; s2++; } - return -E2BIG; + return i == XATTR_SIZE_MAX ? -E2BIG : 0; err_out: return -EFAULT; } @@ -3451,7 +3453,7 @@ static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) */ __bpf_kfunc int bpf_strcmp(const char *s1__ign, const char *s2__ign) { - return __bpf_strcasecmp(s1__ign, s2__ign, false); + return __bpf_strncasecmp(s1__ign, s2__ign, false, XATTR_SIZE_MAX); } /** @@ -3469,7 +3471,26 @@ __bpf_kfunc int bpf_strcmp(const char *s1__ign, const char *s2__ign) */ __bpf_kfunc int bpf_strcasecmp(const char *s1__ign, const char *s2__ign) { - return __bpf_strcasecmp(s1__ign, s2__ign, true); + return __bpf_strncasecmp(s1__ign, s2__ign, true, XATTR_SIZE_MAX); +} + +/* + * bpf_strncasecmp - Compare two length-limited strings, ignoring case + * @s1__ign: One string + * @s2__ign: Another string + * @len: The maximum number of characters to compare + * + * Return: + * * %0 - Strings are equal + * * %-1 - @s1__ign is smaller + * * %1 - @s2__ign is smaller + * * %-EFAULT - Cannot read one of the strings + * * %-E2BIG - One of strings is too large + * * %-ERANGE - One of strings is outside of kernel address space + */ +__bpf_kfunc int bpf_strncasecmp(const char *s1__ign, const char *s2__ign, size_t len) +{ + return __bpf_strncasecmp(s1__ign, s2__ign, true, len); } /** @@ -4521,6 +4542,7 @@ BTF_ID_FLAGS(func, bpf_iter_dmabuf_destroy, KF_ITER_DESTROY | KF_SLEEPABLE) BTF_ID_FLAGS(func, __bpf_trap) BTF_ID_FLAGS(func, bpf_strcmp); BTF_ID_FLAGS(func, bpf_strcasecmp); +BTF_ID_FLAGS(func, bpf_strncasecmp); BTF_ID_FLAGS(func, bpf_strchr); BTF_ID_FLAGS(func, bpf_strchrnul); BTF_ID_FLAGS(func, bpf_strnchr); -- 2.52.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc 2026-01-20 7:03 ` [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc Yuzuki Ishiyama @ 2026-01-20 7:21 ` bot+bpf-ci 2026-01-20 9:29 ` Viktor Malik 0 siblings, 1 reply; 9+ messages in thread From: bot+bpf-ci @ 2026-01-20 7:21 UTC (permalink / raw) To: ishiyama, bpf Cc: mykyta.yatsenko5, vmalik, andrii, ast, daniel, martin.lau, ishiyama, ast, andrii, daniel, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai [-- Attachment #1: Type: text/plain, Size: 2065 bytes --] > diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > index 9eaa4185e0a7..753753f039ff 100644 > --- a/kernel/bpf/helpers.c > +++ b/kernel/bpf/helpers.c [ ... ] > -static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) > +static int __bpf_strncasecmp(const char *s1, const char *s2, bool ignore_case, size_t len) > { > char c1, c2; > - int i; > + int i, max_sz; > > if (!copy_from_kernel_nofault_allowed(s1, 1) || > !copy_from_kernel_nofault_allowed(s2, 1)) { > return -ERANGE; > } > > + max_sz = min_t(int, len, XATTR_SIZE_MAX); ^^^ Can this truncation cause incorrect results when len > INT_MAX? The len parameter is size_t, but min_t(int, ...) casts it to signed int before the comparison. When len is larger than INT_MAX, the cast produces a negative value, and min_t returns that negative value instead of XATTR_SIZE_MAX. For example, if a BPF program calls bpf_strncasecmp(s1, s2, SIZE_MAX): - min_t(int, SIZE_MAX, 65536) evaluates to min_t(int, -1, 65536) = -1 - max_sz becomes -1 - The loop condition (i < max_sz) is (0 < -1), which is false - The loop never executes, and the function returns 0 without comparing This would make bpf_strncasecmp("foo", "bar", SIZE_MAX) return 0 (equal) when the strings are clearly different. Would using min_t(size_t, len, XATTR_SIZE_MAX) avoid this issue? > + > guard(pagefault)(); > - for (i = 0; i < XATTR_SIZE_MAX; i++) { > + for (i = 0; i < max_sz; i++) { [ ... ] > +__bpf_kfunc int bpf_strncasecmp(const char *s1__ign, const char *s2__ign, size_t len) > +{ > + return __bpf_strncasecmp(s1__ign, s2__ign, true, len); > } The BPF verifier does not validate ranges for scalar kfunc parameters, so BPF programs can pass arbitrary size_t values to len, triggering the truncation issue described above. --- AI reviewed your patch. Please fix the bug or email reply why it's not a bug. See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21162711653 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc 2026-01-20 7:21 ` bot+bpf-ci @ 2026-01-20 9:29 ` Viktor Malik 2026-01-20 10:59 ` Yuzuki Ishiyama 2026-01-20 11:02 ` Mykyta Yatsenko 0 siblings, 2 replies; 9+ messages in thread From: Viktor Malik @ 2026-01-20 9:29 UTC (permalink / raw) To: bot+bpf-ci, ishiyama, bpf Cc: mykyta.yatsenko5, andrii, ast, daniel, martin.lau, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai On 1/20/26 08:21, bot+bpf-ci@kernel.org wrote: >> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >> index 9eaa4185e0a7..753753f039ff 100644 >> --- a/kernel/bpf/helpers.c >> +++ b/kernel/bpf/helpers.c > > [ ... ] > >> -static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) >> +static int __bpf_strncasecmp(const char *s1, const char *s2, bool ignore_case, size_t len) >> { >> char c1, c2; >> - int i; >> + int i, max_sz; >> >> if (!copy_from_kernel_nofault_allowed(s1, 1) || >> !copy_from_kernel_nofault_allowed(s2, 1)) { >> return -ERANGE; >> } >> >> + max_sz = min_t(int, len, XATTR_SIZE_MAX); > ^^^ > > Can this truncation cause incorrect results when len > INT_MAX? The len > parameter is size_t, but min_t(int, ...) casts it to signed int before the > comparison. When len is larger than INT_MAX, the cast produces a negative > value, and min_t returns that negative value instead of XATTR_SIZE_MAX. > > For example, if a BPF program calls bpf_strncasecmp(s1, s2, SIZE_MAX): > - min_t(int, SIZE_MAX, 65536) evaluates to min_t(int, -1, 65536) = -1 > - max_sz becomes -1 > - The loop condition (i < max_sz) is (0 < -1), which is false > - The loop never executes, and the function returns 0 without comparing > > This would make bpf_strncasecmp("foo", "bar", SIZE_MAX) return 0 (equal) > when the strings are clearly different. This is a good point and we should IMO address it. > > Would using min_t(size_t, len, XATTR_SIZE_MAX) avoid this issue? Other string kfuncs use `i < len && i < XATTR_SIZE_MAX` in the loop condition, I'd stick to that for consistency. Viktor > >> + >> guard(pagefault)(); >> - for (i = 0; i < XATTR_SIZE_MAX; i++) { >> + for (i = 0; i < max_sz; i++) { > > [ ... ] > >> +__bpf_kfunc int bpf_strncasecmp(const char *s1__ign, const char *s2__ign, size_t len) >> +{ >> + return __bpf_strncasecmp(s1__ign, s2__ign, true, len); >> } > > The BPF verifier does not validate ranges for scalar kfunc parameters, so > BPF programs can pass arbitrary size_t values to len, triggering the > truncation issue described above. > > > --- > AI reviewed your patch. Please fix the bug or email reply why it's not a bug. > See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md > > CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21162711653 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc 2026-01-20 9:29 ` Viktor Malik @ 2026-01-20 10:59 ` Yuzuki Ishiyama 2026-01-20 11:02 ` Mykyta Yatsenko 1 sibling, 0 replies; 9+ messages in thread From: Yuzuki Ishiyama @ 2026-01-20 10:59 UTC (permalink / raw) To: Viktor Malik Cc: bot+bpf-ci, bpf, mykyta.yatsenko5, andrii, ast, daniel, martin.lau, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai Understood. I'll send v4 soon! Yuzuki 2026年1月20日(火) 18:29 Viktor Malik <vmalik@redhat.com>: > > On 1/20/26 08:21, bot+bpf-ci@kernel.org wrote: > >> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c > >> index 9eaa4185e0a7..753753f039ff 100644 > >> --- a/kernel/bpf/helpers.c > >> +++ b/kernel/bpf/helpers.c > > > > [ ... ] > > > >> -static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) > >> +static int __bpf_strncasecmp(const char *s1, const char *s2, bool ignore_case, size_t len) > >> { > >> char c1, c2; > >> - int i; > >> + int i, max_sz; > >> > >> if (!copy_from_kernel_nofault_allowed(s1, 1) || > >> !copy_from_kernel_nofault_allowed(s2, 1)) { > >> return -ERANGE; > >> } > >> > >> + max_sz = min_t(int, len, XATTR_SIZE_MAX); > > ^^^ > > > > Can this truncation cause incorrect results when len > INT_MAX? The len > > parameter is size_t, but min_t(int, ...) casts it to signed int before the > > comparison. When len is larger than INT_MAX, the cast produces a negative > > value, and min_t returns that negative value instead of XATTR_SIZE_MAX. > > > > For example, if a BPF program calls bpf_strncasecmp(s1, s2, SIZE_MAX): > > - min_t(int, SIZE_MAX, 65536) evaluates to min_t(int, -1, 65536) = -1 > > - max_sz becomes -1 > > - The loop condition (i < max_sz) is (0 < -1), which is false > > - The loop never executes, and the function returns 0 without comparing > > > > This would make bpf_strncasecmp("foo", "bar", SIZE_MAX) return 0 (equal) > > when the strings are clearly different. > > This is a good point and we should IMO address it. > > > > > Would using min_t(size_t, len, XATTR_SIZE_MAX) avoid this issue? > > Other string kfuncs use `i < len && i < XATTR_SIZE_MAX` in the loop > condition, I'd stick to that for consistency. > > Viktor > > > > >> + > >> guard(pagefault)(); > >> - for (i = 0; i < XATTR_SIZE_MAX; i++) { > >> + for (i = 0; i < max_sz; i++) { > > > > [ ... ] > > > >> +__bpf_kfunc int bpf_strncasecmp(const char *s1__ign, const char *s2__ign, size_t len) > >> +{ > >> + return __bpf_strncasecmp(s1__ign, s2__ign, true, len); > >> } > > > > The BPF verifier does not validate ranges for scalar kfunc parameters, so > > BPF programs can pass arbitrary size_t values to len, triggering the > > truncation issue described above. > > > > > > --- > > AI reviewed your patch. Please fix the bug or email reply why it's not a bug. > > See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md > > > > CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21162711653 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc 2026-01-20 9:29 ` Viktor Malik 2026-01-20 10:59 ` Yuzuki Ishiyama @ 2026-01-20 11:02 ` Mykyta Yatsenko 2026-01-20 11:15 ` Viktor Malik 1 sibling, 1 reply; 9+ messages in thread From: Mykyta Yatsenko @ 2026-01-20 11:02 UTC (permalink / raw) To: Viktor Malik, bot+bpf-ci, ishiyama, bpf Cc: andrii, ast, daniel, martin.lau, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai On 1/20/26 09:29, Viktor Malik wrote: > On 1/20/26 08:21, bot+bpf-ci@kernel.org wrote: >>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >>> index 9eaa4185e0a7..753753f039ff 100644 >>> --- a/kernel/bpf/helpers.c >>> +++ b/kernel/bpf/helpers.c >> [ ... ] >> >>> -static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) >>> +static int __bpf_strncasecmp(const char *s1, const char *s2, bool ignore_case, size_t len) >>> { >>> char c1, c2; >>> - int i; >>> + int i, max_sz; >>> >>> if (!copy_from_kernel_nofault_allowed(s1, 1) || >>> !copy_from_kernel_nofault_allowed(s2, 1)) { >>> return -ERANGE; >>> } >>> >>> + max_sz = min_t(int, len, XATTR_SIZE_MAX); >> ^^^ >> >> Can this truncation cause incorrect results when len > INT_MAX? The len >> parameter is size_t, but min_t(int, ...) casts it to signed int before the >> comparison. When len is larger than INT_MAX, the cast produces a negative >> value, and min_t returns that negative value instead of XATTR_SIZE_MAX. >> >> For example, if a BPF program calls bpf_strncasecmp(s1, s2, SIZE_MAX): >> - min_t(int, SIZE_MAX, 65536) evaluates to min_t(int, -1, 65536) = -1 >> - max_sz becomes -1 >> - The loop condition (i < max_sz) is (0 < -1), which is false >> - The loop never executes, and the function returns 0 without comparing >> >> This would make bpf_strncasecmp("foo", "bar", SIZE_MAX) return 0 (equal) >> when the strings are clearly different. > This is a good point and we should IMO address it. > >> Would using min_t(size_t, len, XATTR_SIZE_MAX) avoid this issue? > Other string kfuncs use `i < len && i < XATTR_SIZE_MAX` in the loop > condition, I'd stick to that for consistency. > > Viktor Why not just use proper type (size_t for max_sz), obviously truncation is a problem there, so use the wider type? > >>> + >>> guard(pagefault)(); >>> - for (i = 0; i < XATTR_SIZE_MAX; i++) { >>> + for (i = 0; i < max_sz; i++) { >> [ ... ] >> >>> +__bpf_kfunc int bpf_strncasecmp(const char *s1__ign, const char *s2__ign, size_t len) >>> +{ >>> + return __bpf_strncasecmp(s1__ign, s2__ign, true, len); >>> } >> The BPF verifier does not validate ranges for scalar kfunc parameters, so >> BPF programs can pass arbitrary size_t values to len, triggering the >> truncation issue described above. >> >> >> --- >> AI reviewed your patch. Please fix the bug or email reply why it's not a bug. >> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md >> >> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21162711653 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc 2026-01-20 11:02 ` Mykyta Yatsenko @ 2026-01-20 11:15 ` Viktor Malik 0 siblings, 0 replies; 9+ messages in thread From: Viktor Malik @ 2026-01-20 11:15 UTC (permalink / raw) To: Mykyta Yatsenko, bot+bpf-ci, ishiyama, bpf Cc: andrii, ast, daniel, martin.lau, martin.lau, eddyz87, yonghong.song, clm, ihor.solodrai On 1/20/26 12:02, Mykyta Yatsenko wrote: > On 1/20/26 09:29, Viktor Malik wrote: >> On 1/20/26 08:21, bot+bpf-ci@kernel.org wrote: >>>> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c >>>> index 9eaa4185e0a7..753753f039ff 100644 >>>> --- a/kernel/bpf/helpers.c >>>> +++ b/kernel/bpf/helpers.c >>> [ ... ] >>> >>>> -static int __bpf_strcasecmp(const char *s1, const char *s2, bool ignore_case) >>>> +static int __bpf_strncasecmp(const char *s1, const char *s2, bool ignore_case, size_t len) >>>> { >>>> char c1, c2; >>>> - int i; >>>> + int i, max_sz; >>>> >>>> if (!copy_from_kernel_nofault_allowed(s1, 1) || >>>> !copy_from_kernel_nofault_allowed(s2, 1)) { >>>> return -ERANGE; >>>> } >>>> >>>> + max_sz = min_t(int, len, XATTR_SIZE_MAX); >>> ^^^ >>> >>> Can this truncation cause incorrect results when len > INT_MAX? The len >>> parameter is size_t, but min_t(int, ...) casts it to signed int before the >>> comparison. When len is larger than INT_MAX, the cast produces a negative >>> value, and min_t returns that negative value instead of XATTR_SIZE_MAX. >>> >>> For example, if a BPF program calls bpf_strncasecmp(s1, s2, SIZE_MAX): >>> - min_t(int, SIZE_MAX, 65536) evaluates to min_t(int, -1, 65536) = -1 >>> - max_sz becomes -1 >>> - The loop condition (i < max_sz) is (0 < -1), which is false >>> - The loop never executes, and the function returns 0 without comparing >>> >>> This would make bpf_strncasecmp("foo", "bar", SIZE_MAX) return 0 (equal) >>> when the strings are clearly different. >> This is a good point and we should IMO address it. >> >>> Would using min_t(size_t, len, XATTR_SIZE_MAX) avoid this issue? >> Other string kfuncs use `i < len && i < XATTR_SIZE_MAX` in the loop >> condition, I'd stick to that for consistency. >> >> Viktor > Why not just use proper type (size_t for max_sz), obviously truncation is a > problem there, so use the wider type? No problem with that either. I slightly prefer consistency but using min_t with size_t is a good solution, too (and slightly more efficient one). >> >>>> + >>>> guard(pagefault)(); >>>> - for (i = 0; i < XATTR_SIZE_MAX; i++) { >>>> + for (i = 0; i < max_sz; i++) { >>> [ ... ] >>> >>>> +__bpf_kfunc int bpf_strncasecmp(const char *s1__ign, const char *s2__ign, size_t len) >>>> +{ >>>> + return __bpf_strncasecmp(s1__ign, s2__ign, true, len); >>>> } >>> The BPF verifier does not validate ranges for scalar kfunc parameters, so >>> BPF programs can pass arbitrary size_t values to len, triggering the >>> truncation issue described above. >>> >>> >>> --- >>> AI reviewed your patch. Please fix the bug or email reply why it's not a bug. >>> See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md >>> >>> CI run summary: https://github.com/kernel-patches/bpf/actions/runs/21162711653 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH bpf-next v3 2/2] selftests/bpf: Test kfunc bpf_strncasecmp 2026-01-20 7:03 [PATCH bpf-next v3 0/2] bpf: Add kfunc bpf_strncasecmp() Yuzuki Ishiyama 2026-01-20 7:03 ` [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc Yuzuki Ishiyama @ 2026-01-20 7:03 ` Yuzuki Ishiyama 2026-01-20 9:30 ` Viktor Malik 1 sibling, 1 reply; 9+ messages in thread From: Yuzuki Ishiyama @ 2026-01-20 7:03 UTC (permalink / raw) To: bpf Cc: mykyta.yatsenko5, vmalik, andrii, ast, daniel, martin.lau, Yuzuki Ishiyama Add testsuites for kfunc bpf_strncasecmp. Signed-off-by: Yuzuki Ishiyama <ishiyama@hpc.is.uec.ac.jp> --- tools/testing/selftests/bpf/prog_tests/string_kfuncs.c | 1 + tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c | 6 ++++++ tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c | 1 + tools/testing/selftests/bpf/progs/string_kfuncs_success.c | 7 +++++++ 4 files changed, 15 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c b/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c index 0f3bf594e7a5..300032a19445 100644 --- a/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c +++ b/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c @@ -9,6 +9,7 @@ static const char * const test_cases[] = { "strcmp", "strcasecmp", + "strncasecmp", "strchr", "strchrnul", "strnchr", diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c b/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c index 826e6b6aff7e..bddc4e8579d2 100644 --- a/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c @@ -33,6 +33,8 @@ SEC("syscall") __retval(USER_PTR_ERR) int test_strcmp_null1(void *ctx) { return SEC("syscall") __retval(USER_PTR_ERR)int test_strcmp_null2(void *ctx) { return bpf_strcmp("hello", NULL); } SEC("syscall") __retval(USER_PTR_ERR) int test_strcasecmp_null1(void *ctx) { return bpf_strcasecmp(NULL, "HELLO"); } SEC("syscall") __retval(USER_PTR_ERR)int test_strcasecmp_null2(void *ctx) { return bpf_strcasecmp("HELLO", NULL); } +SEC("syscall") __retval(USER_PTR_ERR)int test_strncasecmp_null1(void *ctx) { return bpf_strncasecmp(NULL, "HELLO", 5); } +SEC("syscall") __retval(USER_PTR_ERR)int test_strncasecmp_null2(void *ctx) { return bpf_strncasecmp("HELLO", NULL, 5); } SEC("syscall") __retval(USER_PTR_ERR)int test_strchr_null(void *ctx) { return bpf_strchr(NULL, 'a'); } SEC("syscall") __retval(USER_PTR_ERR)int test_strchrnul_null(void *ctx) { return bpf_strchrnul(NULL, 'a'); } SEC("syscall") __retval(USER_PTR_ERR)int test_strnchr_null(void *ctx) { return bpf_strnchr(NULL, 1, 'a'); } @@ -57,6 +59,8 @@ SEC("syscall") __retval(USER_PTR_ERR) int test_strcmp_user_ptr1(void *ctx) { ret SEC("syscall") __retval(USER_PTR_ERR) int test_strcmp_user_ptr2(void *ctx) { return bpf_strcmp("hello", user_ptr); } SEC("syscall") __retval(USER_PTR_ERR) int test_strcasecmp_user_ptr1(void *ctx) { return bpf_strcasecmp(user_ptr, "HELLO"); } SEC("syscall") __retval(USER_PTR_ERR) int test_strcasecmp_user_ptr2(void *ctx) { return bpf_strcasecmp("HELLO", user_ptr); } +SEC("syscall") __retval(USER_PTR_ERR) int test_strncasecmp_user_ptr1(void *ctx) { return bpf_strncasecmp(user_ptr, "HELLO", 5); } +SEC("syscall") __retval(USER_PTR_ERR) int test_strncasecmp_user_ptr2(void *ctx) { return bpf_strncasecmp("HELLO", user_ptr, 5); } SEC("syscall") __retval(USER_PTR_ERR) int test_strchr_user_ptr(void *ctx) { return bpf_strchr(user_ptr, 'a'); } SEC("syscall") __retval(USER_PTR_ERR) int test_strchrnul_user_ptr(void *ctx) { return bpf_strchrnul(user_ptr, 'a'); } SEC("syscall") __retval(USER_PTR_ERR) int test_strnchr_user_ptr(void *ctx) { return bpf_strnchr(user_ptr, 1, 'a'); } @@ -83,6 +87,8 @@ SEC("syscall") __retval(-EFAULT) int test_strcmp_pagefault1(void *ctx) { return SEC("syscall") __retval(-EFAULT) int test_strcmp_pagefault2(void *ctx) { return bpf_strcmp("hello", invalid_kern_ptr); } SEC("syscall") __retval(-EFAULT) int test_strcasecmp_pagefault1(void *ctx) { return bpf_strcasecmp(invalid_kern_ptr, "HELLO"); } SEC("syscall") __retval(-EFAULT) int test_strcasecmp_pagefault2(void *ctx) { return bpf_strcasecmp("HELLO", invalid_kern_ptr); } +SEC("syscall") __retval(-EFAULT) int test_strncasecmp_pagefault1(void *ctx) { return bpf_strncasecmp(invalid_kern_ptr, "HELLO", 5); } +SEC("syscall") __retval(-EFAULT) int test_strncasecmp_pagefault2(void *ctx) { return bpf_strncasecmp("HELLO", invalid_kern_ptr, 5); } SEC("syscall") __retval(-EFAULT) int test_strchr_pagefault(void *ctx) { return bpf_strchr(invalid_kern_ptr, 'a'); } SEC("syscall") __retval(-EFAULT) int test_strchrnul_pagefault(void *ctx) { return bpf_strchrnul(invalid_kern_ptr, 'a'); } SEC("syscall") __retval(-EFAULT) int test_strnchr_pagefault(void *ctx) { return bpf_strnchr(invalid_kern_ptr, 1, 'a'); } diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c b/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c index 05e1da1f250f..412c53b87b18 100644 --- a/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c @@ -8,6 +8,7 @@ char long_str[XATTR_SIZE_MAX + 1]; SEC("syscall") int test_strcmp_too_long(void *ctx) { return bpf_strcmp(long_str, long_str); } SEC("syscall") int test_strcasecmp_too_long(void *ctx) { return bpf_strcasecmp(long_str, long_str); } +SEC("syscall") int test_strncasecmp_too_long(void *ctx) { return bpf_strncasecmp(long_str, long_str, sizeof(long_str)); } SEC("syscall") int test_strchr_too_long(void *ctx) { return bpf_strchr(long_str, 'b'); } SEC("syscall") int test_strchrnul_too_long(void *ctx) { return bpf_strchrnul(long_str, 'b'); } SEC("syscall") int test_strnchr_too_long(void *ctx) { return bpf_strnchr(long_str, sizeof(long_str), 'b'); } diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_success.c b/tools/testing/selftests/bpf/progs/string_kfuncs_success.c index a8513964516b..3ccfae4d27d3 100644 --- a/tools/testing/selftests/bpf/progs/string_kfuncs_success.c +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_success.c @@ -17,6 +17,13 @@ __test(0) int test_strcasecmp_eq2(void *ctx) { return bpf_strcasecmp(str, "HELLO __test(0) int test_strcasecmp_eq3(void *ctx) { return bpf_strcasecmp(str, "HELLO world"); } __test(1) int test_strcasecmp_neq1(void *ctx) { return bpf_strcasecmp(str, "hello"); } __test(1) int test_strcasecmp_neq2(void *ctx) { return bpf_strcasecmp(str, "HELLO"); } +__test(0) int test_strncasecmp_eq1(void *ctx) { return bpf_strncasecmp(str, "hello world", 11); } +__test(0) int test_strncasecmp_eq2(void *ctx) { return bpf_strncasecmp(str, "HELLO WORLD", 11); } +__test(0) int test_strncasecmp_eq3(void *ctx) { return bpf_strncasecmp(str, "HELLO world", 11); } +__test(0) int test_strncasecmp_eq4(void *ctx) { return bpf_strncasecmp(str, "hello", 5); } +__test(0) int test_strncasecmp_eq6(void *ctx) { return bpf_strncasecmp(str, "hello world!", 11); } +__test(-1) int test_strncasecmp_neq1(void *ctx) { return bpf_strncasecmp(str, "hello!", 6); } +__test(1) int test_strncasecmp_neq2(void *ctx) { return bpf_strncasecmp(str, "abc", 3); } __test(1) int test_strchr_found(void *ctx) { return bpf_strchr(str, 'e'); } __test(11) int test_strchr_null(void *ctx) { return bpf_strchr(str, '\0'); } __test(-ENOENT) int test_strchr_notfound(void *ctx) { return bpf_strchr(str, 'x'); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH bpf-next v3 2/2] selftests/bpf: Test kfunc bpf_strncasecmp 2026-01-20 7:03 ` [PATCH bpf-next v3 2/2] selftests/bpf: Test kfunc bpf_strncasecmp Yuzuki Ishiyama @ 2026-01-20 9:30 ` Viktor Malik 0 siblings, 0 replies; 9+ messages in thread From: Viktor Malik @ 2026-01-20 9:30 UTC (permalink / raw) To: Yuzuki Ishiyama, bpf; +Cc: mykyta.yatsenko5, andrii, ast, daniel, martin.lau On 1/20/26 08:03, Yuzuki Ishiyama wrote: > Add testsuites for kfunc bpf_strncasecmp. > > Signed-off-by: Yuzuki Ishiyama <ishiyama@hpc.is.uec.ac.jp> Please include my ack from v2 (unless you change the patch significantly): Acked-by: Viktor Malik <vmalik@redhat.com> > --- > tools/testing/selftests/bpf/prog_tests/string_kfuncs.c | 1 + > tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c | 6 ++++++ > tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c | 1 + > tools/testing/selftests/bpf/progs/string_kfuncs_success.c | 7 +++++++ > 4 files changed, 15 insertions(+) > > diff --git a/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c b/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c > index 0f3bf594e7a5..300032a19445 100644 > --- a/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c > +++ b/tools/testing/selftests/bpf/prog_tests/string_kfuncs.c > @@ -9,6 +9,7 @@ > static const char * const test_cases[] = { > "strcmp", > "strcasecmp", > + "strncasecmp", > "strchr", > "strchrnul", > "strnchr", > diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c b/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c > index 826e6b6aff7e..bddc4e8579d2 100644 > --- a/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c > +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_failure1.c > @@ -33,6 +33,8 @@ SEC("syscall") __retval(USER_PTR_ERR) int test_strcmp_null1(void *ctx) { return > SEC("syscall") __retval(USER_PTR_ERR)int test_strcmp_null2(void *ctx) { return bpf_strcmp("hello", NULL); } > SEC("syscall") __retval(USER_PTR_ERR) int test_strcasecmp_null1(void *ctx) { return bpf_strcasecmp(NULL, "HELLO"); } > SEC("syscall") __retval(USER_PTR_ERR)int test_strcasecmp_null2(void *ctx) { return bpf_strcasecmp("HELLO", NULL); } > +SEC("syscall") __retval(USER_PTR_ERR)int test_strncasecmp_null1(void *ctx) { return bpf_strncasecmp(NULL, "HELLO", 5); } > +SEC("syscall") __retval(USER_PTR_ERR)int test_strncasecmp_null2(void *ctx) { return bpf_strncasecmp("HELLO", NULL, 5); } > SEC("syscall") __retval(USER_PTR_ERR)int test_strchr_null(void *ctx) { return bpf_strchr(NULL, 'a'); } > SEC("syscall") __retval(USER_PTR_ERR)int test_strchrnul_null(void *ctx) { return bpf_strchrnul(NULL, 'a'); } > SEC("syscall") __retval(USER_PTR_ERR)int test_strnchr_null(void *ctx) { return bpf_strnchr(NULL, 1, 'a'); } > @@ -57,6 +59,8 @@ SEC("syscall") __retval(USER_PTR_ERR) int test_strcmp_user_ptr1(void *ctx) { ret > SEC("syscall") __retval(USER_PTR_ERR) int test_strcmp_user_ptr2(void *ctx) { return bpf_strcmp("hello", user_ptr); } > SEC("syscall") __retval(USER_PTR_ERR) int test_strcasecmp_user_ptr1(void *ctx) { return bpf_strcasecmp(user_ptr, "HELLO"); } > SEC("syscall") __retval(USER_PTR_ERR) int test_strcasecmp_user_ptr2(void *ctx) { return bpf_strcasecmp("HELLO", user_ptr); } > +SEC("syscall") __retval(USER_PTR_ERR) int test_strncasecmp_user_ptr1(void *ctx) { return bpf_strncasecmp(user_ptr, "HELLO", 5); } > +SEC("syscall") __retval(USER_PTR_ERR) int test_strncasecmp_user_ptr2(void *ctx) { return bpf_strncasecmp("HELLO", user_ptr, 5); } > SEC("syscall") __retval(USER_PTR_ERR) int test_strchr_user_ptr(void *ctx) { return bpf_strchr(user_ptr, 'a'); } > SEC("syscall") __retval(USER_PTR_ERR) int test_strchrnul_user_ptr(void *ctx) { return bpf_strchrnul(user_ptr, 'a'); } > SEC("syscall") __retval(USER_PTR_ERR) int test_strnchr_user_ptr(void *ctx) { return bpf_strnchr(user_ptr, 1, 'a'); } > @@ -83,6 +87,8 @@ SEC("syscall") __retval(-EFAULT) int test_strcmp_pagefault1(void *ctx) { return > SEC("syscall") __retval(-EFAULT) int test_strcmp_pagefault2(void *ctx) { return bpf_strcmp("hello", invalid_kern_ptr); } > SEC("syscall") __retval(-EFAULT) int test_strcasecmp_pagefault1(void *ctx) { return bpf_strcasecmp(invalid_kern_ptr, "HELLO"); } > SEC("syscall") __retval(-EFAULT) int test_strcasecmp_pagefault2(void *ctx) { return bpf_strcasecmp("HELLO", invalid_kern_ptr); } > +SEC("syscall") __retval(-EFAULT) int test_strncasecmp_pagefault1(void *ctx) { return bpf_strncasecmp(invalid_kern_ptr, "HELLO", 5); } > +SEC("syscall") __retval(-EFAULT) int test_strncasecmp_pagefault2(void *ctx) { return bpf_strncasecmp("HELLO", invalid_kern_ptr, 5); } > SEC("syscall") __retval(-EFAULT) int test_strchr_pagefault(void *ctx) { return bpf_strchr(invalid_kern_ptr, 'a'); } > SEC("syscall") __retval(-EFAULT) int test_strchrnul_pagefault(void *ctx) { return bpf_strchrnul(invalid_kern_ptr, 'a'); } > SEC("syscall") __retval(-EFAULT) int test_strnchr_pagefault(void *ctx) { return bpf_strnchr(invalid_kern_ptr, 1, 'a'); } > diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c b/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c > index 05e1da1f250f..412c53b87b18 100644 > --- a/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c > +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_failure2.c > @@ -8,6 +8,7 @@ char long_str[XATTR_SIZE_MAX + 1]; > > SEC("syscall") int test_strcmp_too_long(void *ctx) { return bpf_strcmp(long_str, long_str); } > SEC("syscall") int test_strcasecmp_too_long(void *ctx) { return bpf_strcasecmp(long_str, long_str); } > +SEC("syscall") int test_strncasecmp_too_long(void *ctx) { return bpf_strncasecmp(long_str, long_str, sizeof(long_str)); } > SEC("syscall") int test_strchr_too_long(void *ctx) { return bpf_strchr(long_str, 'b'); } > SEC("syscall") int test_strchrnul_too_long(void *ctx) { return bpf_strchrnul(long_str, 'b'); } > SEC("syscall") int test_strnchr_too_long(void *ctx) { return bpf_strnchr(long_str, sizeof(long_str), 'b'); } > diff --git a/tools/testing/selftests/bpf/progs/string_kfuncs_success.c b/tools/testing/selftests/bpf/progs/string_kfuncs_success.c > index a8513964516b..3ccfae4d27d3 100644 > --- a/tools/testing/selftests/bpf/progs/string_kfuncs_success.c > +++ b/tools/testing/selftests/bpf/progs/string_kfuncs_success.c > @@ -17,6 +17,13 @@ __test(0) int test_strcasecmp_eq2(void *ctx) { return bpf_strcasecmp(str, "HELLO > __test(0) int test_strcasecmp_eq3(void *ctx) { return bpf_strcasecmp(str, "HELLO world"); } > __test(1) int test_strcasecmp_neq1(void *ctx) { return bpf_strcasecmp(str, "hello"); } > __test(1) int test_strcasecmp_neq2(void *ctx) { return bpf_strcasecmp(str, "HELLO"); } > +__test(0) int test_strncasecmp_eq1(void *ctx) { return bpf_strncasecmp(str, "hello world", 11); } > +__test(0) int test_strncasecmp_eq2(void *ctx) { return bpf_strncasecmp(str, "HELLO WORLD", 11); } > +__test(0) int test_strncasecmp_eq3(void *ctx) { return bpf_strncasecmp(str, "HELLO world", 11); } > +__test(0) int test_strncasecmp_eq4(void *ctx) { return bpf_strncasecmp(str, "hello", 5); } > +__test(0) int test_strncasecmp_eq6(void *ctx) { return bpf_strncasecmp(str, "hello world!", 11); } > +__test(-1) int test_strncasecmp_neq1(void *ctx) { return bpf_strncasecmp(str, "hello!", 6); } > +__test(1) int test_strncasecmp_neq2(void *ctx) { return bpf_strncasecmp(str, "abc", 3); } > __test(1) int test_strchr_found(void *ctx) { return bpf_strchr(str, 'e'); } > __test(11) int test_strchr_null(void *ctx) { return bpf_strchr(str, '\0'); } > __test(-ENOENT) int test_strchr_notfound(void *ctx) { return bpf_strchr(str, 'x'); } ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-01-20 11:15 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-20 7:03 [PATCH bpf-next v3 0/2] bpf: Add kfunc bpf_strncasecmp() Yuzuki Ishiyama 2026-01-20 7:03 ` [PATCH bpf-next v3 1/2] bpf: add bpf_strncasecmp kfunc Yuzuki Ishiyama 2026-01-20 7:21 ` bot+bpf-ci 2026-01-20 9:29 ` Viktor Malik 2026-01-20 10:59 ` Yuzuki Ishiyama 2026-01-20 11:02 ` Mykyta Yatsenko 2026-01-20 11:15 ` Viktor Malik 2026-01-20 7:03 ` [PATCH bpf-next v3 2/2] selftests/bpf: Test kfunc bpf_strncasecmp Yuzuki Ishiyama 2026-01-20 9:30 ` Viktor Malik
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox