Merge branch 'ax25-fixes'

Duoming Zhou says:

====================
Fix refcount leak and NPD bugs in ax25

The first patch fixes refcount leak in ax25 that could cause
ax25-ex-connected-session-now-listening-state-bug.

The second patch fixes NPD bugs in ax25 timers.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2022-03-21 10:56:19 +00:00
commit ed32641e06
2 changed files with 27 additions and 11 deletions

View file

@ -89,18 +89,20 @@ static void ax25_kill_by_device(struct net_device *dev)
sk = s->sk;
if (!sk) {
spin_unlock_bh(&ax25_list_lock);
s->ax25_dev = NULL;
ax25_disconnect(s, ENETUNREACH);
s->ax25_dev = NULL;
spin_lock_bh(&ax25_list_lock);
goto again;
}
sock_hold(sk);
spin_unlock_bh(&ax25_list_lock);
lock_sock(sk);
s->ax25_dev = NULL;
dev_put_track(ax25_dev->dev, &ax25_dev->dev_tracker);
ax25_dev_put(ax25_dev);
ax25_disconnect(s, ENETUNREACH);
s->ax25_dev = NULL;
if (sk->sk_socket) {
dev_put_track(ax25_dev->dev, &ax25_dev->dev_tracker);
ax25_dev_put(ax25_dev);
}
release_sock(sk);
spin_lock_bh(&ax25_list_lock);
sock_put(sk);
@ -979,14 +981,20 @@ static int ax25_release(struct socket *sock)
{
struct sock *sk = sock->sk;
ax25_cb *ax25;
ax25_dev *ax25_dev;
if (sk == NULL)
return 0;
sock_hold(sk);
sock_orphan(sk);
lock_sock(sk);
sock_orphan(sk);
ax25 = sk_to_ax25(sk);
ax25_dev = ax25->ax25_dev;
if (ax25_dev) {
dev_put_track(ax25_dev->dev, &ax25_dev->dev_tracker);
ax25_dev_put(ax25_dev);
}
if (sk->sk_type == SOCK_SEQPACKET) {
switch (ax25->state) {

View file

@ -261,12 +261,20 @@ void ax25_disconnect(ax25_cb *ax25, int reason)
{
ax25_clear_queues(ax25);
if (!ax25->sk || !sock_flag(ax25->sk, SOCK_DESTROY))
ax25_stop_heartbeat(ax25);
ax25_stop_t1timer(ax25);
ax25_stop_t2timer(ax25);
ax25_stop_t3timer(ax25);
ax25_stop_idletimer(ax25);
if (reason == ENETUNREACH) {
del_timer_sync(&ax25->timer);
del_timer_sync(&ax25->t1timer);
del_timer_sync(&ax25->t2timer);
del_timer_sync(&ax25->t3timer);
del_timer_sync(&ax25->idletimer);
} else {
if (!ax25->sk || !sock_flag(ax25->sk, SOCK_DESTROY))
ax25_stop_heartbeat(ax25);
ax25_stop_t1timer(ax25);
ax25_stop_t2timer(ax25);
ax25_stop_t3timer(ax25);
ax25_stop_idletimer(ax25);
}
ax25->state = AX25_STATE_0;