]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Mar 2020 10:19:59 +0000 (11:19 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Mar 2020 10:19:59 +0000 (11:19 +0100)
added patches:
batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch

queue-4.19/batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch b/queue-4.19/batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch
new file mode 100644 (file)
index 0000000..267f53d
--- /dev/null
@@ -0,0 +1,151 @@
+From a8d23cbbf6c9f515ed678204ad2962be7c336344 Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Thu, 3 Oct 2019 17:02:01 +0200
+Subject: batman-adv: Avoid free/alloc race when handling OGM2 buffer
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit a8d23cbbf6c9f515ed678204ad2962be7c336344 upstream.
+
+A B.A.T.M.A.N. V virtual interface has an OGM2 packet buffer which is
+initialized using data from the netdevice notifier and other rtnetlink
+related hooks. It is sent regularly via various slave interfaces of the
+batadv virtual interface and in this process also modified (realloced) to
+integrate additional state information via TVLV containers.
+
+It must be avoided that the worker item is executed without a common lock
+with the netdevice notifier/rtnetlink helpers. Otherwise it can either
+happen that half modified data is sent out or the functions modifying the
+OGM2 buffer try to access already freed memory regions.
+
+Fixes: 0da0035942d4 ("batman-adv: OGMv2 - add basic infrastructure")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/batman-adv/bat_v_ogm.c |   42 ++++++++++++++++++++++++++++++++++--------
+ net/batman-adv/types.h     |    4 ++++
+ 2 files changed, 38 insertions(+), 8 deletions(-)
+
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -29,6 +29,8 @@
+ #include <linux/kernel.h>
+ #include <linux/kref.h>
+ #include <linux/list.h>
++#include <linux/lockdep.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/random.h>
+ #include <linux/rculist.h>
+@@ -128,14 +130,12 @@ static void batadv_v_ogm_send_to_if(stru
+ }
+ /**
+- * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
+- * @work: work queue item
++ * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM
++ * @bat_priv: the bat priv with all the soft interface information
+  */
+-static void batadv_v_ogm_send(struct work_struct *work)
++static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
+ {
+       struct batadv_hard_iface *hard_iface;
+-      struct batadv_priv_bat_v *bat_v;
+-      struct batadv_priv *bat_priv;
+       struct batadv_ogm2_packet *ogm_packet;
+       struct sk_buff *skb, *skb_tmp;
+       unsigned char *ogm_buff;
+@@ -143,8 +143,7 @@ static void batadv_v_ogm_send(struct wor
+       u16 tvlv_len = 0;
+       int ret;
+-      bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
+-      bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
++      lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
+       if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
+               goto out;
+@@ -236,6 +235,23 @@ out:
+ }
+ /**
++ * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
++ * @work: work queue item
++ */
++static void batadv_v_ogm_send(struct work_struct *work)
++{
++      struct batadv_priv_bat_v *bat_v;
++      struct batadv_priv *bat_priv;
++
++      bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
++      bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
++
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
++      batadv_v_ogm_send_softif(bat_priv);
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
++}
++
++/**
+  * batadv_v_ogm_iface_enable() - prepare an interface for B.A.T.M.A.N. V
+  * @hard_iface: the interface to prepare
+  *
+@@ -261,11 +277,15 @@ void batadv_v_ogm_primary_iface_set(stru
+       struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
+       struct batadv_ogm2_packet *ogm_packet;
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
+       if (!bat_priv->bat_v.ogm_buff)
+-              return;
++              goto unlock;
+       ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
+       ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
++
++unlock:
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+ /**
+@@ -887,6 +907,8 @@ int batadv_v_ogm_init(struct batadv_priv
+       atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
+       INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
++      mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
++
+       return 0;
+ }
+@@ -898,7 +920,11 @@ void batadv_v_ogm_free(struct batadv_pri
+ {
+       cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
++
+       kfree(bat_priv->bat_v.ogm_buff);
+       bat_priv->bat_v.ogm_buff = NULL;
+       bat_priv->bat_v.ogm_buff_len = 0;
++
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -28,6 +28,7 @@
+ #include <linux/compiler.h>
+ #include <linux/if_ether.h>
+ #include <linux/kref.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/netlink.h>
+ #include <linux/sched.h> /* for linux/wait.h */
+@@ -1493,6 +1494,9 @@ struct batadv_priv_bat_v {
+       /** @ogm_seqno: OGM sequence number - used to identify each OGM */
+       atomic_t ogm_seqno;
++      /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
++      struct mutex ogm_buff_mutex;
++
+       /** @ogm_wq: workqueue used to schedule OGM transmissions */
+       struct delayed_work ogm_wq;
+ };
index 1ee8c47f59e985a213d00d7a2cb99b1b285ad406..452ec76cd43c33e86fed60d799bbf8616ac93e59 100644 (file)
@@ -86,3 +86,4 @@ ipv6-restrict-ipv6_addrform-operation.patch
 net-smc-check-for-valid-ib_client_data.patch
 net-smc-cancel-event-worker-during-device-removal.patch
 efi-add-a-sanity-check-to-efivar_store_raw.patch
+batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch