[NET]: Fix free_netdev on register_netdev failure.
authorDaniel Lezcano <dlezcano@fr.ibm.com>
Tue, 30 Oct 2007 22:38:18 +0000 (15:38 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Wed, 31 Oct 2007 04:16:18 +0000 (21:16 -0700)
commit93ee31f14f6f7b5b427c2fdc715d5571eb0be9e5
treeb2edac4817e12bc85c45d02d77a2226dd5df2d10
parent5c41542bdeaafe922a07bcdebc10d96a3b8ffeee
[NET]: Fix free_netdev on register_netdev failure.

Point 1:
The unregistering of a network device schedule a netdev_run_todo.
This function calls dev->destructor when it is set and the
destructor calls free_netdev.

Point 2:
In the case of an initialization of a network device the usual code
is:
 * alloc_netdev
 * register_netdev
    -> if this one fails, call free_netdev and exit with error.

Point 3:
In the register_netdevice function at the later state, when the device
is at the registered state, a call to the netdevice_notifiers is made.
If one of the notification falls into an error, a rollback to the
registered state is done using unregister_netdevice.

Conclusion:
When a network device fails to register during initialization because
one network subsystem returned an error during a notification call
chain, the network device is freed twice because of fact 1 and fact 2.
The second free_netdev will be done with an invalid pointer.

Proposed solution:
The following patch move all the code of unregister_netdevice *except*
the call to net_set_todo, to a new function "rollback_registered".

The following functions are changed in this way:
 * register_netdevice: calls rollback_registered when a notification fails
 * unregister_netdevice: calls rollback_register + net_set_todo, the call
                         order to net_set_todo is changed because it is the
                         latest now. Since it justs add an element to a list
                         that should not break anything.

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/dev.c