Commit 98991848 authored by Taehee Yoo's avatar Taehee Yoo Committed by Paolo Abeni
Browse files

amt: do not use amt->nr_tunnels outside of lock



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.

Fixes: cbc21dc1 ("amt: add data plane of amt interface")
Signed-off-by: default avatarTaehee Yoo <ap420073@gmail.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent e882827d
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -2679,7 +2679,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
		if (tunnel->ip4 == iph->saddr)
			goto send;

	spin_lock_bh(&amt->lock);
	if (amt->nr_tunnels >= amt->max_tunnels) {
		spin_unlock_bh(&amt->lock);
		icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
		return true;
	}
@@ -2687,8 +2689,10 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)
	tunnel = kzalloc(sizeof(*tunnel) +
			 (sizeof(struct hlist_head) * amt->hash_buckets),
			 GFP_ATOMIC);
	if (!tunnel)
	if (!tunnel) {
		spin_unlock_bh(&amt->lock);
		return true;
	}

	tunnel->source_port = udph->source;
	tunnel->ip4 = iph->saddr;
@@ -2701,10 +2705,9 @@ static bool amt_request_handler(struct amt_dev *amt, struct sk_buff *skb)

	INIT_DELAYED_WORK(&tunnel->gc_wq, amt_tunnel_expire);

	spin_lock_bh(&amt->lock);
	list_add_tail_rcu(&tunnel->list, &amt->tunnel_list);
	tunnel->key = amt->key;
	amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true);
	__amt_update_relay_status(tunnel, AMT_STATUS_RECEIVED_REQUEST, true);
	amt->nr_tunnels++;
	mod_delayed_work(amt_wq, &tunnel->gc_wq,
			 msecs_to_jiffies(amt_gmi(amt)));