]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Mar 2020 10:16:01 +0000 (11:16 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Mar 2020 10:16:01 +0000 (11:16 +0100)
added patches:
batman-adv-always-initialize-fragment-header-priority.patch
batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch
batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch
batman-adv-avoid-race-in-tt-tvlv-allocator-helper.patch
batman-adv-avoid-spurious-warnings-from-bat_v-neigh_cmp-implementation.patch
batman-adv-don-t-schedule-ogm-for-disabled-interface.patch
batman-adv-fix-check-of-retrieved-orig_gw-in-batadv_v_gw_is_eligible.patch
batman-adv-fix-debugfs-path-for-renamed-hardif.patch
batman-adv-fix-debugfs-path-for-renamed-softif.patch
batman-adv-fix-duplicated-ogms-on-netdev_up.patch
batman-adv-fix-internal-interface-indices-types.patch
batman-adv-fix-lock-for-ogm-cnt-access-in-batadv_iv_ogm_calc_tq.patch
batman-adv-fix-tt-sync-flags-for-intermediate-tt-responses.patch
batman-adv-prevent-tt-request-storms-by-not-sending-inconsistent-tt-tlvls.patch
batman-adv-update-data-pointers-after-skb_cow.patch

16 files changed:
queue-4.14/batman-adv-always-initialize-fragment-header-priority.patch [new file with mode: 0644]
queue-4.14/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch [new file with mode: 0644]
queue-4.14/batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch [new file with mode: 0644]
queue-4.14/batman-adv-avoid-race-in-tt-tvlv-allocator-helper.patch [new file with mode: 0644]
queue-4.14/batman-adv-avoid-spurious-warnings-from-bat_v-neigh_cmp-implementation.patch [new file with mode: 0644]
queue-4.14/batman-adv-don-t-schedule-ogm-for-disabled-interface.patch [new file with mode: 0644]
queue-4.14/batman-adv-fix-check-of-retrieved-orig_gw-in-batadv_v_gw_is_eligible.patch [new file with mode: 0644]
queue-4.14/batman-adv-fix-debugfs-path-for-renamed-hardif.patch [new file with mode: 0644]
queue-4.14/batman-adv-fix-debugfs-path-for-renamed-softif.patch [new file with mode: 0644]
queue-4.14/batman-adv-fix-duplicated-ogms-on-netdev_up.patch [new file with mode: 0644]
queue-4.14/batman-adv-fix-internal-interface-indices-types.patch [new file with mode: 0644]
queue-4.14/batman-adv-fix-lock-for-ogm-cnt-access-in-batadv_iv_ogm_calc_tq.patch [new file with mode: 0644]
queue-4.14/batman-adv-fix-tt-sync-flags-for-intermediate-tt-responses.patch [new file with mode: 0644]
queue-4.14/batman-adv-prevent-tt-request-storms-by-not-sending-inconsistent-tt-tlvls.patch [new file with mode: 0644]
queue-4.14/batman-adv-update-data-pointers-after-skb_cow.patch [new file with mode: 0644]
queue-4.14/series

diff --git a/queue-4.14/batman-adv-always-initialize-fragment-header-priority.patch b/queue-4.14/batman-adv-always-initialize-fragment-header-priority.patch
new file mode 100644 (file)
index 0000000..5c9f2cc
--- /dev/null
@@ -0,0 +1,36 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:19 +0100
+Subject: batman-adv: Always initialize fragment header priority
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven.eckelmann@open-mesh.com>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-3-sven@narfation.org>
+
+From: Sven Eckelmann <sven.eckelmann@open-mesh.com>
+
+commit fe77d8257c4d838c5976557ddb87bd789f312412 upstream.
+
+The batman-adv unuicast fragment header contains 3 bits for the priority of
+the packet. These bits will be initialized when the skb->priority contains
+a value between 256 and 263. But otherwise, the uninitialized bits from the
+stack will be used.
+
+Fixes: c0f25c802b33 ("batman-adv: Include frame priority in fragment header")
+Signed-off-by: Sven Eckelmann <sven.eckelmann@open-mesh.com>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/fragmentation.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/batman-adv/fragmentation.c
++++ b/net/batman-adv/fragmentation.c
+@@ -500,6 +500,8 @@ int batadv_frag_send_packet(struct sk_bu
+        */
+       if (skb->priority >= 256 && skb->priority <= 263)
+               frag_header.priority = skb->priority - 256;
++      else
++              frag_header.priority = 0;
+       ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr);
+       ether_addr_copy(frag_header.dest, orig_node->orig);
diff --git a/queue-4.14/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch b/queue-4.14/batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch
new file mode 100644 (file)
index 0000000..6fb1c81
--- /dev/null
@@ -0,0 +1,205 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:31 +0100
+Subject: batman-adv: Avoid free/alloc race when handling OGM buffer
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-15-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 40e220b4218bb3d278e5e8cc04ccdfd1c7ff8307 upstream.
+
+Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM
+packet buffer which is initialized using data from 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/freed data is sent out or functions modifying the
+OGM buffer try to access already freed memory regions.
+
+Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com
+Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
+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_iv_ogm.c     |   60 ++++++++++++++++++++++++++++++++++------
+ net/batman-adv/hard-interface.c |    2 +
+ net/batman-adv/types.h          |    2 +
+ 3 files changed, 55 insertions(+), 9 deletions(-)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -34,6 +34,7 @@
+ #include <linux/kref.h>
+ #include <linux/list.h>
+ #include <linux/lockdep.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/netlink.h>
+ #include <linux/pkt_sched.h>
+@@ -370,14 +371,18 @@ static int batadv_iv_ogm_iface_enable(st
+       unsigned char *ogm_buff;
+       u32 random_seqno;
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
+       /* randomize initial seqno to avoid collision */
+       get_random_bytes(&random_seqno, sizeof(random_seqno));
+       atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
+       hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
+       ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
+-      if (!ogm_buff)
++      if (!ogm_buff) {
++              mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+               return -ENOMEM;
++      }
+       hard_iface->bat_iv.ogm_buff = ogm_buff;
+@@ -389,35 +394,59 @@ static int batadv_iv_ogm_iface_enable(st
+       batadv_ogm_packet->reserved = 0;
+       batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
++
+       return 0;
+ }
+ static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
+ {
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
+       kfree(hard_iface->bat_iv.ogm_buff);
+       hard_iface->bat_iv.ogm_buff = NULL;
++
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_ogm_packet *batadv_ogm_packet;
+-      unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      void *ogm_buff;
+-      batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
++      ogm_buff = hard_iface->bat_iv.ogm_buff;
++      if (!ogm_buff)
++              goto unlock;
++
++      batadv_ogm_packet = ogm_buff;
+       ether_addr_copy(batadv_ogm_packet->orig,
+                       hard_iface->net_dev->dev_addr);
+       ether_addr_copy(batadv_ogm_packet->prev_sender,
+                       hard_iface->net_dev->dev_addr);
++
++unlock:
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ static void
+ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_ogm_packet *batadv_ogm_packet;
+-      unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      void *ogm_buff;
+-      batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++
++      ogm_buff = hard_iface->bat_iv.ogm_buff;
++      if (!ogm_buff)
++              goto unlock;
++
++      batadv_ogm_packet = ogm_buff;
+       batadv_ogm_packet->ttl = BATADV_TTL;
++
++unlock:
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ /* when do we schedule our own ogm to be sent */
+@@ -915,7 +944,11 @@ batadv_iv_ogm_slide_own_bcast_window(str
+       }
+ }
+-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
++/**
++ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
++ * @hard_iface: interface whose ogm buffer should be transmitted
++ */
++static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
+@@ -926,9 +959,7 @@ static void batadv_iv_ogm_schedule(struc
+       u16 tvlv_len = 0;
+       unsigned long send_time;
+-      if ((hard_iface->if_status == BATADV_IF_NOT_IN_USE) ||
+-          (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED))
+-              return;
++      lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
+       /* the interface gets activated here to avoid race conditions between
+        * the moment of activating the interface in
+@@ -996,6 +1027,17 @@ out:
+               batadv_hardif_put(primary_if);
+ }
++static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
++{
++      if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
++          hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
++              return;
++
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++      batadv_iv_ogm_schedule_buff(hard_iface);
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
++}
++
+ /**
+  * batadv_iv_ogm_orig_update - use OGM to update corresponding data in an
+  *  originator
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -28,6 +28,7 @@
+ #include <linux/kernel.h>
+ #include <linux/kref.h>
+ #include <linux/list.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/printk.h>
+ #include <linux/rculist.h>
+@@ -901,6 +902,7 @@ batadv_hardif_add_interface(struct net_d
+       INIT_LIST_HEAD(&hard_iface->list);
+       INIT_HLIST_HEAD(&hard_iface->neigh_list);
++      mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
+       spin_lock_init(&hard_iface->neigh_list_lock);
+       kref_init(&hard_iface->refcount);
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -82,11 +82,13 @@ enum batadv_dhcp_recipient {
+  * @ogm_buff: buffer holding the OGM packet
+  * @ogm_buff_len: length of the OGM packet buffer
+  * @ogm_seqno: OGM sequence number - used to identify each OGM
++ * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len
+  */
+ struct batadv_hard_iface_bat_iv {
+       unsigned char *ogm_buff;
+       int ogm_buff_len;
+       atomic_t ogm_seqno;
++      struct mutex ogm_buff_mutex;
+ };
+ /**
diff --git a/queue-4.14/batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch b/queue-4.14/batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch
new file mode 100644 (file)
index 0000000..3cf698d
--- /dev/null
@@ -0,0 +1,158 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:30 +0100
+Subject: batman-adv: Avoid free/alloc race when handling OGM2 buffer
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-14-sven@narfation.org>
+
+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     |    3 +++
+ 2 files changed, 37 insertions(+), 8 deletions(-)
+
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -28,6 +28,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>
+@@ -127,14 +129,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;
+@@ -142,8 +142,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;
+@@ -235,6 +234,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
+  *
+@@ -260,11 +276,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);
+ }
+ /**
+@@ -886,6 +906,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;
+ }
+@@ -897,7 +919,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
+@@ -27,6 +27,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 */
+@@ -989,12 +990,14 @@ struct batadv_softif_vlan {
+  * @ogm_buff: buffer holding the OGM packet
+  * @ogm_buff_len: length of the OGM packet buffer
+  * @ogm_seqno: OGM sequence number - used to identify each OGM
++ * @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len
+  * @ogm_wq: workqueue used to schedule OGM transmissions
+  */
+ struct batadv_priv_bat_v {
+       unsigned char *ogm_buff;
+       int ogm_buff_len;
+       atomic_t ogm_seqno;
++      struct mutex ogm_buff_mutex;
+       struct delayed_work ogm_wq;
+ };
diff --git a/queue-4.14/batman-adv-avoid-race-in-tt-tvlv-allocator-helper.patch b/queue-4.14/batman-adv-avoid-race-in-tt-tvlv-allocator-helper.patch
new file mode 100644 (file)
index 0000000..2911f28
--- /dev/null
@@ -0,0 +1,81 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:24 +0100
+Subject: batman-adv: Avoid race in TT TVLV allocator helper
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, Antonio Quartulli <a@unstable.cc>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-8-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 8ba0f9bd3bdea1058c2b2676bec7905724418e40 upstream.
+
+The functions batadv_tt_prepare_tvlv_local_data and
+batadv_tt_prepare_tvlv_global_data are responsible for preparing a buffer
+which can be used to store the TVLV container for TT and add the VLAN
+information to it.
+
+This will be done in three phases:
+
+1. count the number of VLANs and their entries
+2. allocate the buffer using the counters from the previous step and limits
+   from the caller (parameter tt_len)
+3. insert the VLAN information to the buffer
+
+The step 1 and 3 operate on a list which contains the VLANs. The access to
+these lists must be protected with an appropriate lock or otherwise they
+might operate on on different entries. This could for example happen when
+another context is adding VLAN entries to this list.
+
+This could lead to a buffer overflow in these functions when enough entries
+were added between step 1 and 3 to the VLAN lists that the buffer room for
+the entries (*tt_change) is smaller then the now required extra buffer for
+new VLAN entries.
+
+Fixes: 7ea7b4a14275 ("batman-adv: make the TT CRC logic VLAN specific")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Acked-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/translation-table.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -872,7 +872,7 @@ batadv_tt_prepare_tvlv_global_data(struc
+       struct batadv_orig_node_vlan *vlan;
+       u8 *tt_change_ptr;
+-      rcu_read_lock();
++      spin_lock_bh(&orig_node->vlan_list_lock);
+       hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
+               num_vlan++;
+               num_entries += atomic_read(&vlan->tt.num_entries);
+@@ -910,7 +910,7 @@ batadv_tt_prepare_tvlv_global_data(struc
+       *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
+ out:
+-      rcu_read_unlock();
++      spin_unlock_bh(&orig_node->vlan_list_lock);
+       return tvlv_len;
+ }
+@@ -946,7 +946,7 @@ batadv_tt_prepare_tvlv_local_data(struct
+       u8 *tt_change_ptr;
+       int change_offset;
+-      rcu_read_lock();
++      spin_lock_bh(&bat_priv->softif_vlan_list_lock);
+       hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+               num_vlan++;
+               num_entries += atomic_read(&vlan->tt.num_entries);
+@@ -984,7 +984,7 @@ batadv_tt_prepare_tvlv_local_data(struct
+       *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
+ out:
+-      rcu_read_unlock();
++      spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
+       return tvlv_len;
+ }
diff --git a/queue-4.14/batman-adv-avoid-spurious-warnings-from-bat_v-neigh_cmp-implementation.patch b/queue-4.14/batman-adv-avoid-spurious-warnings-from-bat_v-neigh_cmp-implementation.patch
new file mode 100644 (file)
index 0000000..afbde0b
--- /dev/null
@@ -0,0 +1,69 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:18 +0100
+Subject: batman-adv: Avoid spurious warnings from bat_v neigh_cmp implementation
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven.eckelmann@openmesh.com>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-2-sven@narfation.org>
+
+From: Sven Eckelmann <sven.eckelmann@openmesh.com>
+
+commit 6a4bc44b012cbc29c9d824be2c7ab9eac8ee6b6f upstream.
+
+The neighbor compare API implementation for B.A.T.M.A.N. V checks whether
+the neigh_ifinfo for this neighbor on a specific interface exists. A
+warning is printed when it isn't found.
+
+But it is not called inside a lock which would prevent that this
+information is lost right before batadv_neigh_ifinfo_get. It must therefore
+be expected that batadv_v_neigh_(cmp|is_sob) might not be able to get the
+requested neigh_ifinfo.
+
+A WARN_ON for such a situation seems not to be appropriate because this
+will only flood the kernel logs. The warnings must therefore be removed.
+
+Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/bat_v.c |    9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/net/batman-adv/bat_v.c
++++ b/net/batman-adv/bat_v.c
+@@ -19,7 +19,6 @@
+ #include "main.h"
+ #include <linux/atomic.h>
+-#include <linux/bug.h>
+ #include <linux/cache.h>
+ #include <linux/errno.h>
+ #include <linux/if_ether.h>
+@@ -623,11 +622,11 @@ static int batadv_v_neigh_cmp(struct bat
+       int ret = 0;
+       ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
+-      if (WARN_ON(!ifinfo1))
++      if (!ifinfo1)
+               goto err_ifinfo1;
+       ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+-      if (WARN_ON(!ifinfo2))
++      if (!ifinfo2)
+               goto err_ifinfo2;
+       ret = ifinfo1->bat_v.throughput - ifinfo2->bat_v.throughput;
+@@ -649,11 +648,11 @@ static bool batadv_v_neigh_is_sob(struct
+       bool ret = false;
+       ifinfo1 = batadv_neigh_ifinfo_get(neigh1, if_outgoing1);
+-      if (WARN_ON(!ifinfo1))
++      if (!ifinfo1)
+               goto err_ifinfo1;
+       ifinfo2 = batadv_neigh_ifinfo_get(neigh2, if_outgoing2);
+-      if (WARN_ON(!ifinfo2))
++      if (!ifinfo2)
+               goto err_ifinfo2;
+       threshold = ifinfo1->bat_v.throughput / 4;
diff --git a/queue-4.14/batman-adv-don-t-schedule-ogm-for-disabled-interface.patch b/queue-4.14/batman-adv-don-t-schedule-ogm-for-disabled-interface.patch
new file mode 100644 (file)
index 0000000..08d5d0d
--- /dev/null
@@ -0,0 +1,45 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:32 +0100
+Subject: batman-adv: Don't schedule OGM for disabled interface
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, syzbot+a98f2016f40b9cd3818a@syzkaller.appspotmail.com, syzbot+ac36b6a33c28a491e929@syzkaller.appspotmail.com, Hillf Danton <hdanton@sina.com>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-16-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 8e8ce08198de193e3d21d42e96945216e3d9ac7f upstream.
+
+A transmission scheduling for an interface which is currently dropped by
+batadv_iv_ogm_iface_disable could still be in progress. The B.A.T.M.A.N. V
+is simply cancelling the workqueue item in an synchronous way but this is
+not possible with B.A.T.M.A.N. IV because the OGM submissions are
+intertwined.
+
+Instead it has to stop submitting the OGM when it detect that the buffer
+pointer is set to NULL.
+
+Reported-by: syzbot+a98f2016f40b9cd3818a@syzkaller.appspotmail.com
+Reported-by: syzbot+ac36b6a33c28a491e929@syzkaller.appspotmail.com
+Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Cc: Hillf Danton <hdanton@sina.com>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/bat_iv_ogm.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -961,6 +961,10 @@ static void batadv_iv_ogm_schedule_buff(
+       lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
++      /* interface already disabled by batadv_iv_ogm_iface_disable */
++      if (!*ogm_buff)
++              return;
++
+       /* the interface gets activated here to avoid race conditions between
+        * the moment of activating the interface in
+        * hardif_activate_interface() where the originator mac is set and
diff --git a/queue-4.14/batman-adv-fix-check-of-retrieved-orig_gw-in-batadv_v_gw_is_eligible.patch b/queue-4.14/batman-adv-fix-check-of-retrieved-orig_gw-in-batadv_v_gw_is_eligible.patch
new file mode 100644 (file)
index 0000000..986f365
--- /dev/null
@@ -0,0 +1,37 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:20 +0100
+Subject: batman-adv: Fix check of retrieved orig_gw in batadv_v_gw_is_eligible
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven.eckelmann@openmesh.com>, Antonio Quartulli <a@unstable.cc>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-4-sven@narfation.org>
+
+From: Sven Eckelmann <sven.eckelmann@openmesh.com>
+
+commit 198a62ddffa4a4ffaeb741f642b7b52f2d91ae9b upstream.
+
+The batadv_v_gw_is_eligible function already assumes that orig_node is not
+NULL. But batadv_gw_node_get may have failed to find the originator. It
+must therefore be checked whether the batadv_gw_node_get failed and not
+whether orig_node is NULL to detect this error.
+
+Fixes: 50164d8f500f ("batman-adv: B.A.T.M.A.N. V - implement GW selection logic")
+Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
+Acked-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/bat_v.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/batman-adv/bat_v.c
++++ b/net/batman-adv/bat_v.c
+@@ -814,7 +814,7 @@ static bool batadv_v_gw_is_eligible(stru
+       }
+       orig_gw = batadv_gw_node_get(bat_priv, orig_node);
+-      if (!orig_node)
++      if (!orig_gw)
+               goto out;
+       if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0)
diff --git a/queue-4.14/batman-adv-fix-debugfs-path-for-renamed-hardif.patch b/queue-4.14/batman-adv-fix-debugfs-path-for-renamed-hardif.patch
new file mode 100644 (file)
index 0000000..8bf6828
--- /dev/null
@@ -0,0 +1,115 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:27 +0100
+Subject: batman-adv: Fix debugfs path for renamed hardif
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, John Soros <sorosj@gmail.com>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-11-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 36dc621ceca1be3ec885aeade5fdafbbcc452a6d upstream.
+
+batman-adv is creating special debugfs directories in the init
+net_namespace for each valid hard-interface (net_device). But it is
+possible to rename a net_device to a completely different name then the
+original one.
+
+It can therefore happen that a user registers a new net_device which gets
+the name "wlan0" assigned by default. batman-adv is also adding a new
+directory under $debugfs/batman-adv/ with the name "wlan0".
+
+The user then decides to rename this device to "wl_pri" and registers a
+different device. The kernel may now decide to use the name "wlan0" again
+for this new device. batman-adv will detect it as a valid net_device and
+tries to create a directory with the name "wlan0" under
+$debugfs/batman-adv/. But there already exists one with this name under
+this path and thus this fails. batman-adv will detect a problem and
+rollback the registering of this device.
+
+batman-adv must therefore take care of renaming the debugfs directories
+for hard-interfaces whenever it detects such a net_device rename.
+
+Fixes: 5bc7c1eb44f2 ("batman-adv: add debugfs structure for information per interface")
+Reported-by: John Soros <sorosj@gmail.com>
+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/debugfs.c        |   22 +++++++++++++++++++++-
+ net/batman-adv/debugfs.h        |    6 ++++++
+ net/batman-adv/hard-interface.c |    3 +++
+ 3 files changed, 30 insertions(+), 1 deletion(-)
+
+--- a/net/batman-adv/debugfs.c
++++ b/net/batman-adv/debugfs.c
+@@ -18,6 +18,7 @@
+ #include "debugfs.h"
+ #include "main.h"
++#include <linux/dcache.h>
+ #include <linux/debugfs.h>
+ #include <linux/err.h>
+ #include <linux/errno.h>
+@@ -338,7 +339,26 @@ out:
+ }
+ /**
+- * batadv_debugfs_del_hardif - delete the base directory for a hard interface
++ * batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif
++ * @hard_iface: hard interface which was renamed
++ */
++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
++{
++      const char *name = hard_iface->net_dev->name;
++      struct dentry *dir;
++      struct dentry *d;
++
++      dir = hard_iface->debug_dir;
++      if (!dir)
++              return;
++
++      d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
++      if (!d)
++              pr_err("Can't rename debugfs dir to %s\n", name);
++}
++
++/**
++ * batadv_debugfs_del_hardif() - delete the base directory for a hard interface
+  *  in debugfs.
+  * @hard_iface: hard interface which is deleted.
+  */
+--- a/net/batman-adv/debugfs.h
++++ b/net/batman-adv/debugfs.h
+@@ -31,6 +31,7 @@ void batadv_debugfs_destroy(void);
+ int batadv_debugfs_add_meshif(struct net_device *dev);
+ void batadv_debugfs_del_meshif(struct net_device *dev);
+ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface);
++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface);
+ void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface);
+ #else
+@@ -59,6 +60,11 @@ int batadv_debugfs_add_hardif(struct bat
+ }
+ static inline
++void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
++{
++}
++
++static inline
+ void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface)
+ {
+ }
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -1017,6 +1017,9 @@ static int batadv_hard_if_event(struct n
+               if (batadv_is_wifi_hardif(hard_iface))
+                       hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
+               break;
++      case NETDEV_CHANGENAME:
++              batadv_debugfs_rename_hardif(hard_iface);
++              break;
+       default:
+               break;
+       }
diff --git a/queue-4.14/batman-adv-fix-debugfs-path-for-renamed-softif.patch b/queue-4.14/batman-adv-fix-debugfs-path-for-renamed-softif.patch
new file mode 100644 (file)
index 0000000..9de1367
--- /dev/null
@@ -0,0 +1,145 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:28 +0100
+Subject: batman-adv: Fix debugfs path for renamed softif
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-12-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 6da7be7d24b2921f8215473ba7552796dff05fe1 upstream.
+
+batman-adv is creating special debugfs directories in the init
+net_namespace for each created soft-interface (batadv net_device). But it
+is possible to rename a net_device to a completely different name then the
+original one.
+
+It can therefore happen that a user registers a new batadv net_device with
+the name "bat0". batman-adv is then also adding a new directory under
+$debugfs/batman-adv/ with the name "wlan0".
+
+The user then decides to rename this device to "bat1" and registers a
+different batadv device with the name "bat0". batman-adv will then try to
+create a directory with the name "bat0" under $debugfs/batman-adv/ again.
+But there already exists one with this name under this path and thus this
+fails. batman-adv will detect a problem and rollback the registering of
+this device.
+
+batman-adv must therefore take care of renaming the debugfs directories for
+soft-interfaces whenever it detects such a net_device rename.
+
+Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
+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/debugfs.c        |   24 ++++++++++++++++++++++++
+ net/batman-adv/debugfs.h        |    5 +++++
+ net/batman-adv/hard-interface.c |   34 ++++++++++++++++++++++++++++------
+ 3 files changed, 57 insertions(+), 6 deletions(-)
+
+--- a/net/batman-adv/debugfs.c
++++ b/net/batman-adv/debugfs.c
+@@ -421,6 +421,30 @@ out:
+       return -ENOMEM;
+ }
++/**
++ * batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif
++ * @dev: net_device which was renamed
++ */
++void batadv_debugfs_rename_meshif(struct net_device *dev)
++{
++      struct batadv_priv *bat_priv = netdev_priv(dev);
++      const char *name = dev->name;
++      struct dentry *dir;
++      struct dentry *d;
++
++      dir = bat_priv->debug_dir;
++      if (!dir)
++              return;
++
++      d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
++      if (!d)
++              pr_err("Can't rename debugfs dir to %s\n", name);
++}
++
++/**
++ * batadv_debugfs_del_meshif() - Remove interface dependent debugfs entries
++ * @dev: netdev struct of the soft interface
++ */
+ void batadv_debugfs_del_meshif(struct net_device *dev)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(dev);
+--- a/net/batman-adv/debugfs.h
++++ b/net/batman-adv/debugfs.h
+@@ -29,6 +29,7 @@ struct net_device;
+ void batadv_debugfs_init(void);
+ void batadv_debugfs_destroy(void);
+ int batadv_debugfs_add_meshif(struct net_device *dev);
++void batadv_debugfs_rename_meshif(struct net_device *dev);
+ void batadv_debugfs_del_meshif(struct net_device *dev);
+ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface);
+ void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface);
+@@ -49,6 +50,10 @@ static inline int batadv_debugfs_add_mes
+       return 0;
+ }
++static inline void batadv_debugfs_rename_meshif(struct net_device *dev)
++{
++}
++
+ static inline void batadv_debugfs_del_meshif(struct net_device *dev)
+ {
+ }
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -955,6 +955,32 @@ void batadv_hardif_remove_interfaces(voi
+       rtnl_unlock();
+ }
++/**
++ * batadv_hard_if_event_softif() - Handle events for soft interfaces
++ * @event: NETDEV_* event to handle
++ * @net_dev: net_device which generated an event
++ *
++ * Return: NOTIFY_* result
++ */
++static int batadv_hard_if_event_softif(unsigned long event,
++                                     struct net_device *net_dev)
++{
++      struct batadv_priv *bat_priv;
++
++      switch (event) {
++      case NETDEV_REGISTER:
++              batadv_sysfs_add_meshif(net_dev);
++              bat_priv = netdev_priv(net_dev);
++              batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
++              break;
++      case NETDEV_CHANGENAME:
++              batadv_debugfs_rename_meshif(net_dev);
++              break;
++      }
++
++      return NOTIFY_DONE;
++}
++
+ static int batadv_hard_if_event(struct notifier_block *this,
+                               unsigned long event, void *ptr)
+ {
+@@ -963,12 +989,8 @@ static int batadv_hard_if_event(struct n
+       struct batadv_hard_iface *primary_if = NULL;
+       struct batadv_priv *bat_priv;
+-      if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
+-              batadv_sysfs_add_meshif(net_dev);
+-              bat_priv = netdev_priv(net_dev);
+-              batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
+-              return NOTIFY_DONE;
+-      }
++      if (batadv_softif_is_valid(net_dev))
++              return batadv_hard_if_event_softif(event, net_dev);
+       hard_iface = batadv_hardif_get_by_netdev(net_dev);
+       if (!hard_iface && (event == NETDEV_REGISTER ||
diff --git a/queue-4.14/batman-adv-fix-duplicated-ogms-on-netdev_up.patch b/queue-4.14/batman-adv-fix-duplicated-ogms-on-netdev_up.patch
new file mode 100644 (file)
index 0000000..3e9f0ef
--- /dev/null
@@ -0,0 +1,92 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:29 +0100
+Subject: batman-adv: Fix duplicated OGMs on NETDEV_UP
+To: stable@vger.kernel.org
+Cc: "Sven Eckelmann" <sven@narfation.org>, "Linus Lüssing" <linus.luessing@c0d3.blue>, "Marek Lindner" <mareklindner@neomailbox.ch>, "Simon Wunderlich" <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-13-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 9e6b5648bbc4cd48fab62cecbb81e9cc3c6e7e88 upstream.
+
+The state of slave interfaces are handled differently depending on whether
+the interface is up or not. All active interfaces (IFF_UP) will transmit
+OGMs. But for B.A.T.M.A.N. IV, also non-active interfaces are scheduling
+(low TTL) OGMs on active interfaces. The code which setups and schedules
+the OGMs must therefore already be called when the interfaces gets added as
+slave interface and the transmit function must then check whether it has to
+send out the OGM or not on the specific slave interface.
+
+But the commit f0d97253fb5f ("batman-adv: remove ogm_emit and ogm_schedule
+API calls") moved the setup code from the enable function to the activate
+function. The latter is called either when the added slave was already up
+when batadv_hardif_enable_interface processed the new interface or when a
+NETDEV_UP event was received for this slave interfac. As result, each
+NETDEV_UP would schedule a new OGM worker for the interface and thus OGMs
+would be send a lot more than expected.
+
+Fixes: f0d97253fb5f ("batman-adv: remove ogm_emit and ogm_schedule API calls")
+Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Tested-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Acked-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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/bat_iv_ogm.c     |    4 ++--
+ net/batman-adv/hard-interface.c |    3 +++
+ net/batman-adv/types.h          |    2 ++
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -2481,7 +2481,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv
+       return ret;
+ }
+-static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
++static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
+ {
+       /* begin scheduling originator messages on that interface */
+       batadv_iv_ogm_schedule(hard_iface);
+@@ -2821,8 +2821,8 @@ unlock:
+ static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
+       .name = "BATMAN_IV",
+       .iface = {
+-              .activate = batadv_iv_iface_activate,
+               .enable = batadv_iv_ogm_iface_enable,
++              .enabled = batadv_iv_iface_enabled,
+               .disable = batadv_iv_ogm_iface_disable,
+               .update_mac = batadv_iv_ogm_iface_update_mac,
+               .primary_set = batadv_iv_ogm_primary_iface_set,
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -795,6 +795,9 @@ int batadv_hardif_enable_interface(struc
+       batadv_hardif_recalc_extra_skbroom(soft_iface);
++      if (bat_priv->algo_ops->iface.enabled)
++              bat_priv->algo_ops->iface.enabled(hard_iface);
++
+ out:
+       return 0;
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -1424,6 +1424,7 @@ struct batadv_forw_packet {
+  * @activate: start routing mechanisms when hard-interface is brought up
+  *  (optional)
+  * @enable: init routing info when hard-interface is enabled
++ * @enabled: notification when hard-interface was enabled (optional)
+  * @disable: de-init routing info when hard-interface is disabled
+  * @update_mac: (re-)init mac addresses of the protocol information
+  *  belonging to this hard-interface
+@@ -1432,6 +1433,7 @@ struct batadv_forw_packet {
+ struct batadv_algo_iface_ops {
+       void (*activate)(struct batadv_hard_iface *hard_iface);
+       int (*enable)(struct batadv_hard_iface *hard_iface);
++      void (*enabled)(struct batadv_hard_iface *hard_iface);
+       void (*disable)(struct batadv_hard_iface *hard_iface);
+       void (*update_mac)(struct batadv_hard_iface *hard_iface);
+       void (*primary_set)(struct batadv_hard_iface *hard_iface);
diff --git a/queue-4.14/batman-adv-fix-internal-interface-indices-types.patch b/queue-4.14/batman-adv-fix-internal-interface-indices-types.patch
new file mode 100644 (file)
index 0000000..5a9e5d0
--- /dev/null
@@ -0,0 +1,237 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:22 +0100
+Subject: batman-adv: Fix internal interface indices types
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-6-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit f22e08932c2960f29b5e828e745c9f3fb7c1bb86 upstream.
+
+batman-adv uses internal indices for each enabled and active interface.
+It is currently used by the B.A.T.M.A.N. IV algorithm to identifify the
+correct position in the ogm_cnt bitmaps.
+
+The type for the number of enabled interfaces (which defines the next
+interface index) was set to char. This type can be (depending on the
+architecture) either signed (limiting batman-adv to 127 active slave
+interfaces) or unsigned (limiting batman-adv to 255 active slave
+interfaces).
+
+This limit was not correctly checked when an interface was enabled and thus
+an overflow happened. This was only catched on systems with the signed char
+type when the B.A.T.M.A.N. IV code tried to resize its counter arrays with
+a negative size.
+
+The if_num interface index was only a s16 and therefore significantly
+smaller than the ifindex (int) used by the code net code.
+
+Both &batadv_hard_iface->if_num and &batadv_priv->num_ifaces must be
+(unsigned) int to support the same number of slave interfaces as the net
+core code. And the interface activation code must check the number of
+active slave interfaces to avoid integer overflows.
+
+Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
+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_iv_ogm.c     |   24 ++++++++++++++----------
+ net/batman-adv/hard-interface.c |    9 +++++++--
+ net/batman-adv/originator.c     |    4 ++--
+ net/batman-adv/originator.h     |    4 ++--
+ net/batman-adv/types.h          |   11 ++++++-----
+ 5 files changed, 31 insertions(+), 21 deletions(-)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -149,7 +149,7 @@ static void batadv_iv_ogm_orig_free(stru
+  * Return: 0 on success, a negative error code otherwise.
+  */
+ static int batadv_iv_ogm_orig_add_if(struct batadv_orig_node *orig_node,
+-                                   int max_if_num)
++                                   unsigned int max_if_num)
+ {
+       void *data_ptr;
+       size_t old_size;
+@@ -193,7 +193,8 @@ unlock:
+  */
+ static void
+ batadv_iv_ogm_drop_bcast_own_entry(struct batadv_orig_node *orig_node,
+-                                 int max_if_num, int del_if_num)
++                                 unsigned int max_if_num,
++                                 unsigned int del_if_num)
+ {
+       size_t chunk_size;
+       size_t if_offset;
+@@ -231,7 +232,8 @@ batadv_iv_ogm_drop_bcast_own_entry(struc
+  */
+ static void
+ batadv_iv_ogm_drop_bcast_own_sum_entry(struct batadv_orig_node *orig_node,
+-                                     int max_if_num, int del_if_num)
++                                     unsigned int max_if_num,
++                                     unsigned int del_if_num)
+ {
+       size_t if_offset;
+       void *data_ptr;
+@@ -268,7 +270,8 @@ batadv_iv_ogm_drop_bcast_own_sum_entry(s
+  * Return: 0 on success, a negative error code otherwise.
+  */
+ static int batadv_iv_ogm_orig_del_if(struct batadv_orig_node *orig_node,
+-                                   int max_if_num, int del_if_num)
++                                   unsigned int max_if_num,
++                                   unsigned int del_if_num)
+ {
+       spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
+@@ -302,7 +305,8 @@ static struct batadv_orig_node *
+ batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
+ {
+       struct batadv_orig_node *orig_node;
+-      int size, hash_added;
++      int hash_added;
++      size_t size;
+       orig_node = batadv_orig_hash_find(bat_priv, addr);
+       if (orig_node)
+@@ -890,7 +894,7 @@ batadv_iv_ogm_slide_own_bcast_window(str
+       u32 i;
+       size_t word_index;
+       u8 *w;
+-      int if_num;
++      unsigned int if_num;
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+@@ -1020,7 +1024,7 @@ batadv_iv_ogm_orig_update(struct batadv_
+       struct batadv_neigh_node *tmp_neigh_node = NULL;
+       struct batadv_neigh_node *router = NULL;
+       struct batadv_orig_node *orig_node_tmp;
+-      int if_num;
++      unsigned int if_num;
+       u8 sum_orig, sum_neigh;
+       u8 *neigh_addr;
+       u8 tq_avg;
+@@ -1179,7 +1183,7 @@ static bool batadv_iv_ogm_calc_tq(struct
+       u8 total_count;
+       u8 orig_eq_count, neigh_rq_count, neigh_rq_inv, tq_own;
+       unsigned int neigh_rq_inv_cube, neigh_rq_max_cube;
+-      int if_num;
++      unsigned int if_num;
+       unsigned int tq_asym_penalty, inv_asym_penalty;
+       unsigned int combined_tq;
+       unsigned int tq_iface_penalty;
+@@ -1698,9 +1702,9 @@ static void batadv_iv_ogm_process(const
+       if (is_my_orig) {
+               unsigned long *word;
+-              int offset;
++              size_t offset;
+               s32 bit_pos;
+-              s16 if_num;
++              unsigned int if_num;
+               u8 *weight;
+               orig_neigh_node = batadv_iv_ogm_orig_get(bat_priv,
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -738,6 +738,11 @@ int batadv_hardif_enable_interface(struc
+       hard_iface->soft_iface = soft_iface;
+       bat_priv = netdev_priv(hard_iface->soft_iface);
++      if (bat_priv->num_ifaces >= UINT_MAX) {
++              ret = -ENOSPC;
++              goto err_dev;
++      }
++
+       ret = netdev_master_upper_dev_link(hard_iface->net_dev,
+                                          soft_iface, NULL, NULL);
+       if (ret)
+@@ -845,7 +850,7 @@ void batadv_hardif_disable_interface(str
+       batadv_hardif_recalc_extra_skbroom(hard_iface->soft_iface);
+       /* nobody uses this interface anymore */
+-      if (!bat_priv->num_ifaces) {
++      if (bat_priv->num_ifaces == 0) {
+               batadv_gw_check_client_stop(bat_priv);
+               if (autodel == BATADV_IF_CLEANUP_AUTO)
+@@ -881,7 +886,7 @@ batadv_hardif_add_interface(struct net_d
+       if (ret)
+               goto free_if;
+-      hard_iface->if_num = -1;
++      hard_iface->if_num = 0;
+       hard_iface->net_dev = net_dev;
+       hard_iface->soft_iface = NULL;
+       hard_iface->if_status = BATADV_IF_NOT_IN_USE;
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -1500,7 +1500,7 @@ int batadv_orig_dump(struct sk_buff *msg
+ }
+ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num)
++                          unsigned int max_if_num)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_algo_ops *bao = bat_priv->algo_ops;
+@@ -1535,7 +1535,7 @@ err:
+ }
+ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num)
++                          unsigned int max_if_num)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       struct batadv_hashtable *hash = bat_priv->orig_hash;
+--- a/net/batman-adv/originator.h
++++ b/net/batman-adv/originator.h
+@@ -78,9 +78,9 @@ int batadv_orig_seq_print_text(struct se
+ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
+ int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
+ int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num);
++                          unsigned int max_if_num);
+ int batadv_orig_hash_del_if(struct batadv_hard_iface *hard_iface,
+-                          int max_if_num);
++                          unsigned int max_if_num);
+ struct batadv_orig_node_vlan *
+ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node,
+                         unsigned short vid);
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -155,7 +155,7 @@ enum batadv_hard_iface_wifi_flags {
+  */
+ struct batadv_hard_iface {
+       struct list_head list;
+-      s16 if_num;
++      unsigned int if_num;
+       char if_status;
+       u8 num_bcasts;
+       u32 wifi_flags;
+@@ -1081,7 +1081,7 @@ struct batadv_priv {
+       atomic_t bcast_seqno;
+       atomic_t bcast_queue_left;
+       atomic_t batman_queue_left;
+-      char num_ifaces;
++      unsigned int num_ifaces;
+       struct kobject *mesh_obj;
+       struct dentry *debug_dir;
+       struct hlist_head forw_bat_list;
+@@ -1479,9 +1479,10 @@ struct batadv_algo_neigh_ops {
+  */
+ struct batadv_algo_orig_ops {
+       void (*free)(struct batadv_orig_node *orig_node);
+-      int (*add_if)(struct batadv_orig_node *orig_node, int max_if_num);
+-      int (*del_if)(struct batadv_orig_node *orig_node, int max_if_num,
+-                    int del_if_num);
++      int (*add_if)(struct batadv_orig_node *orig_node,
++                    unsigned int max_if_num);
++      int (*del_if)(struct batadv_orig_node *orig_node,
++                    unsigned int max_if_num, unsigned int del_if_num);
+ #ifdef CONFIG_BATMAN_ADV_DEBUGFS
+       void (*print)(struct batadv_priv *priv, struct seq_file *seq,
+                     struct batadv_hard_iface *hard_iface);
diff --git a/queue-4.14/batman-adv-fix-lock-for-ogm-cnt-access-in-batadv_iv_ogm_calc_tq.patch b/queue-4.14/batman-adv-fix-lock-for-ogm-cnt-access-in-batadv_iv_ogm_calc_tq.patch
new file mode 100644 (file)
index 0000000..68df5b1
--- /dev/null
@@ -0,0 +1,47 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:21 +0100
+Subject: batman-adv: Fix lock for ogm cnt access in batadv_iv_ogm_calc_tq
+To: stable@vger.kernel.org
+Cc: Sven Eckelmann <sven@narfation.org>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-5-sven@narfation.org>
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 5ba7dcfe77037b67016263ea597a8b431692ecab upstream.
+
+The originator node object orig_neigh_node is used to when accessing the
+bcast_own(_sum) and real_packet_count information. The access to them has
+to be protected with the spinlock in orig_neigh_node.
+
+But the function uses the lock in orig_node instead. This is incorrect
+because they could be two different originator node objects.
+
+Fixes: 0ede9f41b217 ("batman-adv: protect bit operations to count OGMs with spinlock")
+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_iv_ogm.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -1220,7 +1220,7 @@ static bool batadv_iv_ogm_calc_tq(struct
+       orig_node->last_seen = jiffies;
+       /* find packet count of corresponding one hop neighbor */
+-      spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock);
++      spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
+       if_num = if_incoming->if_num;
+       orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num];
+       neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing);
+@@ -1230,7 +1230,7 @@ static bool batadv_iv_ogm_calc_tq(struct
+       } else {
+               neigh_rq_count = 0;
+       }
+-      spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock);
++      spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock);
+       /* pay attention to not get a value bigger than 100 % */
+       if (orig_eq_count > neigh_rq_count)
diff --git a/queue-4.14/batman-adv-fix-tt-sync-flags-for-intermediate-tt-responses.patch b/queue-4.14/batman-adv-fix-tt-sync-flags-for-intermediate-tt-responses.patch
new file mode 100644 (file)
index 0000000..a31af64
--- /dev/null
@@ -0,0 +1,187 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:25 +0100
+Subject: batman-adv: Fix TT sync flags for intermediate TT responses
+To: stable@vger.kernel.org
+Cc: "Linus Lüssing" <linus.luessing@c0d3.blue>, "Leonardo Mörlein" <me@irrelefant.net>, "Sven Eckelmann" <sven@narfation.org>, "Simon Wunderlich" <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-9-sven@narfation.org>
+
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+
+commit 7072337e52b3e9d5460500d8dc9cbc1ba2db084c upstream.
+
+The previous TT sync fix so far only fixed TT responses issued by the
+target node directly. So far, TT responses issued by intermediate nodes
+still lead to the wrong flags being added, leading to CRC mismatches.
+
+This behaviour was observed at Freifunk Hannover in a 800 nodes setup
+where a considerable amount of nodes were still infected with 'WI'
+TT flags even with (most) nodes having the previous TT sync fix applied.
+
+I was able to reproduce the issue with intermediate TT responses in a
+four node test setup and this patch fixes this issue by ensuring to
+use the per originator instead of the summarized, OR'd ones.
+
+Fixes: e9c00136a475 ("batman-adv: fix tt_global_entries flags update")
+Reported-by: Leonardo Mörlein <me@irrelefant.net>
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+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/translation-table.c |   61 ++++++++++++++++++++++++++++++-------
+ 1 file changed, 51 insertions(+), 10 deletions(-)
+
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -1544,6 +1544,8 @@ batadv_tt_global_orig_entry_find(const s
+  *  by a given originator
+  * @entry: the TT global entry to check
+  * @orig_node: the originator to search in the list
++ * @flags: a pointer to store TT flags for the given @entry received
++ *  from @orig_node
+  *
+  * find out if an orig_node is already in the list of a tt_global_entry.
+  *
+@@ -1551,7 +1553,8 @@ batadv_tt_global_orig_entry_find(const s
+  */
+ static bool
+ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
+-                              const struct batadv_orig_node *orig_node)
++                              const struct batadv_orig_node *orig_node,
++                              u8 *flags)
+ {
+       struct batadv_tt_orig_list_entry *orig_entry;
+       bool found = false;
+@@ -1559,6 +1562,10 @@ batadv_tt_global_entry_has_orig(const st
+       orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
+       if (orig_entry) {
+               found = true;
++
++              if (flags)
++                      *flags = orig_entry->flags;
++
+               batadv_tt_orig_list_entry_put(orig_entry);
+       }
+@@ -1741,7 +1748,7 @@ static bool batadv_tt_global_add(struct
+                       if (!(common->flags & BATADV_TT_CLIENT_TEMP))
+                               goto out;
+                       if (batadv_tt_global_entry_has_orig(tt_global_entry,
+-                                                          orig_node))
++                                                          orig_node, NULL))
+                               goto out_remove;
+                       batadv_tt_global_del_orig_list(tt_global_entry);
+                       goto add_orig_entry;
+@@ -2884,23 +2891,46 @@ unlock:
+ }
+ /**
+- * batadv_tt_local_valid - verify that given tt entry is a valid one
++ * batadv_tt_local_valid() - verify local tt entry and get flags
+  * @entry_ptr: to be checked local tt entry
+  * @data_ptr: not used but definition required to satisfy the callback prototype
++ * @flags: a pointer to store TT flags for this client to
++ *
++ * Checks the validity of the given local TT entry. If it is, then the provided
++ * flags pointer is updated.
+  *
+  * Return: true if the entry is a valid, false otherwise.
+  */
+-static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
++static bool batadv_tt_local_valid(const void *entry_ptr,
++                                const void *data_ptr,
++                                u8 *flags)
+ {
+       const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
+       if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
+               return false;
++
++      if (flags)
++              *flags = tt_common_entry->flags;
++
+       return true;
+ }
++/**
++ * batadv_tt_global_valid() - verify global tt entry and get flags
++ * @entry_ptr: to be checked global tt entry
++ * @data_ptr: an orig_node object (may be NULL)
++ * @flags: a pointer to store TT flags for this client to
++ *
++ * Checks the validity of the given global TT entry. If it is, then the provided
++ * flags pointer is updated either with the common (summed) TT flags if data_ptr
++ * is NULL or the specific, per originator TT flags otherwise.
++ *
++ * Return: true if the entry is a valid, false otherwise.
++ */
+ static bool batadv_tt_global_valid(const void *entry_ptr,
+-                                 const void *data_ptr)
++                                 const void *data_ptr,
++                                 u8 *flags)
+ {
+       const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
+       const struct batadv_tt_global_entry *tt_global_entry;
+@@ -2914,7 +2944,8 @@ static bool batadv_tt_global_valid(const
+                                      struct batadv_tt_global_entry,
+                                      common);
+-      return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
++      return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
++                                             flags);
+ }
+ /**
+@@ -2924,25 +2955,34 @@ static bool batadv_tt_global_valid(const
+  * @hash: hash table containing the tt entries
+  * @tt_len: expected tvlv tt data buffer length in number of bytes
+  * @tvlv_buff: pointer to the buffer to fill with the TT data
+- * @valid_cb: function to filter tt change entries
++ * @valid_cb: function to filter tt change entries and to return TT flags
+  * @cb_data: data passed to the filter function as argument
++ *
++ * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
++ * is not provided then this becomes a no-op.
+  */
+ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
+                                   struct batadv_hashtable *hash,
+                                   void *tvlv_buff, u16 tt_len,
+                                   bool (*valid_cb)(const void *,
+-                                                   const void *),
++                                                   const void *,
++                                                   u8 *flags),
+                                   void *cb_data)
+ {
+       struct batadv_tt_common_entry *tt_common_entry;
+       struct batadv_tvlv_tt_change *tt_change;
+       struct hlist_head *head;
+       u16 tt_tot, tt_num_entries = 0;
++      u8 flags;
++      bool ret;
+       u32 i;
+       tt_tot = batadv_tt_entries(tt_len);
+       tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
++      if (!valid_cb)
++              return;
++
+       rcu_read_lock();
+       for (i = 0; i < hash->size; i++) {
+               head = &hash->table[i];
+@@ -2952,11 +2992,12 @@ static void batadv_tt_tvlv_generate(stru
+                       if (tt_tot == tt_num_entries)
+                               break;
+-                      if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
++                      ret = valid_cb(tt_common_entry, cb_data, &flags);
++                      if (!ret)
+                               continue;
+                       ether_addr_copy(tt_change->addr, tt_common_entry->addr);
+-                      tt_change->flags = tt_common_entry->flags;
++                      tt_change->flags = flags;
+                       tt_change->vid = htons(tt_common_entry->vid);
+                       memset(tt_change->reserved, 0,
+                              sizeof(tt_change->reserved));
diff --git a/queue-4.14/batman-adv-prevent-tt-request-storms-by-not-sending-inconsistent-tt-tlvls.patch b/queue-4.14/batman-adv-prevent-tt-request-storms-by-not-sending-inconsistent-tt-tlvls.patch
new file mode 100644 (file)
index 0000000..1453285
--- /dev/null
@@ -0,0 +1,82 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:26 +0100
+Subject: batman-adv: prevent TT request storms by not sending inconsistent TT TLVLs
+To: stable@vger.kernel.org
+Cc: Marek Lindner <mareklindner@neomailbox.ch>, Sven Eckelmann <sven@narfation.org>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-10-sven@narfation.org>
+
+From: Marek Lindner <mareklindner@neomailbox.ch>
+
+commit 16116dac23396e73c01eeee97b102e4833a4b205 upstream.
+
+A translation table TVLV changset sent with an OGM consists
+of a number of headers (one per VLAN) plus the changeset
+itself (addition and/or deletion of entries).
+
+The per-VLAN headers are used by OGM recipients for consistency
+checks. Said consistency check might determine that a full
+translation table request is needed to restore consistency. If
+the TT sender adds per-VLAN headers of empty VLANs into the OGM,
+recipients are led to believe to have reached an inconsistent
+state and thus request a full table update. The full table does
+not contain empty VLANs (due to missing entries) the cycle
+restarts when the next OGM is issued.
+
+Consequently, when the translation table TVLV headers are
+composed, empty VLANs are to be excluded.
+
+Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific")
+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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/translation-table.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -941,15 +941,20 @@ batadv_tt_prepare_tvlv_local_data(struct
+       struct batadv_tvlv_tt_vlan_data *tt_vlan;
+       struct batadv_softif_vlan *vlan;
+       u16 num_vlan = 0;
+-      u16 num_entries = 0;
++      u16 vlan_entries = 0;
++      u16 total_entries = 0;
+       u16 tvlv_len;
+       u8 *tt_change_ptr;
+       int change_offset;
+       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
+       hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
++              vlan_entries = atomic_read(&vlan->tt.num_entries);
++              if (vlan_entries < 1)
++                      continue;
++
+               num_vlan++;
+-              num_entries += atomic_read(&vlan->tt.num_entries);
++              total_entries += vlan_entries;
+       }
+       change_offset = sizeof(**tt_data);
+@@ -957,7 +962,7 @@ batadv_tt_prepare_tvlv_local_data(struct
+       /* if tt_len is negative, allocate the space needed by the full table */
+       if (*tt_len < 0)
+-              *tt_len = batadv_tt_len(num_entries);
++              *tt_len = batadv_tt_len(total_entries);
+       tvlv_len = *tt_len;
+       tvlv_len += change_offset;
+@@ -974,6 +979,10 @@ batadv_tt_prepare_tvlv_local_data(struct
+       tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
+       hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
++              vlan_entries = atomic_read(&vlan->tt.num_entries);
++              if (vlan_entries < 1)
++                      continue;
++
+               tt_vlan->vid = htons(vlan->vid);
+               tt_vlan->crc = htonl(vlan->tt.crc);
diff --git a/queue-4.14/batman-adv-update-data-pointers-after-skb_cow.patch b/queue-4.14/batman-adv-update-data-pointers-after-skb_cow.patch
new file mode 100644 (file)
index 0000000..902edfe
--- /dev/null
@@ -0,0 +1,67 @@
+From foo@baz Tue 17 Mar 2020 10:56:59 AM CET
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 16 Mar 2020 23:30:23 +0100
+Subject: batman-adv: update data pointers after skb_cow()
+To: stable@vger.kernel.org
+Cc: Matthias Schiffer <mschiffer@universe-factory.net>, Sven Eckelmann <sven@narfation.org>, Simon Wunderlich <sw@simonwunderlich.de>
+Message-ID: <20200316223032.6236-7-sven@narfation.org>
+
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+
+commit bc44b78157f621ff2a2618fe287a827bcb094ac4 upstream.
+
+batadv_check_unicast_ttvn() calls skb_cow(), so pointers into the SKB data
+must be (re)set after calling it. The ethhdr variable is dropped
+altogether.
+
+Fixes: 7cdcf6dddc42 ("batman-adv: add UNICAST_4ADDR packet type")
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+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/routing.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/net/batman-adv/routing.c
++++ b/net/batman-adv/routing.c
+@@ -950,14 +950,10 @@ int batadv_recv_unicast_packet(struct sk
+       struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL;
+       int check, hdr_size = sizeof(*unicast_packet);
+       enum batadv_subtype subtype;
+-      struct ethhdr *ethhdr;
+       int ret = NET_RX_DROP;
+       bool is4addr, is_gw;
+       unicast_packet = (struct batadv_unicast_packet *)skb->data;
+-      unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
+-      ethhdr = eth_hdr(skb);
+-
+       is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR;
+       /* the caller function should have already pulled 2 bytes */
+       if (is4addr)
+@@ -977,12 +973,14 @@ int batadv_recv_unicast_packet(struct sk
+       if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
+               goto free_skb;
++      unicast_packet = (struct batadv_unicast_packet *)skb->data;
++
+       /* packet for me */
+       if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
+               /* If this is a unicast packet from another backgone gw,
+                * drop it.
+                */
+-              orig_addr_gw = ethhdr->h_source;
++              orig_addr_gw = eth_hdr(skb)->h_source;
+               orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw);
+               if (orig_node_gw) {
+                       is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw,
+@@ -997,6 +995,8 @@ int batadv_recv_unicast_packet(struct sk
+               }
+               if (is4addr) {
++                      unicast_4addr_packet =
++                              (struct batadv_unicast_4addr_packet *)skb->data;
+                       subtype = unicast_4addr_packet->subtype;
+                       batadv_dat_inc_counter(bat_priv, subtype);
index dddc16f02cb32b473782838428c5f59dd5734cbd..9ed0ba9c18a2f4d40af0457404d8385241a34866 100644 (file)
@@ -64,3 +64,18 @@ i2c-acpi-put-device-when-verifying-client-fails.patch
 ipv6-restrict-ipv6_addrform-operation.patch
 net-smc-check-for-valid-ib_client_data.patch
 efi-add-a-sanity-check-to-efivar_store_raw.patch
+batman-adv-avoid-spurious-warnings-from-bat_v-neigh_cmp-implementation.patch
+batman-adv-always-initialize-fragment-header-priority.patch
+batman-adv-fix-check-of-retrieved-orig_gw-in-batadv_v_gw_is_eligible.patch
+batman-adv-fix-lock-for-ogm-cnt-access-in-batadv_iv_ogm_calc_tq.patch
+batman-adv-fix-internal-interface-indices-types.patch
+batman-adv-update-data-pointers-after-skb_cow.patch
+batman-adv-avoid-race-in-tt-tvlv-allocator-helper.patch
+batman-adv-fix-tt-sync-flags-for-intermediate-tt-responses.patch
+batman-adv-prevent-tt-request-storms-by-not-sending-inconsistent-tt-tlvls.patch
+batman-adv-fix-debugfs-path-for-renamed-hardif.patch
+batman-adv-fix-debugfs-path-for-renamed-softif.patch
+batman-adv-fix-duplicated-ogms-on-netdev_up.patch
+batman-adv-avoid-free-alloc-race-when-handling-ogm2-buffer.patch
+batman-adv-avoid-free-alloc-race-when-handling-ogm-buffer.patch
+batman-adv-don-t-schedule-ogm-for-disabled-interface.patch