Skip to content

Commit

Permalink
netrom: Decrease sock refcount when sock timers expire
Browse files Browse the repository at this point in the history
[ Upstream commit 517a16b ]

Commit 6334665 ("netrom: switch to sock timer API") switched to use
sock timer API. It replaces mod_timer() by sk_reset_timer(), and
del_timer() by sk_stop_timer().

Function sk_reset_timer() will increase the refcount of sock if it is
called on an inactive timer, hence, in case the timer expires, we need to
decrease the refcount ourselves in the handler, otherwise, the sock
refcount will be unbalanced and the sock will never be freed.

Signed-off-by: Nguyen Dinh Phi <phind.uet@gmail.com>
Reported-by: syzbot+10f1194569953b72f1ae@syzkaller.appspotmail.com
Fixes: 6334665 ("netrom: switch to sock timer API")
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
ita93 authored and gregkh committed Jul 28, 2021
1 parent c943765 commit bc16602
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions net/netrom/nr_timer.c
Expand Up @@ -121,11 +121,9 @@ static void nr_heartbeat_expiry(struct timer_list *t)
is accepted() it isn't 'dead' so doesn't get removed. */
if (sock_flag(sk, SOCK_DESTROY) ||
(sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
sock_hold(sk);
bh_unlock_sock(sk);
nr_destroy_socket(sk);
sock_put(sk);
return;
goto out;
}
break;

Expand All @@ -146,6 +144,8 @@ static void nr_heartbeat_expiry(struct timer_list *t)

nr_start_heartbeat(sk);
bh_unlock_sock(sk);
out:
sock_put(sk);
}

static void nr_t2timer_expiry(struct timer_list *t)
Expand All @@ -159,6 +159,7 @@ static void nr_t2timer_expiry(struct timer_list *t)
nr_enquiry_response(sk);
}
bh_unlock_sock(sk);
sock_put(sk);
}

static void nr_t4timer_expiry(struct timer_list *t)
Expand All @@ -169,6 +170,7 @@ static void nr_t4timer_expiry(struct timer_list *t)
bh_lock_sock(sk);
nr_sk(sk)->condition &= ~NR_COND_PEER_RX_BUSY;
bh_unlock_sock(sk);
sock_put(sk);
}

static void nr_idletimer_expiry(struct timer_list *t)
Expand Down Expand Up @@ -197,6 +199,7 @@ static void nr_idletimer_expiry(struct timer_list *t)
sock_set_flag(sk, SOCK_DEAD);
}
bh_unlock_sock(sk);
sock_put(sk);
}

static void nr_t1timer_expiry(struct timer_list *t)
Expand All @@ -209,8 +212,7 @@ static void nr_t1timer_expiry(struct timer_list *t)
case NR_STATE_1:
if (nr->n2count == nr->n2) {
nr_disconnect(sk, ETIMEDOUT);
bh_unlock_sock(sk);
return;
goto out;
} else {
nr->n2count++;
nr_write_internal(sk, NR_CONNREQ);
Expand All @@ -220,8 +222,7 @@ static void nr_t1timer_expiry(struct timer_list *t)
case NR_STATE_2:
if (nr->n2count == nr->n2) {
nr_disconnect(sk, ETIMEDOUT);
bh_unlock_sock(sk);
return;
goto out;
} else {
nr->n2count++;
nr_write_internal(sk, NR_DISCREQ);
Expand All @@ -231,8 +232,7 @@ static void nr_t1timer_expiry(struct timer_list *t)
case NR_STATE_3:
if (nr->n2count == nr->n2) {
nr_disconnect(sk, ETIMEDOUT);
bh_unlock_sock(sk);
return;
goto out;
} else {
nr->n2count++;
nr_requeue_frames(sk);
Expand All @@ -241,5 +241,7 @@ static void nr_t1timer_expiry(struct timer_list *t)
}

nr_start_t1timer(sk);
out:
bh_unlock_sock(sk);
sock_put(sk);
}

0 comments on commit bc16602

Please sign in to comment.