Re: [net-next PATCH 3/9] octeontx2-pf: Create representor netdev

From: Dan Carpenter
Date: Wed Apr 17 2024 - 11:24:39 EST


Hi Geetha,

kernel test robot noticed the following build warnings:

url: https://github.com/intel-lab-lkp/linux/commits/Geetha-sowjanya/octeontx2-pf-Refactoring-RVU-driver/20240416-131052
base: net-next/main
patch link: https://lore.kernel.org/r/20240416050616.6056-4-gakula%40marvell.com
patch subject: [net-next PATCH 3/9] octeontx2-pf: Create representor netdev
config: alpha-randconfig-r081-20240417 (https://download.01.org/0day-ci/archive/20240417/202404172208.4REfSKKS-lkp@xxxxxxxxx/config)
compiler: alpha-linux-gcc (GCC) 13.2.0

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
| Closes: https://lore.kernel.org/r/202404172208.4REfSKKS-lkp@xxxxxxxxx/

New smatch warnings:
drivers/net/ethernet/marvell/octeontx2/nic/rep.c:170 rvu_rep_create() error: dereferencing freed memory 'ndev'

vim +/ndev +170 drivers/net/ethernet/marvell/octeontx2/nic/rep.c

f9a5b510759eeb Geetha sowjanya 2024-04-16 131
f9a5b510759eeb Geetha sowjanya 2024-04-16 132 int rvu_rep_create(struct otx2_nic *priv)
f9a5b510759eeb Geetha sowjanya 2024-04-16 133 {
f9a5b510759eeb Geetha sowjanya 2024-04-16 134 int rep_cnt = priv->rep_cnt;
f9a5b510759eeb Geetha sowjanya 2024-04-16 135 struct net_device *ndev;
f9a5b510759eeb Geetha sowjanya 2024-04-16 136 struct rep_dev *rep;
f9a5b510759eeb Geetha sowjanya 2024-04-16 137 int rep_id, err;
f9a5b510759eeb Geetha sowjanya 2024-04-16 138 u16 pcifunc;
f9a5b510759eeb Geetha sowjanya 2024-04-16 139
f9a5b510759eeb Geetha sowjanya 2024-04-16 140 priv->reps = devm_kcalloc(priv->dev, rep_cnt, sizeof(struct rep_dev), GFP_KERNEL);
f9a5b510759eeb Geetha sowjanya 2024-04-16 141 if (!priv->reps)
f9a5b510759eeb Geetha sowjanya 2024-04-16 142 return -ENOMEM;
f9a5b510759eeb Geetha sowjanya 2024-04-16 143
f9a5b510759eeb Geetha sowjanya 2024-04-16 144 for (rep_id = 0; rep_id < rep_cnt; rep_id++) {
f9a5b510759eeb Geetha sowjanya 2024-04-16 145 ndev = alloc_etherdev(sizeof(*rep));
f9a5b510759eeb Geetha sowjanya 2024-04-16 146 if (!ndev) {
f9a5b510759eeb Geetha sowjanya 2024-04-16 147 dev_err(priv->dev, "PFVF representor:%d creation failed\n", rep_id);
f9a5b510759eeb Geetha sowjanya 2024-04-16 148 err = -ENOMEM;
f9a5b510759eeb Geetha sowjanya 2024-04-16 149 goto exit;
f9a5b510759eeb Geetha sowjanya 2024-04-16 150 }
f9a5b510759eeb Geetha sowjanya 2024-04-16 151
f9a5b510759eeb Geetha sowjanya 2024-04-16 152 rep = netdev_priv(ndev);
f9a5b510759eeb Geetha sowjanya 2024-04-16 153 priv->reps[rep_id] = rep;
f9a5b510759eeb Geetha sowjanya 2024-04-16 154 rep->mdev = priv;
f9a5b510759eeb Geetha sowjanya 2024-04-16 155 rep->netdev = ndev;
f9a5b510759eeb Geetha sowjanya 2024-04-16 156 rep->rep_id = rep_id;
f9a5b510759eeb Geetha sowjanya 2024-04-16 157
f9a5b510759eeb Geetha sowjanya 2024-04-16 158 ndev->min_mtu = OTX2_MIN_MTU;
f9a5b510759eeb Geetha sowjanya 2024-04-16 159 ndev->max_mtu = priv->hw.max_mtu;
f9a5b510759eeb Geetha sowjanya 2024-04-16 160 pcifunc = priv->rep_pf_map[rep_id];
f9a5b510759eeb Geetha sowjanya 2024-04-16 161 rep->pcifunc = pcifunc;
f9a5b510759eeb Geetha sowjanya 2024-04-16 162
f9a5b510759eeb Geetha sowjanya 2024-04-16 163 snprintf(ndev->name, sizeof(ndev->name), "r%dp%dv%d", rep_id,
f9a5b510759eeb Geetha sowjanya 2024-04-16 164 rvu_get_pf(pcifunc), (pcifunc & RVU_PFVF_FUNC_MASK));
f9a5b510759eeb Geetha sowjanya 2024-04-16 165
f9a5b510759eeb Geetha sowjanya 2024-04-16 166 eth_hw_addr_random(ndev);
f9a5b510759eeb Geetha sowjanya 2024-04-16 167 if (register_netdev(ndev)) {

err = register_netdev(ndev);
if (err) {

f9a5b510759eeb Geetha sowjanya 2024-04-16 168 dev_err(priv->dev, "PFVF reprentator registration failed\n");
f9a5b510759eeb Geetha sowjanya 2024-04-16 169 free_netdev(ndev);
^^^^
freed

f9a5b510759eeb Geetha sowjanya 2024-04-16 @170 ndev->netdev_ops = NULL;
^^^^^^^^^^^^^^^^^^^^^^^
Use after free

f9a5b510759eeb Geetha sowjanya 2024-04-16 171 goto exit;
f9a5b510759eeb Geetha sowjanya 2024-04-16 172 }
f9a5b510759eeb Geetha sowjanya 2024-04-16 173 }
f9a5b510759eeb Geetha sowjanya 2024-04-16 174 err = rvu_rep_napi_init(priv);
f9a5b510759eeb Geetha sowjanya 2024-04-16 175 if (err)
f9a5b510759eeb Geetha sowjanya 2024-04-16 176 goto exit;
f9a5b510759eeb Geetha sowjanya 2024-04-16 177
f9a5b510759eeb Geetha sowjanya 2024-04-16 178 return 0;
f9a5b510759eeb Geetha sowjanya 2024-04-16 179 exit:
f9a5b510759eeb Geetha sowjanya 2024-04-16 180 rvu_rep_free_netdev(priv);

rvu_rep_free_netdev() also calls free_netdev() so it's a double free. I
would normally write this as:

exit:
while (--rep_id >= 0) {
unregister_netdev(priv->reps[rep_id]);
free_netdev(priv->reps[rep_id]);
}

return err;

When you write it that way then rvu_rep_free_netdev() can be made easier
as well:

static void rvu_rep_free_netdev(struct otx2_nic *priv)
{
int rep_id;

for (rep_id = 0; rep_id < priv->rep_cnt; rep_id++) {
unregister_netdev(priv->reps[rep_id]);
free_netdev(priv->reps[rep_id]);
}
}

There should be no need to call devm_kfree(priv->dev, priv->reps);.

f9a5b510759eeb Geetha sowjanya 2024-04-16 @181 return err;
f9a5b510759eeb Geetha sowjanya 2024-04-16 182 }

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki