[OLK-5.10 1/3] RDMA/hns: Fix Use-After-Free of rsv_qp

From: wenglianfa <wenglianfa@huawei.com> driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8N7BG ---------------------------------------------------------------------- For the HIP08, the reserved loopback QP is used to release MRs before the MPT is destroyed. After free_mr_exit() and before hns_roce_unregister_device(), rsv_qp is released and set to NULL, and ib_device is not unregister. During this period, the user mode can use ib_device to execute dereg_mr(). As a result, rsv_qp is accessed again and a NULL pointer is reported. To fix Use-After-Free of rsv_qp, execute free_mr_exit() after hns_roce_unregister_device(). Fixes: 6f5f556d3795 ("RDMA/hns: Use the reserved loopback QPs to free MR before destroying MPT") Signed-off-by: wenglianfa <wenglianfa@huawei.com> Signed-off-by: Juan Zhou <zhoujuan51@h-partners.com> --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 2b474c22cafa..34d5d1476db2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -3339,6 +3339,9 @@ static int hns_roce_v2_init(struct hns_roce_dev *hr_dev) static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev) { + if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) + free_mr_exit(hr_dev); + hns_roce_function_clear(hr_dev); if (!hr_dev->is_vf) @@ -7699,9 +7702,6 @@ static void __hns_roce_hw_v2_uninit_instance(struct hnae3_handle *handle, hr_dev->state = HNS_ROCE_DEVICE_STATE_UNINIT; hns_roce_handle_device_err(hr_dev); - if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) - free_mr_exit(hr_dev); - hns_roce_exit(hr_dev, bond_cleanup); kfree(hr_dev->priv); ib_dealloc_device(&hr_dev->ib_dev); -- 2.30.0

From: Junxian Huang <huangjunxian6@hisilicon.com> driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8QLD3 ---------------------------------------------------------------------- This reverts commit 2185e6513c793a4a2c5c3fc1ac6b57c5df2b8d9b. Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com> --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 34d5d1476db2..4909c9c186cc 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -7653,8 +7653,7 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) hns_roce_hw_v2_get_cfg(hr_dev, handle); - if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_BOND && - hr_dev->is_vf && !check_vf_support(hr_dev->pci_dev)) { + if (hr_dev->is_vf && !check_vf_support(hr_dev->pci_dev)) { ret = -EOPNOTSUPP; goto error_failed_roce_init; } -- 2.30.0

From: Junxian Huang <huangjunxian6@hisilicon.com> driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I8QLD3 ---------------------------------------------------------------------- This patch makes 2 changes for check_vf_support(): 1. add check of RDMA over UBLink VFs before check_vf_support(), since VFs in this case will never be of RoCE bonding slaves. 2. since RDMA over UBLink VFs won't enter check_vf_support() anymore, the return value is changed to false when the PF doesn't have a corresponding hr_dev so that VFs init can be correctly blocked on those non-main_hr_dev slaves. Fixes: 67fc10550307 ("RDMA/hns: Add support for RDMA VF over UBL") Signed-off-by: Junxian Huang <huangjunxian6@hisilicon.com> --- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 4909c9c186cc..2c03f556f8e0 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -7624,9 +7624,8 @@ static bool check_vf_support(struct pci_dev *vf) handle = &hdev->vport[0].roce; hr_dev = handle->priv; - /* In UB link vf can not find the pf device */ if (!hr_dev) - return true; + return false; bond_grp = hns_roce_get_bond_grp(get_hr_netdev(hr_dev, 0), pf->bus->number); @@ -7639,6 +7638,7 @@ static bool check_vf_support(struct pci_dev *vf) static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) { struct hns_roce_dev *hr_dev; + struct pci_dev *pdev; int ret; hr_dev = ib_alloc_device(hns_roce_dev, ib_dev); @@ -7653,7 +7653,9 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) hns_roce_hw_v2_get_cfg(hr_dev, handle); - if (hr_dev->is_vf && !check_vf_support(hr_dev->pci_dev)) { + pdev = hr_dev->pci_dev; + if (pdev->device != HNAE3_DEV_ID_RDMA_OVER_UBL_VF && + hr_dev->is_vf && !check_vf_support(pdev)) { ret = -EOPNOTSUPP; goto error_failed_roce_init; } @@ -7664,7 +7666,7 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) goto error_failed_roce_init; } - if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) { + if (pdev->revision == PCI_REVISION_ID_HIP08) { ret = free_mr_init(hr_dev); if (ret) { dev_err(hr_dev->dev, "failed to init free mr!\n"); -- 2.30.0
participants (1)
-
Chengchang Tang