On Tue, Jan 06, 2026 at 01:14 PM +08, Jiayuan Chen wrote: > A socket using sockmap has its own independent receive queue: ingress_msg. > This queue may contain data from its own protocol stack or from other > sockets. > > The issue is that when reading from ingress_msg, we update tp->copied_seq > by default. However, if the data is not from its own protocol stack, > tcp->rcv_nxt is not increased. Later, if we convert this socket to a > native socket, reading from this socket may fail because copied_seq might > be significantly larger than rcv_nxt. > > This fix also addresses the syzkaller-reported bug referenced in the > Closes tag. > > This patch marks the skmsg objects in ingress_msg. When reading, we update > copied_seq only if the data is from its own protocol stack. > > FD1:read() > -- FD1->copied_seq++ > | [read data] > | > [enqueue data] v > [sockmap] -> ingress to self -> ingress_msg queue > FD1 native stack ------> ^ > -- FD1->rcv_nxt++ -> redirect to other | [enqueue data] > | | > | ingress to FD1 > v ^ > ... | [sockmap] > FD2 native stack > > Closes: https://syzkaller.appspot.com/bug?extid=06dbd397158ec0ea4983 > Fixes: 04919bed948dc ("tcp: Introduce tcp_read_skb()") > Signed-off-by: Jiayuan Chen <[email protected]> > --- > include/linux/skmsg.h | 2 ++ > net/core/skmsg.c | 25 ++++++++++++++++++++++--- > net/ipv4/tcp_bpf.c | 5 +++-- > 3 files changed, 27 insertions(+), 5 deletions(-) > > diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h > index 49847888c287..0323a2b6cf5e 100644 > --- a/include/linux/skmsg.h > +++ b/include/linux/skmsg.h > @@ -141,6 +141,8 @@ int sk_msg_memcopy_from_iter(struct sock *sk, struct > iov_iter *from, > struct sk_msg *msg, u32 bytes); > int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr > *msg, > int len, int flags); > +int __sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr > *msg, > + int len, int flags, int *from_self_copied); > bool sk_msg_is_readable(struct sock *sk); > > static inline void sk_msg_check_to_free(struct sk_msg *msg, u32 i, u32 bytes) > diff --git a/net/core/skmsg.c b/net/core/skmsg.c > index 2ac7731e1e0a..d73e03f7713a 100644 > --- a/net/core/skmsg.c > +++ b/net/core/skmsg.c > @@ -409,14 +409,14 @@ int sk_msg_memcopy_from_iter(struct sock *sk, struct > iov_iter *from, > } > EXPORT_SYMBOL_GPL(sk_msg_memcopy_from_iter); > > -/* Receive sk_msg from psock->ingress_msg to @msg. */ > -int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr > *msg, > - int len, int flags) > +int __sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr > *msg, > + int len, int flags, int *from_self_copied) > { > struct iov_iter *iter = &msg->msg_iter; > int peek = flags & MSG_PEEK; > struct sk_msg *msg_rx; > int i, copied = 0; > + bool to_self;
Nit: Can we unify the naming and make it read more naturally? s/to_self/from_self/ s/from_self_copied/copied_from_self/ Otherwise LGTM: Reviewed-by: Jakub Sitnicki <[email protected]>

