batman-adv: Refresh patches
[feed/routing.git] / batman-adv / patches / 0048-batman-adv-Fix-segfault-when-writing-to-sysfs-elp_in.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Fri, 31 Aug 2018 16:56:29 +0200
3 Subject: batman-adv: Fix segfault when writing to sysfs elp_interval
4
5 The per hardif sysfs file "batman_adv/elp_interval" is using the generic
6 functions to store/show uint values. The helper __batadv_store_uint_attr
7 requires the softif net_device as parameter to print the resulting change
8 as info text when the users writes to this file. It uses the helper
9 function batadv_info to add it at the same time to the kernel ring buffer
10 and to the batman-adv debug log (when CONFIG_BATMAN_ADV_DEBUG is enabled).
11
12 The function batadv_info requires as first parameter the batman-adv softif
13 net_device. This parameter is then used to find the private buffer which
14 contains the debug log for this batman-adv interface. But
15 batadv_store_throughput_override used as first argument the slave
16 net_device. This slave device doesn't have the batadv_priv private data
17 which is access by batadv_info.
18
19 Writing to this file with CONFIG_BATMAN_ADV_DEBUG enabled can either lead
20 to a segfault or to memory corruption.
21
22 Fixes: ec46535b8275 ("batman-adv: Add hard_iface specific sysfs wrapper macros for UINT")
23 Signed-off-by: Sven Eckelmann <sven@narfation.org>
24 Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
25
26 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/848be9859b0109a6e428f92f21f2e660153b1c75
27
28 diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
29 index ae22db3d6637dde2fcc238826a624ef2d6dbd8f5..a4e6f158de26dea0e8e3fefd5b9aeec3dcd64457 100644
30 --- a/net/batman-adv/sysfs.c
31 +++ b/net/batman-adv/sysfs.c
32 @@ -186,7 +186,8 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
33 \
34 return __batadv_store_uint_attr(buff, count, _min, _max, \
35 _post_func, attr, \
36 - &bat_priv->_var, net_dev); \
37 + &bat_priv->_var, net_dev, \
38 + NULL); \
39 }
40
41 #define BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \
42 @@ -260,7 +261,9 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
43 \
44 length = __batadv_store_uint_attr(buff, count, _min, _max, \
45 _post_func, attr, \
46 - &hard_iface->_var, net_dev); \
47 + &hard_iface->_var, \
48 + hard_iface->soft_iface, \
49 + net_dev); \
50 \
51 batadv_hardif_put(hard_iface); \
52 return length; \
53 @@ -354,10 +357,12 @@ __batadv_store_bool_attr(char *buff, size_t count,
54
55 static int batadv_store_uint_attr(const char *buff, size_t count,
56 struct net_device *net_dev,
57 + struct net_device *slave_dev,
58 const char *attr_name,
59 unsigned int min, unsigned int max,
60 atomic_t *attr)
61 {
62 + char ifname[IFNAMSIZ + 3] = "";
63 unsigned long uint_val;
64 int ret;
65
66 @@ -383,8 +388,11 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
67 if (atomic_read(attr) == uint_val)
68 return count;
69
70 - batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
71 - attr_name, atomic_read(attr), uint_val);
72 + if (slave_dev)
73 + snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name);
74 +
75 + batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n",
76 + attr_name, ifname, atomic_read(attr), uint_val);
77
78 atomic_set(attr, uint_val);
79 return count;
80 @@ -395,12 +403,13 @@ static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
81 void (*post_func)(struct net_device *),
82 const struct attribute *attr,
83 atomic_t *attr_store,
84 - struct net_device *net_dev)
85 + struct net_device *net_dev,
86 + struct net_device *slave_dev)
87 {
88 int ret;
89
90 - ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
91 - attr_store);
92 + ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev,
93 + attr->name, min, max, attr_store);
94 if (post_func && ret)
95 post_func(net_dev);
96
97 @@ -569,7 +578,7 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
98 return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
99 batadv_post_gw_reselect, attr,
100 &bat_priv->gw.sel_class,
101 - bat_priv->soft_iface);
102 + bat_priv->soft_iface, NULL);
103 }
104
105 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,