On Mon, 19 Oct 2026 at 02:07, Thorsten Blum <[email protected]> wrote:
>
> Hi PrasannaKumar,
>
> On Sun, Oct 18, 2026 at 10:30:08PM +0530, PrasannaKumar Muralidharan wrote:
> > Hi Thorsten,
> >
> > On Fri, 16 Oct 2026 at 16:16, Thorsten Blum <[email protected]> wrote:
> > >
> > > remove_common() frees the driver data during freeze, but does not clear
> > > vdev->priv, which points to freed memory. If probe_common() then fails
> > > during restore, a later remove or freeze can dereference the dangling
> > > pointer.
> > >
> > > Clear vdev->priv on the probe_common() error cleanup path and before
> > > freeing the driver data in remove_common(). Also reset the device and
> > > return early from remove_common() if vdev->priv is already NULL for a
> > > safe teardown after a failed restore.
> > >
> > > Fixes: 08e53fbdb85c ("virtio-rng: support multiple virtio-rng devices")
> > > Cc: [email protected]
> > > Signed-off-by: Thorsten Blum <[email protected]>
> > > ---
> > >  drivers/char/hw_random/virtio-rng.c | 7 +++++++
> > >  1 file changed, 7 insertions(+)
> > >
> > > diff --git a/drivers/char/hw_random/virtio-rng.c 
> > > b/drivers/char/hw_random/virtio-rng.c
> > > index 5e83ffa105e4..a9ff520975a7 100644
> > > --- a/drivers/char/hw_random/virtio-rng.c
> > > +++ b/drivers/char/hw_random/virtio-rng.c
> > > @@ -190,6 +190,7 @@ static int probe_common(struct virtio_device *vdev)
> > >  err_find:
> > >         ida_free(&rng_index_ida, index);
> > >  err_ida:
> > > +       vdev->priv = NULL;
> > >         kfree(vi);
> > >         return err;
> > >  }
> > > @@ -198,6 +199,11 @@ static void remove_common(struct virtio_device *vdev)
> > >  {
> > >         struct virtrng_info *vi = vdev->priv;
> > >
> > > +       if (!vi) {
> > > +               virtio_reset_device(vdev);
> > > +               return;
> > > +       }
> > > +
> >
> > The virtio_reset_device() is always called before setting vdev->priv
> > to NULL. So the virtio device is already quiesced, no need to do early
> > return. Isn't it?
>
> The check is still needed.
>
> For example, during hibernation or suspend, .freeze (virtrng_freeze() ->
> remove_common()) frees vi and sets vdev->priv to NULL.
>
> On resume, .restore (virtrng_restore()) calls probe_common(), which
> could fail and leave vdev->priv NULL. A later .freeze or .remove calls
> remove_common() again, which would dereference NULL without the check.

Yes, it makes sense.

> Best regards,
> Thorsten

Change looks good to me.

Feel free to add:
Reviewed-by: PrasannaKumar Muralidharan <[email protected]>.

Thanks,
PrasannaKumar

Reply via email to