mptcp: fix soft lockup in mptcp_recvmsg()
Subsystems (3)
Matthieu Baerts (NGI0)
maintainerPATCH 1/1 mptcp: fix soft lockup in mptcp_recvmsg()
From: Li Xiasong <[email protected]>
commit 5dd8025a49c268ab6b94d978532af3ad341132a7 upstream.
syzbot reported a soft lockup in mptcp_recvmsg() [0].
When receiving data with MSG_PEEK | MSG_WAITALL flags, the skb is not removed from the sk_receive_queue. This causes sk_wait_data() to always find available data and never perform actual waiting, leading to a soft lockup.
Fix this by adding a 'last' parameter to track the last peeked skb. This allows sk_wait_data() to make informed waiting decisions and prevent infinite loops when MSG_PEEK is used.
[0]:
watchdog: BUG: soft lockup - CPU#2 stuck for 156s! [server:1963] Modules linked in: CPU: 2 UID: 0 PID: 1963 Comm: server Not tainted 6.19.0-rc8 #61 PREEMPT(none) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:sk_wait_data+0x15/0x190 Code: 80 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 41 56 41 55 41 54 49 89 f4 55 48 89 d5 53 48 89 fb <48> 83 ec 30 65 48 8b 05 17 a4 6b 01 48 89 44 24 28 31 c0 65 48 8b RSP: 0018:ffffc90000603ca0 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffff888102bf0800 RCX: 0000000000000001 RDX: 0000000000000000 RSI: ffffc90000603d18 RDI: ffff888102bf0800 RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000101 R10: 0000000000000000 R11: 0000000000000075 R12: ffffc90000603d18 R13: ffff888102bf0800 R14: ffff888102bf0800 R15: 0000000000000000 FS: 00007f6e38b8c4c0(0000) GS:ffff8881b877e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055aa7bff1680 CR3: 0000000105cbe000 CR4: 00000000000006f0 Call Trace: <TASK> mptcp_recvmsg+0x547/0x8c0 net/mptcp/protocol.c:2329 inet_recvmsg+0x11f/0x130 net/ipv4/af_inet.c:891 sock_recvmsg+0x94/0xc0 net/socket.c:1100 __sys_recvfrom+0xb2/0x130 net/socket.c:2256 __x64_sys_recvfrom+0x1f/0x30 net/socket.c:2267 do_syscall_64+0x59/0x2d0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e arch/x86/entry/entry_64.S:131 RIP: 0033:0x7f6e386a4a1d Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 f1 de 2c 00 41 89 ca 8b 00 85 c0 75 20 45 31 c9 45 31 c0 b8 2d 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 6b f3 c3 66 0f 1f 84 00 00 00 00 00 41 56 41 RSP: 002b:00007ffc3c4bb078 EFLAGS: 00000246 ORIG_RAX: 000000000000002d RAX: ffffffffffffffda RBX: 000000000000861e RCX: 00007f6e386a4a1d RDX: 00000000000003ff RSI: 00007ffc3c4bb150 RDI: 0000000000000004 RBP: 00007ffc3c4bb570 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000103 R11: 0000000000000246 R12: 00005605dbc00be0 R13: 00007ffc3c4bb650 R14: 0000000000000000 R15: 0000000000000000 </TASK>
[ Conflicts in protocol.c, because commit bc68b0efa1bf ("mptcp: move the
whole rx path under msk socket lock protection") and commit d88b2127b242 ("mptcp: add eat_recv_skb helper") (with some dependences) are not in this version. These conflicts were in the context, and not related to this fix. ]
--- net/mptcp/protocol.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
net/mptcp/protocol.c +8 -3
@@ -1960,7 +1960,7 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk,struct msghdr *msg, size_t len, int flags, int copied_total, struct scm_timestamping_internal *tss, - int *cmsg_flags) + int *cmsg_flags, struct sk_buff **last) { struct sk_buff *skb, *tmp;int total_data_len =0 ;
@@ -1976,6 +1976,7 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk,/* skip already peeked skbs */ if (total_data_len + data_len <= copied_total) { total_data_len += data_len; + *last = skb;continue ; }
@@ -2016,6 +2017,8 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk,WRITE_ONCE (msk->rmem_released, msk->rmem_released + skb->truesize);__skb_unlink (skb, &msk->receive_queue);__kfree_skb (skb); + }else { + *last = skb; }if (copied >= len)
@@ -2237,10 +2240,12 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, cmsg_flags =MPTCP_CMSG_INQ ;while (copied < len) { +struct sk_buff *last =NULL ;int err, bytes_read; bytes_read =__mptcp_recvmsg_mskq (msk, msg, len - copied, flags, - copied, &tss, &cmsg_flags); + copied, &tss, &cmsg_flags, + &last);if (unlikely (bytes_read <0 )) {if (!copied) copied = bytes_read;
@@ -2298,7 +2303,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,pr_debug ("block timeout %ld\n" , timeo);mptcp_cleanup_rbuf (msk, copied); - err =sk_wait_data (sk, &timeo,NULL ); + err =sk_wait_data (sk, &timeo, last);if (err <0 ) { err = copied ? : err; goto out_err;
Signature · 1 line
2.53.0
Patch "mptcp: fix soft lockup in mptcp_recvmsg()" has been added to the 6.6-stable tree
This is a note to let you know that I've just added the patch titled
mptcp: fix soft lockup in mptcp_recvmsg()
to the 6.6-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch
and it can be found in the queue-6.6 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
From [email protected] Thu Apr 9 13:45:35 2026
From: "Matthieu Baerts (NGI0)" <[email protected]>
Date: Thu, 9 Apr 2026 13:45:26 +0200
Subject: mptcp: fix soft lockup in mptcp_recvmsg()
To: [email protected], [email protected], [email protected]
Cc: MPTCP Upstream <[email protected]>, Li Xiasong <[email protected]>, "Matthieu Baerts (NGI0)" <[email protected]>, Jakub Kicinski <[email protected]>
Message-ID: <[email protected]>
From: Li Xiasong <[email protected]>
commit 5dd8025a49c268ab6b94d978532af3ad341132a7 upstream.
syzbot reported a soft lockup in mptcp_recvmsg() [0].
When receiving data with MSG_PEEK | MSG_WAITALL flags, the skb is not removed from the sk_receive_queue. This causes sk_wait_data() to always find available data and never perform actual waiting, leading to a soft lockup.
Fix this by adding a 'last' parameter to track the last peeked skb. This allows sk_wait_data() to make informed waiting decisions and prevent infinite loops when MSG_PEEK is used.
[0]:
watchdog: BUG: soft lockup - CPU#2 stuck for 156s! [server:1963] Modules linked in: CPU: 2 UID: 0 PID: 1963 Comm: server Not tainted 6.19.0-rc8 #61 PREEMPT(none) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 RIP: 0010:sk_wait_data+0x15/0x190 Code: 80 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 41 56 41 55 41 54 49 89 f4 55 48 89 d5 53 48 89 fb <48> 83 ec 30 65 48 8b 05 17 a4 6b 01 48 89 44 24 28 31 c0 65 48 8b RSP: 0018:ffffc90000603ca0 EFLAGS: 00000246 RAX: 0000000000000000 RBX: ffff888102bf0800 RCX: 0000000000000001 RDX: 0000000000000000 RSI: ffffc90000603d18 RDI: ffff888102bf0800 RBP: 0000000000000000 R08: 0000000000000002 R09: 0000000000000101 R10: 0000000000000000 R11: 0000000000000075 R12: ffffc90000603d18 R13: ffff888102bf0800 R14: ffff888102bf0800 R15: 0000000000000000 FS: 00007f6e38b8c4c0(0000) GS:ffff8881b877e000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055aa7bff1680 CR3: 0000000105cbe000 CR4: 00000000000006f0 Call Trace: <TASK> mptcp_recvmsg+0x547/0x8c0 net/mptcp/protocol.c:2329 inet_recvmsg+0x11f/0x130 net/ipv4/af_inet.c:891 sock_recvmsg+0x94/0xc0 net/socket.c:1100 __sys_recvfrom+0xb2/0x130 net/socket.c:2256 __x64_sys_recvfrom+0x1f/0x30 net/socket.c:2267 do_syscall_64+0x59/0x2d0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x76/0x7e arch/x86/entry/entry_64.S:131 RIP: 0033:0x7f6e386a4a1d Code: 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 8d 05 f1 de 2c 00 41 89 ca 8b 00 85 c0 75 20 45 31 c9 45 31 c0 b8 2d 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 6b f3 c3 66 0f 1f 84 00 00 00 00 00 41 56 41 RSP: 002b:00007ffc3c4bb078 EFLAGS: 00000246 ORIG_RAX: 000000000000002d RAX: ffffffffffffffda RBX: 000000000000861e RCX: 00007f6e386a4a1d RDX: 00000000000003ff RSI: 00007ffc3c4bb150 RDI: 0000000000000004 RBP: 00007ffc3c4bb570 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000103 R11: 0000000000000246 R12: 00005605dbc00be0 R13: 00007ffc3c4bb650 R14: 0000000000000000 R15: 0000000000000000 </TASK>
[ Conflicts in protocol.c, because commit bc68b0efa1bf ("mptcp: move the
whole rx path under msk socket lock protection") and commit d88b2127b242 ("mptcp: add eat_recv_skb helper") (with some dependences) are not in this version. These conflicts were in the context, and not related to this fix. ]
--- net/mptcp/protocol.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
net/mptcp/protocol.c +8 -3
@@ -1960,7 +1960,7 @@ static int __mptcp_recvmsg_mskq(struct mstruct msghdr *msg, size_t len, int flags, int copied_total, struct scm_timestamping_internal *tss, - int *cmsg_flags) + int *cmsg_flags, struct sk_buff **last) { struct sk_buff *skb, *tmp;int total_data_len =0 ;
@@ -1976,6 +1976,7 @@ static int __mptcp_recvmsg_mskq(struct m/* skip already peeked skbs */ if (total_data_len + data_len <= copied_total) { total_data_len += data_len; + *last = skb;continue ; }
@@ -2016,6 +2017,8 @@ static int __mptcp_recvmsg_mskq(struct mWRITE_ONCE (msk->rmem_released, msk->rmem_released + skb->truesize);__skb_unlink (skb, &msk->receive_queue);__kfree_skb (skb); + }else { + *last = skb; }if (copied >= len)
@@ -2237,10 +2240,12 @@ static int mptcp_recvmsg(struct sock *sk cmsg_flags =MPTCP_CMSG_INQ ;while (copied < len) { +struct sk_buff *last =NULL ;int err, bytes_read; bytes_read =__mptcp_recvmsg_mskq (msk, msg, len - copied, flags, - copied, &tss, &cmsg_flags); + copied, &tss, &cmsg_flags, + &last);if (unlikely (bytes_read <0 )) {if (!copied) copied = bytes_read;
@@ -2298,7 +2303,7 @@ static int mptcp_recvmsg(struct sock *skpr_debug ("block timeout %ld\n" , timeo);mptcp_cleanup_rbuf (msk, copied); - err =sk_wait_data (sk, &timeo,NULL ); + err =sk_wait_data (sk, &timeo, last);if (err <0 ) { err = copied ? : err; goto out_err;
Patches currently in stable-queue which might be from [email protected] are
queue-6.6/mptcp-fix-slab-use-after-free-in-__inet_lookup_established.patch queue-6.6/revert-mptcp-add-needs_id-for-netlink-appending-addr.patch queue-6.6/mptcp-fix-soft-lockup-in-mptcp_recvmsg.patch