From 33bc3dfa51d1f9dae918fed4f8326f04fb5c496d Mon Sep 17 00:00:00 2001 From: jsg Date: Thu, 15 Jun 2023 02:33:23 +0000 Subject: [PATCH] drm/fbdev-generic: prohibit potential out-of-bounds access From Sui Jingfeng efd2821b8abeccb6b51423002e2a62921481a26e in linux-6.1.y/6.1.30 c8687694bb1f5c48134f152f8c5c2e53483eb99d in mainline linux --- sys/dev/pci/drm/drm_fb_helper.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sys/dev/pci/drm/drm_fb_helper.c b/sys/dev/pci/drm/drm_fb_helper.c index b86d690e2a6..449ee168a8d 100644 --- a/sys/dev/pci/drm/drm_fb_helper.c +++ b/sys/dev/pci/drm/drm_fb_helper.c @@ -724,19 +724,27 @@ static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y, static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, size_t len, struct drm_rect *clip) { + u32 line_length = info->fix.line_length; + u32 fb_height = info->var.yres; off_t end = off + len; u32 x1 = 0; - u32 y1 = off / info->fix.line_length; + u32 y1 = off / line_length; u32 x2 = info->var.xres; - u32 y2 = DIV_ROUND_UP(end, info->fix.line_length); + u32 y2 = DIV_ROUND_UP(end, line_length); + + /* Don't allow any of them beyond the bottom bound of display area */ + if (y1 > fb_height) + y1 = fb_height; + if (y2 > fb_height) + y2 = fb_height; if ((y2 - y1) == 1) { /* * We've only written to a single scanline. Try to reduce * the number of horizontal pixels that need an update. */ - off_t bit_off = (off % info->fix.line_length) * 8; - off_t bit_end = (end % info->fix.line_length) * 8; + off_t bit_off = (off % line_length) * 8; + off_t bit_end = (end % line_length) * 8; x1 = bit_off / info->var.bits_per_pixel; x2 = DIV_ROUND_UP(bit_end, info->var.bits_per_pixel); -- 2.20.1