Skip to content

Commit 71ca59e

Browse files
committed
Merge branch 'fix-bpf_strnstr-len-error'
Rong Tao says: ==================== Fix bpf_strnstr len error From: Rong Tao <[email protected]> Fix bpf_strnstr() wrong 'len' parameter, bpf_strnstr("open", "open", 4) should return 0 instead of -ENOENT. And fix a more general case when s2 is a suffix of the first len characters of s1. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents c7d19d1 + 19139f4 commit 71ca59e

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

kernel/bpf/helpers.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3664,10 +3664,17 @@ __bpf_kfunc int bpf_strnstr(const char *s1__ign, const char *s2__ign, size_t len
36643664

36653665
guard(pagefault)();
36663666
for (i = 0; i < XATTR_SIZE_MAX; i++) {
3667-
for (j = 0; i + j < len && j < XATTR_SIZE_MAX; j++) {
3667+
for (j = 0; i + j <= len && j < XATTR_SIZE_MAX; j++) {
36683668
__get_kernel_nofault(&c2, s2__ign + j, char, err_out);
36693669
if (c2 == '\0')
36703670
return i;
3671+
/*
3672+
* We allow reading an extra byte from s2 (note the
3673+
* `i + j <= len` above) to cover the case when s2 is
3674+
* a suffix of the first len chars of s1.
3675+
*/
3676+
if (i + j == len)
3677+
break;
36713678
__get_kernel_nofault(&c1, s1__ign + j, char, err_out);
36723679
if (c1 == '\0')
36733680
return -ENOENT;

tools/testing/selftests/bpf/progs/string_kfuncs_success.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ __test(2) int test_strcspn(void *ctx) { return bpf_strcspn(str, "lo"); }
3030
__test(6) int test_strstr_found(void *ctx) { return bpf_strstr(str, "world"); }
3131
__test(-ENOENT) int test_strstr_notfound(void *ctx) { return bpf_strstr(str, "hi"); }
3232
__test(0) int test_strstr_empty(void *ctx) { return bpf_strstr(str, ""); }
33-
__test(0) int test_strnstr_found(void *ctx) { return bpf_strnstr(str, "hello", 6); }
34-
__test(-ENOENT) int test_strnstr_notfound(void *ctx) { return bpf_strnstr(str, "hi", 10); }
33+
__test(0) int test_strnstr_found1(void *ctx) { return bpf_strnstr("", "", 0); }
34+
__test(0) int test_strnstr_found2(void *ctx) { return bpf_strnstr(str, "hello", 5); }
35+
__test(0) int test_strnstr_found3(void *ctx) { return bpf_strnstr(str, "hello", 6); }
36+
__test(-ENOENT) int test_strnstr_notfound1(void *ctx) { return bpf_strnstr(str, "hi", 10); }
37+
__test(-ENOENT) int test_strnstr_notfound2(void *ctx) { return bpf_strnstr(str, "hello", 4); }
38+
__test(-ENOENT) int test_strnstr_notfound3(void *ctx) { return bpf_strnstr("", "a", 0); }
3539
__test(0) int test_strnstr_empty(void *ctx) { return bpf_strnstr(str, "", 1); }
3640

3741
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)