Messages in this thread | | | Date | Wed, 17 Apr 2024 18:36:47 +0300 | From | Dan Carpenter <> | Subject | Re: [net-next PATCH 3/9] octeontx2-pf: Create representor netdev |
| |
On Wed, Apr 17, 2024 at 06:24:13PM +0300, Dan Carpenter wrote: > 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.
Actually the rep->netdev->netdev_ops check in rvu_rep_free_netdev() was supposed to prevent the double free. But since rep->netdev is already freed, then it's another use after free. You could use a different flag instead of rep->netdev->netdev_ops to mean "don't free this". But really, it's just better to write it how I have suggested.
My patch adds some duplicate code but when you remove the conditions in rvu_rep_free_netdev() and the "ndev->netdev_ops = NULL" assignment, then overall it's fewer lines of code this way.
https://staticthinking.wordpress.com/2022/04/28/free-the-last-thing-style/
regards, dan carpenter
| |