<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <p><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 2024/4/9 16:30, Aleksandr Mishin
      wrote:<br>
    </div>
    <blockquote cite="mid:20240409083047.15784-1-amishin@t-argos.ru"
      type="cite">
      <pre wrap="">In hns_roce_hw_v2_get_cfg() pci_match_id() may return
NULL which is later dereferenced. Fix this bug by adding NULL check.</pre>
    </blockquote>
    <br>
    <pre wrap=""><span class="Y2IQFc" lang="en">pci_match_id() will be called multiple times on the same device. When
the device is loaded, it is called for the first time in
hns_roce_hw_v2_init_instance(). In this function, the result of the
pci_device_id() will be verified. If the verification fails, the device
will fail to load.

</span><span class="Y2IQFc" lang="en">Therefore, pci_match_id() in hns_roce_hw_v2_get_cfg() cannot return NULL.</span>
</pre>
    <blockquote cite="mid:20240409083047.15784-1-amishin@t-argos.ru"
      type="cite">
      <pre wrap="">

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 0b567cde9d7a ("RDMA/hns: Enable RoCE on virtual functions")
Signed-off-by: Aleksandr Mishin <a class="moz-txt-link-rfc2396E" href="mailto:amishin@t-argos.ru"><amishin@t-argos.ru></a>
---
 drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 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 ba7ae792d279..31a2093334d9 100644
--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
@@ -6754,7 +6754,7 @@ static const struct pci_device_id hns_roce_hw_v2_pci_tbl[] = {
 
 MODULE_DEVICE_TABLE(pci, hns_roce_hw_v2_pci_tbl);
 
-static void hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev,
+static int hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev,
                                  struct hnae3_handle *handle)
 {
        struct hns_roce_v2_priv *priv = hr_dev->priv;
@@ -6763,6 +6763,9 @@ static void hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev,
 
        hr_dev->pci_dev = handle->pdev;
        id = pci_match_id(hns_roce_hw_v2_pci_tbl, hr_dev->pci_dev);
+       if (!id)
+               return -ENXIO;
+
        hr_dev->is_vf = id->driver_data;
        hr_dev->dev = &handle->pdev->dev;
        hr_dev->hw = &hns_roce_hw_v2;
@@ -6789,6 +6792,8 @@ static void hns_roce_hw_v2_get_cfg(struct hns_roce_dev *hr_dev,
 
        hr_dev->reset_cnt = handle->ae_algo->ops->ae_dev_reset_cnt(handle);
        priv->handle = handle;
+
+       return 0;
 }
 
 static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
@@ -6806,7 +6811,11 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle)
                goto error_failed_kzalloc;
        }
 
-       hns_roce_hw_v2_get_cfg(hr_dev, handle);
+       ret = hns_roce_hw_v2_get_cfg(hr_dev, handle);
+       if (ret) {
+               dev_err(hr_dev->dev, "RoCE Engine cfg failed!\n");
+               goto error_failed_roce_init;
+       }
 
        ret = hns_roce_init(hr_dev);
        if (ret) {
</pre>
    </blockquote>
    <br>
  </body>
</html>