6.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Bernard Pidoux When a SABM comes in for a listening socket, ax25_rcv() creates the new socket, puts the skb on the listener's receive queue and only then allocates the digipeater path. If that allocation fails, the skb is freed with kfree_skb() while it is still linked on the queue, and the accept backlog count taken by sk_acceptq_added() is never given back. The next accept() or the close of the listener then walks a queue that contains a freed skb. Allocate the path before the skb is queued, so that the error path only has to free an skb nobody else knows about and to destroy the new socket. The later allocation remains for a connection that has no listening socket. Only reachable when the atomic allocation fails for a call that comes through digipeaters. Regression tested in QEMU (6.12.94 with lockdep and KASAN): 14 incoming connections to a listening socket, each accepted, served and closed, before and after; no report. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Bernard Pidoux (cherry picked from commit 2d67e8e9f3d627327114fb946c3a28ef72becb2d) Signed-off-by: Sasha Levin --- net/ax25/ax25_in.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c index c81bc8c4563b5..1bcb5e321467d 100644 --- a/net/ax25/ax25_in.c +++ b/net/ax25/ax25_in.c @@ -383,6 +383,24 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, } ax25 = sk_to_ax25(make); + + /* + * Get the digipeater path before the skb goes on the + * listener's queue: once queued it belongs to that queue + * and cannot simply be freed if the allocation fails. + */ + if (dp.ndigi && !ax25->digipeat) { + ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC); + if (!ax25->digipeat) { + kfree_skb(skb); + ax25_destroy_socket(ax25); + bh_unlock_sock(sk); + sock_put(sk); + + return 0; + } + } + skb_set_owner_r(skb, make); skb_queue_head(&sk->sk_receive_queue, skb); @@ -406,14 +424,13 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25->dest_addr = src; /* - * Sort out any digipeated paths. + * Sort out any digipeated paths. A socket made from a listener + * already has its path allocated, see above. */ if (dp.ndigi && !ax25->digipeat && (ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { kfree_skb(skb); ax25_destroy_socket(ax25); - if (sk) - sock_put(sk); return 0; } -- 2.53.0