Re: [PATCH net v1] net/rose: fix NULL pointer dereference in rose_transmit_link on reconnect
"Jiayuan Chen" <[email protected]> Tue, 10 Mar 2026 11:28:25 +0000
| Newsgroups | gmane.linux.hams,gmane.linux.network,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
March 10, 2026 at 18:24, "Eric Dumazet" <[email protected] mailto:[email protected]?to=%22Eric%20Dumazet%22%20%3Cedumazet%40google.com%3E > wrote: > > On Tue, Mar 10, 2026 at 11:14 AM Jiayuan Chen <[email protected]> wrote: > > > > > From: Jiayuan Chen <[email protected]> > > > > syzkaller reported a bug [1], and the reproducer is available at [2]. > > > > When rose_connect() is called a second time on an already-connecting > > socket, it overwrites rose->neighbour with the result of rose_get_neigh() > > without releasing the previous reference. If rose_get_neigh() returns > > NULL, the socket is left in an inconsistent state: rose->state remains > > ROSE_STATE_1 from the first connect while rose->neighbour is NULL. > > > > When the socket is subsequently closed, rose_release() sees ROSE_STATE_1 > > and calls rose_write_internal() -> rose_transmit_link(skb, NULL), causing > > a NULL pointer dereference when accessing neigh->loopback. > > > > Fix this by: > > 1. Releasing the old neighbour reference before attempting a reconnect > > 2. Resetting rose->state to ROSE_STATE_0 before the new connect attempt, > > so a failure leaves the socket in a clean state > > 3. Setting rose->neighbour to NULL in all error paths after > > rose_neigh_put() to prevent use-after-free on subsequent reconnects > > > > [1] https://syzkaller.appspot.com/bug?extid=d00f90e0af54102fb271 > > [2] https://gist.github.com/mrpre/9e6779e0d13e2c66779b1653fef80516 > > > > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") > > Reported-by: [email protected] > > Closes: https://lore.kernel.org/all/[email protected]/T/ > > Cc: Jiayuan Chen <[email protected]> > > Signed-off-by: Jiayuan Chen <[email protected]> > > --- > > net/rose/af_rose.c | 11 +++++++++++ > > 1 file changed, 11 insertions(+) > > > Normally, a connect() on a socket already connected should return an error. > > disconnect is a special operation involving AF_UNSPEC > > man connect > ... > Some protocol sockets (e.g., TCP sockets as well as datagram > sockets in the UNIX and Internet domains) may dissolve the association > by > connecting to an address with the sa_family member of sockaddr > set to AF_UNSPEC; thereafter, the socket can be connected to another > ad‐ > dress. (AF_UNSPEC is supported since Linux 2.2.) > Thanks for pointing this out. I should have checked the man page earlier. diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 841d62481048..ba56213e0a2a 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -811,6 +811,11 @@ static int rose_connect(struct socket *sock, struct sockaddr_unsized *uaddr, int goto out_release; } + if (sk->sk_state == TCP_SYN_SENT) { + err = -EALREADY; + goto out_release; + } + sk->sk_state = TCP_CLOSE; sock->state = SS_UNCONNECTED; Tested and the panic is gone. Will send v2 after the cool-down period.