Merge pull request #413 from ecsv/batadv-17.01
lede-17.01: batman-adv: Merge bugfixes from 2018.3
This commit is contained in:
commit
ad22c771eb
12 changed files with 676 additions and 1 deletions
|
@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk
|
||||||
PKG_NAME:=batman-adv
|
PKG_NAME:=batman-adv
|
||||||
|
|
||||||
PKG_VERSION:=2016.5
|
PKG_VERSION:=2016.5
|
||||||
PKG_RELEASE:=9
|
PKG_RELEASE:=10
|
||||||
PKG_MD5SUM:=6717a933a08dd2a01b00df30cb9f16a8
|
PKG_MD5SUM:=6717a933a08dd2a01b00df30cb9f16a8
|
||||||
PKG_HASH:=d0a0fc90c4f410b57d043215e253bb0b855efa5edbe165d87c17bfdcfafd0db7
|
PKG_HASH:=d0a0fc90c4f410b57d043215e253bb0b855efa5edbe165d87c17bfdcfafd0db7
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,35 @@ static inline int batadv_nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
|
||||||
|
|
||||||
#endif /* < KERNEL_VERSION(4, 7, 0) */
|
#endif /* < KERNEL_VERSION(4, 7, 0) */
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
|
||||||
|
|
||||||
|
static inline void *batadv_skb_put(struct sk_buff *skb, unsigned int len)
|
||||||
|
{
|
||||||
|
return (void *)skb_put(skb, len);
|
||||||
|
}
|
||||||
|
#define skb_put batadv_skb_put
|
||||||
|
|
||||||
|
static inline void *skb_put_zero(struct sk_buff *skb, unsigned int len)
|
||||||
|
{
|
||||||
|
void *tmp = skb_put(skb, len);
|
||||||
|
|
||||||
|
memset(tmp, 0, len);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *skb_put_data(struct sk_buff *skb, const void *data,
|
||||||
|
unsigned int len)
|
||||||
|
{
|
||||||
|
void *tmp = skb_put(skb, len);
|
||||||
|
|
||||||
|
memcpy(tmp, data, len);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* < KERNEL_VERSION(4, 13, 0) */
|
||||||
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Fri, 31 Aug 2018 15:08:44 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Avoid probe ELP information leak
|
||||||
|
|
||||||
|
The probe ELPs for WiFi interfaces are expanded to contain at least
|
||||||
|
BATADV_ELP_MIN_PROBE_SIZE bytes. This is usually a lot more than the
|
||||||
|
number of bytes which the template ELP packet requires.
|
||||||
|
|
||||||
|
These extra padding bytes were not initialized and thus could contain data
|
||||||
|
which were previously stored at the same location. It is therefore required
|
||||||
|
to set it to some predefined or random values to avoid leaking private
|
||||||
|
information from the system transmitting these kind of packets.
|
||||||
|
|
||||||
|
Fixes: bedcadfaa92b ("batman-adv: ELP - send unicast ELP packets for throughput sampling")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Antonio Quartulli <a@unstable.cc>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6c876e572f592c31132a55b5fb8427e168e5fb3c
|
||||||
|
---
|
||||||
|
net/batman-adv/bat_v_elp.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
|
||||||
|
index 06b2924f4cb7dde54bab97ad2d28aecd9b1a4ceb..e988a14f3eb01de1f52fe6dcaa91af898060140e 100644
|
||||||
|
--- a/net/batman-adv/bat_v_elp.c
|
||||||
|
+++ b/net/batman-adv/bat_v_elp.c
|
||||||
|
@@ -227,7 +227,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
|
||||||
|
* the packet to be exactly of that size to make the link
|
||||||
|
* throughput estimation effective.
|
||||||
|
*/
|
||||||
|
- skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
|
||||||
|
+ skb_put_zero(skb, probe_len - hard_iface->bat_v.elp_skb->len);
|
||||||
|
|
||||||
|
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||||
|
"Sending unicast (probe) ELP packet on interface %s to %pM\n",
|
|
@ -0,0 +1,45 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Fri, 31 Aug 2018 16:46:47 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Fix segfault when writing to throughput_override
|
||||||
|
|
||||||
|
The per hardif sysfs file "batman_adv/throughput_override" prints the
|
||||||
|
resulting change as info text when the users writes to this file. It uses
|
||||||
|
the helper function batadv_info to add it at the same time to the kernel
|
||||||
|
ring buffer and to the batman-adv debug log (when CONFIG_BATMAN_ADV_DEBUG
|
||||||
|
is enabled).
|
||||||
|
|
||||||
|
The function batadv_info requires as first parameter the batman-adv softif
|
||||||
|
net_device. This parameter is then used to find the private buffer which
|
||||||
|
contains the debug log for this batman-adv interface. But
|
||||||
|
batadv_store_throughput_override used as first argument the slave
|
||||||
|
net_device. This slave device doesn't have the batadv_priv private data
|
||||||
|
which is access by batadv_info.
|
||||||
|
|
||||||
|
Writing to this file with CONFIG_BATMAN_ADV_DEBUG enabled can either lead
|
||||||
|
to a segfault or to memory corruption.
|
||||||
|
|
||||||
|
Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/ddf99b78e255530cbadc0f67656a549e19520280
|
||||||
|
---
|
||||||
|
net/batman-adv/sysfs.c | 5 +++--
|
||||||
|
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
|
||||||
|
index 17c844196eb26c9faf9fd543b88cd86cc1c2c029..ae22db3d6637dde2fcc238826a624ef2d6dbd8f5 100644
|
||||||
|
--- a/net/batman-adv/sysfs.c
|
||||||
|
+++ b/net/batman-adv/sysfs.c
|
||||||
|
@@ -1078,8 +1078,9 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
|
||||||
|
if (old_tp_override == tp_override)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
- batadv_info(net_dev, "%s: Changing from: %u.%u MBit to: %u.%u MBit\n",
|
||||||
|
- "throughput_override",
|
||||||
|
+ batadv_info(hard_iface->soft_iface,
|
||||||
|
+ "%s: %s: Changing from: %u.%u MBit to: %u.%u MBit\n",
|
||||||
|
+ "throughput_override", net_dev->name,
|
||||||
|
old_tp_override / 10, old_tp_override % 10,
|
||||||
|
tp_override / 10, tp_override % 10);
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Fri, 31 Aug 2018 16:56:29 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Fix segfault when writing to sysfs elp_interval
|
||||||
|
|
||||||
|
The per hardif sysfs file "batman_adv/elp_interval" is using the generic
|
||||||
|
functions to store/show uint values. The helper __batadv_store_uint_attr
|
||||||
|
requires the softif net_device as parameter to print the resulting change
|
||||||
|
as info text when the users writes to this file. It uses the helper
|
||||||
|
function batadv_info to add it at the same time to the kernel ring buffer
|
||||||
|
and to the batman-adv debug log (when CONFIG_BATMAN_ADV_DEBUG is enabled).
|
||||||
|
|
||||||
|
The function batadv_info requires as first parameter the batman-adv softif
|
||||||
|
net_device. This parameter is then used to find the private buffer which
|
||||||
|
contains the debug log for this batman-adv interface. But
|
||||||
|
batadv_store_throughput_override used as first argument the slave
|
||||||
|
net_device. This slave device doesn't have the batadv_priv private data
|
||||||
|
which is access by batadv_info.
|
||||||
|
|
||||||
|
Writing to this file with CONFIG_BATMAN_ADV_DEBUG enabled can either lead
|
||||||
|
to a segfault or to memory corruption.
|
||||||
|
|
||||||
|
Fixes: ec46535b8275 ("batman-adv: Add hard_iface specific sysfs wrapper macros for UINT")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/848be9859b0109a6e428f92f21f2e660153b1c75
|
||||||
|
---
|
||||||
|
net/batman-adv/sysfs.c | 25 +++++++++++++++++--------
|
||||||
|
1 file changed, 17 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
|
||||||
|
index ae22db3d6637dde2fcc238826a624ef2d6dbd8f5..a4e6f158de26dea0e8e3fefd5b9aeec3dcd64457 100644
|
||||||
|
--- a/net/batman-adv/sysfs.c
|
||||||
|
+++ b/net/batman-adv/sysfs.c
|
||||||
|
@@ -186,7 +186,8 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
|
||||||
|
\
|
||||||
|
return __batadv_store_uint_attr(buff, count, _min, _max, \
|
||||||
|
_post_func, attr, \
|
||||||
|
- &bat_priv->_var, net_dev); \
|
||||||
|
+ &bat_priv->_var, net_dev, \
|
||||||
|
+ NULL); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \
|
||||||
|
@@ -260,7 +261,9 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
|
||||||
|
\
|
||||||
|
length = __batadv_store_uint_attr(buff, count, _min, _max, \
|
||||||
|
_post_func, attr, \
|
||||||
|
- &hard_iface->_var, net_dev); \
|
||||||
|
+ &hard_iface->_var, \
|
||||||
|
+ hard_iface->soft_iface, \
|
||||||
|
+ net_dev); \
|
||||||
|
\
|
||||||
|
batadv_hardif_put(hard_iface); \
|
||||||
|
return length; \
|
||||||
|
@@ -354,10 +357,12 @@ __batadv_store_bool_attr(char *buff, size_t count,
|
||||||
|
|
||||||
|
static int batadv_store_uint_attr(const char *buff, size_t count,
|
||||||
|
struct net_device *net_dev,
|
||||||
|
+ struct net_device *slave_dev,
|
||||||
|
const char *attr_name,
|
||||||
|
unsigned int min, unsigned int max,
|
||||||
|
atomic_t *attr)
|
||||||
|
{
|
||||||
|
+ char ifname[IFNAMSIZ + 3] = "";
|
||||||
|
unsigned long uint_val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
@@ -383,8 +388,11 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
|
||||||
|
if (atomic_read(attr) == uint_val)
|
||||||
|
return count;
|
||||||
|
|
||||||
|
- batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
|
||||||
|
- attr_name, atomic_read(attr), uint_val);
|
||||||
|
+ if (slave_dev)
|
||||||
|
+ snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name);
|
||||||
|
+
|
||||||
|
+ batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n",
|
||||||
|
+ attr_name, ifname, atomic_read(attr), uint_val);
|
||||||
|
|
||||||
|
atomic_set(attr, uint_val);
|
||||||
|
return count;
|
||||||
|
@@ -395,12 +403,13 @@ static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
|
||||||
|
void (*post_func)(struct net_device *),
|
||||||
|
const struct attribute *attr,
|
||||||
|
atomic_t *attr_store,
|
||||||
|
- struct net_device *net_dev)
|
||||||
|
+ struct net_device *net_dev,
|
||||||
|
+ struct net_device *slave_dev)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
|
||||||
|
- attr_store);
|
||||||
|
+ ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev,
|
||||||
|
+ attr->name, min, max, attr_store);
|
||||||
|
if (post_func && ret)
|
||||||
|
post_func(net_dev);
|
||||||
|
|
||||||
|
@@ -569,7 +578,7 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
|
||||||
|
return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
|
||||||
|
batadv_post_gw_reselect, attr,
|
||||||
|
&bat_priv->gw.sel_class,
|
||||||
|
- bat_priv->soft_iface);
|
||||||
|
+ bat_priv->soft_iface, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
|
|
@ -0,0 +1,45 @@
|
||||||
|
From: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
Date: Fri, 7 Sep 2018 05:45:54 +0800
|
||||||
|
Subject: [PATCH] batman-adv: fix backbone_gw refcount on queue_work() failure
|
||||||
|
|
||||||
|
The backbone_gw 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>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/24d83a50421c1c5d39cd9c015516a1a293ae8d0c
|
||||||
|
---
|
||||||
|
net/batman-adv/bridge_loop_avoidance.c | 10 ++++++++--
|
||||||
|
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
index aecf34503e95d9aa723449ddbf0bb3035336b878..258a74fd1c237fbf1b81dfc1c48720d8359b0ecc 100644
|
||||||
|
--- a/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
+++ b/net/batman-adv/bridge_loop_avoidance.c
|
||||||
|
@@ -1767,6 +1767,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
{
|
||||||
|
struct batadv_bla_backbone_gw *backbone_gw;
|
||||||
|
struct ethhdr *ethhdr;
|
||||||
|
+ bool ret;
|
||||||
|
|
||||||
|
ethhdr = eth_hdr(skb);
|
||||||
|
|
||||||
|
@@ -1790,8 +1791,13 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
|
||||||
|
if (unlikely(!backbone_gw))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
- queue_work(batadv_event_workqueue, &backbone_gw->report_work);
|
||||||
|
- /* backbone_gw is unreferenced in the report work function function */
|
||||||
|
+ ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
|
||||||
|
+
|
||||||
|
+ /* backbone_gw is unreferenced in the report work function function
|
||||||
|
+ * if queue_work() call was successful
|
||||||
|
+ */
|
||||||
|
+ if (!ret)
|
||||||
|
+ batadv_backbone_gw_put(backbone_gw);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
From: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
Date: Fri, 7 Sep 2018 05:45:55 +0800
|
||||||
|
Subject: [PATCH] batman-adv: fix hardif_neigh refcount on queue_work() failure
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/85100b602c127cecf1bcfd620d20eb867d685df2
|
||||||
|
---
|
||||||
|
net/batman-adv/bat_v_elp.c | 8 ++++++--
|
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
|
||||||
|
index e988a14f3eb01de1f52fe6dcaa91af898060140e..2ec0ecab0493ff88fdc01e55c8557de5b772e8bf 100644
|
||||||
|
--- a/net/batman-adv/bat_v_elp.c
|
||||||
|
+++ b/net/batman-adv/bat_v_elp.c
|
||||||
|
@@ -254,6 +254,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);
|
||||||
|
@@ -315,8 +316,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();
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 6 Sep 2018 14:35:24 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Prevent duplicated gateway_node entry
|
||||||
|
|
||||||
|
The function batadv_gw_node_add is responsible for adding new gw_node to
|
||||||
|
the gateway_list. It is expecting that the caller already checked that
|
||||||
|
there is not already an entry with the same key or not.
|
||||||
|
|
||||||
|
But the lock for the list is only held when the list is really modified.
|
||||||
|
This could lead to duplicated entries because another context could create
|
||||||
|
an entry with the same key between the check and the list manipulation.
|
||||||
|
|
||||||
|
The check and the manipulation of the list must therefore be in the same
|
||||||
|
locked code section.
|
||||||
|
|
||||||
|
Fixes: bc3538cabac5 ("batman-adv: adding gateway functionality")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/69b3ca714eba608fe79a51ccd89ce7050ee0b770
|
||||||
|
---
|
||||||
|
net/batman-adv/gateway_client.c | 11 +++++++++--
|
||||||
|
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
|
||||||
|
index f1fdf4e7f5c3ce7f20339dcee3b6e43290ea3b4e..a6f5a3969529745d6efa1d43a89440745e1926ad 100644
|
||||||
|
--- a/net/batman-adv/gateway_client.c
|
||||||
|
+++ b/net/batman-adv/gateway_client.c
|
||||||
|
@@ -31,6 +31,7 @@
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/kref.h>
|
||||||
|
#include <linux/list.h>
|
||||||
|
+#include <linux/lockdep.h>
|
||||||
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rculist.h>
|
||||||
|
@@ -325,6 +326,9 @@ out:
|
||||||
|
* @bat_priv: the bat priv with all the soft interface information
|
||||||
|
* @orig_node: originator announcing gateway capabilities
|
||||||
|
* @gateway: announced bandwidth information
|
||||||
|
+ *
|
||||||
|
+ * Has to be called with the appropriate locks being acquired
|
||||||
|
+ * (gw.list_lock).
|
||||||
|
*/
|
||||||
|
static void batadv_gw_node_add(struct batadv_priv *bat_priv,
|
||||||
|
struct batadv_orig_node *orig_node,
|
||||||
|
@@ -332,6 +336,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
|
||||||
|
{
|
||||||
|
struct batadv_gw_node *gw_node;
|
||||||
|
|
||||||
|
+ lockdep_assert_held(&bat_priv->gw.list_lock);
|
||||||
|
+
|
||||||
|
if (gateway->bandwidth_down == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -346,10 +352,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
|
||||||
|
gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
|
||||||
|
gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
|
||||||
|
|
||||||
|
- spin_lock_bh(&bat_priv->gw.list_lock);
|
||||||
|
kref_get(&gw_node->refcount);
|
||||||
|
hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list);
|
||||||
|
- spin_unlock_bh(&bat_priv->gw.list_lock);
|
||||||
|
|
||||||
|
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
||||||
|
"Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
|
||||||
|
@@ -405,11 +409,14 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
|
||||||
|
{
|
||||||
|
struct batadv_gw_node *gw_node, *curr_gw = NULL;
|
||||||
|
|
||||||
|
+ spin_lock_bh(&bat_priv->gw.list_lock);
|
||||||
|
gw_node = batadv_gw_node_get(bat_priv, orig_node);
|
||||||
|
if (!gw_node) {
|
||||||
|
batadv_gw_node_add(bat_priv, orig_node, gateway);
|
||||||
|
+ spin_unlock_bh(&bat_priv->gw.list_lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
+ spin_unlock_bh(&bat_priv->gw.list_lock);
|
||||||
|
|
||||||
|
if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) &&
|
||||||
|
(gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)))
|
|
@ -0,0 +1,90 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 6 Sep 2018 14:35:25 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Prevent duplicated nc_node entry
|
||||||
|
|
||||||
|
The function batadv_nc_get_nc_node is responsible for adding new nc_nodes
|
||||||
|
to the in_coding_list and out_coding_list. It first checks whether the
|
||||||
|
entry already is in the list or not. If it is, then the creation of a new
|
||||||
|
entry is aborted.
|
||||||
|
|
||||||
|
But the lock for the list is only held when the list is really modified.
|
||||||
|
This could lead to duplicated entries because another context could create
|
||||||
|
an entry with the same key between the check and the list manipulation.
|
||||||
|
|
||||||
|
The check and the manipulation of the list must therefore be in the same
|
||||||
|
locked code section.
|
||||||
|
|
||||||
|
Fixes: 3ed7ada3f0bb ("batman-adv: network coding - detect coding nodes and remove these after timeout")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/bab8447ad1850b25188f9652c0c52f8e58acd656
|
||||||
|
---
|
||||||
|
net/batman-adv/network-coding.c | 41 ++++++++++++++++++---------------
|
||||||
|
1 file changed, 22 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
|
||||||
|
index ab5a3bf0765f36f2fe14ff4a91d43d905e08a1f3..3279f7f3b97fd56535071b857cebebd68a5b3484 100644
|
||||||
|
--- a/net/batman-adv/network-coding.c
|
||||||
|
+++ b/net/batman-adv/network-coding.c
|
||||||
|
@@ -850,24 +850,6 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
|
||||||
|
spinlock_t *lock; /* Used to lock list selected by "int in_coding" */
|
||||||
|
struct list_head *list;
|
||||||
|
|
||||||
|
- /* Check if nc_node is already added */
|
||||||
|
- nc_node = batadv_nc_find_nc_node(orig_node, orig_neigh_node, in_coding);
|
||||||
|
-
|
||||||
|
- /* Node found */
|
||||||
|
- if (nc_node)
|
||||||
|
- return nc_node;
|
||||||
|
-
|
||||||
|
- nc_node = kzalloc(sizeof(*nc_node), GFP_ATOMIC);
|
||||||
|
- if (!nc_node)
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- /* Initialize nc_node */
|
||||||
|
- INIT_LIST_HEAD(&nc_node->list);
|
||||||
|
- kref_init(&nc_node->refcount);
|
||||||
|
- ether_addr_copy(nc_node->addr, orig_node->orig);
|
||||||
|
- kref_get(&orig_neigh_node->refcount);
|
||||||
|
- nc_node->orig_node = orig_neigh_node;
|
||||||
|
-
|
||||||
|
/* Select ingoing or outgoing coding node */
|
||||||
|
if (in_coding) {
|
||||||
|
lock = &orig_neigh_node->in_coding_list_lock;
|
||||||
|
@@ -877,13 +859,34 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
|
||||||
|
list = &orig_neigh_node->out_coding_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ spin_lock_bh(lock);
|
||||||
|
+
|
||||||
|
+ /* Check if nc_node is already added */
|
||||||
|
+ nc_node = batadv_nc_find_nc_node(orig_node, orig_neigh_node, in_coding);
|
||||||
|
+
|
||||||
|
+ /* Node found */
|
||||||
|
+ if (nc_node)
|
||||||
|
+ goto unlock;
|
||||||
|
+
|
||||||
|
+ nc_node = kzalloc(sizeof(*nc_node), GFP_ATOMIC);
|
||||||
|
+ if (!nc_node)
|
||||||
|
+ goto unlock;
|
||||||
|
+
|
||||||
|
+ /* Initialize nc_node */
|
||||||
|
+ INIT_LIST_HEAD(&nc_node->list);
|
||||||
|
+ kref_init(&nc_node->refcount);
|
||||||
|
+ ether_addr_copy(nc_node->addr, orig_node->orig);
|
||||||
|
+ kref_get(&orig_neigh_node->refcount);
|
||||||
|
+ nc_node->orig_node = orig_neigh_node;
|
||||||
|
+
|
||||||
|
batadv_dbg(BATADV_DBG_NC, bat_priv, "Adding nc_node %pM -> %pM\n",
|
||||||
|
nc_node->addr, nc_node->orig_node->orig);
|
||||||
|
|
||||||
|
/* Add nc_node to orig_node */
|
||||||
|
- spin_lock_bh(lock);
|
||||||
|
kref_get(&nc_node->refcount);
|
||||||
|
list_add_tail_rcu(&nc_node->list, list);
|
||||||
|
+
|
||||||
|
+unlock:
|
||||||
|
spin_unlock_bh(lock);
|
||||||
|
|
||||||
|
return nc_node;
|
|
@ -0,0 +1,81 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 6 Sep 2018 14:35:26 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Prevent duplicated softif_vlan entry
|
||||||
|
|
||||||
|
The function batadv_softif_vlan_get is responsible for adding new
|
||||||
|
softif_vlan to the softif_vlan_list. It first checks whether the entry
|
||||||
|
already is in the list or not. If it is, then the creation of a new entry
|
||||||
|
is aborted.
|
||||||
|
|
||||||
|
But the lock for the list is only held when the list is really modified.
|
||||||
|
This could lead to duplicated entries because another context could create
|
||||||
|
an entry with the same key between the check and the list manipulation.
|
||||||
|
|
||||||
|
The check and the manipulation of the list must therefore be in the same
|
||||||
|
locked code section.
|
||||||
|
|
||||||
|
Fixes: 952cebb57518 ("batman-adv: add per VLAN interface attribute framework")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/023d3f64207e8b6a6e6d0718d98e239c5545ef0c
|
||||||
|
---
|
||||||
|
net/batman-adv/soft-interface.c | 27 +++++++++++++++++++--------
|
||||||
|
1 file changed, 19 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
|
||||||
|
index 5da1a1c0f1efb5d95f31bc852b899f61e462feb1..ff797f32fb3bb81dafe1e7d3e9c6307e6a5aaff1 100644
|
||||||
|
--- a/net/batman-adv/soft-interface.c
|
||||||
|
+++ b/net/batman-adv/soft-interface.c
|
||||||
|
@@ -587,15 +587,20 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
|
||||||
|
struct batadv_softif_vlan *vlan;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
+ spin_lock_bh(&bat_priv->softif_vlan_list_lock);
|
||||||
|
+
|
||||||
|
vlan = batadv_softif_vlan_get(bat_priv, vid);
|
||||||
|
if (vlan) {
|
||||||
|
batadv_softif_vlan_put(vlan);
|
||||||
|
+ spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
|
||||||
|
return -EEXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
|
||||||
|
- if (!vlan)
|
||||||
|
+ if (!vlan) {
|
||||||
|
+ spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
vlan->bat_priv = bat_priv;
|
||||||
|
vlan->vid = vid;
|
||||||
|
@@ -603,17 +608,23 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
|
||||||
|
|
||||||
|
atomic_set(&vlan->ap_isolation, 0);
|
||||||
|
|
||||||
|
- err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
|
||||||
|
- if (err) {
|
||||||
|
- kfree(vlan);
|
||||||
|
- return err;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- spin_lock_bh(&bat_priv->softif_vlan_list_lock);
|
||||||
|
kref_get(&vlan->refcount);
|
||||||
|
hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
|
||||||
|
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
|
||||||
|
|
||||||
|
+ /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the
|
||||||
|
+ * sleeping behavior of the sysfs functions and the fs_reclaim lock
|
||||||
|
+ */
|
||||||
|
+ err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
|
||||||
|
+ if (err) {
|
||||||
|
+ /* ref for the function */
|
||||||
|
+ batadv_softif_vlan_put(vlan);
|
||||||
|
+
|
||||||
|
+ /* ref for the list */
|
||||||
|
+ batadv_softif_vlan_put(vlan);
|
||||||
|
+ return err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* add a new TT local entry. This one will be marked with the NOPURGE
|
||||||
|
* flag
|
||||||
|
*/
|
|
@ -0,0 +1,59 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 6 Sep 2018 14:35:27 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Prevent duplicated global TT entry
|
||||||
|
|
||||||
|
The function batadv_tt_global_orig_entry_add is responsible for adding new
|
||||||
|
tt_orig_list_entry to the orig_list. It first checks whether the entry
|
||||||
|
already is in the list or not. If it is, then the creation of a new entry
|
||||||
|
is aborted.
|
||||||
|
|
||||||
|
But the lock for the list is only held when the list is really modified.
|
||||||
|
This could lead to duplicated entries because another context could create
|
||||||
|
an entry with the same key between the check and the list manipulation.
|
||||||
|
|
||||||
|
The check and the manipulation of the list must therefore be in the same
|
||||||
|
locked code section.
|
||||||
|
|
||||||
|
Fixes: c5eb5bb30321 ("batman-adv: add reference counting for type batadv_tt_orig_list_entry")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/79097255a1a3e1bd1949be309af941181fbc7b36
|
||||||
|
---
|
||||||
|
net/batman-adv/translation-table.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
|
||||||
|
index 143a00f90d1d925aad7113f897d06f435f28dcd8..b32853cbab028f0a052492545bb803efdcdb0ff3 100644
|
||||||
|
--- a/net/batman-adv/translation-table.c
|
||||||
|
+++ b/net/batman-adv/translation-table.c
|
||||||
|
@@ -1603,6 +1603,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
|
||||||
|
{
|
||||||
|
struct batadv_tt_orig_list_entry *orig_entry;
|
||||||
|
|
||||||
|
+ spin_lock_bh(&tt_global->list_lock);
|
||||||
|
+
|
||||||
|
orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
|
||||||
|
if (orig_entry) {
|
||||||
|
/* refresh the ttvn: the current value could be a bogus one that
|
||||||
|
@@ -1625,11 +1627,9 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
|
||||||
|
orig_entry->flags = flags;
|
||||||
|
kref_init(&orig_entry->refcount);
|
||||||
|
|
||||||
|
- spin_lock_bh(&tt_global->list_lock);
|
||||||
|
kref_get(&orig_entry->refcount);
|
||||||
|
hlist_add_head_rcu(&orig_entry->list,
|
||||||
|
&tt_global->orig_list);
|
||||||
|
- spin_unlock_bh(&tt_global->list_lock);
|
||||||
|
atomic_inc(&tt_global->orig_list_count);
|
||||||
|
|
||||||
|
sync_flags:
|
||||||
|
@@ -1637,6 +1637,8 @@ sync_flags:
|
||||||
|
out:
|
||||||
|
if (orig_entry)
|
||||||
|
batadv_tt_orig_list_entry_put(orig_entry);
|
||||||
|
+
|
||||||
|
+ spin_unlock_bh(&tt_global->list_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
|
@ -0,0 +1,59 @@
|
||||||
|
From: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Date: Thu, 6 Sep 2018 14:35:28 +0200
|
||||||
|
Subject: [PATCH] batman-adv: Prevent duplicated tvlv handler
|
||||||
|
|
||||||
|
The function batadv_tvlv_handler_register is responsible for adding new
|
||||||
|
tvlv_handler to the handler_list. It first checks whether the entry
|
||||||
|
already is in the list or not. If it is, then the creation of a new entry
|
||||||
|
is aborted.
|
||||||
|
|
||||||
|
But the lock for the list is only held when the list is really modified.
|
||||||
|
This could lead to duplicated entries because another context could create
|
||||||
|
an entry with the same key between the check and the list manipulation.
|
||||||
|
|
||||||
|
The check and the manipulation of the list must therefore be in the same
|
||||||
|
locked code section.
|
||||||
|
|
||||||
|
Fixes: 0b6aa0d43767 ("batman-adv: tvlv - basic infrastructure")
|
||||||
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
||||||
|
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
|
||||||
|
|
||||||
|
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/acabad79e01740525cf4ff8ce6e9a210b683d420
|
||||||
|
---
|
||||||
|
net/batman-adv/tvlv.c | 8 ++++++--
|
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c
|
||||||
|
index a783420356ae0cd4a6273b3b7a04781242e37a82..1eccc49a793004db82346f9dc3be7fcc2386417b 100644
|
||||||
|
--- a/net/batman-adv/tvlv.c
|
||||||
|
+++ b/net/batman-adv/tvlv.c
|
||||||
|
@@ -528,15 +528,20 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
|
||||||
|
{
|
||||||
|
struct batadv_tvlv_handler *tvlv_handler;
|
||||||
|
|
||||||
|
+ spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
|
||||||
|
+
|
||||||
|
tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
|
||||||
|
if (tvlv_handler) {
|
||||||
|
+ spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
|
||||||
|
batadv_tvlv_handler_put(tvlv_handler);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
|
||||||
|
- if (!tvlv_handler)
|
||||||
|
+ if (!tvlv_handler) {
|
||||||
|
+ spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
|
||||||
|
return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
tvlv_handler->ogm_handler = optr;
|
||||||
|
tvlv_handler->unicast_handler = uptr;
|
||||||
|
@@ -546,7 +551,6 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
|
||||||
|
kref_init(&tvlv_handler->refcount);
|
||||||
|
INIT_HLIST_NODE(&tvlv_handler->list);
|
||||||
|
|
||||||
|
- spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
|
||||||
|
kref_get(&tvlv_handler->refcount);
|
||||||
|
hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
|
||||||
|
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
|
Loading…
Reference in a new issue