netns: Fix arbitrary net_device-s corruptions on net_ns stop.
authorPavel Emelyanov <xemul@openvz.org>
Thu, 8 May 2008 08:24:25 +0000 (01:24 -0700)
committerDavid S. Miller <davem@davemloft.net>
Thu, 8 May 2008 08:24:25 +0000 (01:24 -0700)
commitaca51397d01474f80cab8fc978559b45f2e453ad
tree767ec47cfb981775294301d33208c0d2b52a01a3
parentf3261aff35cbc811fee0e23eaea277f1b7286eca
netns: Fix arbitrary net_device-s corruptions on net_ns stop.

When a net namespace is destroyed, some devices (those, not killed
on ns stop explicitly) are moved back to init_net.

The problem, is that this net_ns change has one point of failure -
the __dev_alloc_name() may be called if a name collision occurs (and
this is easy to trigger). This allocator performs a likely-to-fail
GFP_ATOMIC allocation to find a suitable number. Other possible
conditions that may cause error (for device being ns local or not
registered) are always false in this case.

So, when this call fails, the device is unregistered. But this is
*not* the right thing to do, since after this the device may be
released (and kfree-ed) improperly. E. g. bridges require more
actions (sysfs update, timer disarming, etc.), some other devices
want to remove their private areas from lists, etc.

I. e. arbitrary use-after-free cases may occur.

The proposed fix is the following: since the only reason for the
dev_change_net_namespace to fail is the name generation, we may
give it a unique fall-back name w/o %d-s in it - the dev<ifindex>
one, since ifindexes are still unique.

So make this change, raise the failure-case printk loglevel to
EMERG and replace the unregister_netdevice call with BUG().

[ Use snprintf() -DaveM ]

Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/dev.c