[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250725004220.3189-1-hdanton@sina.com>
Date: Fri, 25 Jul 2025 08:42:19 +0800
From: Hillf Danton <hdanton@...a.com>
To: syzbot <syzbot+0fc08dad8f34563208d5@...kaller.appspotmail.com>
Cc: linux-kernel@...r.kernel.org,
syzkaller-bugs@...glegroups.com
Subject: Re: [syzbot] [hams?] KASAN: slab-use-after-free Read in rose_new_lci
> Date: Thu, 24 Jul 2025 02:38:33 -0700 [thread overview]
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: d086c886ceb9 Add linux-next specific files for 20250718
> git tree: linux-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=1517af22580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=69896dd7b8c4e81e
> dashboard link: https://syzkaller.appspot.com/bug?extid=0fc08dad8f34563208d5
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1317af22580000
#syz test
--- x/include/net/rose.h
+++ y/include/net/rose.h
@@ -98,6 +98,7 @@ struct rose_neigh {
unsigned short count;
unsigned short use;
unsigned int number;
+ atomic_t ref;
char restarted;
char dce_mode;
char loopback;
@@ -214,6 +215,7 @@ void rose_link_device_down(struct net_de
struct net_device *rose_dev_first(void);
struct net_device *rose_dev_get(rose_address *);
struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
+void rose_put_neigh(struct rose_neigh *);
struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *,
unsigned char *, int);
int rose_rt_ioctl(unsigned int, void __user *);
--- x/net/rose/af_rose.c
+++ y/net/rose/af_rose.c
@@ -171,6 +171,7 @@ void rose_kill_by_neigh(struct rose_neig
if (rose->neighbour == neigh) {
rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
rose->neighbour->use--;
+ rose_put_neigh(rose->neighbour);
rose->neighbour = NULL;
}
}
@@ -383,8 +384,10 @@ void rose_destroy_socket(struct sock *sk
timer_setup(&sk->sk_timer, rose_destroy_timer, 0);
sk->sk_timer.expires = jiffies + 10 * HZ;
add_timer(&sk->sk_timer);
- } else
+ } else {
+ rose_put_neigh(rose_sk(sk)->neighbour);
sock_put(sk);
+ }
}
/*
--- x/net/rose/rose_route.c
+++ y/net/rose/rose_route.c
@@ -97,6 +97,7 @@ static int __must_check rose_add_node(st
rose_neigh->dce_mode = 0;
rose_neigh->loopback = 0;
rose_neigh->number = rose_neigh_no++;
+ atomic_set(&rose_neigh->ref, 1);
rose_neigh->restarted = 0;
skb_queue_head_init(&rose_neigh->queue);
@@ -237,7 +238,7 @@ static void rose_remove_neigh(struct ros
if (rose_neigh->ax25)
ax25_cb_put(rose_neigh->ax25);
kfree(rose_neigh->digipeat);
- kfree(rose_neigh);
+ rose_put_neigh(rose_neigh);
return;
}
@@ -247,7 +248,7 @@ static void rose_remove_neigh(struct ros
if (rose_neigh->ax25)
ax25_cb_put(rose_neigh->ax25);
kfree(rose_neigh->digipeat);
- kfree(rose_neigh);
+ rose_put_neigh(rose_neigh);
return;
}
@@ -265,8 +266,10 @@ static void rose_remove_route(struct ros
if (rose_route->neigh1 != NULL)
rose_route->neigh1->use--;
- if (rose_route->neigh2 != NULL)
+ if (rose_route->neigh2 != NULL) {
rose_route->neigh2->use--;
+ rose_put_neigh(rose_route->neigh2);
+ }
if ((s = rose_route_list) == rose_route) {
rose_route_list = rose_route->next;
@@ -667,6 +670,11 @@ struct rose_route *rose_route_free_lci(u
return NULL;
}
+void rose_put_neigh(struct rose_neigh *n)
+{
+ if (n && atomic_dec_and_test(&n->ref))
+ kfree(n);
+}
/*
* Find a neighbour or a route given a ROSE address.
*/
@@ -712,6 +720,8 @@ struct rose_neigh *rose_get_neigh(rose_a
}
out:
+ if (res)
+ atomic_inc(&res->ref);
if (!route_frame) spin_unlock_bh(&rose_node_list_lock);
return res;
}
@@ -1061,6 +1071,7 @@ int rose_route_frame(struct sk_buff *skb
rose_route->neigh1 = rose_neigh;
rose_route->lci2 = new_lci;
rose_route->neigh2 = new_neigh;
+ new_neigh = NULL;
rose_route->neigh1->use++;
rose_route->neigh2->use++;
@@ -1076,6 +1087,8 @@ int rose_route_frame(struct sk_buff *skb
res = 1;
out:
+ if (new_neigh)
+ rose_put_neigh(new_neigh);
spin_unlock_bh(&rose_route_list_lock);
spin_unlock_bh(&rose_neigh_list_lock);
--- x/net/unix/af_unix.c
+++ y/net/unix/af_unix.c
@@ -1750,12 +1750,6 @@ restart:
goto out_unlock;
}
- err = security_unix_stream_connect(sk, other, newsk);
- if (err) {
- unix_state_unlock(sk);
- goto out_unlock;
- }
-
/* The way is open! Fastly set all the necessary fields... */
sock_hold(sk);
--
Powered by blists - more mailing lists