* [PATCH net 0/5] batman-adv: Fixes for Linux 4.7
@ 2016-06-26 9:15 Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 1/5] batman-adv: replace WARN with rate limited output on non-existing VLAN Sven Eckelmann
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Sven Eckelmann @ 2016-06-26 9:15 UTC (permalink / raw)
To: David Miller
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r, Antonio Quartulli
[-- Attachment #1: Type: text/plain, Size: 2715 bytes --]
Hi David,
Antonio currently seems to be occupied. This is currently rather unfortunate
because there are patches waiting in the batman-adv development repository
maint(enance) branch [1] since up to 6 weeks. I am now getting asked when
these patches will hit the distribution kernels and therefore decided to
submit these patches directly to netdev.
The patch from Simon works around the problem that warnings could be triggered
in the translation table code via packets using a VLAN not configured on the
target host. This warning was replaced with a rate limited info message.
Ben Hutchings found an superfluous batadv_softif_vlan_put in the error
handling code of the translation table while he backported the "batman-adv:
Fix reference counting of vlan object for tt_local_entry" patch to the stable
kernels. He noticed correctly that this batadv_softif_vlan_put should also
have been removed by the said patch.
The most requested fix at the moment is related to a double free in the
translation table code. It is a race condition which mostly happens on systems
with multiple cores and multiple network interface attached to batman-adv. Two
Freifunk communities which were haunted by weird crashes (with backtraces
reporting problems in other parts of the kernel) were kind enough to test this
patch. They reported that there systems are now running stable after applying
this patch.
An invalid memory access was detected in the batadv_icmp_packet_rr handling
code when receiving a skbuff with fragments. The last patch is fixing a memory
leak when the interface is removed via .dellink. The code to fix it was copied
from the code handling the legacy sysfs interface to remove netdevices from a
batman-adv netdevice.
There are still 28 patches in the development tree for v4.8 but I will leave
them to Antonio because these are cleanups and features and therefore for net-
next.
Ben Hutchings (1):
batman-adv: Fix double-put of vlan object
Simon Wunderlich (1):
batman-adv: replace WARN with rate limited output on non-existing VLAN
Sven Eckelmann (3):
batman-adv: Fix use-after-free/double-free of tt_req_node
batman-adv: Fix ICMP RR ethernet access after skb_linearize
batman-adv: Clean up untagged vlan when destroying via rtnl-link
net/batman-adv/routing.c | 1 +
net/batman-adv/soft-interface.c | 9 +++++++
net/batman-adv/translation-table.c | 50 +++++++++++++++++++++++++++++++-------
net/batman-adv/types.h | 2 ++
4 files changed, 53 insertions(+), 9 deletions(-)
Kind regards,
Sven
[1] https://git.open-mesh.org/batman-adv.git/shortlog/refs/heads/maint
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net 1/5] batman-adv: replace WARN with rate limited output on non-existing VLAN
2016-06-26 9:15 [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 Sven Eckelmann
@ 2016-06-26 9:16 ` Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 2/5] batman-adv: Fix use-after-free/double-free of tt_req_node Sven Eckelmann
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2016-06-26 9:16 UTC (permalink / raw)
To: David Miller
Cc: netdev, b.a.t.m.a.n, Simon Wunderlich, Marek Lindner,
Sven Eckelmann
From: Simon Wunderlich <sw@simonwunderlich.de>
If a VLAN tagged frame is received and the corresponding VLAN is not
configured on the soft interface, it will splat a WARN on every packet
received. This is a quite annoying behaviour for some scenarios, e.g. if
bat0 is bridged with eth0, and there are arbitrary VLAN tagged frames
from Ethernet coming in without having any VLAN configuration on bat0.
The code should probably create vlan objects on the fly and
transparently transport these VLAN-tagged Ethernet frames, but until
this is done, at least the WARN splat should be replaced by a rate
limited output.
Fixes: 354136bcc3c4 ("batman-adv: fix kernel crash due to missing NULL checks")
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
net/batman-adv/translation-table.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index feaf492b..72abab7 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -650,8 +650,10 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
/* increase the refcounter of the related vlan */
vlan = batadv_softif_vlan_get(bat_priv, vid);
- if (WARN(!vlan, "adding TT local entry %pM to non-existent VLAN %d",
- addr, BATADV_PRINT_VID(vid))) {
+ if (!vlan) {
+ net_ratelimited_function(batadv_info, soft_iface,
+ "adding TT local entry %pM to non-existent VLAN %d\n",
+ addr, BATADV_PRINT_VID(vid));
kfree(tt_local);
tt_local = NULL;
goto out;
--
2.8.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net 2/5] batman-adv: Fix use-after-free/double-free of tt_req_node
2016-06-26 9:15 [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 1/5] batman-adv: replace WARN with rate limited output on non-existing VLAN Sven Eckelmann
@ 2016-06-26 9:16 ` Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 3/5] batman-adv: Fix double-put of vlan object Sven Eckelmann
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2016-06-26 9:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann, Marek Lindner
The tt_req_node is added and removed from a list inside a spinlock. But the
locking is sometimes removed even when the object is still referenced and
will be used later via this reference. For example batadv_send_tt_request
can create a new tt_req_node (including add to a list) and later
re-acquires the lock to remove it from the list and to free it. But at this
time another context could have already removed this tt_req_node from the
list and freed it.
CPU#0
batadv_batman_skb_recv from net_device 0
-> batadv_iv_ogm_receive
-> batadv_iv_ogm_process
-> batadv_iv_ogm_process_per_outif
-> batadv_tvlv_ogm_receive
-> batadv_tvlv_ogm_receive
-> batadv_tvlv_containers_process
-> batadv_tvlv_call_handler
-> batadv_tt_tvlv_ogm_handler_v1
-> batadv_tt_update_orig
-> batadv_send_tt_request
-> batadv_tt_req_node_new
spin_lock(...)
allocates new tt_req_node and adds it to list
spin_unlock(...)
return tt_req_node
CPU#1
batadv_batman_skb_recv from net_device 1
-> batadv_recv_unicast_tvlv
-> batadv_tvlv_containers_process
-> batadv_tvlv_call_handler
-> batadv_tt_tvlv_unicast_handler_v1
-> batadv_handle_tt_response
spin_lock(...)
tt_req_node gets removed from list and is freed
spin_unlock(...)
CPU#0
<- returned to batadv_send_tt_request
spin_lock(...)
tt_req_node gets removed from list and is freed
MEMORY CORRUPTION/SEGFAULT/...
spin_unlock(...)
This can only be solved via reference counting to allow multiple contexts
to handle the list manipulation while making sure that only the last
context holding a reference will free the object.
Fixes: a73105b8d4c7 ("batman-adv: improved client announcement mechanism")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Tested-by: Martin Weinelt <martin@darmstadt.freifunk.net>
Tested-by: Amadeus Alfa <amadeus@chemnitz.freifunk.net>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
net/batman-adv/translation-table.c | 43 ++++++++++++++++++++++++++++++++------
net/batman-adv/types.h | 2 ++
2 files changed, 39 insertions(+), 6 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 72abab7..cfb5ccd 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -2271,6 +2271,29 @@ static u32 batadv_tt_local_crc(struct batadv_priv *bat_priv,
return crc;
}
+/**
+ * batadv_tt_req_node_release - free tt_req node entry
+ * @ref: kref pointer of the tt req_node entry
+ */
+static void batadv_tt_req_node_release(struct kref *ref)
+{
+ struct batadv_tt_req_node *tt_req_node;
+
+ tt_req_node = container_of(ref, struct batadv_tt_req_node, refcount);
+
+ kfree(tt_req_node);
+}
+
+/**
+ * batadv_tt_req_node_put - decrement the tt_req_node refcounter and
+ * possibly release it
+ * @tt_req_node: tt_req_node to be free'd
+ */
+static void batadv_tt_req_node_put(struct batadv_tt_req_node *tt_req_node)
+{
+ kref_put(&tt_req_node->refcount, batadv_tt_req_node_release);
+}
+
static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
{
struct batadv_tt_req_node *node;
@@ -2280,7 +2303,7 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
hlist_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
hlist_del_init(&node->list);
- kfree(node);
+ batadv_tt_req_node_put(node);
}
spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2317,7 +2340,7 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
if (batadv_has_timed_out(node->issued_at,
BATADV_TT_REQUEST_TIMEOUT)) {
hlist_del_init(&node->list);
- kfree(node);
+ batadv_tt_req_node_put(node);
}
}
spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2349,9 +2372,11 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
if (!tt_req_node)
goto unlock;
+ kref_init(&tt_req_node->refcount);
ether_addr_copy(tt_req_node->addr, orig_node->orig);
tt_req_node->issued_at = jiffies;
+ kref_get(&tt_req_node->refcount);
hlist_add_head(&tt_req_node->list, &bat_priv->tt.req_list);
unlock:
spin_unlock_bh(&bat_priv->tt.req_list_lock);
@@ -2615,13 +2640,19 @@ static bool batadv_send_tt_request(struct batadv_priv *bat_priv,
out:
if (primary_if)
batadv_hardif_put(primary_if);
+
if (ret && tt_req_node) {
spin_lock_bh(&bat_priv->tt.req_list_lock);
- /* hlist_del_init() verifies tt_req_node still is in the list */
- hlist_del_init(&tt_req_node->list);
+ if (!hlist_unhashed(&tt_req_node->list)) {
+ hlist_del_init(&tt_req_node->list);
+ batadv_tt_req_node_put(tt_req_node);
+ }
spin_unlock_bh(&bat_priv->tt.req_list_lock);
- kfree(tt_req_node);
}
+
+ if (tt_req_node)
+ batadv_tt_req_node_put(tt_req_node);
+
kfree(tvlv_tt_data);
return ret;
}
@@ -3057,7 +3088,7 @@ static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
if (!batadv_compare_eth(node->addr, resp_src))
continue;
hlist_del_init(&node->list);
- kfree(node);
+ batadv_tt_req_node_put(node);
}
spin_unlock_bh(&bat_priv->tt.req_list_lock);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 6a577f4..ba846b0 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1137,11 +1137,13 @@ struct batadv_tt_change_node {
* struct batadv_tt_req_node - data to keep track of the tt requests in flight
* @addr: mac address address of the originator this request was sent to
* @issued_at: timestamp used for purging stale tt requests
+ * @refcount: number of contexts the object is used by
* @list: list node for batadv_priv_tt::req_list
*/
struct batadv_tt_req_node {
u8 addr[ETH_ALEN];
unsigned long issued_at;
+ struct kref refcount;
struct hlist_node list;
};
--
2.8.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net 3/5] batman-adv: Fix double-put of vlan object
2016-06-26 9:15 [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 1/5] batman-adv: replace WARN with rate limited output on non-existing VLAN Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 2/5] batman-adv: Fix use-after-free/double-free of tt_req_node Sven Eckelmann
@ 2016-06-26 9:16 ` Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 4/5] batman-adv: Fix ICMP RR ethernet access after skb_linearize Sven Eckelmann
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2016-06-26 9:16 UTC (permalink / raw)
To: David Miller
Cc: netdev, b.a.t.m.a.n, Ben Hutchings, Marek Lindner, Sven Eckelmann
From: Ben Hutchings <ben@decadent.org.uk>
Each batadv_tt_local_entry hold a single reference to a
batadv_softif_vlan. In case a new entry cannot be added to the hash
table, the error path puts the reference, but the reference will also
now be dropped by batadv_tt_local_entry_release().
Fixes: a33d970d0b54 ("batman-adv: Fix reference counting of vlan object for tt_local_entry")
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
net/batman-adv/translation-table.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index cfb5ccd..57ec87f 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -693,7 +693,6 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const u8 *addr,
if (unlikely(hash_added != 0)) {
/* remove the reference for the hash */
batadv_tt_local_entry_put(tt_local);
- batadv_softif_vlan_put(vlan);
goto out;
}
--
2.8.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net 4/5] batman-adv: Fix ICMP RR ethernet access after skb_linearize
2016-06-26 9:15 [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 Sven Eckelmann
` (2 preceding siblings ...)
2016-06-26 9:16 ` [PATCH net 3/5] batman-adv: Fix double-put of vlan object Sven Eckelmann
@ 2016-06-26 9:16 ` Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 5/5] batman-adv: Clean up untagged vlan when destroying via rtnl-link Sven Eckelmann
2016-06-29 8:03 ` [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2016-06-26 9:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann, Marek Lindner
The skb_linearize may reallocate the skb. This makes the calculated pointer
for ethhdr invalid. But it the pointer is used later to fill in the RR
field of the batadv_icmp_packet_rr packet.
Instead re-evaluate eth_hdr after the skb_linearize+skb_cow to fix the
pointer and avoid the invalid read.
Fixes: da6b8c20a5b8 ("batman-adv: generalize batman-adv icmp packet handling")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
net/batman-adv/routing.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index e3857ed..6c2901a 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -374,6 +374,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
if (skb_cow(skb, ETH_HLEN) < 0)
goto out;
+ ethhdr = eth_hdr(skb);
icmph = (struct batadv_icmp_header *)skb->data;
icmp_packet_rr = (struct batadv_icmp_packet_rr *)icmph;
if (icmp_packet_rr->rr_cur >= BATADV_RR_LEN)
--
2.8.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net 5/5] batman-adv: Clean up untagged vlan when destroying via rtnl-link
2016-06-26 9:15 [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 Sven Eckelmann
` (3 preceding siblings ...)
2016-06-26 9:16 ` [PATCH net 4/5] batman-adv: Fix ICMP RR ethernet access after skb_linearize Sven Eckelmann
@ 2016-06-26 9:16 ` Sven Eckelmann
2016-06-29 8:03 ` [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2016-06-26 9:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev, b.a.t.m.a.n, Sven Eckelmann, Marek Lindner
The untagged vlan object is only destroyed when the interface is removed
via the legacy sysfs interface. But it also has to be destroyed when the
standard rtnl-link interface is used.
Fixes: 5d2c05b21337 ("batman-adv: add per VLAN interface attribute framework")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Antonio Quartulli <a@unstable.cc>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
---
net/batman-adv/soft-interface.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 343d2c9..287a387 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -1033,7 +1033,9 @@ void batadv_softif_destroy_sysfs(struct net_device *soft_iface)
static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
struct list_head *head)
{
+ struct batadv_priv *bat_priv = netdev_priv(soft_iface);
struct batadv_hard_iface *hard_iface;
+ struct batadv_softif_vlan *vlan;
list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
if (hard_iface->soft_iface == soft_iface)
@@ -1041,6 +1043,13 @@ static void batadv_softif_destroy_netlink(struct net_device *soft_iface,
BATADV_IF_CLEANUP_KEEP);
}
+ /* destroy the "untagged" VLAN */
+ vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
+ if (vlan) {
+ batadv_softif_destroy_vlan(bat_priv, vlan);
+ batadv_softif_vlan_put(vlan);
+ }
+
batadv_sysfs_del_meshif(soft_iface);
unregister_netdevice_queue(soft_iface, head);
}
--
2.8.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH net 0/5] batman-adv: Fixes for Linux 4.7
2016-06-26 9:15 [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 Sven Eckelmann
` (4 preceding siblings ...)
2016-06-26 9:16 ` [PATCH net 5/5] batman-adv: Clean up untagged vlan when destroying via rtnl-link Sven Eckelmann
@ 2016-06-29 8:03 ` David Miller
5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2016-06-29 8:03 UTC (permalink / raw)
To: sven; +Cc: netdev, b.a.t.m.a.n, a
From: Sven Eckelmann <sven@narfation.org>
Date: Sun, 26 Jun 2016 11:15:12 +0200
> Antonio currently seems to be occupied. This is currently rather
> unfortunate because there are patches waiting in the batman-adv
> development repository maint(enance) branch [1] since up to 6
> weeks. I am now getting asked when these patches will hit the
> distribution kernels and therefore decided to submit these patches
> directly to netdev.
Series applied, thanks Sven.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-06-29 8:03 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-26 9:15 [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 1/5] batman-adv: replace WARN with rate limited output on non-existing VLAN Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 2/5] batman-adv: Fix use-after-free/double-free of tt_req_node Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 3/5] batman-adv: Fix double-put of vlan object Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 4/5] batman-adv: Fix ICMP RR ethernet access after skb_linearize Sven Eckelmann
2016-06-26 9:16 ` [PATCH net 5/5] batman-adv: Clean up untagged vlan when destroying via rtnl-link Sven Eckelmann
2016-06-29 8:03 ` [PATCH net 0/5] batman-adv: Fixes for Linux 4.7 David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).