|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |