* [B.A.T.M.A.N.] [PATCH 1/4] batman-adv: fix skb deref after free
2016-05-15 15:11 [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515 Antonio Quartulli
@ 2016-05-15 15:11 ` Antonio Quartulli
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 2/4] batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob Antonio Quartulli
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Antonio Quartulli @ 2016-05-15 15:11 UTC (permalink / raw)
To: davem
Cc: netdev, Antonio Quartulli, b.a.t.m.a.n, Florian Westphal,
Marek Lindner
From: Florian Westphal <fw@strlen.de>
batadv_send_skb_to_orig() calls dev_queue_xmit() so we can't use skb->len.
Fixes: 953324776d6d ("batman-adv: network coding - buffer unicast packets before forward")
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
net/batman-adv/routing.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index b781bf753250..0c0c30e101a1 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -601,6 +601,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_unicast_packet *unicast_packet;
struct ethhdr *ethhdr = eth_hdr(skb);
int res, hdr_len, ret = NET_RX_DROP;
+ unsigned int len;
unicast_packet = (struct batadv_unicast_packet *)skb->data;
@@ -641,6 +642,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
if (hdr_len > 0)
batadv_skb_set_priority(skb, hdr_len);
+ len = skb->len;
res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
/* translate transmit result into receive result */
@@ -648,7 +650,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
/* skb was transmitted and consumed */
batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
- skb->len + ETH_HLEN);
+ len + ETH_HLEN);
ret = NET_RX_SUCCESS;
} else if (res == NET_XMIT_POLICED) {
--
2.8.2
^ permalink raw reply related [flat|nested] 6+ messages in thread* [B.A.T.M.A.N.] [PATCH 2/4] batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob
2016-05-15 15:11 [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515 Antonio Quartulli
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 1/4] batman-adv: fix skb deref after free Antonio Quartulli
@ 2016-05-15 15:11 ` Antonio Quartulli
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 3/4] batman-adv: Fix double neigh_node_put in batadv_v_ogm_route_update Antonio Quartulli
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Antonio Quartulli @ 2016-05-15 15:11 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
From: Sven Eckelmann <sven@narfation.org>
batadv_neigh_ifinfo_get can return NULL when it cannot find (even when only
temporarily) anymore the neigh_ifinfo in the list neigh->ifinfo_list. This
has to be checked to avoid kernel Oopses when the ifinfo is dereferenced.
This a situation which isn't expected but is already handled by functions
like batadv_v_neigh_cmp. The same kind of warning is therefore used before
the function returns without dereferencing the pointers.
Fixes: 9786906022eb ("batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
net/batman-adv/bat_v.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 4026f198a734..e81ad4b8e5c8 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -27,6 +27,7 @@
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/seq_file.h>
+#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/workqueue.h>
@@ -277,6 +278,9 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+ if (WARN_ON(!ifinfo1 || !ifinfo2))
+ return false;
+
threshold = ifinfo1->bat_v.throughput / 4;
threshold = ifinfo1->bat_v.throughput - threshold;
--
2.8.2
^ permalink raw reply related [flat|nested] 6+ messages in thread* [B.A.T.M.A.N.] [PATCH 3/4] batman-adv: Fix double neigh_node_put in batadv_v_ogm_route_update
2016-05-15 15:11 [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515 Antonio Quartulli
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 1/4] batman-adv: fix skb deref after free Antonio Quartulli
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 2/4] batman-adv: Avoid nullptr derefence in batadv_v_neigh_is_sob Antonio Quartulli
@ 2016-05-15 15:11 ` Antonio Quartulli
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 4/4] batman-adv: Fix refcnt leak in batadv_v_neigh_* Antonio Quartulli
2016-05-16 18:01 ` [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515 David Miller
4 siblings, 0 replies; 6+ messages in thread
From: Antonio Quartulli @ 2016-05-15 15:11 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli
From: Sven Eckelmann <sven@narfation.org>
The router is put down twice when it was non-NULL and either orig_ifinfo is
NULL afterwards or batman-adv receives a packet with the same sequence
number. This will end up in a use-after-free when the batadv_neigh_node is
removed because the reference counter ended up too early at 0.
Fixes: 9323158ef9f4 ("batman-adv: OGMv2 - implement originators logic")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
net/batman-adv/bat_v_ogm.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index d9bcbe6e7d65..91df28a100f9 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -529,8 +529,10 @@ static void batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
goto out;
}
- if (router)
+ if (router) {
batadv_neigh_node_put(router);
+ router = NULL;
+ }
/* Update routes, and check if the OGM is from the best next hop */
batadv_v_ogm_orig_update(bat_priv, orig_node, neigh_node, ogm2,
--
2.8.2
^ permalink raw reply related [flat|nested] 6+ messages in thread* [B.A.T.M.A.N.] [PATCH 4/4] batman-adv: Fix refcnt leak in batadv_v_neigh_*
2016-05-15 15:11 [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515 Antonio Quartulli
` (2 preceding siblings ...)
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 3/4] batman-adv: Fix double neigh_node_put in batadv_v_ogm_route_update Antonio Quartulli
@ 2016-05-15 15:11 ` Antonio Quartulli
2016-05-16 18:01 ` [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515 David Miller
4 siblings, 0 replies; 6+ messages in thread
From: Antonio Quartulli @ 2016-05-15 15:11 UTC (permalink / raw)
To: davem; +Cc: netdev, b.a.t.m.a.n, Antonio Quartulli, Marek Lindner
From: Sven Eckelmann <sven@narfation.org>
The functions batadv_neigh_ifinfo_get increase the reference counter of the
batadv_neigh_ifinfo. These have to be reduced again when the reference is
not used anymore to correctly free the objects.
Fixes: 9786906022eb ("batman-adv: B.A.T.M.A.N. V - implement neighbor comparison API calls")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Antonio Quartulli <a@unstable.cc>
---
net/batman-adv/bat_v.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index e81ad4b8e5c8..7fd477583eb0 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -257,14 +257,23 @@ static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
struct batadv_hard_iface *if_outgoing2)
{
struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
+ int ret = 0;
ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
+ if (WARN_ON(!ifinfo1))
+ goto err_ifinfo1;
+
ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+ if (WARN_ON(!ifinfo2))
+ goto err_ifinfo2;
- if (WARN_ON(!ifinfo1 || !ifinfo2))
- return 0;
+ ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
- return ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
+ batadv_neigh_ifinfo_put(ifinfo2);
+err_ifinfo2:
+ batadv_neigh_ifinfo_put(ifinfo1);
+err_ifinfo1:
+ return ret;
}
static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
@@ -274,17 +283,26 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
{
struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
u32 threshold;
+ bool ret = false;
ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
- ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+ if (WARN_ON(!ifinfo1))
+ goto err_ifinfo1;
- if (WARN_ON(!ifinfo1 || !ifinfo2))
- return false;
+ ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+ if (WARN_ON(!ifinfo2))
+ goto err_ifinfo2;
threshold = ifinfo1->bat_v.throughput / 4;
threshold = ifinfo1->bat_v.throughput - threshold;
- return ifinfo2->bat_v.throughput > threshold;
+ ret = ifinfo2->bat_v.throughput > threshold;
+
+ batadv_neigh_ifinfo_put(ifinfo2);
+err_ifinfo2:
+ batadv_neigh_ifinfo_put(ifinfo1);
+err_ifinfo1:
+ return ret;
}
static struct batadv_algo_ops batadv_batman_v __read_mostly = {
--
2.8.2
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515
2016-05-15 15:11 [B.A.T.M.A.N.] pull request [net]: batman-adv 20160515 Antonio Quartulli
` (3 preceding siblings ...)
2016-05-15 15:11 ` [B.A.T.M.A.N.] [PATCH 4/4] batman-adv: Fix refcnt leak in batadv_v_neigh_* Antonio Quartulli
@ 2016-05-16 18:01 ` David Miller
4 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2016-05-16 18:01 UTC (permalink / raw)
To: a; +Cc: netdev, b.a.t.m.a.n
From: Antonio Quartulli <a@unstable.cc>
Date: Sun, 15 May 2016 23:11:29 +0800
> Please pull or let me know if you rather prefer to get this through net-next.
Since the merge window is open, please send me this via net-next.
Thank you.
^ permalink raw reply [flat|nested] 6+ messages in thread