Skip to content

Commit

Permalink
batman-adv: Avoid sysfs name collision for netns moves
Browse files Browse the repository at this point in the history
The kobject_put is only removing the sysfs entry and corresponding entries
when its reference counter becomes zero. This tends to lead to collisions
when a device is moved between two different network namespaces because
some of the sysfs files have to be removed first and then added again to
the already moved sysfs entry.

    WARNING: CPU: 0 PID: 290 at lib/kobject.c:240 kobject_add_internal+0x5ec/0x8a0
    kobject_add_internal failed for batman_adv with -EEXIST, don't try to register things with the same name in the same directory.

But the caller of kobject_put can already remove the sysfs entry before it
does the kobject_put. This removal is done even when the reference counter
is not yet zero and thus avoids the problem.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
  • Loading branch information
Sven Eckelmann authored and Simon Wunderlich committed Aug 9, 2016
1 parent 569c985 commit f4acb10
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions net/batman-adv/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,8 @@ int batadv_sysfs_add_meshif(struct net_device *dev)
for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));

kobject_uevent(bat_priv->mesh_obj, KOBJ_REMOVE);
kobject_del(bat_priv->mesh_obj);
kobject_put(bat_priv->mesh_obj);
bat_priv->mesh_obj = NULL;
out:
Expand All @@ -727,6 +729,8 @@ void batadv_sysfs_del_meshif(struct net_device *dev)
for (bat_attr = batadv_mesh_attrs; *bat_attr; ++bat_attr)
sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr));

kobject_uevent(bat_priv->mesh_obj, KOBJ_REMOVE);
kobject_del(bat_priv->mesh_obj);
kobject_put(bat_priv->mesh_obj);
bat_priv->mesh_obj = NULL;
}
Expand Down Expand Up @@ -782,6 +786,10 @@ int batadv_sysfs_add_vlan(struct net_device *dev,
for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));

if (vlan->kobj != bat_priv->mesh_obj) {
kobject_uevent(vlan->kobj, KOBJ_REMOVE);
kobject_del(vlan->kobj);
}
kobject_put(vlan->kobj);
vlan->kobj = NULL;
out:
Expand All @@ -801,6 +809,10 @@ void batadv_sysfs_del_vlan(struct batadv_priv *bat_priv,
for (bat_attr = batadv_vlan_attrs; *bat_attr; ++bat_attr)
sysfs_remove_file(vlan->kobj, &((*bat_attr)->attr));

if (vlan->kobj != bat_priv->mesh_obj) {
kobject_uevent(vlan->kobj, KOBJ_REMOVE);
kobject_del(vlan->kobj);
}
kobject_put(vlan->kobj);
vlan->kobj = NULL;
}
Expand Down Expand Up @@ -1103,6 +1115,8 @@ int batadv_sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev)

void batadv_sysfs_del_hardif(struct kobject **hardif_obj)
{
kobject_uevent(*hardif_obj, KOBJ_REMOVE);
kobject_del(*hardif_obj);
kobject_put(*hardif_obj);
*hardif_obj = NULL;
}
Expand Down

0 comments on commit f4acb10

Please sign in to comment.