qlcnic: potential dereference null pointer of rx_queue->page_ring
authorJiasheng Jiang <jiasheng@iscas.ac.cn>
Fri, 17 Dec 2021 09:39:11 +0000 (17:39 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 29 Dec 2021 11:17:33 +0000 (12:17 +0100)
[ Upstream commit 60ec7fcfe76892a1479afab51ff17a4281923156 ]

The return value of kcalloc() needs to be checked.
To avoid dereference of null pointer in case of the failure of alloc.
Therefore, it might be better to change the return type of
qlcnic_sriov_alloc_vlans() and return -ENOMEM when alloc fails and
return 0 the others.
Also, qlcnic_sriov_set_guest_vlan_mode() and __qlcnic_pci_sriov_enable()
should deal with the return value of qlcnic_sriov_alloc_vlans().

Fixes: 154d0c810c53 ("qlcnic: VLAN enhancement for 84XX adapters")
Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c

index 5f327659efa7a34c3bd6211a6247b734a34f4382..85b688f60b8765b8045bc9332b64526ca33bf2df 100644 (file)
@@ -202,7 +202,7 @@ int qlcnic_sriov_get_vf_vport_info(struct qlcnic_adapter *,
                                   struct qlcnic_info *, u16);
 int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *, u16, u8);
 void qlcnic_sriov_free_vlans(struct qlcnic_adapter *);
-void qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *);
+int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *);
 bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *);
 void qlcnic_sriov_del_vlan_id(struct qlcnic_sriov *,
                              struct qlcnic_vf_info *, u16);
index c58180f408448e9a86a7ce40c6fb286063a6afb0..44caa7c2077ec921e448c22c69c9eb31e205cf3c 100644 (file)
@@ -433,7 +433,7 @@ static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter,
                                            struct qlcnic_cmd_args *cmd)
 {
        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
-       int i, num_vlans;
+       int i, num_vlans, ret;
        u16 *vlans;
 
        if (sriov->allowed_vlans)
@@ -444,7 +444,9 @@ static int qlcnic_sriov_set_guest_vlan_mode(struct qlcnic_adapter *adapter,
        dev_info(&adapter->pdev->dev, "Number of allowed Guest VLANs = %d\n",
                 sriov->num_allowed_vlans);
 
-       qlcnic_sriov_alloc_vlans(adapter);
+       ret = qlcnic_sriov_alloc_vlans(adapter);
+       if (ret)
+               return ret;
 
        if (!sriov->any_vlan)
                return 0;
@@ -2164,7 +2166,7 @@ static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *adapter)
        return err;
 }
 
-void qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter)
+int qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter)
 {
        struct qlcnic_sriov *sriov = adapter->ahw->sriov;
        struct qlcnic_vf_info *vf;
@@ -2174,7 +2176,11 @@ void qlcnic_sriov_alloc_vlans(struct qlcnic_adapter *adapter)
                vf = &sriov->vf_info[i];
                vf->sriov_vlans = kcalloc(sriov->num_allowed_vlans,
                                          sizeof(*vf->sriov_vlans), GFP_KERNEL);
+               if (!vf->sriov_vlans)
+                       return -ENOMEM;
        }
+
+       return 0;
 }
 
 void qlcnic_sriov_free_vlans(struct qlcnic_adapter *adapter)
index 50eaafa3eaba362d0ed9b35821234dcf2551e03f..c9f2cd246223091fe63915c3b7802871d48cdcbb 100644 (file)
@@ -598,7 +598,9 @@ static int __qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter,
        if (err)
                goto del_flr_queue;
 
-       qlcnic_sriov_alloc_vlans(adapter);
+       err = qlcnic_sriov_alloc_vlans(adapter);
+       if (err)
+               goto del_flr_queue;
 
        return err;