aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2016-05-06 05:43:39 -0400
committerAntonio Quartulli <a@unstable.cc>2016-05-17 23:49:40 -0400
commit71f9d27daa2cbcca7159c27f0c0c381cc2dd1053 (patch)
tree5feaba3744a53cfb781720c9438cb9f03faaa6f3
parenta45e932a3c58eac11a7458c6888910e23f615077 (diff)
batman-adv: Fix refcnt leak in batadv_v_neigh_*
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>
-rw-r--r--net/batman-adv/bat_v.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index 50bfcf87f569..4f626a6b8ebd 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -256,14 +256,23 @@ static int batadv_v_neigh_cmp(struct batadv_neigh_node *neigh1,
256 struct batadv_hard_iface *if_outgoing2) 256 struct batadv_hard_iface *if_outgoing2)
257{ 257{
258 struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; 258 struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
259 int ret = 0;
259 260
260 ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); 261 ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
262 if (WARN_ON(!ifinfo1))
263 goto err_ifinfo1;
264
261 ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); 265 ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
266 if (WARN_ON(!ifinfo2))
267 goto err_ifinfo2;
262 268
263 if (WARN_ON(!ifinfo1 || !ifinfo2)) 269 ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
264 return 0;
265 270
266 return ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput; 271 batadv_neigh_ifinfo_put(ifinfo2);
272err_ifinfo2:
273 batadv_neigh_ifinfo_put(ifinfo1);
274err_ifinfo1:
275 return ret;
267} 276}
268 277
269static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1, 278static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
@@ -273,17 +282,26 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
273{ 282{
274 struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2; 283 struct batadv_neigh_ifinfo *ifinfo1, *ifinfo2;
275 u32 threshold; 284 u32 threshold;
285 bool ret = false;
276 286
277 ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1); 287 ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
278 ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2); 288 if (WARN_ON(!ifinfo1))
289 goto err_ifinfo1;
279 290
280 if (WARN_ON(!ifinfo1 || !ifinfo2)) 291 ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
281 return false; 292 if (WARN_ON(!ifinfo2))
293 goto err_ifinfo2;
282 294
283 threshold = ifinfo1->bat_v.throughput / 4; 295 threshold = ifinfo1->bat_v.throughput / 4;
284 threshold = ifinfo1->bat_v.throughput - threshold; 296 threshold = ifinfo1->bat_v.throughput - threshold;
285 297
286 return ifinfo2->bat_v.throughput > threshold; 298 ret = ifinfo2->bat_v.throughput > threshold;
299
300 batadv_neigh_ifinfo_put(ifinfo2);
301err_ifinfo2:
302 batadv_neigh_ifinfo_put(ifinfo1);
303err_ifinfo1:
304 return ret;
287} 305}
288 306
289static struct batadv_algo_ops batadv_batman_v __read_mostly = { 307static struct batadv_algo_ops batadv_batman_v __read_mostly = {