All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Alex Markuze" <amarkuze@redhat.com>
Cc: bpf@vger.kernel.org
Subject: Re: [RFC PATCH net-next 01/12] net: add an exclusive TCP receive claim
Date: Wed, 11 Nov 2026 13:20:44 +0000	[thread overview]
Message-ID: <sashiko-outbox-209058@kernel.org> (raw)
In-Reply-To: <20261110132006.3280986-2-amarkuze@redhat.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [Medium] tcp: returning -EBUSY in tcp_disconnect() breaks internal
  callers
- [Medium] net: missing sock_rx_owned() checks in kcm_attach() and
  ovpn_tcp_socket_attach()
--

commit db5306ce28288ea69fe78b0895ec7be46b42bf0b
Author: Alex Markuze <amarkuze@redhat.com>

net: add an exclusive TCP receive claim

This commit adds an optional sk_rx_owner pointer to struct sock so a
tcp_read_sock() consumer can claim exclusive access to a TCP socket's
receive sequence and reject competing readers or operations that reset the
receive stream.

> diff --git a/net/core/skmsg.c b/net/core/skmsg.c
> index df385a5a961e8..5c753bcb808c5 100644
> --- a/net/core/skmsg.c
> +++ b/net/core/skmsg.c
> @@ -754,6 +754,10 @@ struct sk_psock *sk_psock_init(struct sock *sk, int node)
>  
>  	write_lock_bh(&sk->sk_callback_lock);
>  
> +	if (sock_rx_owned(sk)) {
> +		psock = ERR_PTR(-EBUSY);
> +		goto out;
> +	}
>  	if (sk_is_inet(sk) && inet_csk_has_ulp(sk)) {
>  		psock = ERR_PTR(-EINVAL);
>  		goto out;

[Severity: Medium]
Should kcm_attach() and ovpn_tcp_socket_attach() also check
sock_rx_owned()?

Like sk_psock_init(), both attach to a TCP socket by checking only
sk->sk_user_data, which remains NULL when sk_rx_owner is set.  Attaching
via kcm_attach() installs a strparser and replaces sk->sk_state_change
with psock_state_change(), which sets sk->sk_err = EPIPE on a normal peer
FIN and causes the receive owner to fail with -EPIPE instead of clean EOF.
Attaching via ovpn_tcp_socket_attach() replaces sk->sk_prot and
sk->sk_socket->ops with ovpn_tcp_recvmsg(), bypassing the sock_rx_owned()
checks.

> diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> index 7677b0343abd4..54c30a59bbce4 100644
> --- a/net/ipv4/af_inet.c
> +++ b/net/ipv4/af_inet.c
> @@ -649,6 +649,8 @@ int __inet_stream_connect(struct socket *sock, struct sockaddr_unsized *uaddr,
>  			return -EINVAL;
>  
>  		if (uaddr->sa_family == AF_UNSPEC) {
> +			if (sock_rx_owned(sk))
> +				return -EBUSY;
>  			sk->sk_disconnects++;
>  			err = sk->sk_prot->disconnect(sk, flags);
>  			sock->state = err ? SS_DISCONNECTING : SS_UNCONNECTED;
> diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
> index b9de7c302ba83..6de6ce153fda1 100644
> --- a/net/ipv4/tcp.c
> +++ b/net/ipv4/tcp.c

[ ... ]

> @@ -3374,6 +3389,9 @@ int tcp_disconnect(struct sock *sk, int flags)
>  	struct request_sock *req;
>  	u32 seq;
>  
> +	if (sock_rx_owned(sk))
> +		return -EBUSY;
> +
>  	if (old_state != TCP_CLOSE)
>  		tcp_set_state(sk, TCP_CLOSE);
>  

[Severity: Medium]
Does returning -EBUSY from tcp_disconnect() break internal callers of
sk->sk_prot->disconnect()?

__inet_stream_connect() already rejects connect(AF_UNSPEC) above before
calling sk->sk_prot->disconnect().  Other callers expect tcp_disconnect()
to succeed unconditionally:

net/ipv4/af_inet.c:__inet_stream_connect() {
    ...
sock_error:
	err = sock_error(sk) ? : -ECONNABORTED;
	sock->state = SS_UNCONNECTED;
	sk->sk_disconnects++;
	if (sk->sk_prot->disconnect(sk, flags))
		sock->state = SS_DISCONNECTING;
	goto out;
}

When a socket connects via non-blocking connect(), sock->state stays
SS_CONNECTING after the handshake reaches TCP_ESTABLISHED.  If a receive
owner is attached and the connection is then closed by a peer RST or
timeout (moving sk->sk_state to TCP_CLOSE while sk_rx_owner is still set),
a subsequent connect() jumps to sock_error:, where disconnect() returns
-EBUSY without cleaning up the socket and leaves sock->state permanently
wedged in SS_DISCONNECTING even after the owner detaches.

__tcp_close() also ignores the return value of sk->sk_prot->disconnect(sk,
0) on a zero-linger close and assumes it moves sk->sk_state to TCP_CLOSE.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261110132006.3280986-1-amarkuze@redhat.com?part=1

  reply	other threads:[~2026-11-11 13:20 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-10 13:19 [RFC PATCH net-next 00/12] io_uring: opaque TCP payload objects Alex Markuze
2026-11-10 13:19 ` [RFC PATCH net-next 01/12] net: add an exclusive TCP receive claim Alex Markuze
2026-11-11 13:20   ` sashiko-bot [this message]
2026-11-10 13:19 ` [RFC PATCH net-next 02/12] io_uring/opaque: add data structures and the UAPI header Alex Markuze
2026-11-10 13:19 ` [RFC PATCH net-next 03/12] io_uring/opaque: add backing accounting and immutable versions Alex Markuze
2026-11-11 13:20   ` sashiko-bot
2026-11-10 13:19 ` [RFC PATCH net-next 04/12] io_uring/opaque: add owned-page helpers for dense copies Alex Markuze
2026-11-10 13:19 ` [RFC PATCH net-next 05/12] io_uring/opaque: add store registration and IORING_OP_OPAQUE_OBJ Alex Markuze
2026-11-10 13:20 ` [RFC PATCH net-next 06/12] io_uring/opaque: allow rings to share a store Alex Markuze
2026-11-10 13:20 ` [RFC PATCH net-next 07/12] io_uring/opaque: add IORING_OP_OPAQUE_OBJ_SEND Alex Markuze
2026-11-11 13:20   ` sashiko-bot
2026-11-10 13:20 ` [RFC PATCH net-next 08/12] io_uring/opaque: add vectored IORING_OP_OPAQUE_OBJ_SEND Alex Markuze
2026-11-10 13:20 ` [RFC PATCH net-next 09/12] io_uring/opaque: add IORING_OP_OPAQUE_COLLECT Alex Markuze
2026-11-11 13:20   ` sashiko-bot
2026-11-10 13:20 ` [RFC PATCH net-next 10/12] io_uring/opaque: add IORING_OPAQUE_CREATE Alex Markuze
2026-11-11 13:20   ` sashiko-bot
2026-11-10 13:20 ` [RFC PATCH net-next 11/12] io_uring/opaque: add manual and automatic compaction Alex Markuze
2026-11-10 13:20 ` [RFC PATCH net-next 12/12] io_uring/opaque: add basic KUnit tests Alex Markuze

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-209058@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=amarkuze@redhat.com \
    --cc=bpf@vger.kernel.org \
    --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.