Re: [PATCH v2] hw/display/vmware_vga: Don't allow guest to trigger long running loop in host

Daniel P. Berrangé <[email protected]> Thu, 23 Jul 2026 17:20:13 +0100
Newsgroups org.nongnu.qemu-trivial,org.nongnu.qemu-devel
Message-ID <[email protected]>
On Thu, Jul 23, 2026 at 06:18:28PM +0200, Thomas Huth wrote:
> On 23/07/2026 17.16, Daniel P. Berrangé wrote:
> > On Thu, Jul 23, 2026 at 03:54:41PM +0200, Philippe Mathieu-Daudé wrote:
> > > On 23/7/26 14:44, Thomas Huth wrote:
> > > > From: Thomas Huth <[email protected]>
> > > > 
> > > > The code in the SVGA_CMD_DEFINE_ALPHA_CURSOR handler in vmsvga_fifo_run()
> > > > basically does:
> > > > 
> > > >               x = vmsvga_fifo_read(s);
> > > >               y = vmsvga_fifo_read(s);
> > > >               args = x * y;
> > > >               goto badcmd;
> > > >               ...
> > > > badcmd:
> > > >               len -= args;
> > > >               if (len < 0) {
> > > >                   goto rewind;
> > > >               }
> > > >               while (args--) {
> > > >                   vmsvga_fifo_read(s);
> > > >               }
> > > > 
> > > > Thus by supplying huge values for x and y that overflow the result of
> > > > the multiplication, the guest can trigger a long-running loop here
> > > > that burns the host's CPU cycles.
> > > > 
> > > > Add some sanity checks so that this cannot happen anymore.
> > > > 
> > > > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3782
> > > > Reported-by: Feifan Qian <[email protected]>
> > > > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4026
> > > > Reported-by: Tristan Madani <[email protected]>
> > > > Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4076
> > > > Reported-by: Sunday Jiang
> > > > Signed-off-by: Thomas Huth <[email protected]>
> > > > ---
> > > >    v2: Use SVGA_MAX_WIDTH and SVGA_MAX_HEIGHT instead of an arbitrary value
> > > > 
> > > >    hw/display/vmware_vga.c | 6 +++++-
> > > >    1 file changed, 5 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
> > > > index f6f9edfd1d9..567806f0e47 100644
> > > > --- a/hw/display/vmware_vga.c
> > > > +++ b/hw/display/vmware_vga.c
> > > > @@ -737,6 +737,10 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
> > > >                vmsvga_fifo_read(s);
> > > >                x = vmsvga_fifo_read(s);
> > > >                y = vmsvga_fifo_read(s);
> > > > +            if (x < 0 || x >= SVGA_MAX_WIDTH ||
> > > > +                y < 0 || y >= SVGA_MAX_HEIGHT) {
> > > 
> > > vmsvga_fifo_read() returns unsigned... otherwise:
> > 
> > But x & y  are declared 'int', so at least on 32-bit builds
> > a large uint32_t value would wrap and become negative.
> > Although we dropped support for 32-bit platforms, IMHO it would
> > be better to use uint32_t for 'x' and 'y' too rather than
> > assuming the 'int' value won't be negative.
> x and y are used as signed int all over the place here ... so reworking that
> goes way beyond fixing this problem. Could we please get this patch merged
> first for 11.1, and if someone then still feels like reworking the code,
> this could be done for 11.2 ?

Ok, then the < 0 checks should be kept.

With regards,
Daniel
-- 
|: https://berrange.com       ~~        https://hachyderm.io/@berrange :|
|: https://libvirt.org          ~~          https://entangle-photo.org :|
|: https://pixelfed.art/berrange   ~~    https://fstop138.berrange.com :|