History

RDMA/core: Add CM to restrack after successful attachment to a device

The device attach triggers addition of CM_ID to the restrack DB. However, when error occurs, we releasing this device, but defer CM_ID release. This causes to the situation where restrack sees CM_ID that is not valid anymore. As a solution, add the CM_ID to the resource tracking DB only after the attachment is finished. Found by syzcaller: infiniband syz0: added syz_tun rdma_rxe: ignoring netdev event = 10 for syz_tun infiniband syz0: set down infiniband syz0: ib_query_port failed (-19) restrack: ------------[ cut here ]------------ infiniband syz0: BUG: RESTRACK detected leak of resources restrack: User CM_ID object allocated by syz-executor716 is not freed restrack: ------------[ cut here ]------------

Shay Drory committed 5 years ago

Commit cb5cd0e1 parent 4d51c3d1 file · +10 −2Browse files

Unified · Split

drivers/infiniband/core/cma.c+10−2
@@ -454,7 +454,6 @@ static void _cma_attach_to_dev(struct rdma_id_private *id_priv, · 453 unmodified lines
454454 id_priv->id.route.addr.dev_addr.transport =
455455 rdma_node_get_transport(cma_dev->device->node_type);
456456 list_add_tail(&id_priv->list, &cma_dev->id_list);
457− rdma_restrack_add(&id_priv->res);
458457
459458 trace_cm_id_attach(id_priv, cma_dev->device);
460459 }
@@ -691,6 +690,7 @@ static int cma_ib_acquire_dev(struct rdma_id_private *id_priv, · 230 unmodified lines
691690 mutex_lock(&lock);
692691 cma_attach_to_dev(id_priv, listen_id_priv->cma_dev);
693692 mutex_unlock(&lock);
693+ rdma_restrack_add(&id_priv->res);
694694 return 0;
695695 }
696696
@@ -745,8 +745,10 @@ static int cma_iw_acquire_dev(struct rdma_id_private *id_priv, · 48 unmodified lines
745745 }
746746
747747 out:
748− if (!ret)
748+ if (!ret) {
749749 cma_attach_to_dev(id_priv, cma_dev);
750+ rdma_restrack_add(&id_priv->res);
751+ }
750752
751753 mutex_unlock(&lock);
752754 return ret;
@@ -807,6 +809,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) · 54 unmodified lines
807809
808810 found:
809811 cma_attach_to_dev(id_priv, cma_dev);
812+ rdma_restrack_add(&id_priv->res);
810813 mutex_unlock(&lock);
811814 addr = (struct sockaddr_ib *)cma_src_addr(id_priv);
812815 memcpy(&addr->sib_addr, &sgid, sizeof(sgid));
@@ -2526,6 +2529,7 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv, · 1713 unmodified lines
25262529 rdma_addr_size(cma_src_addr(id_priv)));
25272530
25282531 _cma_attach_to_dev(dev_id_priv, cma_dev);
2532+ rdma_restrack_add(&dev_id_priv->res);
25292533 cma_id_get(id_priv);
25302534 dev_id_priv->internal_id = 1;
25312535 dev_id_priv->afonly = id_priv->afonly;
@@ -3203,6 +3207,7 @@ port_found: · 671 unmodified lines
32033207 ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
32043208 id_priv->id.port_num = p;
32053209 cma_attach_to_dev(id_priv, cma_dev);
3210+ rdma_restrack_add(&id_priv->res);
32063211 cma_set_loopback(cma_src_addr(id_priv));
32073212 out:
32083213 mutex_unlock(&lock);
@@ -3235,6 +3240,7 @@ static void addr_handler(int status, struct sockaddr *src_addr, · 26 unmodified lines
32353240 if (status)
32363241 pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to acquire device. status %d\n",
32373242 status);
3243+ rdma_restrack_add(&id_priv->res);
32383244 } else if (status) {
32393245 pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to resolve IP. status %d\n", status);
32403246 }
@@ -3846,6 +3852,8 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) · 605 unmodified lines
38463852 if (ret)
38473853 goto err2;
38483854
3855+ if (!cma_any_addr(addr))
3856+ rdma_restrack_add(&id_priv->res);
38493857 return 0;
38503858 err2:
38513859 if (id_priv->cma_dev)