amt->nr_tunnels is protected by amt->lock. But, amt_request_handler() has been using this variable without the amt->lock. So, it expands context of amt->lock in the amt_request_handler() to protect amt->nr_tunnels variable.
Showing the changes to drivers/net (1 of 1 file). Show all
Unified · Split
| @@ -2679,7 +2679,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb) · 2678 unmodified lines | |||
| 2679 | if (tunnel->ip4 == iph->saddr) | 2679 | if (tunnel->ip4 == iph->saddr) |
| 2680 | goto send; | 2680 | goto send; |
| 2681 | 2681 | ||
| 2682 | spin_lock_bh(&amt->lock); | ||
| 2682 | if (amt->nr_tunnels >= amt->max_tunnels) { | 2683 | if (amt->nr_tunnels >= amt->max_tunnels) { |
| 2684 | spin_unlock_bh(&amt->lock); | ||
| 2683 | icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); | 2685 | icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); |
| 2684 | return true; | 2686 | return true; |
| 2685 | } | 2687 | } |
| @@ -2687,8 +2689,10 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb) · 1 unmodified line | |||
| 2687 | tunnel = kzalloc(sizeof(*tunnel) + | 2689 | tunnel = kzalloc(sizeof(*tunnel) + |
| 2688 | (sizeof(struct hlist_head) * amt->hash_buckets), | 2690 | (sizeof(struct hlist_head) * amt->hash_buckets), |
| 2689 | GFP_ATOMIC); | 2691 | GFP_ATOMIC); |
| 2690 | if (!tunnel) | 2692 | if (!tunnel) { |
| 2693 | spin_unlock_bh(&amt->lock); | ||
| 2691 | return true; | 2694 | return true; |
| 2695 | } | ||
| 2692 | 2696 | ||
| 2693 | tunnel->source_port = udph->source; | 2697 | tunnel->source_port = udph->source; |
| 2694 | tunnel->ip4 = iph->saddr; | 2698 | tunnel->ip4 = iph->saddr; |
| @@ -2701,10 +2705,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb) · 6 unmodified lines | |||
| 2701 | 2705 | ||
| 2702 | INIT_DELAYED_WORK(&tunnel->gc_wq, amt_tunnel_expire); | 2706 | INIT_DELAYED_WORK(&tunnel->gc_wq, amt_tunnel_expire); |
| 2703 | 2707 | ||
| 2704 | spin_lock_bh(&amt->lock); | ||
| 2705 | list_add_tail_rcu(&tunnel->list, &amt->tunnel_list); | 2708 | list_add_tail_rcu(&tunnel->list, &amt->tunnel_list); |
| 2706 | tunnel->key = amt->key; | 2709 | tunnel->key = amt->key; |
| 2707 | amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true); | 2710 | __amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true); |
| 2708 | amt->nr_tunnels++; | 2711 | amt->nr_tunnels++; |
| 2709 | mod_delayed_work(amt_wq, &tunnel->gc_wq, | 2712 | mod_delayed_work(amt_wq, &tunnel->gc_wq, |
| 2710 | msecs_to_jiffies(amt_gmi(amt))); | 2713 | msecs_to_jiffies(amt_gmi(amt))); |