Commit 07c63fd0 authored by Parav Pandit's avatar Parav Pandit Committed by Greg Kroah-Hartman

RDMA/cma: Protect cma dev list with lock

commit 954a8e3a upstream.

When AF_IB addresses are used during rdma_resolve_addr() a lock is not
held. A cma device can get removed while list traversal is in progress
which may lead to crash. ie

        CPU0                                     CPU1
        ====                                     ====
rdma_resolve_addr()
 cma_resolve_ib_dev()
  list_for_each()                         cma_remove_one()
    cur_dev->device                        mutex_lock(&lock)
                                            list_del();
                                           mutex_unlock(&lock);
                                           cma_process_remove();


Therefore, hold a lock while traversing the list which avoids such
situation.

Cc: <stable@vger.kernel.org> # 3.10
Fixes: f17df3b0 ("RDMA/cma: Add support for AF_IB to rdma_resolve_addr()")
Signed-off-by: default avatarParav Pandit <parav@mellanox.com>
Reviewed-by: default avatarDaniel Jurgens <danielj@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 12c3ba18
...@@ -544,6 +544,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) ...@@ -544,6 +544,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
dgid = (union ib_gid *) &addr->sib_addr; dgid = (union ib_gid *) &addr->sib_addr;
pkey = ntohs(addr->sib_pkey); pkey = ntohs(addr->sib_pkey);
mutex_lock(&lock);
list_for_each_entry(cur_dev, &dev_list, list) { list_for_each_entry(cur_dev, &dev_list, list) {
for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) { for (p = 1; p <= cur_dev->device->phys_port_cnt; ++p) {
if (!rdma_cap_af_ib(cur_dev->device, p)) if (!rdma_cap_af_ib(cur_dev->device, p))
...@@ -567,18 +568,19 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) ...@@ -567,18 +568,19 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv)
cma_dev = cur_dev; cma_dev = cur_dev;
sgid = gid; sgid = gid;
id_priv->id.port_num = p; id_priv->id.port_num = p;
goto found;
} }
} }
} }
} }
mutex_unlock(&lock);
if (!cma_dev) return -ENODEV;
return -ENODEV;
found: found:
cma_attach_to_dev(id_priv, cma_dev); cma_attach_to_dev(id_priv, cma_dev);
addr = (struct sockaddr_ib *) cma_src_addr(id_priv); mutex_unlock(&lock);
memcpy(&addr->sib_addr, &sgid, sizeof sgid); addr = (struct sockaddr_ib *)cma_src_addr(id_priv);
memcpy(&addr->sib_addr, &sgid, sizeof(sgid));
cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr); cma_translate_ib(addr, &id_priv->id.route.addr.dev_addr);
return 0; return 0;
} }
......
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