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

Commit 2f67cc87 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

Include changes:
- fix NULL dereference in batadv_orig_hardif_seq_print_text()
- fix reference counting imbalance when using fragmentation
- avoid access to orig_node objects after they have been free'd
- fix local TT check for outgoing arp requests in DAT
parents 0d08fceb cc2f3386
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -940,8 +940,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
		 * 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,
					BATADV_NO_FLAGS)) {
		if (batadv_is_my_client(bat_priv, dat_entry->mac_addr, vid)) {
			ret = true;
			goto out;
		}
+8 −3
Original line number Diff line number Diff line
@@ -418,12 +418,13 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
			     struct batadv_neigh_node *neigh_node)
{
	struct batadv_priv *bat_priv;
	struct batadv_hard_iface *primary_if;
	struct batadv_hard_iface *primary_if = NULL;
	struct batadv_frag_packet frag_header;
	struct sk_buff *skb_fragment;
	unsigned mtu = neigh_node->if_incoming->net_dev->mtu;
	unsigned header_size = sizeof(frag_header);
	unsigned max_fragment_size, max_packet_size;
	bool ret = false;

	/* To avoid merge and refragmentation at next-hops we never send
	 * fragments larger than BATADV_FRAG_MAX_FRAG_SIZE
@@ -483,7 +484,11 @@ bool batadv_frag_send_packet(struct sk_buff *skb,
			   skb->len + ETH_HLEN);
	batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);

	return true;
	ret = true;

out_err:
	return false;
	if (primary_if)
		batadv_hardif_free_ref(primary_if);

	return ret;
}
+9 −2
Original line number Diff line number Diff line
@@ -42,9 +42,11 @@

static void batadv_gw_node_free_ref(struct batadv_gw_node *gw_node)
{
	if (atomic_dec_and_test(&gw_node->refcount))
	if (atomic_dec_and_test(&gw_node->refcount)) {
		batadv_orig_node_free_ref(gw_node->orig_node);
		kfree_rcu(gw_node, rcu);
	}
}

static struct batadv_gw_node *
batadv_gw_get_selected_gw_node(struct batadv_priv *bat_priv)
@@ -406,9 +408,14 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
	if (gateway->bandwidth_down == 0)
		return;

	if (!atomic_inc_not_zero(&orig_node->refcount))
		return;

	gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC);
	if (!gw_node)
	if (!gw_node) {
		batadv_orig_node_free_ref(orig_node);
		return;
	}

	INIT_HLIST_NODE(&gw_node->list);
	gw_node->orig_node = orig_node;
+2 −1
Original line number Diff line number Diff line
@@ -1079,6 +1079,7 @@ int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset)
	bat_priv->bat_algo_ops->bat_orig_print(bat_priv, seq, hard_iface);

out:
	if (hard_iface)
		batadv_hardif_free_ref(hard_iface);
	return 0;
}