Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA/cma: Use correct address when leaving multicast group

In RoCE we should use cma_iboe_set_mgid() and not cma_set_mgid to generate
the mgid, otherwise we will generate an IGMP for an incorrect address.

Fixes: b5de0c60cc30 ("RDMA/cma: Fix use after free race in roce multicast join")
Link: https://lore.kernel.org/r/913bc6783fd7a95fe71ad9454e01653ee6fb4a9a.1642491047.git.leonro@nvidia.com
Signed-off-by: Maor Gottlieb <maorg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Maor Gottlieb and committed by
Jason Gunthorpe
d9e410eb e5cce44a

+12 -10
+12 -10
drivers/infiniband/core/cma.c
··· 67 67 [RDMA_CM_EVENT_TIMEWAIT_EXIT] = "timewait exit", 68 68 }; 69 69 70 - static void cma_set_mgid(struct rdma_id_private *id_priv, struct sockaddr *addr, 71 - union ib_gid *mgid); 70 + static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid, 71 + enum ib_gid_type gid_type); 72 72 73 73 const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event) 74 74 { ··· 1846 1846 if (dev_addr->bound_dev_if) 1847 1847 ndev = dev_get_by_index(dev_addr->net, 1848 1848 dev_addr->bound_dev_if); 1849 - if (ndev) { 1849 + if (ndev && !send_only) { 1850 + enum ib_gid_type gid_type; 1850 1851 union ib_gid mgid; 1851 1852 1852 - cma_set_mgid(id_priv, (struct sockaddr *)&mc->addr, 1853 - &mgid); 1854 - 1855 - if (!send_only) 1856 - cma_igmp_send(ndev, &mgid, false); 1857 - 1858 - dev_put(ndev); 1853 + gid_type = id_priv->cma_dev->default_gid_type 1854 + [id_priv->id.port_num - 1855 + rdma_start_port( 1856 + id_priv->cma_dev->device)]; 1857 + cma_iboe_set_mgid((struct sockaddr *)&mc->addr, &mgid, 1858 + gid_type); 1859 + cma_igmp_send(ndev, &mgid, false); 1859 1860 } 1861 + dev_put(ndev); 1860 1862 1861 1863 cancel_work_sync(&mc->iboe_join.work); 1862 1864 }