Validate the stride value provided by guest firmware before using it:
it must be at least linesize (otherwise scanlines overlap and the
mapped region would be too small), 4-byte aligned (pixman requirement),
and the stride*height product must not overflow INT_MAX (since
pixman_image_get_stride returns int, used in the unmap callback).

Without these checks, a malicious guest can craft stride values that
lead to undersized memory mappings or integer overflow.

Reported-by: Pavee Hui <[email protected]>
Fixes: 3fcf15df0073 ("ramfb: fix size calculation")
Signed-off-by: Marc-André Lureau <[email protected]>
---
 hw/display/ramfb.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/display/ramfb.c b/hw/display/ramfb.c
index f477bdcc2186..2d5378754717 100644
--- a/hw/display/ramfb.c
+++ b/hw/display/ramfb.c
@@ -63,6 +63,9 @@ static DisplaySurface *ramfb_create_display_surface(int 
width, int height,
     if (stride == 0) {
         stride = linesize;
     }
+    if (stride < linesize || stride % 4 != 0 || stride > INT_MAX / height) {
+        return NULL;
+    }
 
     mapsize = size = stride * (height - 1) + linesize;
     data = physical_memory_map(addr, &mapsize, false);

-- 
2.56.0.rc0.29.g47ce80527c56


Reply via email to