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

[PATCH 47/63] hw/display/xenfb: fix 24-bit pixel read in BLT macro



For depth == 24, each pixel is 3 bytes, but the BLT macro was using
uint32_t as the source type, reading 4 bytes per pixel. The last pixel
on the last row would read 1 byte past the framebuffer.

Read 24-bit pixels byte-by-byte instead, so the access stays within
the 3-byte pixel boundary.

Reported-by: Pavee Hui <phui@xxxxxxxxxx>
Signed-off-by: Marc-André Lureau <marcandre.lureau@xxxxxxxxxx>
---
 hw/display/xenfb.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index ae302b217fe9..10785e6843ae 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -560,8 +560,13 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t 
fb_len_lim,
     return 0;
 }
 
+static inline uint32_t read_pixel24(const uint8_t *p)
+{
+    return p[0] | (p[1] << 8) | (p[2] << 16);
+}
+
 /* A convenient function for munging pixels between different depths */
-#define BLT(SRC_T,DST_T,RSB,GSB,BSB,RDB,GDB,BDB)                        \
+#define BLT(SRC_T,DST_T,READ_PIX,RSB,GSB,BSB,RDB,GDB,BDB)               \
     for (line = y ; line < (y+h) ; line++) {                            \
         SRC_T *src = (SRC_T *)(xenfb->pixels                            \
                                + xenfb->offset                          \
@@ -584,7 +589,7 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t 
fb_len_lim,
         const uint32_t GDM = (~0U) << (32 - GDB);                       \
         const uint32_t BDM = (~0U) << (32 - BDB);                       \
         for (col = x ; col < (x+w) ; col++) {                           \
-            uint32_t spix = *src;                                       \
+            uint32_t spix = READ_PIX(src);                              \
             *dst = (((spix << RSS) & RSM & RDM) >> RDS) |               \
                 (((spix << GSS) & GSM & GDM) >> GDS) |                  \
                 (((spix << BSS) & BSM & BDM) >> BDS);                   \
@@ -593,6 +598,8 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t 
fb_len_lim,
         }                                                               \
     }
 
+#define READ_DEREF(p) (*(p))
+
 
 /*
  * This copies data from the guest framebuffer region, into QEMU's
@@ -612,18 +619,18 @@ static void xenfb_guest_copy(struct XenFB *xenfb, int x, 
int y, int w, int h)
         switch (xenfb->depth) {
         case 8:
             if (bpp == 16) {
-                BLT(uint8_t, uint16_t,   3, 3, 2,   5, 6, 5);
+                BLT(uint8_t, uint16_t, READ_DEREF, 3, 3, 2,  5, 6, 5);
             } else if (bpp == 32) {
-                BLT(uint8_t, uint32_t,   3, 3, 2,   8, 8, 8);
+                BLT(uint8_t, uint32_t, READ_DEREF, 3, 3, 2,  8, 8, 8);
             } else {
                 oops = 1;
             }
             break;
         case 24:
             if (bpp == 16) {
-                BLT(uint32_t, uint16_t,  8, 8, 8,   5, 6, 5);
+                BLT(uint8_t, uint16_t, read_pixel24, 8, 8, 8,  5, 6, 5);
             } else if (bpp == 32) {
-                BLT(uint32_t, uint32_t,  8, 8, 8,   8, 8, 8);
+                BLT(uint8_t, uint32_t, read_pixel24, 8, 8, 8,  8, 8, 8);
             } else {
                 oops = 1;
             }

-- 
2.56.0.rc0.29.g47ce80527c56




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.