Skip to content

Commit

Permalink
Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux…
Browse files Browse the repository at this point in the history
…-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>
  • Loading branch information
David S. Miller committed Apr 28, 2016
2 parents eb63efb + c4fdb6c commit 956a7ff
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
3 changes: 1 addition & 2 deletions net/batman-adv/hard-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface,
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_hard_iface *primary_if = NULL;

if (hard_iface->if_status == BATADV_IF_ACTIVE)
batadv_hardif_deactivate_interface(hard_iface);
batadv_hardif_deactivate_interface(hard_iface);

if (hard_iface->if_status != BATADV_IF_INACTIVE)
goto out;
Expand Down
1 change: 1 addition & 0 deletions net/batman-adv/originator.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,7 @@ batadv_neigh_node_new(struct batadv_orig_node *orig_node,
ether_addr_copy(neigh_node->addr, neigh_addr);
neigh_node->if_incoming = hard_iface;
neigh_node->orig_node = orig_node;
neigh_node->last_seen = jiffies;

/* extra reference for return */
kref_init(&neigh_node->refcount);
Expand Down
9 changes: 9 additions & 0 deletions net/batman-adv/routing.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
neigh_node = NULL;

spin_lock_bh(&orig_node->neigh_list_lock);
/* curr_router used earlier may not be the current orig_ifinfo->router
* anymore because it was dereferenced outside of the neigh_list_lock
* protected region. After the new best neighbor has replace the current
* best neighbor the reference counter needs to decrease. Consequently,
* the code needs to ensure the curr_router variable contains a pointer
* to the replaced best neighbor.
*/
curr_router = rcu_dereference_protected(orig_ifinfo->router, true);

rcu_assign_pointer(orig_ifinfo->router, neigh_node);
spin_unlock_bh(&orig_node->neigh_list_lock);
batadv_orig_ifinfo_put(orig_ifinfo);
Expand Down
6 changes: 6 additions & 0 deletions net/batman-adv/send.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,

if (pending) {
hlist_del(&forw_packet->list);
if (!forw_packet->own)
atomic_inc(&bat_priv->bcast_queue_left);

batadv_forw_packet_free(forw_packet);
}
}
Expand Down Expand Up @@ -702,6 +705,9 @@ batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,

if (pending) {
hlist_del(&forw_packet->list);
if (!forw_packet->own)
atomic_inc(&bat_priv->batman_queue_left);

batadv_forw_packet_free(forw_packet);
}
}
Expand Down
8 changes: 6 additions & 2 deletions net/batman-adv/soft-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,17 @@ void batadv_interface_rx(struct net_device *soft_iface,
*/
nf_reset(skb);

if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
goto dropped;

vid = batadv_get_vid(skb, 0);
ethhdr = eth_hdr(skb);

switch (ntohs(ethhdr->h_proto)) {
case ETH_P_8021Q:
if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
goto dropped;

vhdr = (struct vlan_ethhdr *)skb->data;

if (vhdr->h_vlan_encapsulated_proto != ethertype)
Expand All @@ -424,8 +430,6 @@ void batadv_interface_rx(struct net_device *soft_iface,
}

/* skb->dev & skb->pkt_type are set here */
if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
goto dropped;
skb->protocol = eth_type_trans(skb, soft_iface);

/* should not be necessary anymore as we use skb_pull_rcsum()
Expand Down

0 comments on commit 956a7ff

Please sign in to comment.