On Fri, 9 Sep 2022 18:22:38 +0800 Kevin Tian <kevin.tian@xxxxxxxxx> wrote: > From: Yi Liu <yi.l.liu@xxxxxxxxx> > > and manage available ports inside @init/@release. > > Signed-off-by: Yi Liu <yi.l.liu@xxxxxxxxx> > Signed-off-by: Kevin Tian <kevin.tian@xxxxxxxxx> > Reviewed-by: Jason Gunthorpe <jgg@xxxxxxxxxx> > --- > samples/vfio-mdev/mtty.c | 67 +++++++++++++++++++++++----------------- > 1 file changed, 39 insertions(+), 28 deletions(-) > > diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c > index f42a59ed2e3f..41301d50b247 100644 > --- a/samples/vfio-mdev/mtty.c > +++ b/samples/vfio-mdev/mtty.c ... > +static int mtty_probe(struct mdev_device *mdev) > +{ > + struct mdev_state *mdev_state; > + int ret; > + > + mdev_state = vfio_alloc_device(mdev_state, vdev, &mdev->dev, > + &mtty_dev_ops); > + if (IS_ERR(mdev_state)) > + return PTR_ERR(mdev_state); > > ret = vfio_register_emulated_iommu_dev(&mdev_state->vdev); > if (ret) > - goto err_vconfig; > + goto err_put_vdev; > dev_set_drvdata(&mdev->dev, mdev_state); > return 0; > > -err_vconfig: > - kfree(mdev_state->vconfig); > -err_state: > - vfio_uninit_group_dev(&mdev_state->vdev); > - kfree(mdev_state); > -err_nr_ports: > - atomic_add(nr_ports, &mdev_avail_ports); > +err_put_vdev: > + vfio_put_device(&mdev_state->vdev); > return ret; > } > > +static void mtty_release_dev(struct vfio_device *vdev) > +{ > + struct mdev_state *mdev_state = > + container_of(vdev, struct mdev_state, vdev); > + > + kfree(mdev_state->vconfig); > + vfio_free_device(vdev); > + atomic_add(mdev_state->nr_ports, &mdev_avail_ports); I must be missing something, isn't this a use-after-free? mdev_state is allocated via vfio_alloc_device(), where vdev is the first entry in that structure, so this is equivalent to kvfree(mdev_state). mbochs has the same issue. mdpy and vfio-ap adjust global counters after vfio_free_device(), which I think muddies the situation. Shouldn't we look suspiciously at any .release callback where vfio_free_device() isn't the last thing executed? Thanks, Alex