The function fb_pad_unaligned_buffer() was reading idx+1 bytes per row
from the source buffer, but when mod == 0 (font width is a multiple of
8 bits), the source buffer only has idx bytes per row. This caused a
slab-out-of-bounds read when accessing src[idx] after the inner loop.

Fix this by only reading the extra byte when mod != 0, ensuring we
never read beyond the source buffer boundaries.

This fixes the KASAN slab-out-of-bounds read reported by syzkaller:
https://syzkaller.appspot.com/bug?extid=55e03490a0175b8dd81d

Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=55e03490a0175b8dd81d
Signed-off-by: Osama Abdelkader <[email protected]>
---
 drivers/video/fbdev/core/fbmem.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index eff757ebbed1..a0c4932a6758 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -113,15 +113,17 @@ void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 
*src, u32 idx, u32 height,
                        dst[j+1] = tmp;
                        src++;
                }
-               tmp = dst[idx];
-               tmp &= mask;
-               tmp |= *src >> shift_low;
-               dst[idx] = tmp;
-               if (shift_high < mod) {
-                       tmp = *src << shift_high;
-                       dst[idx+1] = tmp;
+               if (mod) {
+                       tmp = dst[idx];
+                       tmp &= mask;
+                       tmp |= *src >> shift_low;
+                       dst[idx] = tmp;
+                       if (shift_high < mod) {
+                               tmp = *src << shift_high;
+                               dst[idx+1] = tmp;
+                       }
+                       src++;
                }
-               src++;
                dst += d_pitch;
        }
 }
-- 
2.43.0

Reply via email to