summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2016-04-28 16:42:40 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-28 16:42:40 -0400
commit956a7ffe00b4e8b75d98881ae4d0bd1b580648cb (patch)
tree0ab08c63c6952eaf07e1f50bf80226334c27afd4 /net
parenteb63efb4f263f1f4c2375731d3a9e2040030bc6a (diff)
parentc4fdb6cff2aa0ae740c5f19b6f745cbbe786d42f (diff)
Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge
Antonio Quartulli says: ==================== In this patchset you can find the following fixes: 1) check skb size to avoid reading beyond its border when delivering payloads, by Sven Eckelmann 2) initialize last_seen time in neigh_node object to prevent cleanup routine from accidentally purge it, by Marek Lindner 3) release "recently added" slave interfaces upon virtual/batman interface shutdown, by Sven Eckelmann 4) properly decrease router object reference counter upon routing table update, by Sven Eckelmann 5) release queue slots when purging OGM packets of deactivating slave interface, by Linus Lüssing Patch 2 and 3 have no "Fixes:" tag because the offending commits date back to when batman-adv was not yet officially in the net tree. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/hard-interface.c3
-rw-r--r--net/batman-adv/originator.c1
-rw-r--r--net/batman-adv/routing.c9
-rw-r--r--net/batman-adv/send.c6
-rw-r--r--net/batman-adv/soft-interface.c8
5 files changed, 23 insertions, 4 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index b22b2775a0a5..c61d5b0b24d2 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -572,8 +572,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
572 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); 572 struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
573 struct batadv_hard_iface *primary_if = NULL; 573 struct batadv_hard_iface *primary_if = NULL;
574 574
575 if (hard_iface->if_status == BATADV_IF_ACTIVE) 575 batadv_hardif_deactivate_interface(hard_iface);
576 batadv_hardif_deactivate_interface(hard_iface);
577 576
578 if (hard_iface->if_status != BATADV_IF_INACTIVE) 577 if (hard_iface->if_status != BATADV_IF_INACTIVE)
579 goto out; 578 goto out;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index e4cbb0753e37..d52f67a0c057 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -663,6 +663,7 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
663 ether_addr_copy(neigh_node->addr, neigh_addr); 663 ether_addr_copy(neigh_node->addr, neigh_addr);
664 neigh_node->if_incoming = hard_iface; 664 neigh_node->if_incoming = hard_iface;
665 neigh_node->orig_node = orig_node; 665 neigh_node->orig_node = orig_node;
666 neigh_node->last_seen = jiffies;
666 667
667 /* extra reference for return */ 668 /* extra reference for return */
668 kref_init(&neigh_node->refcount); 669 kref_init(&neigh_node->refcount);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 4dd646a52f1a..b781bf753250 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
105 neigh_node = NULL; 105 neigh_node = NULL;
106 106
107 spin_lock_bh(&orig_node->neigh_list_lock); 107 spin_lock_bh(&orig_node->neigh_list_lock);
108 /* curr_router used earlier may not be the current orig_ifinfo->router
109 * anymore because it was dereferenced outside of the neigh_list_lock
110 * protected region. After the new best neighbor has replace the current
111 * best neighbor the reference counter needs to decrease. Consequently,
112 * the code needs to ensure the curr_router variable contains a pointer
113 * to the replaced best neighbor.
114 */
115 curr_router = rcu_dereference_protected(orig_ifinfo->router, true);
116
108 rcu_assign_pointer(orig_ifinfo->router, neigh_node); 117 rcu_assign_pointer(orig_ifinfo->router, neigh_node);
109 spin_unlock_bh(&orig_node->neigh_list_lock); 118 spin_unlock_bh(&orig_node->neigh_list_lock);
110 batadv_orig_ifinfo_put(orig_ifinfo); 119 batadv_orig_ifinfo_put(orig_ifinfo);
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 3ce06e0a91b1..76417850d3fc 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -675,6 +675,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
675 675
676 if (pending) { 676 if (pending) {
677 hlist_del(&forw_packet->list); 677 hlist_del(&forw_packet->list);
678 if (!forw_packet->own)
679 atomic_inc(&bat_priv->bcast_queue_left);
680
678 batadv_forw_packet_free(forw_packet); 681 batadv_forw_packet_free(forw_packet);
679 } 682 }
680 } 683 }
@@ -702,6 +705,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
702 705
703 if (pending) { 706 if (pending) {
704 hlist_del(&forw_packet->list); 707 hlist_del(&forw_packet->list);
708 if (!forw_packet->own)
709 atomic_inc(&bat_priv->batman_queue_left);
710
705 batadv_forw_packet_free(forw_packet); 711 batadv_forw_packet_free(forw_packet);
706 } 712 }
707 } 713 }
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 0710379491bf..8a136b6a1ff0 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface,
408 */ 408 */
409 nf_reset(skb); 409 nf_reset(skb);
410 410
411 if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
412 goto dropped;
413
411 vid = batadv_get_vid(skb, 0); 414 vid = batadv_get_vid(skb, 0);
412 ethhdr = eth_hdr(skb); 415 ethhdr = eth_hdr(skb);
413 416
414 switch (ntohs(ethhdr->h_proto)) { 417 switch (ntohs(ethhdr->h_proto)) {
415 case ETH_P_8021Q: 418 case ETH_P_8021Q:
419 if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
420 goto dropped;
421
416 vhdr = (struct vlan_ethhdr *)skb->data; 422 vhdr = (struct vlan_ethhdr *)skb->data;
417 423
418 if (vhdr->h_vlan_encapsulated_proto != ethertype) 424 if (vhdr->h_vlan_encapsulated_proto != ethertype)
@@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface,
424 } 430 }
425 431
426 /* skb->dev & skb->pkt_type are set here */ 432 /* skb->dev & skb->pkt_type are set here */
427 if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
428 goto dropped;
429 skb->protocol = eth_type_trans(skb, soft_iface); 433 skb->protocol = eth_type_trans(skb, soft_iface);
430 434
431 /* should not be necessary anymore as we use skb_pull_rcsum() 435 /* should not be necessary anymore as we use skb_pull_rcsum()