Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb863b8b authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 2fbd9679 a4361860
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -837,6 +837,19 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,

	dat_entry = batadv_dat_entry_hash_find(bat_priv, ip_dst);
	if (dat_entry) {
		/* If the ARP request is destined for a local client the local
		 * client will answer itself. DAT would only generate a
		 * duplicate packet.
		 *
		 * Moreover, if the soft-interface is enslaved into a bridge, an
		 * additional DAT answer may trigger kernel warnings about
		 * a packet coming from the wrong port.
		 */
		if (batadv_is_my_client(bat_priv, dat_entry->mac_addr)) {
			ret = true;
			goto out;
		}

		skb_new = arp_create(ARPOP_REPLY, ETH_P_ARP, ip_src,
				     bat_priv->soft_iface, ip_dst, hw_src,
				     dat_entry->mac_addr, hw_src);
+13 −5
Original line number Diff line number Diff line
@@ -163,14 +163,22 @@ void batadv_mesh_free(struct net_device *soft_iface)
	batadv_vis_quit(bat_priv);

	batadv_gw_node_purge(bat_priv);
	batadv_originator_free(bat_priv);
	batadv_nc_free(bat_priv);
	batadv_dat_free(bat_priv);
	batadv_bla_free(bat_priv);

	/* Free the TT and the originator tables only after having terminated
	 * all the other depending components which may use these structures for
	 * their purposes.
	 */
	batadv_tt_free(bat_priv);

	batadv_bla_free(bat_priv);

	batadv_dat_free(bat_priv);
	/* Since the originator table clean up routine is accessing the TT
	 * tables as well, it has to be invoked after the TT tables have been
	 * freed and marked as empty. This ensures that no cleanup RCU callbacks
	 * accessing the TT data are scheduled for later execution.
	 */
	batadv_originator_free(bat_priv);

	free_percpu(bat_priv->bat_counters);

@@ -475,7 +483,7 @@ static int batadv_param_set_ra(const char *val, const struct kernel_param *kp)
	char *algo_name = (char *)val;
	size_t name_len = strlen(algo_name);

	if (algo_name[name_len - 1] == '\n')
	if (name_len > 0 && algo_name[name_len - 1] == '\n')
		algo_name[name_len - 1] = '\0';

	bat_algo_ops = batadv_algo_get(algo_name);
+6 −2
Original line number Diff line number Diff line
@@ -1514,6 +1514,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
	struct ethhdr *ethhdr, ethhdr_tmp;
	uint8_t *orig_dest, ttl, ttvn;
	unsigned int coding_len;
	int err;

	/* Save headers temporarily */
	memcpy(&coded_packet_tmp, skb->data, sizeof(coded_packet_tmp));
@@ -1568,8 +1569,11 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
			 coding_len);

	/* Resize decoded skb if decoded with larger packet */
	if (nc_packet->skb->len > coding_len + h_size)
		pskb_trim_rcsum(skb, coding_len + h_size);
	if (nc_packet->skb->len > coding_len + h_size) {
		err = pskb_trim_rcsum(skb, coding_len + h_size);
		if (err)
			return NULL;
	}

	/* Create decoded unicast packet */
	unicast_packet = (struct batadv_unicast_packet *)skb->data;