batman-adv: fix hardif_neigh refcount on queue_work() failure
authorMarek Lindner <mareklindner@neomailbox.ch>
Thu, 6 Sep 2018 21:45:55 +0000 (05:45 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Oct 2018 07:51:30 +0000 (09:51 +0200)
[ Upstream commit 4c4af6900844ab04c9434c972021d7b48610e06a ]

The hardif_neigh refcounter is to be decreased by the queued work and
currently is never decreased if the queue_work() call fails.
Fix by checking the queue_work() return value and decrease refcount
if necessary.

Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/batman-adv/bat_v_elp.c

index ee08540..5d79004 100644 (file)
@@ -243,6 +243,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
        struct batadv_priv *bat_priv;
        struct sk_buff *skb;
        u32 elp_interval;
+       bool ret;
 
        bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work);
        hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
@@ -304,8 +305,11 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
                 * may sleep and that is not allowed in an rcu protected
                 * context. Therefore schedule a task for that.
                 */
-               queue_work(batadv_event_workqueue,
-                          &hardif_neigh->bat_v.metric_work);
+               ret = queue_work(batadv_event_workqueue,
+                                &hardif_neigh->bat_v.metric_work);
+
+               if (!ret)
+                       batadv_hardif_neigh_put(hardif_neigh);
        }
        rcu_read_unlock();