Skip to content

Commit aa86b03

Browse files
committed
Merge tag 'batadv-net-for-davem-20180919' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says: ==================== pull request for net: batman-adv 2018-09-19 here are some bugfixes which we would like to see integrated into net. We forgot to bump the version number in the last round for net-next, so the belated patch to do that is included - we hope you can adopt it. This will most likely create a merge conflict later when merging into net-next with this rounds net-next patchset, but net-next should keep the 2018.4 version[1]. [1] resolution: --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h @@ -25,11 +25,7 @@ #define BATADV_DRIVER_DEVICE "batman-adv" #ifndef BATADV_SOURCE_VERSION -<<<<<<< -#define BATADV_SOURCE_VERSION "2018.3" -======= #define BATADV_SOURCE_VERSION "2018.4" ->>>>>>> #endif /* B.A.T.M.A.N. parameters */ Please pull or let me know of any problem! Here are some batman-adv bugfixes: - Avoid ELP information leak, by Sven Eckelmann - Fix sysfs segfault issues, by Sven Eckelmann (2 patches) - Fix locking when adding entries in various lists, by Sven Eckelmann (5 patches) - Fix refcount if queue_work() fails, by Marek Lindner (2 patches) - Fixup forgotten version bump, by Sven Eckelmann ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 69ba423 + dabeb13 commit aa86b03

File tree

9 files changed

+88
-41
lines changed

9 files changed

+88
-41
lines changed

net/batman-adv/bat_v_elp.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
241241
* the packet to be exactly of that size to make the link
242242
* throughput estimation effective.
243243
*/
244-
skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
244+
skb_put_zero(skb, probe_len - hard_iface->bat_v.elp_skb->len);
245245

246246
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
247247
"Sending unicast (probe) ELP packet on interface %s to %pM\n",
@@ -268,6 +268,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
268268
struct batadv_priv *bat_priv;
269269
struct sk_buff *skb;
270270
u32 elp_interval;
271+
bool ret;
271272

272273
bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work);
273274
hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
@@ -329,8 +330,11 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
329330
* may sleep and that is not allowed in an rcu protected
330331
* context. Therefore schedule a task for that.
331332
*/
332-
queue_work(batadv_event_workqueue,
333-
&hardif_neigh->bat_v.metric_work);
333+
ret = queue_work(batadv_event_workqueue,
334+
&hardif_neigh->bat_v.metric_work);
335+
336+
if (!ret)
337+
batadv_hardif_neigh_put(hardif_neigh);
334338
}
335339
rcu_read_unlock();
336340

net/batman-adv/bridge_loop_avoidance.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
17721772
{
17731773
struct batadv_bla_backbone_gw *backbone_gw;
17741774
struct ethhdr *ethhdr;
1775+
bool ret;
17751776

17761777
ethhdr = eth_hdr(skb);
17771778

@@ -1795,8 +1796,13 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
17951796
if (unlikely(!backbone_gw))
17961797
return true;
17971798

1798-
queue_work(batadv_event_workqueue, &backbone_gw->report_work);
1799-
/* backbone_gw is unreferenced in the report work function function */
1799+
ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
1800+
1801+
/* backbone_gw is unreferenced in the report work function function
1802+
* if queue_work() call was successful
1803+
*/
1804+
if (!ret)
1805+
batadv_backbone_gw_put(backbone_gw);
18001806

18011807
return true;
18021808
}

net/batman-adv/gateway_client.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <linux/kernel.h>
3333
#include <linux/kref.h>
3434
#include <linux/list.h>
35+
#include <linux/lockdep.h>
3536
#include <linux/netdevice.h>
3637
#include <linux/netlink.h>
3738
#include <linux/rculist.h>
@@ -348,13 +349,18 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
348349
* @bat_priv: the bat priv with all the soft interface information
349350
* @orig_node: originator announcing gateway capabilities
350351
* @gateway: announced bandwidth information
352+
*
353+
* Has to be called with the appropriate locks being acquired
354+
* (gw.list_lock).
351355
*/
352356
static void batadv_gw_node_add(struct batadv_priv *bat_priv,
353357
struct batadv_orig_node *orig_node,
354358
struct batadv_tvlv_gateway_data *gateway)
355359
{
356360
struct batadv_gw_node *gw_node;
357361

362+
lockdep_assert_held(&bat_priv->gw.list_lock);
363+
358364
if (gateway->bandwidth_down == 0)
359365
return;
360366

@@ -369,10 +375,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
369375
gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
370376
gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
371377

372-
spin_lock_bh(&bat_priv->gw.list_lock);
373378
kref_get(&gw_node->refcount);
374379
hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list);
375-
spin_unlock_bh(&bat_priv->gw.list_lock);
376380

377381
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
378382
"Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
@@ -428,11 +432,14 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
428432
{
429433
struct batadv_gw_node *gw_node, *curr_gw = NULL;
430434

435+
spin_lock_bh(&bat_priv->gw.list_lock);
431436
gw_node = batadv_gw_node_get(bat_priv, orig_node);
432437
if (!gw_node) {
433438
batadv_gw_node_add(bat_priv, orig_node, gateway);
439+
spin_unlock_bh(&bat_priv->gw.list_lock);
434440
goto out;
435441
}
442+
spin_unlock_bh(&bat_priv->gw.list_lock);
436443

437444
if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) &&
438445
gw_node->bandwidth_up == ntohl(gateway->bandwidth_up))

net/batman-adv/main.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#define BATADV_DRIVER_DEVICE "batman-adv"
2626

2727
#ifndef BATADV_SOURCE_VERSION
28-
#define BATADV_SOURCE_VERSION "2018.2"
28+
#define BATADV_SOURCE_VERSION "2018.3"
2929
#endif
3030

3131
/* B.A.T.M.A.N. parameters */

net/batman-adv/network-coding.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -854,16 +854,27 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
854854
spinlock_t *lock; /* Used to lock list selected by "int in_coding" */
855855
struct list_head *list;
856856

857+
/* Select ingoing or outgoing coding node */
858+
if (in_coding) {
859+
lock = &orig_neigh_node->in_coding_list_lock;
860+
list = &orig_neigh_node->in_coding_list;
861+
} else {
862+
lock = &orig_neigh_node->out_coding_list_lock;
863+
list = &orig_neigh_node->out_coding_list;
864+
}
865+
866+
spin_lock_bh(lock);
867+
857868
/* Check if nc_node is already added */
858869
nc_node = batadv_nc_find_nc_node(orig_node, orig_neigh_node, in_coding);
859870

860871
/* Node found */
861872
if (nc_node)
862-
return nc_node;
873+
goto unlock;
863874

864875
nc_node = kzalloc(sizeof(*nc_node), GFP_ATOMIC);
865876
if (!nc_node)
866-
return NULL;
877+
goto unlock;
867878

868879
/* Initialize nc_node */
869880
INIT_LIST_HEAD(&nc_node->list);
@@ -872,22 +883,14 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
872883
kref_get(&orig_neigh_node->refcount);
873884
nc_node->orig_node = orig_neigh_node;
874885

875-
/* Select ingoing or outgoing coding node */
876-
if (in_coding) {
877-
lock = &orig_neigh_node->in_coding_list_lock;
878-
list = &orig_neigh_node->in_coding_list;
879-
} else {
880-
lock = &orig_neigh_node->out_coding_list_lock;
881-
list = &orig_neigh_node->out_coding_list;
882-
}
883-
884886
batadv_dbg(BATADV_DBG_NC, bat_priv, "Adding nc_node %pM -> %pM\n",
885887
nc_node->addr, nc_node->orig_node->orig);
886888

887889
/* Add nc_node to orig_node */
888-
spin_lock_bh(lock);
889890
kref_get(&nc_node->refcount);
890891
list_add_tail_rcu(&nc_node->list, list);
892+
893+
unlock:
891894
spin_unlock_bh(lock);
892895

893896
return nc_node;

net/batman-adv/soft-interface.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -574,33 +574,44 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
574574
struct batadv_softif_vlan *vlan;
575575
int err;
576576

577+
spin_lock_bh(&bat_priv->softif_vlan_list_lock);
578+
577579
vlan = batadv_softif_vlan_get(bat_priv, vid);
578580
if (vlan) {
579581
batadv_softif_vlan_put(vlan);
582+
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
580583
return -EEXIST;
581584
}
582585

583586
vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
584-
if (!vlan)
587+
if (!vlan) {
588+
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
585589
return -ENOMEM;
590+
}
586591

587592
vlan->bat_priv = bat_priv;
588593
vlan->vid = vid;
589594
kref_init(&vlan->refcount);
590595

591596
atomic_set(&vlan->ap_isolation, 0);
592597

598+
kref_get(&vlan->refcount);
599+
hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
600+
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
601+
602+
/* batadv_sysfs_add_vlan cannot be in the spinlock section due to the
603+
* sleeping behavior of the sysfs functions and the fs_reclaim lock
604+
*/
593605
err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
594606
if (err) {
595-
kfree(vlan);
607+
/* ref for the function */
608+
batadv_softif_vlan_put(vlan);
609+
610+
/* ref for the list */
611+
batadv_softif_vlan_put(vlan);
596612
return err;
597613
}
598614

599-
spin_lock_bh(&bat_priv->softif_vlan_list_lock);
600-
kref_get(&vlan->refcount);
601-
hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
602-
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
603-
604615
/* add a new TT local entry. This one will be marked with the NOPURGE
605616
* flag
606617
*/

net/batman-adv/sysfs.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
188188
\
189189
return __batadv_store_uint_attr(buff, count, _min, _max, \
190190
_post_func, attr, \
191-
&bat_priv->_var, net_dev); \
191+
&bat_priv->_var, net_dev, \
192+
NULL); \
192193
}
193194

194195
#define BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \
@@ -262,7 +263,9 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
262263
\
263264
length = __batadv_store_uint_attr(buff, count, _min, _max, \
264265
_post_func, attr, \
265-
&hard_iface->_var, net_dev); \
266+
&hard_iface->_var, \
267+
hard_iface->soft_iface, \
268+
net_dev); \
266269
\
267270
batadv_hardif_put(hard_iface); \
268271
return length; \
@@ -356,10 +359,12 @@ __batadv_store_bool_attr(char *buff, size_t count,
356359

357360
static int batadv_store_uint_attr(const char *buff, size_t count,
358361
struct net_device *net_dev,
362+
struct net_device *slave_dev,
359363
const char *attr_name,
360364
unsigned int min, unsigned int max,
361365
atomic_t *attr)
362366
{
367+
char ifname[IFNAMSIZ + 3] = "";
363368
unsigned long uint_val;
364369
int ret;
365370

@@ -385,8 +390,11 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
385390
if (atomic_read(attr) == uint_val)
386391
return count;
387392

388-
batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
389-
attr_name, atomic_read(attr), uint_val);
393+
if (slave_dev)
394+
snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name);
395+
396+
batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n",
397+
attr_name, ifname, atomic_read(attr), uint_val);
390398

391399
atomic_set(attr, uint_val);
392400
return count;
@@ -397,12 +405,13 @@ static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
397405
void (*post_func)(struct net_device *),
398406
const struct attribute *attr,
399407
atomic_t *attr_store,
400-
struct net_device *net_dev)
408+
struct net_device *net_dev,
409+
struct net_device *slave_dev)
401410
{
402411
int ret;
403412

404-
ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
405-
attr_store);
413+
ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev,
414+
attr->name, min, max, attr_store);
406415
if (post_func && ret)
407416
post_func(net_dev);
408417

@@ -571,7 +580,7 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
571580
return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
572581
batadv_post_gw_reselect, attr,
573582
&bat_priv->gw.sel_class,
574-
bat_priv->soft_iface);
583+
bat_priv->soft_iface, NULL);
575584
}
576585

577586
static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
@@ -1090,8 +1099,9 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
10901099
if (old_tp_override == tp_override)
10911100
goto out;
10921101

1093-
batadv_info(net_dev, "%s: Changing from: %u.%u MBit to: %u.%u MBit\n",
1094-
"throughput_override",
1102+
batadv_info(hard_iface->soft_iface,
1103+
"%s: %s: Changing from: %u.%u MBit to: %u.%u MBit\n",
1104+
"throughput_override", net_dev->name,
10951105
old_tp_override / 10, old_tp_override % 10,
10961106
tp_override / 10, tp_override % 10);
10971107

net/batman-adv/translation-table.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
16131613
{
16141614
struct batadv_tt_orig_list_entry *orig_entry;
16151615

1616+
spin_lock_bh(&tt_global->list_lock);
1617+
16161618
orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
16171619
if (orig_entry) {
16181620
/* refresh the ttvn: the current value could be a bogus one that
@@ -1635,18 +1637,18 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
16351637
orig_entry->flags = flags;
16361638
kref_init(&orig_entry->refcount);
16371639

1638-
spin_lock_bh(&tt_global->list_lock);
16391640
kref_get(&orig_entry->refcount);
16401641
hlist_add_head_rcu(&orig_entry->list,
16411642
&tt_global->orig_list);
1642-
spin_unlock_bh(&tt_global->list_lock);
16431643
atomic_inc(&tt_global->orig_list_count);
16441644

16451645
sync_flags:
16461646
batadv_tt_global_sync_flags(tt_global);
16471647
out:
16481648
if (orig_entry)
16491649
batadv_tt_orig_list_entry_put(orig_entry);
1650+
1651+
spin_unlock_bh(&tt_global->list_lock);
16501652
}
16511653

16521654
/**

net/batman-adv/tvlv.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -529,15 +529,20 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
529529
{
530530
struct batadv_tvlv_handler *tvlv_handler;
531531

532+
spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
533+
532534
tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
533535
if (tvlv_handler) {
536+
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
534537
batadv_tvlv_handler_put(tvlv_handler);
535538
return;
536539
}
537540

538541
tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
539-
if (!tvlv_handler)
542+
if (!tvlv_handler) {
543+
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
540544
return;
545+
}
541546

542547
tvlv_handler->ogm_handler = optr;
543548
tvlv_handler->unicast_handler = uptr;
@@ -547,7 +552,6 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
547552
kref_init(&tvlv_handler->refcount);
548553
INIT_HLIST_NODE(&tvlv_handler->list);
549554

550-
spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
551555
kref_get(&tvlv_handler->refcount);
552556
hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
553557
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);

0 commit comments

Comments
 (0)