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
454 id_priv->id.route.addr.dev_addr.transport =454 id_priv->id.route.addr.dev_addr.transport =
455 rdma_node_get_transport(cma_dev->device->node_type);455 rdma_node_get_transport(cma_dev->device->node_type);
456 list_add_tail(&id_priv->list, &cma_dev->id_list);456 list_add_tail(&id_priv->list, &cma_dev->id_list);
457 rdma_restrack_add(&id_priv->res);
458 457
459 trace_cm_id_attach(id_priv, cma_dev->device);458 trace_cm_id_attach(id_priv, cma_dev->device);
460}459}
@@ -691,6 +690,7 @@ static int cma_ib_acquire_dev(struct rdma_id_private *id_priv, · 230 unmodified lines
691 mutex_lock(&lock);690 mutex_lock(&lock);
692 cma_attach_to_dev(id_priv, listen_id_priv->cma_dev);691 cma_attach_to_dev(id_priv, listen_id_priv->cma_dev);
693 mutex_unlock(&lock);692 mutex_unlock(&lock);
693 rdma_restrack_add(&id_priv->res);
694 return 0;694 return 0;
695}695}
696 696
@@ -745,8 +745,10 @@ static int cma_iw_acquire_dev(struct rdma_id_private *id_priv, · 48 unmodified lines
745 }745 }
746 746
747out:747out:
748 if (!ret)748 if (!ret) {
749 cma_attach_to_dev(id_priv, cma_dev);749 cma_attach_to_dev(id_priv, cma_dev);
750 rdma_restrack_add(&id_priv->res);
751 }
750 752
751 mutex_unlock(&lock);753 mutex_unlock(&lock);
752 return ret;754 return ret;
@@ -807,6 +809,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) · 54 unmodified lines
807 809
808found:810found:
809 cma_attach_to_dev(id_priv, cma_dev);811 cma_attach_to_dev(id_priv, cma_dev);
812 rdma_restrack_add(&id_priv->res);
810 mutex_unlock(&lock);813 mutex_unlock(&lock);
811 addr = (struct sockaddr_ib *)cma_src_addr(id_priv);814 addr = (struct sockaddr_ib *)cma_src_addr(id_priv);
812 memcpy(&addr->sib_addr, &sgid, sizeof(sgid));815 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
2526 rdma_addr_size(cma_src_addr(id_priv)));2529 rdma_addr_size(cma_src_addr(id_priv)));
2527 2530
2528 _cma_attach_to_dev(dev_id_priv, cma_dev);2531 _cma_attach_to_dev(dev_id_priv, cma_dev);
2532 rdma_restrack_add(&dev_id_priv->res);
2529 cma_id_get(id_priv);2533 cma_id_get(id_priv);
2530 dev_id_priv->internal_id = 1;2534 dev_id_priv->internal_id = 1;
2531 dev_id_priv->afonly = id_priv->afonly;2535 dev_id_priv->afonly = id_priv->afonly;
@@ -3203,6 +3207,7 @@ port_found: · 671 unmodified lines
3203 ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);3207 ib_addr_set_pkey(&id_priv->id.route.addr.dev_addr, pkey);
3204 id_priv->id.port_num = p;3208 id_priv->id.port_num = p;
3205 cma_attach_to_dev(id_priv, cma_dev);3209 cma_attach_to_dev(id_priv, cma_dev);
3210 rdma_restrack_add(&id_priv->res);
3206 cma_set_loopback(cma_src_addr(id_priv));3211 cma_set_loopback(cma_src_addr(id_priv));
3207out:3212out:
3208 mutex_unlock(&lock);3213 mutex_unlock(&lock);
@@ -3235,6 +3240,7 @@ static void addr_handler(int status, struct sockaddr *src_addr, · 26 unmodified lines
3235 if (status)3240 if (status)
3236 pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to acquire device. status %d\n",3241 pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to acquire device. status %d\n",
3237 status);3242 status);
3243 rdma_restrack_add(&id_priv->res);
3238 } else if (status) {3244 } else if (status) {
3239 pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to resolve IP. status %d\n", status);3245 pr_debug_ratelimited("RDMA CM: ADDR_ERROR: failed to resolve IP. status %d\n", status);
3240 }3246 }
@@ -3846,6 +3852,8 @@ int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr) · 605 unmodified lines
3846 if (ret)3852 if (ret)
3847 goto err2;3853 goto err2;
3848 3854
3855 if (!cma_any_addr(addr))
3856 rdma_restrack_add(&id_priv->res);
3849 return 0;3857 return 0;
3850err2:3858err2:
3851 if (id_priv->cma_dev)3859 if (id_priv->cma_dev)