• Pavel Emelyanov's avatar
    netns: Fix arbitrary net_device-s corruptions on net_ns stop. · aca51397
    Pavel Emelyanov authored
    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: default avatarPavel Emelyanov <xemul@openvz.org>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    aca51397
dev.c 111 KB