From: Alexander Aring Date: Thu, 30 Jul 2015 07:40:53 +0000 (+0200) Subject: Bluetooth: 6lowpan: Fix possible race X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=5857d1dbae7d5bf4219efc39996ad002362a2951;p=linux-beck.git 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 Signed-off-by: Marcel Holtmann --- diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 2fb7b3064904..0ffe2e24020a 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -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_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); 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; } @@ -871,16 +884,6 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev) &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; - 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; out: