diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-11-20 19:21:55 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-11-26 15:49:07 -0500 |
commit | 8a6e77d5209e459a9ec5c268c39800c06cd1dc86 (patch) | |
tree | 141421761c5ac9b398cab84b3674d30ec2fd4e00 /net | |
parent | fc0b927d9a5024e138c4318fe19a590f23e3eeec (diff) |
decnet: proper socket refcounting
Better use sk_reset_timer() / sk_stop_timer() helpers to make sure we
dont access already freed/reused memory later.
Reported-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Tested-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/decnet/dn_timer.c | 17 |
1 files changed, 5 insertions, 12 deletions
diff --git a/net/decnet/dn_timer.c b/net/decnet/dn_timer.c index 67f691bd4acf..d9c150cc59a9 100644 --- a/net/decnet/dn_timer.c +++ b/net/decnet/dn_timer.c | |||
@@ -36,16 +36,13 @@ static void dn_slow_timer(unsigned long arg); | |||
36 | 36 | ||
37 | void dn_start_slow_timer(struct sock *sk) | 37 | void dn_start_slow_timer(struct sock *sk) |
38 | { | 38 | { |
39 | sk->sk_timer.expires = jiffies + SLOW_INTERVAL; | 39 | setup_timer(&sk->sk_timer, dn_slow_timer, (unsigned long)sk); |
40 | sk->sk_timer.function = dn_slow_timer; | 40 | sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL); |
41 | sk->sk_timer.data = (unsigned long)sk; | ||
42 | |||
43 | add_timer(&sk->sk_timer); | ||
44 | } | 41 | } |
45 | 42 | ||
46 | void dn_stop_slow_timer(struct sock *sk) | 43 | void dn_stop_slow_timer(struct sock *sk) |
47 | { | 44 | { |
48 | del_timer(&sk->sk_timer); | 45 | sk_stop_timer(sk, &sk->sk_timer); |
49 | } | 46 | } |
50 | 47 | ||
51 | static void dn_slow_timer(unsigned long arg) | 48 | static void dn_slow_timer(unsigned long arg) |
@@ -53,12 +50,10 @@ static void dn_slow_timer(unsigned long arg) | |||
53 | struct sock *sk = (struct sock *)arg; | 50 | struct sock *sk = (struct sock *)arg; |
54 | struct dn_scp *scp = DN_SK(sk); | 51 | struct dn_scp *scp = DN_SK(sk); |
55 | 52 | ||
56 | sock_hold(sk); | ||
57 | bh_lock_sock(sk); | 53 | bh_lock_sock(sk); |
58 | 54 | ||
59 | if (sock_owned_by_user(sk)) { | 55 | if (sock_owned_by_user(sk)) { |
60 | sk->sk_timer.expires = jiffies + HZ / 10; | 56 | sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 10); |
61 | add_timer(&sk->sk_timer); | ||
62 | goto out; | 57 | goto out; |
63 | } | 58 | } |
64 | 59 | ||
@@ -100,9 +95,7 @@ static void dn_slow_timer(unsigned long arg) | |||
100 | scp->keepalive_fxn(sk); | 95 | scp->keepalive_fxn(sk); |
101 | } | 96 | } |
102 | 97 | ||
103 | sk->sk_timer.expires = jiffies + SLOW_INTERVAL; | 98 | sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL); |
104 | |||
105 | add_timer(&sk->sk_timer); | ||
106 | out: | 99 | out: |
107 | bh_unlock_sock(sk); | 100 | bh_unlock_sock(sk); |
108 | sock_put(sk); | 101 | sock_put(sk); |