| From: Eric Dumazet <edumazet@google.com> |
| Date: Thu, 6 Jun 2019 14:32:34 -0700 |
| Subject: ipv6: flowlabel: fl6_sock_lookup() must use atomic_inc_not_zero |
| |
| commit 65a3c497c0e965a552008db8bc2653f62bc925a1 upstream. |
| |
| Before taking a refcount, make sure the object is not already |
| scheduled for deletion. |
| |
| Same fix is needed in ipv6_flowlabel_opt() |
| |
| Fixes: 18367681a10b ("ipv6 flowlabel: Convert np->ipv6_fl_list to RCU.") |
| Signed-off-by: Eric Dumazet <edumazet@google.com> |
| Cc: Willem de Bruijn <willemb@google.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/ipv6/ip6_flowlabel.c | 7 ++++--- |
| 1 file changed, 4 insertions(+), 3 deletions(-) |
| |
| --- a/net/ipv6/ip6_flowlabel.c |
| +++ b/net/ipv6/ip6_flowlabel.c |
| @@ -255,9 +255,9 @@ struct ip6_flowlabel * fl6_sock_lookup(s |
| rcu_read_lock_bh(); |
| for_each_sk_fl_rcu(np, sfl) { |
| struct ip6_flowlabel *fl = sfl->fl; |
| - if (fl->label == label) { |
| + |
| + if (fl->label == label && atomic_inc_not_zero(&fl->users)) { |
| fl->lastuse = jiffies; |
| - atomic_inc(&fl->users); |
| rcu_read_unlock_bh(); |
| return fl; |
| } |
| @@ -619,7 +619,8 @@ int ipv6_flowlabel_opt(struct sock *sk, |
| goto done; |
| } |
| fl1 = sfl->fl; |
| - atomic_inc(&fl1->users); |
| + if (!atomic_inc_not_zero(&fl1->users)) |
| + fl1 = NULL; |
| break; |
| } |
| } |