From: sashiko-bot@kernel.org
To: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>, bpf@vger.kernel.org
Cc: mptcp@lists.linux.dev
Subject: Re: [PATCH bpf 03/15] bpf, sockmap: Don't let an SK_PASS verdict cover the next message
Date: Sun, 01 Nov 2026 19:42:24 +0000 [thread overview]
Message-ID: <sashiko-outbox-192629@kernel.org> (raw)
In-Reply-To: <20261101192057.2296489-4-alexei.starovoitov@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] bpf: corrupt verdict state after tcp_bpf_push() in tcp_bpf_send_verdict()
--
commit cb1b40f55f45104a6d23bf64e86e3c0a379b2459
Author: Alexei Starovoitov <ast@kernel.org>
bpf, sockmap: Don't let an SK_PASS verdict cover the next message
This commit resets psock->eval before calling tcp_bpf_push() when
psock->apply_bytes is 0, and subtracts any sent bytes from
psock->apply_bytes if tcp_bpf_push() fails.
> diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
> index d90bcc911b36b..072ffd8347a6f 100644
> --- a/net/ipv4/tcp_bpf.c
> +++ b/net/ipv4/tcp_bpf.c
> @@ -457,8 +457,14 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock,
>
> switch (psock->eval) {
> case __SK_PASS:
> + /* The push may sleep without the socket lock, and it may fail */
> + if (!psock->apply_bytes)
> + psock->eval = __SK_NONE;
> + origsize = msg->sg.size;
> ret = tcp_bpf_push(sk, msg, tosend, flags, true);
> if (unlikely(ret)) {
> + /* A part of it may have gone out */
> + sk_msg_apply_bytes(psock, origsize - msg->sg.size);
> *copied -= sk_msg_free(sk, msg);
> break;
> }
[Severity: High]
Can this corrupt a concurrent sender's verdict state or leave psock->eval
set when psock->apply_bytes reaches 0?
In tcp_bpf_send_verdict() under case __SK_PASS, if Thread A enters with
psock->apply_bytes == 0, it resets psock->eval = __SK_NONE before calling
tcp_bpf_push(). If tcp_bpf_push() -> tcp_sendmsg_locked() releases the
socket lock in sk_stream_wait_memory(), a concurrent Thread B in
tcp_bpf_sendmsg() -> tcp_bpf_send_verdict() can see psock->eval == __SK_NONE,
run sk_psock_msg_verdict(), and install a new psock->eval (including
__SK_REDIRECT with psock->sk_redir) and psock->apply_bytes.
When Thread A returns from tcp_bpf_push(), it still calls
sk_msg_apply_bytes() on both the error and success paths, and on success runs
the post-switch cleanup:
net/ipv4/tcp_bpf.c:tcp_bpf_send_verdict() {
...
case __SK_PASS:
/* The push may sleep without the socket lock, and it may fail */
if (!psock->apply_bytes)
psock->eval = __SK_NONE;
origsize = msg->sg.size;
ret = tcp_bpf_push(sk, msg, tosend, flags, true);
if (unlikely(ret)) {
/* A part of it may have gone out */
sk_msg_apply_bytes(psock, origsize - msg->sg.size);
*copied -= sk_msg_free(sk, msg);
break;
}
sk_msg_apply_bytes(psock, tosend);
break;
...
if (likely(!ret)) {
if (!psock->apply_bytes) {
psock->eval = __SK_NONE;
if (psock->sk_redir) {
sock_put(psock->sk_redir);
psock->sk_redir = NULL;
}
}
}
Wouldn't Thread A subtract its own sent bytes from Thread B's
psock->apply_bytes, and if psock->apply_bytes is 0 when ret == 0, reset
Thread B's psock->eval to __SK_NONE and drop Thread B's psock->sk_redir?
Also, on the error path (unlikely(ret)), if sk_msg_apply_bytes(psock,
origsize - msg->sg.size) reduces a non-zero psock->apply_bytes to 0 (for
instance if another sender consumed part of psock->apply_bytes while
tcp_bpf_push() slept), the post-switch block is skipped because ret != 0.
Wouldn't that leave psock->eval as __SK_PASS with psock->apply_bytes == 0,
causing the next message to bypass the sk_msg program?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261101192057.2296489-1-alexei.starovoitov@gmail.com?part=3
next prev parent reply other threads:[~2026-11-01 19:42 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 19:20 [PATCH bpf 00/15] bpf, sockmap: Fixes for verdicts, redirects, corks and recvmsg() Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 01/15] bpf, sockmap: Write sg.start when recvmsg() faults Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 02/15] bpf, sockmap: Don't let an SK_DROP verdict stick Alexei Starovoitov
2026-11-01 19:39 ` bot+bpf-ci
2026-11-02 0:15 ` Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 03/15] bpf, sockmap: Don't let an SK_PASS verdict cover the next message Alexei Starovoitov
2026-11-01 19:42 ` sashiko-bot [this message]
2026-11-02 0:16 ` Alexei Starovoitov
2026-11-01 19:51 ` bot+bpf-ci
2026-11-01 19:20 ` [PATCH bpf 04/15] bpf, sockmap: Subtract all dropped bytes from the return value Alexei Starovoitov
2026-11-01 19:39 ` bot+bpf-ci
2026-11-01 19:20 ` [PATCH bpf 05/15] bpf, sockmap: Clear the resume state of a stopped psock Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 06/15] bpf, sockmap: Give no progs to a TCP listener Alexei Starovoitov
2026-11-01 19:51 ` sashiko-bot
2026-11-02 0:17 ` Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 07/15] bpf, sockmap: Check the target of an egress redirect before each send Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 08/15] net: Leave sk_stream_wait_memory() once the socket is dead Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 09/15] bpf, sockmap: Check the TCP state in recvmsg() Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 10/15] bpf, sockmap: Reset the copy position when corking Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 11/15] bpf, sockmap: Don't copy 0 bytes into a full cork Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 12/15] bpf, sockmap: Clear the redirect target before the sk_msg prog runs Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 13/15] bpf, sockmap: Check that the redirected message is the cork Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 14/15] bpf, sockmap: Keep the rest of the cork after a redirect Alexei Starovoitov
2026-11-01 19:20 ` [PATCH bpf 15/15] bpf, sockmap: Clear the end mark of elements added by push and pop Alexei Starovoitov
2026-11-01 21:30 ` [PATCH bpf 00/15] bpf, sockmap: Fixes for verdicts, redirects, corks and recvmsg() MPTCP 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=sashiko-outbox-192629@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=alexei.starovoitov@gmail.com \
--cc=bpf@vger.kernel.org \
--cc=mptcp@lists.linux.dev \
--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.