Re: [PATCH] virtio_ring : fix vring_packed_desc memory out of bounds bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jun 10, 2022 at 10:51 PM Michael S. Tsirkin <mst@xxxxxxxxxx> wrote:
>
> On Fri, Jun 10, 2022 at 06:33:14PM +0800, huangjie.albert wrote:
> > ksoftirqd may consume the packet and it will call:
> > virtnet_poll
> >       -->virtnet_receive
> >               -->virtqueue_get_buf_ctx
> >                       -->virtqueue_get_buf_ctx_packed
> > and in virtqueue_get_buf_ctx_packed:
> >
> > vq->last_used_idx += vq->packed.desc_state[id].num;
> > if (unlikely(vq->last_used_idx >= vq->packed.vring.num)) {
> >          vq->last_used_idx -= vq->packed.vring.num;
> >          vq->packed.used_wrap_counter ^= 1;
> > }
> >
> > if at the same time, there comes a vring interrupt,in vring_interrupt:
> > we will call:
> > vring_interrupt
> >       -->more_used
> >               -->more_used_packed
> >                       -->is_used_desc_packed
> > in is_used_desc_packed, the last_used_idx maybe >= vq->packed.vring.num.
> > so this could case a memory out of bounds bug.
> >
> > this patch is to fix this.
> >
> > Signed-off-by: huangjie.albert <huangjie.albert@xxxxxxxxxxxxx>
>
>
> This pattern was always iffy, but I don't think the patch
> improves the situation much. last_used_idx and vq->packed.used_wrap_counter
> can still get out of sync.
>
> Maybe refactor code to keep everything in vq->last_used_idx?
>
> Jason what is your take?

I think we can do this since 16bit/32bit operations are guaranteed to be atomic.

Thanks

>
>
>
>
>
> > ---
> >  drivers/virtio/virtio_ring.c | 3 +++
> >  1 file changed, 3 insertions(+)
> >
> > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > index 13a7348cedff..d2abbb3a8187 100644
> > --- a/drivers/virtio/virtio_ring.c
> > +++ b/drivers/virtio/virtio_ring.c
> > @@ -1397,6 +1397,9 @@ static inline bool is_used_desc_packed(const struct vring_virtqueue *vq,
> >       bool avail, used;
> >       u16 flags;
> >
> > +     if (idx >= vq->packed.vring.num)
> > +             return false;
> > +
> >       flags = le16_to_cpu(vq->packed.vring.desc[idx].flags);
> >       avail = !!(flags & (1 << VRING_PACKED_DESC_F_AVAIL));
> >       used = !!(flags & (1 << VRING_PACKED_DESC_F_USED));
> > --
> > 2.27.0
>

_______________________________________________
Virtualization mailing list
Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linuxfoundation.org/mailman/listinfo/virtualization




[Index of Archives]     [KVM Development]     [Libvirt Development]     [Libvirt Users]     [CentOS Virtualization]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux