5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Qingfang Deng [ Upstream commit 92c1bf630abf0af646562398eaa36f80b5ff677d ] PPPIOCGCHAN both returns the channel index and marks a PPPOX socket as bound to generic PPP, despite its getter semantic. Packets received before that transition are queued on sk_receive_queue, but a bound socket is no longer readable. Such packets therefore remain queued until the socket is destroyed. After marking a socket bound, wait for receive paths that observed the old state to finish queueing packets, and then drain the queue into generic PPP. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Qingfang Deng Link: https://patch.msgid.link/20260811035314.302878-1-qingfang.deng@linux.dev Signed-off-by: Jakub Kicinski Signed-off-by: Sasha Levin --- drivers/net/ppp/pppox.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/net/ppp/pppox.c b/drivers/net/ppp/pppox.c index 08364f10a43fa..61b3453469dce 100644 --- a/drivers/net/ppp/pppox.c +++ b/drivers/net/ppp/pppox.c @@ -74,7 +74,9 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) switch (cmd) { case PPPIOCGCHAN: { + struct sk_buff *skb; int index; + rc = -ENOTCONN; if (!(sk->sk_state & PPPOX_CONNECTED)) break; @@ -85,7 +87,22 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) break; rc = 0; + /* PPPIOCGCHAN historically marks the userspace handoff to + * generic PPP; pppd then attaches the returned channel to + * /dev/ppp. + */ sk->sk_state |= PPPOX_BOUND; + /* Let lockless receive paths finish queueing against the old + * state. + */ + synchronize_net(); + /* Drain packets queued before the handoff because a bound + * socket is no longer readable. + */ + while ((skb = skb_dequeue(&sk->sk_receive_queue))) { + skb_orphan(skb); + ppp_input(&po->chan, skb); + } break; } default: -- 2.53.0