Commit fb863b8beaf8121199c3dc32ab0126e8ce9cb34a

Authored by David S. Miller

Merge tag 'batman-adv-fix-for-davem' of git://git.open-mesh.org/linux-merge

Included changes:
- fix parsing of user typed protocol string to avoid random memory access in
  some cases
- check pskb_trim_rcsum() return value
- prevent DAT from sending ARP replies when not needed
- reorder the main clean up routine to prevent race conditions

Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 3 changed files Side-by-side Diff

net/batman-adv/distributed-arp-table.c
... ... @@ -837,6 +837,19 @@
837 837  
838 838 dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
839 839 if (dat_entry) {
  840 + /* If the ARP request is destined for a local client the local
  841 + * client will answer itself. DAT would only generate a
  842 + * duplicate packet.
  843 + *
  844 + * Moreover, if the soft-interface is enslaved into a bridge, an
  845 + * additional DAT answer may trigger kernel warnings about
  846 + * a packet coming from the wrong port.
  847 + */
  848 + if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) {
  849 + ret = true;
  850 + goto out;
  851 + }
  852 +
840 853 skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
841 854 bat_priv->soft_iface, ip_dst, hw_src,
842 855 dat_entry->mac_addr, hw_src);
net/batman-adv/main.c
... ... @@ -163,15 +163,23 @@
163 163 batadv_vis_quit(bat_priv);
164 164  
165 165 batadv_gw_node_purge(bat_priv);
166   - batadv_originator_free(bat_priv);
167 166 batadv_nc_free(bat_priv);
  167 + batadv_dat_free(bat_priv);
  168 + batadv_bla_free(bat_priv);
168 169  
  170 + /* Free the TT and the originator tables only after having terminated
  171 + * all the other depending components which may use these structures for
  172 + * their purposes.
  173 + */
169 174 batadv_tt_free(bat_priv);
170 175  
171   - batadv_bla_free(bat_priv);
  176 + /* Since the originator table clean up routine is accessing the TT
  177 + * tables as well, it has to be invoked after the TT tables have been
  178 + * freed and marked as empty. This ensures that no cleanup RCU callbacks
  179 + * accessing the TT data are scheduled for later execution.
  180 + */
  181 + batadv_originator_free(bat_priv);
172 182  
173   - batadv_dat_free(bat_priv);
174   -
175 183 free_percpu(bat_priv->bat_counters);
176 184  
177 185 atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE);
... ... @@ -475,7 +483,7 @@
475 483 char *algo_name = (char *)val;
476 484 size_t name_len = strlen(algo_name);
477 485  
478   - if (algo_name[name_len - 1] == '\n')
  486 + if (name_len > 0 && algo_name[name_len - 1] == '\n')
479 487 algo_name[name_len - 1] = '\0';
480 488  
481 489 bat_algo_ops = batadv_algo_get(algo_name);
net/batman-adv/network-coding.c
... ... @@ -1514,6 +1514,7 @@
1514 1514 struct ethhdr *ethhdr, ethhdr_tmp;
1515 1515 uint8_t *orig_dest, ttl, ttvn;
1516 1516 unsigned int coding_len;
  1517 + int err;
1517 1518  
1518 1519 /* Save headers temporarily */
1519 1520 memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp));
... ... @@ -1568,8 +1569,11 @@
1568 1569 coding_len);
1569 1570  
1570 1571 /* Resize decoded skb if decoded with larger packet */
1571   - if (nc_packet->skb->len > coding_len + h_size)
1572   - pskb_trim_rcsum(skb, coding_len + h_size);
  1572 + if (nc_packet->skb->len > coding_len + h_size) {
  1573 + err = pskb_trim_rcsum(skb, coding_len + h_size);
  1574 + if (err)
  1575 + return NULL;
  1576 + }
1573 1577  
1574 1578 /* Create decoded unicast packet */
1575 1579 unicast_packet = (struct batadv_unicast_packet *)skb->data;