Messages in this thread Patch in this message |  | | Date | Tue, 10 Mar 2026 11:28:25 +0000 | | From | "Jiayuan Chen" <> | | Subject | Re: [PATCH net v1] net/rose: fix NULL pointer dereference in rose_transmit_link on reconnect |
| |
March 10, 2026 at 18:24, "Eric Dumazet" <edumazet@google.com mailto:edumazet@google.com?to=%22Eric%20Dumazet%22%20%3Cedumazet%40google.com%3E > wrote:
> > On Tue, Mar 10, 2026 at 11:14 AM Jiayuan Chen <jiayuan.chen@linux.dev> wrote: > > > > > From: Jiayuan Chen <jiayuan.chen@shopee.com> > > > > 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: syzbot+d00f90e0af54102fb271@syzkaller.appspotmail.com > > Closes: https://lore.kernel.org/all/69694d6f.050a0220.58bed.0027.GAE@google.com/T/ > > Cc: Jiayuan Chen <jiayuan.chen@linux.dev> > > Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com> > > --- > > 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.
|  |