Commit 5857d1db authored by Alexander Aring's avatar Alexander Aring Committed by Marcel Holtmann

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: default avatarAlexander Aring <alex.aring@gmail.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent c22ff7b4
...@@ -859,9 +859,22 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) ...@@ -859,9 +859,22 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev); SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
SET_NETDEV_DEVTYPE(netdev, &bt_type); SET_NETDEV_DEVTYPE(netdev, &bt_type);
*dev = netdev_priv(netdev);
(*dev)->netdev = netdev;
(*dev)->hdev = chan->conn->hcon->hdev;
INIT_LIST_HEAD(&(*dev)->peers);
spin_lock(&devices_lock);
INIT_LIST_HEAD(&(*dev)->list);
list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
spin_unlock(&devices_lock);
err = register_netdev(netdev); err = register_netdev(netdev);
if (err < 0) { if (err < 0) {
BT_INFO("register_netdev failed %d", err); BT_INFO("register_netdev failed %d", err);
spin_lock(&devices_lock);
list_del_rcu(&(*dev)->list);
spin_unlock(&devices_lock);
free_netdev(netdev); free_netdev(netdev);
goto out; goto out;
} }
...@@ -871,16 +884,6 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) ...@@ -871,16 +884,6 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
&chan->src, chan->src_type); &chan->src, chan->src_type);
set_bit(__LINK_STATE_PRESENT, &netdev->state); set_bit(__LINK_STATE_PRESENT, &netdev->state);
*dev = netdev_priv(netdev);
(*dev)->netdev = netdev;
(*dev)->hdev = chan->conn->hcon->hdev;
INIT_LIST_HEAD(&(*dev)->peers);
spin_lock(&devices_lock);
INIT_LIST_HEAD(&(*dev)->list);
list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
spin_unlock(&devices_lock);
return 0; return 0;
out: out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment