| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/21 00:08 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"BPF_SYSCALL",
"NET_SOCK_MSG"
],
"FocusSymbols": [
"tcp_bpf_recvmsg",
"tcp_bpf_recvmsg_parser",
"tcp_msg_wait_data"
],
"Reasoning": "The patch modifies the timeout handling in `tcp_bpf_recvmsg` and `tcp_bpf_recvmsg_parser` when waiting for data on a TCP socket in a sockmap. It fixes a bug where `recvfrom` could incorrectly return `EAGAIN`. This is a functional change in the core networking/BPF subsystem and should be fuzzed to ensure correct behavior and prevent regressions.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/21 00:08 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 6e3194f081fc8695046f4f3d07a584069aff96c2\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Jul 21 00:08:01 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c\nindex cc0bd73f36b6d6..aa5c5d741599a3 100644\n--- a/net/ipv4/tcp_bpf.c\n+++ b/net/ipv4/tcp_bpf.c\n@@ -179,7 +179,7 @@ EXPORT_SYMBOL_GPL(tcp_bpf_sendmsg_redir);\n \n #ifdef CONFIG_BPF_SYSCALL\n static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,\n-\t\t\t long timeo)\n+\t\t\t long *timeo)\n {\n \tDEFINE_WAIT_FUNC(wait, woken_wake_function);\n \tint ret = 0;\n@@ -187,12 +187,12 @@ static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,\n \tif (sk-\u003esk_shutdown \u0026 RCV_SHUTDOWN)\n \t\treturn 1;\n \n-\tif (!timeo)\n+\tif (!*timeo)\n \t\treturn ret;\n \n \tadd_wait_queue(sk_sleep(sk), \u0026wait);\n \tsk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);\n-\tret = sk_wait_event(sk, \u0026timeo,\n+\tret = sk_wait_event(sk, timeo,\n \t\t\t !list_empty(\u0026psock-\u003eingress_msg) ||\n \t\t\t !skb_queue_empty_lockless(\u0026sk-\u003esk_receive_queue), \u0026wait);\n \tsk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);\n@@ -229,6 +229,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,\n \tint copied_from_self = 0;\n \tint copied = 0;\n \tu32 seq;\n+\tlong timeo;\n \n \tif (unlikely(flags \u0026 MSG_ERRQUEUE))\n \t\treturn inet_recv_error(sk, msg, len);\n@@ -262,6 +263,8 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,\n \t\t}\n \t}\n \n+\ttimeo = sock_rcvtimeo(sk, flags \u0026 MSG_DONTWAIT);\n+\n msg_bytes_ready:\n \tcopied = __sk_msg_recvmsg(sk, psock, msg, len, flags, \u0026copied_from_self);\n \t/* The typical case for EFAULT is the socket was gracefully\n@@ -280,7 +283,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,\n \t}\n \tseq += copied_from_self;\n \tif (!copied) {\n-\t\tlong timeo;\n \t\tint data;\n \n \t\tif (sock_flag(sk, SOCK_DONE))\n@@ -299,7 +301,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,\n \t\t\tgoto out;\n \t\t}\n \n-\t\ttimeo = sock_rcvtimeo(sk, flags \u0026 MSG_DONTWAIT);\n \t\tif (!timeo) {\n \t\t\tcopied = -EAGAIN;\n \t\t\tgoto out;\n@@ -310,13 +311,15 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,\n \t\t\tgoto out;\n \t\t}\n \n-\t\tdata = tcp_msg_wait_data(sk, psock, timeo);\n+\t\tdata = tcp_msg_wait_data(sk, psock, \u0026timeo);\n \t\tif (data \u003c 0) {\n \t\t\tcopied = data;\n \t\t\tgoto unlock;\n \t\t}\n \t\tif (data \u0026\u0026 !sk_psock_queue_empty(psock))\n \t\t\tgoto msg_bytes_ready;\n+\t\tif (!data \u0026\u0026 timeo \u003e 0)\n+\t\t\tgoto msg_bytes_ready;\n \t\tcopied = -EAGAIN;\n \t}\n out:\n@@ -355,6 +358,7 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,\n {\n \tstruct sk_psock *psock;\n \tint copied, ret;\n+\tlong timeo;\n \n \tif (unlikely(flags \u0026 MSG_ERRQUEUE))\n \t\treturn inet_recv_error(sk, msg, len);\n@@ -371,14 +375,59 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,\n \t\treturn tcp_recvmsg(sk, msg, len, flags);\n \t}\n \tlock_sock(sk);\n+\n+\ttimeo = sock_rcvtimeo(sk, flags \u0026 MSG_DONTWAIT);\n+\n msg_bytes_ready:\n \tcopied = sk_msg_recvmsg(sk, psock, msg, len, flags);\n \tif (!copied) {\n-\t\tlong timeo;\n \t\tint data;\n \n-\t\ttimeo = sock_rcvtimeo(sk, flags \u0026 MSG_DONTWAIT);\n-\t\tdata = tcp_msg_wait_data(sk, psock, timeo);\n+\t\tif (sock_flag(sk, SOCK_DONE)) {\n+\t\t\tret = 0;\n+\t\t\tgoto unlock;\n+\t\t}\n+\n+\t\tif (sk-\u003esk_err) {\n+\t\t\tif (!sk_psock_queue_empty(psock))\n+\t\t\t\tgoto msg_bytes_ready;\n+\t\t\tif (!skb_queue_empty(\u0026sk-\u003esk_receive_queue)) {\n+\t\t\t\trelease_sock(sk);\n+\t\t\t\tsk_psock_put(sk, psock);\n+\t\t\t\treturn tcp_recvmsg(sk, msg, len, flags);\n+\t\t\t}\n+\t\t\tret = sock_error(sk);\n+\t\t\tgoto unlock;\n+\t\t}\n+\n+\t\tif (sk-\u003esk_shutdown \u0026 RCV_SHUTDOWN) {\n+\t\t\tif (!sk_psock_queue_empty(psock))\n+\t\t\t\tgoto msg_bytes_ready;\n+\t\t\tif (!skb_queue_empty(\u0026sk-\u003esk_receive_queue)) {\n+\t\t\t\trelease_sock(sk);\n+\t\t\t\tsk_psock_put(sk, psock);\n+\t\t\t\treturn tcp_recvmsg(sk, msg, len, flags);\n+\t\t\t}\n+\t\t\tret = 0;\n+\t\t\tgoto unlock;\n+\t\t}\n+\n+\t\tif (sk-\u003esk_state == TCP_CLOSE) {\n+\t\t\tret = -ENOTCONN;\n+\t\t\tgoto unlock;\n+\t\t}\n+\n+\t\tif (!timeo) {\n+\t\t\tret = -EAGAIN;\n+\t\t\tgoto unlock;\n+\t\t}\n+\n+\t\tif (signal_pending(current)) {\n+\t\t\tret = sock_intr_errno(timeo);\n+\t\t\tgoto unlock;\n+\t\t}\n+\n+\t\tdata = tcp_msg_wait_data(sk, psock, \u0026timeo);\n \t\tif (data \u003c 0) {\n \t\t\tret = data;\n \t\t\tgoto unlock;\n@@ -390,6 +439,8 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,\n \t\t\tsk_psock_put(sk, psock);\n \t\t\treturn tcp_recvmsg(sk, msg, len, flags);\n \t\t}\n+\t\tif (!data \u0026\u0026 timeo \u003e 0)\n+\t\t\tgoto msg_bytes_ready;\n \t\tcopied = -EAGAIN;\n \t}\n \tret = copied;\ndiff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c\nindex cb3229711f93a3..d18faf46fac0c2 100644\n--- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c\n+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c\n@@ -1373,6 +1373,126 @@ static void test_sockmap_multi_channels(int sotype)\n \ttest_sockmap_pass_prog__destroy(skel);\n }\n \n+static void *test_sockmap_recvfrom_eagain_thread(void *arg)\n+{\n+\tint fd = *(int *)arg;\n+\tchar buf[1024];\n+\tvoid *result = NULL;\n+\n+\twhile (true) {\n+\t\tssize_t len = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);\n+\n+\t\tif (len == -1) {\n+\t\t\tif (errno == EINTR)\n+\t\t\t\tcontinue;\n+\t\t\tresult = (void *)1;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tif (!len || buf[len - 1] == 'e')\n+\t\t\tbreak;\n+\t}\n+\n+\tsend(fd, \"test\", 4, MSG_NOSIGNAL);\n+\n+\tclose(fd);\n+\n+\treturn result;\n+}\n+\n+static void test_sockmap_recvfrom_eagain(bool with_verdict)\n+{\n+\tstruct test_sockmap_pass_prog *skel = NULL;\n+\tstruct bpf_program *prog = NULL;\n+\tsize_t buflen = 1024 * 1024 * 25;\n+\tchar *buf = NULL;\n+\tint map, err;\n+\n+\tskel = test_sockmap_pass_prog__open_and_load();\n+\tif (!ASSERT_OK_PTR(skel, \"open_and_load\"))\n+\t\treturn;\n+\n+\tmap = bpf_map__fd(skel-\u003emaps.sock_map_msg);\n+\n+\tif (with_verdict) {\n+\t\tprog = skel-\u003eprogs.prog_skb_verdict;\n+\t\terr = bpf_prog_attach(bpf_program__fd(prog), map, BPF_SK_SKB_STREAM_VERDICT, 0);\n+\t\tif (!ASSERT_OK(err, \"bpf_prog_attach verdict\"))\n+\t\t\tgoto cleanup;\n+\t}\n+\n+\tbuf = malloc(buflen);\n+\tif (!ASSERT_OK_PTR(buf, \"malloc buf\"))\n+\t\tgoto cleanup;\n+\tmemset(buf, 0, buflen);\n+\tbuf[buflen - 1] = 'e';\n+\n+\tfor (int i = 0; i \u003c 200; ++i) {\n+\t\tssize_t sent;\n+\t\tchar ignored[128];\n+\t\tpthread_t thread;\n+\t\tbool thread_created = false;\n+\t\tsize_t rem = buflen;\n+\t\tint c = -1, p = -1, zero = 0;\n+\t\tbool success = false;\n+\n+\t\terr = create_pair(AF_INET, SOCK_STREAM, \u0026c, \u0026p);\n+\t\tif (!ASSERT_OK(err, \"create_pair\"))\n+\t\t\tgoto end_attempt;\n+\n+\t\terr = pthread_create(\u0026thread, NULL, \u0026test_sockmap_recvfrom_eagain_thread, \u0026p);\n+\t\tif (!ASSERT_OK(err, \"pthread_create\"))\n+\t\t\tgoto end_attempt;\n+\t\tthread_created = true;\n+\n+\t\terr = bpf_map_update_elem(map, \u0026zero, \u0026c, BPF_ANY);\n+\t\tif (!ASSERT_OK(err, \"bpf_map_update_elem\"))\n+\t\t\tgoto end_attempt;\n+\n+\t\twhile (rem) {\n+\t\t\tsent = xsend(c, buf + (buflen - rem), rem, 0);\n+\t\t\tif (sent == -1)\n+\t\t\t\tgoto end_attempt;\n+\t\t\trem -= sent;\n+\t\t}\n+\n+\t\t/* we cannot use recv_timeout(), otherwise EAGAIN would be an expected errno. */\n+\t\terr = recvfrom(c, ignored, sizeof(ignored), 0, NULL, NULL);\n+\n+\t\t/*\n+\t\t * we are checking for the invalid return of EAGAIN, any other return is considered\n+\t\t * successful for the purposes of this test.\n+\t\t */\n+\t\tif (err \u003c 0 \u0026\u0026 !ASSERT_NEQ(errno, EAGAIN, \"recvfrom eagain\"))\n+\t\t\tgoto end_attempt;\n+\n+\t\tsuccess = true;\n+\n+end_attempt:\n+\t\tif (c \u003e= 0)\n+\t\t\tclose(c);\n+\n+\t\tif (thread_created) {\n+\t\t\tvoid *retval = NULL;\n+\n+\t\t\tpthread_join(thread, \u0026retval);\n+\t\t\tif (!ASSERT_NULL(retval, \"retval\"))\n+\t\t\t\tsuccess = false;\n+\t\t}\n+\n+\t\tif (!thread_created \u0026\u0026 p \u003e= 0)\n+\t\t\tclose(p);\n+\t\tif (!success)\n+\t\t\tbreak;\n+\t}\n+\n+cleanup:\n+\tif (buf)\n+\t\tfree(buf);\n+\n+\ttest_sockmap_pass_prog__destroy(skel);\n+}\n+\n void test_sockmap_basic(void)\n {\n \tif (test__start_subtest(\"sockmap create_update_free\"))\n@@ -1451,4 +1571,8 @@ void test_sockmap_basic(void)\n \t\ttest_sockmap_multi_channels(SOCK_STREAM);\n \tif (test__start_subtest(\"sockmap udp multi channels\"))\n \t\ttest_sockmap_multi_channels(SOCK_DGRAM);\n+\tif (test__start_subtest(\"sockmap recvfrom eagain\"))\n+\t\ttest_sockmap_recvfrom_eagain(false);\n+\tif (test__start_subtest(\"sockmap recvfrom eagain with verdict\"))\n+\t\ttest_sockmap_recvfrom_eagain(true);\n }\n"
} |
| 2/1 | 2026/07/21 00:08 | agent | patch-evaluator |
0mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"BPF_SYSCALL",
"NET_SOCK_MSG"
],
"FocusSymbols": [
"tcp_bpf_recvmsg",
"tcp_bpf_recvmsg_parser",
"tcp_msg_wait_data"
],
"Reasoning": "The patch modifies the timeout handling in `tcp_bpf_recvmsg` and `tcp_bpf_recvmsg_parser` when waiting for data on a TCP socket in a sockmap. It fixes a bug where `recvfrom` could incorrectly return `EAGAIN`. This is a functional change in the core networking/BPF subsystem and should be fuzzed to ensure correct behavior and prevent regressions.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 6e3194f081fc8695046f4f3d07a584069aff96c2
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Jul 21 00:08:01 2026 +0000
syz-cluster: applied patch under review
diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
index cc0bd73f36b6d6..aa5c5d741599a3 100644
--- a/net/ipv4/tcp_bpf.c
+++ b/net/ipv4/tcp_bpf.c
@@ -179,7 +179,7 @@ EXPORT_SYMBOL_GPL(tcp_bpf_sendmsg_redir);
#ifdef CONFIG_BPF_SYSCALL
static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,
- long timeo)
+ long *timeo)
{
DEFINE_WAIT_FUNC(wait, woken_wake_function);
int ret = 0;
@@ -187,12 +187,12 @@ static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,
if (sk->sk_shutdown & RCV_SHUTDOWN)
return 1;
- if (!timeo)
+ if (!*timeo)
return ret;
add_wait_queue(sk_sleep(sk), &wait);
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
- ret = sk_wait_event(sk, &timeo,
+ ret = sk_wait_event(sk, timeo,
!list_empty(&psock->ingress_msg) ||
!skb_queue_empty_lockless(&sk->sk_receive_queue), &wait);
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
@@ -229,6 +229,7 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
int copied_from_self = 0;
int copied = 0;
u32 seq;
+ long timeo;
if (unlikely(flags & MSG_ERRQUEUE))
return inet_recv_error(sk, msg, len);
@@ -262,6 +263,8 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
}
}
+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
msg_bytes_ready:
copied = __sk_msg_recvmsg(sk, psock, msg, len, flags, &copied_from_self);
/* The typical case for EFAULT is the socket was gracefully
@@ -280,7 +283,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
}
seq += copied_from_self;
if (!copied) {
- long timeo;
int data;
if (sock_flag(sk, SOCK_DONE))
@@ -299,7 +301,6 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
goto out;
}
- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
if (!timeo) {
copied = -EAGAIN;
goto out;
@@ -310,13 +311,15 @@ static int tcp_bpf_recvmsg_parser(struct sock *sk,
goto out;
}
- data = tcp_msg_wait_data(sk, psock, timeo);
+ data = tcp_msg_wait_data(sk, psock, &timeo);
if (data < 0) {
copied = data;
goto unlock;
}
if (data && !sk_psock_queue_empty(psock))
goto msg_bytes_ready;
+ if (!data && timeo > 0)
+ goto msg_bytes_ready;
copied = -EAGAIN;
}
out:
@@ -355,6 +358,7 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
{
struct sk_psock *psock;
int copied, ret;
+ long timeo;
if (unlikely(flags & MSG_ERRQUEUE))
return inet_recv_error(sk, msg, len);
@@ -371,14 +375,59 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
return tcp_recvmsg(sk, msg, len, flags);
}
lock_sock(sk);
+
+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
msg_bytes_ready:
copied = sk_msg_recvmsg(sk, psock, msg, len, flags);
if (!copied) {
- long timeo;
int data;
- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
- data = tcp_msg_wait_data(sk, psock, timeo);
+ if (sock_flag(sk, SOCK_DONE)) {
+ ret = 0;
+ goto unlock;
+ }
+
+ if (sk->sk_err) {
+ if (!sk_psock_queue_empty(psock))
+ goto msg_bytes_ready;
+ if (!skb_queue_empty(&sk->sk_receive_queue)) {
+ release_sock(sk);
+ sk_psock_put(sk, psock);
+ return tcp_recvmsg(sk, msg, len, flags);
+ }
+ ret = sock_error(sk);
+ goto unlock;
+ }
+
+ if (sk->sk_shutdown & RCV_SHUTDOWN) {
+ if (!sk_psock_queue_empty(psock))
+ goto msg_bytes_ready;
+ if (!skb_queue_empty(&sk->sk_receive_queue)) {
+ release_sock(sk);
+ sk_psock_put(sk, psock);
+ return tcp_recvmsg(sk, msg, len, flags);
+ }
+ ret = 0;
+ goto unlock;
+ }
+
+ if (sk->sk_state == TCP_CLOSE) {
+ ret = -ENOTCONN;
+ goto unlock;
+ }
+
+ if (!timeo) {
+ ret = -EAGAIN;
+ goto unlock;
+ }
+
+ if (signal_pending(current)) {
+ ret = sock_intr_errno(timeo);
+ goto unlock;
+ }
+
+ data = tcp_msg_wait_data(sk, psock, &timeo);
if (data < 0) {
ret = data;
goto unlock;
@@ -390,6 +439,8 @@ static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
sk_psock_put(sk, psock);
return tcp_recvmsg(sk, msg, len, flags);
}
+ if (!data && timeo > 0)
+ goto msg_bytes_ready;
copied = -EAGAIN;
}
ret = copied;
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
index cb3229711f93a3..d18faf46fac0c2 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
@@ -1373,6 +1373,126 @@ static void test_sockmap_multi_channels(int sotype)
test_sockmap_pass_prog__destroy(skel);
}
+static void *test_sockmap_recvfrom_eagain_thread(void *arg)
+{
+ int fd = *(int *)arg;
+ char buf[1024];
+ void *result = NULL;
+
+ while (true) {
+ ssize_t len = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
+
+ if (len == -1) {
+ if (errno == EINTR)
+ continue;
+ result = (void *)1;
+ break;
+ }
+
+ if (!len || buf[len - 1] == 'e')
+ break;
+ }
+
+ send(fd, "test", 4, MSG_NOSIGNAL);
+
+ close(fd);
+
+ return result;
+}
+
+static void test_sockmap_recvfrom_eagain(bool with_verdict)
+{
+ struct test_sockmap_pass_prog *skel = NULL;
+ struct bpf_program *prog = NULL;
+ size_t buflen = 1024 * 1024 * 25;
+ char *buf = NULL;
+ int map, err;
+
+ skel = test_sockmap_pass_prog__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "open_and_load"))
+ return;
+
+ map = bpf_map__fd(skel->maps.sock_map_msg);
+
+ if (with_verdict) {
+ prog = skel->progs.prog_skb_verdict;
+ err = bpf_prog_attach(bpf_program__fd(prog), map, BPF_SK_SKB_STREAM_VERDICT, 0);
+ if (!ASSERT_OK(err, "bpf_prog_attach verdict"))
+ goto cleanup;
+ }
+
+ buf = malloc(buflen);
+ if (!ASSERT_OK_PTR(buf, "malloc buf"))
+ goto cleanup;
+ memset(buf, 0, buflen);
+ buf[buflen - 1] = 'e';
+
+ for (int i = 0; i < 200; ++i) {
+ ssize_t sent;
+ char ignored[128];
+ pthread_t thread;
+ bool thread_created = false;
+ size_t rem = buflen;
+ int c = -1, p = -1, zero = 0;
+ bool success = false;
+
+ err = create_pair(AF_INET, SOCK_STREAM, &c, &p);
+ if (!ASSERT_OK(err, "create_pair"))
+ goto end_attempt;
+
+ err = pthread_create(&thread, NULL, &test_sockmap_recvfrom_eagain_thread, &p);
+ if (!ASSERT_OK(err, "pthread_create"))
+ goto end_attempt;
+ thread_created = true;
+
+ err = bpf_map_update_elem(map, &zero, &c, BPF_ANY);
+ if (!ASSERT_OK(err, "bpf_map_update_elem"))
+ goto end_attempt;
+
+ while (rem) {
+ sent = xsend(c, buf + (buflen - rem), rem, 0);
+ if (sent == -1)
+ goto end_attempt;
+ rem -= sent;
+ }
+
+ /* we cannot use recv_timeout(), otherwise EAGAIN would be an expected errno. */
+ err = recvfrom(c, ignored, sizeof(ignored), 0, NULL, NULL);
+
+ /*
+ * we are checking for the invalid return of EAGAIN, any other return is considered
+ * successful for the purposes of this test.
+ */
+ if (err < 0 && !ASSERT_NEQ(errno, EAGAIN, "recvfrom eagain"))
+ goto end_attempt;
+
+ success = true;
+
+end_attempt:
+ if (c >= 0)
+ close(c);
+
+ if (thread_created) {
+ void *retval = NULL;
+
+ pthread_join(thread, &retval);
+ if (!ASSERT_NULL(retval, "retval"))
+ success = false;
+ }
+
+ if (!thread_created && p >= 0)
+ close(p);
+ if (!success)
+ break;
+ }
+
+cleanup:
+ if (buf)
+ free(buf);
+
+ test_sockmap_pass_prog__destroy(skel);
+}
+
void test_sockmap_basic(void)
{
if (test__start_subtest("sockmap create_update_free"))
@@ -1451,4 +1571,8 @@ void test_sockmap_basic(void)
test_sockmap_multi_channels(SOCK_STREAM);
if (test__start_subtest("sockmap udp multi channels"))
test_sockmap_multi_channels(SOCK_DGRAM);
+ if (test__start_subtest("sockmap recvfrom eagain"))
+ test_sockmap_recvfrom_eagain(false);
+ if (test__start_subtest("sockmap recvfrom eagain with verdict"))
+ test_sockmap_recvfrom_eagain(true);
}
|
| 3/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5136 output: 30 thoughts: 217 Thoughts: **Analyzing the TCP BPF Patch** Okay, so I'm looking at this patch. It seems like we've got a modification to `net/ipv4/tcp_bpf.c` and a related test update in `tools/testing/selftests/bpf/prog_tests/sockmap_basic.c`. My initial read tells me it's a functional change, specifically in the kernel's TCP BPF/sockmap area. The core of it seems to be in how the timeout is handled within `tcp_msg_wait_data`. Previously it took a `long timeo`, but this patch changes it to take a `long *timeo` – a pointer. This change ripples through the functions that call it, namely `tcp_bpf_recvmsg_parser` and `tcp_bpf_recvmsg`, where they now pass the address of the timeout variable (`&timeo`) instead of the value itself. This is immediately interesting. This suggests a desire to modify the timeout value *within* `tcp_msg_wait_data`. My hypothesis is that they are trying to provide finer-grained control over the timeout handling. Perhaps, to resolve an issue where `recvfrom` might incorrectly return `EAGAIN` when it shouldn't – as they mentioned. Now, before I dig into the code's minutiae, I need to understand the configuration context for this module. I'll use `grepper` to quickly locate the configuration options associated with `tcp_bpf.c`. Time to see what kernel config options control this functionality. I'll search through `net/ipv4/Makefile` to see how it's defined and included in the build. Knowing those options will help me interpret this change correctly. |
| 4/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "tcp_bpf",
"PathPrefix": "net/ipv4/Makefile"
}Results: {
"Output": "net/ipv4/Makefile=62=obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o\nnet/ipv4/Makefile:63:obj-$(CONFIG_NET_SOCK_MSG) += tcp_bpf.o\nnet/ipv4/Makefile-64-obj-$(CONFIG_BPF_SYSCALL) += udp_bpf.o\n"
} |
| 5/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 5858 output: 33 thoughts: 49 Thoughts: Okay, here's my take on those preliminary thoughts, expressed from a first-person perspective, as a seasoned professional: **Initial Configuration Considerations** Alright, so I'm diving into this and the first thing I'm noting is that `CONFIG_NET_SOCK_MSG` is a hard requirement. No surprises there; we need that foundational socket messaging support, obviously. Then, for leveraging BPF, which I'm assuming is the goal here, `CONFIG_BPF_SYSCALL` is *definitely* going to be needed. That's a given. Now, before I go any further down this rabbit hole, I should quickly do a sanity check to see if `tcp_bpf.c` has any other dependencies. Better to have them all in one place and not find out later I need to recompile. Makes sense, given the focus on tcp and bpf. |
| 6/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_",
"PathPrefix": "net/ipv4/tcp_bpf.c"
}Results: {
"Output": "net/ipv4/tcp_bpf.c=178=EXPORT_SYMBOL_GPL(tcp_bpf_sendmsg_redir);\nnet/ipv4/tcp_bpf.c-179-\nnet/ipv4/tcp_bpf.c:180:#ifdef CONFIG_BPF_SYSCALL\nnet/ipv4/tcp_bpf.c-181-static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock,\n--\nnet/ipv4/tcp_bpf.c=713=static int tcp_bpf_assert_proto_ops(struct proto *ops)\n--\nnet/ipv4/tcp_bpf.c-722-\nnet/ipv4/tcp_bpf.c:723:#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)\nnet/ipv4/tcp_bpf.c-724-int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc,\n--\nnet/ipv4/tcp_bpf.c-756-}\nnet/ipv4/tcp_bpf.c:757:#endif /* CONFIG_BPF_STREAM_PARSER */\nnet/ipv4/tcp_bpf.c-758-\n--\nnet/ipv4/tcp_bpf.c=803=void tcp_bpf_clone(const struct sock *sk, struct sock *newsk)\n--\nnet/ipv4/tcp_bpf.c-809-}\nnet/ipv4/tcp_bpf.c:810:#endif /* CONFIG_BPF_SYSCALL */\n"
} |
| 7/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 6543 output: 38 thoughts: 75 Thoughts: Okay, let's break this down. **Diving into the BPF-Enabled TCP Receive Path** Alright, so I need to focus on these functions: `tcp_msg_wait_data`, `tcp_bpf_recvmsg_parser`, and `tcp_bpf_recvmsg`. The `#ifdef CONFIG_BPF_SYSCALL` indicates these are related to the BPF (Berkeley Packet Filter) integration, and specifically, BPF syscall enhancements. That's good, that confirms my initial hunch. It looks like they're building on the existing TCP receive path to support BPF filtering and processing during `recvmsg` calls. The core of this has to be in the parsing and `recvmsg` functions, so I'm going to start with a closer look at `tcp_bpf_recvmsg_parser` and `tcp_bpf_recvmsg`. I'll need to understand how the BPF logic is integrated into the typical `recvmsg` flow here. Are they using the BPF program to validate or modify the incoming data, control buffer allocation, or something more? The parser function will be crucial for understanding how the BPF program interprets the incoming data. I will be looking for how the BPF program is retrieved, and how data is shared between it and the kernel. The goal is to see exactly how these changes interact with the TCP stack and how they influence the `recvmsg` operation with BPF programs in place. |
| 8/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "tcp_bpf_recvmsg",
"PathPrefix": "net/ipv4/tcp_bpf.c"
}Results: {
"Output": "net/ipv4/tcp_bpf.c=203=static bool is_next_msg_fin(struct sk_psock *psock)\n--\nnet/ipv4/tcp_bpf.c-220-\nnet/ipv4/tcp_bpf.c:221:static int tcp_bpf_recvmsg_parser(struct sock *sk,\nnet/ipv4/tcp_bpf.c-222-\t\t\t\t struct msghdr *msg,\n--\nnet/ipv4/tcp_bpf.c=338=static int tcp_bpf_ioctl(struct sock *sk, int cmd, int *karg)\n--\nnet/ipv4/tcp_bpf.c-355-\nnet/ipv4/tcp_bpf.c:356:static int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,\nnet/ipv4/tcp_bpf.c-357-\t\t\t int flags)\n--\nnet/ipv4/tcp_bpf.c=674=static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS],\n--\nnet/ipv4/tcp_bpf.c-679-\tprot[TCP_BPF_BASE].close\t\t= sock_map_close;\nnet/ipv4/tcp_bpf.c:680:\tprot[TCP_BPF_BASE].recvmsg\t\t= tcp_bpf_recvmsg;\nnet/ipv4/tcp_bpf.c-681-\tprot[TCP_BPF_BASE].sock_is_readable\t= sk_msg_is_readable;\n--\nnet/ipv4/tcp_bpf.c-687-\tprot[TCP_BPF_RX]\t\t\t= prot[TCP_BPF_BASE];\nnet/ipv4/tcp_bpf.c:688:\tprot[TCP_BPF_RX].recvmsg\t\t= tcp_bpf_recvmsg_parser;\nnet/ipv4/tcp_bpf.c-689-\nnet/ipv4/tcp_bpf.c-690-\tprot[TCP_BPF_TXRX]\t\t\t= prot[TCP_BPF_TX];\nnet/ipv4/tcp_bpf.c:691:\tprot[TCP_BPF_TXRX].recvmsg\t\t= tcp_bpf_recvmsg_parser;\nnet/ipv4/tcp_bpf.c-692-}\n--\nnet/ipv4/tcp_bpf.c=724=int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc,\n--\nnet/ipv4/tcp_bpf.c-747-\t * For SK_REDIRECT, we need to ack the frame immediately but for\nnet/ipv4/tcp_bpf.c:748:\t * SK_PASS, we want to delay the ack until tcp_bpf_recvmsg_parser().\nnet/ipv4/tcp_bpf.c-749-\t */\n"
} |
| 9/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 7719 output: 28 thoughts: 149 Thoughts: **Analyzing the TCP BPF Recvmsg Implementation** Okay, so I'm looking at `tcp_bpf_recvmsg_parser` and `tcp_bpf_recvmsg`. They are called via `recvmsg` on a TCP socket that has been added to a sockmap. This means `CONFIG_NET_SOCK_MSG` and `CONFIG_BPF_SYSCALL` are definitely key here. Now, I want to be thorough, so I need to make sure there aren't any other crucial configurations that impact this. I'll need to double check the dependencies. `CONFIG_NET_SOCK_MSG` is selected by either `CONFIG_CGROUP_BPF` or possibly by `CONFIG_BPF_SYSCALL` along with `CONFIG_INET` in some scenarios. Time to dive into the kernel configuration files, specifically `net/Kconfig` and potentially `net/ipv4/Kconfig` to confirm these dependencies and make sure I haven't missed anything subtle. Understanding the config options is key to understanding the overall functionality of the BPF integration with TCP sockets here. |
| 10/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "config NET_SOCK_MSG",
"PathPrefix": "net/"
}Results: {
"Output": "net/Kconfig=475=config NET_SELFTESTS\n--\nnet/Kconfig-478-\nnet/Kconfig:479:config NET_SOCK_MSG\nnet/Kconfig-480-\tbool\n"
} |
| 11/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8200 output: 28 thoughts: 13 Thoughts: Okay, here's my attempt at summarizing that thought process, tailored for an expert audience: **Analyzing the `NET_SOCK_MSG` Selector** Alright, so the task at hand is to pinpoint where `NET_SOCK_MSG` is being utilized. This isn't just a casual exercise; I need to understand its impact and how it fits within the larger network stack I'm working with. I'm thinking I'll need to trace its usage through the code, starting with the immediate context where it's defined and then branching out to identify the functions and structures that interact with it. I'm going to pay close attention to the data flow associated with this selector and any potential implications for performance, security, or error handling. Essentially, I want to form a complete understanding of the role `NET_SOCK_MSG` plays in the network socket messaging system. |
| 12/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "select NET_SOCK_MSG",
"PathPrefix": "net/"
}Results: {
"Output": "net/Kconfig=361=config BPF_STREAM_PARSER\n--\nnet/Kconfig-366-\tselect STREAM_PARSER\nnet/Kconfig:367:\tselect NET_SOCK_MSG\nnet/Kconfig-368-\thelp\n--\nnet/ipv4/Kconfig=382=config INET_ESPINTCP\n--\nnet/ipv4/Kconfig-385-\tselect STREAM_PARSER\nnet/ipv4/Kconfig:386:\tselect NET_SOCK_MSG\nnet/ipv4/Kconfig-387-\tselect XFRM_ESPINTCP\n--\nnet/ipv6/Kconfig=90=config INET6_ESPINTCP\n--\nnet/ipv6/Kconfig-93-\tselect STREAM_PARSER\nnet/ipv6/Kconfig:94:\tselect NET_SOCK_MSG\nnet/ipv6/Kconfig-95-\tselect XFRM_ESPINTCP\n--\nnet/tls/Kconfig=5=config TLS\n--\nnet/tls/Kconfig-10-\tselect CRYPTO_GCM\nnet/tls/Kconfig:11:\tselect NET_SOCK_MSG\nnet/tls/Kconfig-12-\tdefault n\n"
} |
| 13/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8734 output: 30 thoughts: 32 Thoughts: Okay, here's my interpretation of those thoughts, summarized from a first-person expert perspective: **Diving into BPF Stream Parsing** Alright, let's see. My mind is immediately drawn to a specific detail: the `BPF_STREAM_PARSER` seems to be intimately connected with `NET_SOCK_MSG`. That relationship is pretty fundamental, so I need to establish a clearer picture. What's the key that unlocks the `BPF_STREAM_PARSER` then? I have to trace back the logical flow here. I need to understand what component or mechanism is responsible for *selecting* or *triggering* the `BPF_STREAM_PARSER` in the first place. That's the critical question I need to answer to fully understand this connection. |
| 14/2 | 2026/07/21 00:08 | tool | grepper |
0mError:no matches Args: {
"Expression": "select BPF_STREAM_PARSER",
"PathPrefix": "net/"
}Results: {
"error": "no matches"
} |
| 15/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8976 output: 30 thoughts: 20 Thoughts: Here's a summary of my thought process, as requested: **Diving into the Kernel Configuration** Okay, so I need to understand something related to stream parsing, and the kernel config is the natural place to start. My immediate thought is to check the `net/Kconfig` file. I'm going to look for anything related to `BPF_STREAM_PARSER`. I expect that this will give me some key configuration options or dependencies that relate to the functionality I'm interested in. Essentially, I'm trying to map the problem I have to the relevant kernel features. Time to dig in and see what's there. |
| 16/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "config BPF_STREAM_PARSER",
"PathPrefix": "net/"
}Results: {
"Output": "net/Kconfig=354=config BQL\n--\nnet/Kconfig-360-\nnet/Kconfig:361:config BPF_STREAM_PARSER\nnet/Kconfig-362-\tbool \"enable BPF STREAM_PARSER\"\n"
} |
| 17/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9237 output: 26 thoughts: 49 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Kernel Configuration Context** Right, so we're looking at `BPF_STREAM_PARSER` as a user-configurable option. That immediately flags `CGROUP_BPF` as a potential co-dependent or related feature. To get the full picture and understand its place in the kernel's configuration landscape, I need to consult the definitive sources. I'll head straight to `init/Kconfig` or, more likely given the BPF focus, `kernel/bpf/Kconfig`. These should contain the dependencies, defaults, and broader context for both options, and any relationships that need to be understood when integrating them, or considering them in an existing project. I'm after the full picture - what these do, and how they relate to the bigger kernel picture. |
| 18/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "select NET_SOCK_MSG",
"PathPrefix": ""
}Results: {
"Output": "kernel/bpf/Kconfig=27=config BPF_SYSCALL\n--\nkernel/bpf/Kconfig-33-\tselect BINARY_PRINTF\nkernel/bpf/Kconfig:34:\tselect NET_SOCK_MSG if NET\nkernel/bpf/Kconfig-35-\tselect NET_XGRESS if NET\n--\nnet/Kconfig=361=config BPF_STREAM_PARSER\n--\nnet/Kconfig-366-\tselect STREAM_PARSER\nnet/Kconfig:367:\tselect NET_SOCK_MSG\nnet/Kconfig-368-\thelp\n--\nnet/ipv4/Kconfig=382=config INET_ESPINTCP\n--\nnet/ipv4/Kconfig-385-\tselect STREAM_PARSER\nnet/ipv4/Kconfig:386:\tselect NET_SOCK_MSG\nnet/ipv4/Kconfig-387-\tselect XFRM_ESPINTCP\n--\nnet/ipv6/Kconfig=90=config INET6_ESPINTCP\n--\nnet/ipv6/Kconfig-93-\tselect STREAM_PARSER\nnet/ipv6/Kconfig:94:\tselect NET_SOCK_MSG\nnet/ipv6/Kconfig-95-\tselect XFRM_ESPINTCP\n--\nnet/tls/Kconfig=5=config TLS\n--\nnet/tls/Kconfig-10-\tselect CRYPTO_GCM\nnet/tls/Kconfig:11:\tselect NET_SOCK_MSG\nnet/tls/Kconfig-12-\tdefault n\n"
} |
| 19/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 9888 output: 40 thoughts: 323 Thoughts: **Fuzzing Target Identification: TCP Sockmap and recvmsg** Okay, let's see. My initial thought process is leading me to focus on `NET_SOCK_MSG` because `BPF_SYSCALL` (standard for fuzzing, right?) seems to enable it when `NET` is also enabled. That means I'll be looking at code that is compiled under `CONFIG_NET_SOCK_MSG`, which, according to the build system (`net/ipv4/Makefile`), includes `tcp_bpf.o`. Makes sense, so it's compiled in. Now, which functions are modified? Let's see... I have `tcp_msg_wait_data`, `tcp_bpf_recvmsg_parser`, and `tcp_bpf_recvmsg`. Aha! These are definitely reachable when a TCP socket gets added to a sockmap and then `recvmsg` is called. Bingo! This is absolutely worth targeting for fuzzing. My primary focus should be on `tcp_bpf_recvmsg_parser` and `tcp_bpf_recvmsg` – these are where the interesting logic resides. I should also include `tcp_msg_wait_data`, since it's a static helper function. Okay, let's see about the configurations I'll need to enable to build this. I know `CONFIG_BPF_SYSCALL` and `CONFIG_NET_SOCK_MSG` are necessary. Obviously, `CONFIG_INET` is too. What about `CONFIG_BPF_STREAM_PARSER`? That might be needed for `tcp_bpf_recvmsg_parser`. Let's dig in a bit more to be sure. |
| 20/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "tcp_bpf_recvmsg_parser",
"PathPrefix": "net/ipv4/tcp_bpf.c"
}Results: {
"Output": "net/ipv4/tcp_bpf.c=203=static bool is_next_msg_fin(struct sk_psock *psock)\n--\nnet/ipv4/tcp_bpf.c-220-\nnet/ipv4/tcp_bpf.c:221:static int tcp_bpf_recvmsg_parser(struct sock *sk,\nnet/ipv4/tcp_bpf.c-222-\t\t\t\t struct msghdr *msg,\n--\nnet/ipv4/tcp_bpf.c=674=static void tcp_bpf_rebuild_protos(struct proto prot[TCP_BPF_NUM_CFGS],\n--\nnet/ipv4/tcp_bpf.c-687-\tprot[TCP_BPF_RX]\t\t\t= prot[TCP_BPF_BASE];\nnet/ipv4/tcp_bpf.c:688:\tprot[TCP_BPF_RX].recvmsg\t\t= tcp_bpf_recvmsg_parser;\nnet/ipv4/tcp_bpf.c-689-\nnet/ipv4/tcp_bpf.c-690-\tprot[TCP_BPF_TXRX]\t\t\t= prot[TCP_BPF_TX];\nnet/ipv4/tcp_bpf.c:691:\tprot[TCP_BPF_TXRX].recvmsg\t\t= tcp_bpf_recvmsg_parser;\nnet/ipv4/tcp_bpf.c-692-}\n--\nnet/ipv4/tcp_bpf.c=724=int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc,\n--\nnet/ipv4/tcp_bpf.c-747-\t * For SK_REDIRECT, we need to ack the frame immediately but for\nnet/ipv4/tcp_bpf.c:748:\t * SK_PASS, we want to delay the ack until tcp_bpf_recvmsg_parser().\nnet/ipv4/tcp_bpf.c-749-\t */\n"
} |
| 21/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11122 output: 40 thoughts: 174 Thoughts: **Analyzing the BPF-related `recvmsg` Call** Okay, so I'm looking at how `recvmsg` is handled in this context. It appears this code specifically ties into `prot[TCP_BPF_RX].recvmsg` and `prot[TCP_BPF_TXRX].recvmsg`. Right, these are the hooks used when a BPF program is active on a sockmap. This usually means a program like `BPF_SK_SKB_STREAM_VERDICT` or `BPF_SK_SKB_STREAM_PARSER` has been attached. The test case `test_sockmap_recvfrom_eagain` seems to be attaching `BPF_SK_SKB_STREAM_VERDICT`. Therefore, the minimal requirements should be having `CONFIG_BPF_SYSCALL` and `CONFIG_NET_SOCK_MSG` enabled. Now, a quick sanity check to make sure I haven't missed anything: I need to verify that `CONFIG_BPF_STREAM_PARSER` isn't somehow necessary for `tcp_bpf_recvmsg_parser` function. This should be trivial, but it never hurts to be thorough! |
| 22/2 | 2026/07/21 00:08 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_BPF_STREAM_PARSER",
"PathPrefix": "net/ipv4/tcp_bpf.c"
}Results: {
"Output": "net/ipv4/tcp_bpf.c=713=static int tcp_bpf_assert_proto_ops(struct proto *ops)\n--\nnet/ipv4/tcp_bpf.c-722-\nnet/ipv4/tcp_bpf.c:723:#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)\nnet/ipv4/tcp_bpf.c-724-int tcp_bpf_strp_read_sock(struct strparser *strp, read_descriptor_t *desc,\n--\nnet/ipv4/tcp_bpf.c-756-}\nnet/ipv4/tcp_bpf.c:757:#endif /* CONFIG_BPF_STREAM_PARSER */\nnet/ipv4/tcp_bpf.c-758-\n"
} |
| 23/2 | 2026/07/21 00:08 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11799 output: 163 thoughts: 223 Thoughts: **Analyzing the BPF Socketmap Patch** Okay, so I'm looking at this patch and confirming my understanding of where `tcp_bpf_recvmsg_parser` lives within the kernel. It's definitely not behind `#if IS_ENABLED(CONFIG_BPF_STREAM_PARSER)`, as I initially thought; it's guarded by the more general `#ifdef CONFIG_BPF_SYSCALL` – which, of course, covers the majority of that file. Good to make sure I'm precise about those preprocessor directives. Let me just list those relevant configurations for my own clarity: `BPF_SYSCALL` and `NET_SOCK_MSG`. Got it. Now, focusing in on the key symbols, I'm thinking about: `tcp_bpf_recvmsg`, the `tcp_bpf_recvmsg_parser` which seems central to this, and also `tcp_msg_wait_data`. The core of this seems to be around how timeout handling is managed in `tcp_bpf_recvmsg` and its parser when we're waiting for data on a TCP socket within a sockmap context. This patch seems to be addressing a potential bug where `recvfrom` could incorrectly return `EAGAIN` – which would be a pretty nasty regression. This is definitely a functional change in the core networking and BPF subsystem. Therefore, fuzzing is absolutely essential to ensure the code behaves as expected and to guard against introducing any regressions. I need to flag that for consideration. Okay, I think I have a good handle on this. I'll make a call on this using the `set-results` command now. |
| 24/2 | 2026/07/21 00:08 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"BPF_SYSCALL",
"NET_SOCK_MSG"
],
"FocusSymbols": [
"tcp_bpf_recvmsg",
"tcp_bpf_recvmsg_parser",
"tcp_msg_wait_data"
],
"Reasoning": "The patch modifies the timeout handling in `tcp_bpf_recvmsg` and `tcp_bpf_recvmsg_parser` when waiting for data on a TCP socket in a sockmap. It fixes a bug where `recvfrom` could incorrectly return `EAGAIN`. This is a functional change in the core networking/BPF subsystem and should be fuzzed to ensure correct behavior and prevent regressions.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"BPF_SYSCALL",
"NET_SOCK_MSG"
],
"FocusSymbols": [
"tcp_bpf_recvmsg",
"tcp_bpf_recvmsg_parser",
"tcp_msg_wait_data"
],
"Reasoning": "The patch modifies the timeout handling in `tcp_bpf_recvmsg` and `tcp_bpf_recvmsg_parser` when waiting for data on a TCP socket in a sockmap. It fixes a bug where `recvfrom` could incorrectly return `EAGAIN`. This is a functional change in the core networking/BPF subsystem and should be fuzzed to ensure correct behavior and prevent regressions.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|