Bluetooth: 6lowpan: Fix possible race

This patch fix a possible race after calling register_netdev. After
calling netdev_register it could be possible that netdev_ops callbacks
use the uninitialized private data of lowpan_dev. By moving the
initialization of this data before netdev_register we can be sure that
initialized private data is be used after netdev_register.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
This commit is contained in:
Alexander Aring 2015-07-30 09:40:53 +02:00 committed by Marcel Holtmann
parent c22ff7b4e7
commit 5857d1dbae

View File

@ -859,18 +859,6 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
SET_NETDEV_DEVTYPE(netdev, &bt_type);
err = register_netdev(netdev);
if (err < 0) {
BT_INFO("register_netdev failed %d", err);
free_netdev(netdev);
goto out;
}
BT_DBG("ifindex %d peer bdaddr %pMR type %d my addr %pMR type %d",
netdev->ifindex, &chan->dst, chan->dst_type,
&chan->src, chan->src_type);
set_bit(__LINK_STATE_PRESENT, &netdev->state);
*dev = netdev_priv(netdev);
(*dev)->netdev = netdev;
(*dev)->hdev = chan->conn->hcon->hdev;
@ -881,6 +869,21 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
spin_unlock(&devices_lock);
err = register_netdev(netdev);
if (err < 0) {
BT_INFO("register_netdev failed %d", err);
spin_lock(&devices_lock);
list_del_rcu(&(*dev)->list);
spin_unlock(&devices_lock);
free_netdev(netdev);
goto out;
}
BT_DBG("ifindex %d peer bdaddr %pMR type %d my addr %pMR type %d",
netdev->ifindex, &chan->dst, chan->dst_type,
&chan->src, chan->src_type);
set_bit(__LINK_STATE_PRESENT, &netdev->state);
return 0;
out: