]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net/iucv: take a reference on the socket found in afiucv_hs_rcv()
authorBryam Vargas <hexlabsecurity@proton.me>
Mon, 6 Jul 2026 03:24:36 +0000 (22:24 -0500)
committerPaolo Abeni <pabeni@redhat.com>
Fri, 10 Jul 2026 14:24:43 +0000 (16:24 +0200)
afiucv_hs_rcv() looks up the destination socket under iucv_sk_list.lock,
drops the lock, and then passes the socket to the afiucv_hs_callback_*()
handlers without holding a reference. AF_IUCV sockets are not
RCU-protected and are freed synchronously by iucv_sock_kill() ->
sock_put(), so a concurrent close can free the socket in the window
between read_unlock() and the handler, which then dereferences freed
memory (for example sk->sk_data_ready() in afiucv_hs_callback_syn()).

Take a reference with sock_hold() while the socket is still on the list
and release it with sock_put() once the handler has run.

Fixes: 3881ac441f64 ("af_iucv: add HiperSockets transport")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Hidayath Khan <hidayath@linux.ibm.com>
Link: https://patch.msgid.link/20260705-b4-disp-fc79c0dc-v1-1-d2cdcb57afa9@proton.me
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/iucv/af_iucv.c

index fed240b453bd9b517a571d65640f939fa3bbfd0d..b85fb9767dec211918f7e8d6a16e88c0b20455b8 100644 (file)
@@ -2089,6 +2089,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
                        }
                }
        }
+       if (sk)
+               sock_hold(sk);
        read_unlock(&iucv_sk_list.lock);
        if (!iucv)
                sk = NULL;
@@ -2138,6 +2140,8 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev,
                kfree_skb(skb);
        }
 
+       if (sk)
+               sock_put(sk);
        return err;
 }