ufx_realloc_framebuffer() allocates line_length * yres bytes but records
PAGE_ALIGN(line_length * yres) in info->fix.smem_len.  ufx_ops_set_par()
clears the framebuffer by writing smem_len bytes, so the write runs past
the end of the vmalloc() allocation whenever the mode size is not page
aligned:

  BUG: KASAN: vmalloc-out-of-bounds in ufx_ops_set_par
  Write of size 2 at addr ffffc90005518600
  Call Trace:
   ufx_ops_set_par
   ufx_usb_probe
   usb_probe_interface

This runs from the probe path, before any client can open the device: with
the fallback mode of 800x600 at 16 bpp the framebuffer is 960000 bytes and
PAGE_ALIGN() adds 2560 bytes that were never allocated.

Allocate the page aligned size that is published in smem_len instead, so
the buffer covers every byte the driver and the framebuffer core can reach
through smem_start and smem_len.

Fixes: 3c8a63e22a08 ("Add support for SMSC UFX6000/7000 USB display adapters")
Cc: [email protected]
---
 drivers/video/fbdev/smscufx.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 5704f60e1741..d5b9802ea94f 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1277,9 +1277,10 @@ static int ufx_realloc_framebuffer(struct ufx_data *dev, 
struct fb_info *info)
 
        if (PAGE_ALIGN(new_len) > old_len) {
                /*
-                * Alloc system memory for virtual framebuffer
+                * Alloc system memory for virtual framebuffer.  smem_len is
+                * rounded up to a page, so allocate that much as well.
                 */
-               new_fb = vmalloc(new_len);
+               new_fb = vmalloc(PAGE_ALIGN(new_len));
                if (!new_fb)
                        return -ENOMEM;
 
-- 
2.34.1

Reply via email to