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.

Best regards,
Thorsten

Reply via email to