FAILED: patch "[PATCH] drm/fb-helper: Fix out-of-bounds access" failed to apply to 5.18-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From ae25885bdf59fde40726863c57fd20e4a0642183 Mon Sep 17 00:00:00 2001
From: Thomas Zimmermann <[email protected]>
Date: Tue, 21 Jun 2022 12:46:17 +0200
Subject: [PATCH] drm/fb-helper: Fix out-of-bounds access
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Clip memory range to screen-buffer size to avoid out-of-bounds access in fbdev deferred I/O's damage handling.
Fbdev's deferred I/O can only track pages. From the range of pages, the damage handler computes the clipping rectangle for the display update. If the fbdev screen buffer ends near the beginning of a page, that page could contain more scanlines. The damage handler would then track these non-existing scanlines as dirty and provoke an out-of-bounds access during the screen update. Hence, clip the maximum memory range to the size of the screen buffer.
While at it, rename the variables min/max to min_off/max_off in drm_fb_helper_deferred_io(). This avoids confusion with the macros of the same name.
drivers/gpu/drm/drm_fb_helper.c +19 -8
@@ -681,7 +681,11 @@ static void drm_fb_helper_damage(struct fb_info *info, u32 x, u32 y,schedule_work (&helper->damage_work); } -/* Convert memory region into area of scanlines and pixels per scanline */ +/* +* Convert memory region into area of scanlines and pixels per +* scanline. The parameters off and len must not reach beyond +* the end of the framebuffer. +*/ static void drm_fb_helper_memory_range_to_clip (struct fb_info *info,off_t off,size_t len,struct drm_rect *clip) {
@@ -716,22 +720,29 @@ static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off,*/ void drm_fb_helper_deferred_io (struct fb_info *info,struct list_head *pagereflist) { -unsigned long start, end, min, max; +unsigned long start, end, min_off, max_off;struct fb_deferred_io_pageref *pageref;struct drm_rect damage_area; - min =ULONG_MAX ; - max =0 ; + min_off =ULONG_MAX ; + max_off =0 ;list_for_each_entry (pageref, pagereflist, list) { start = pageref->offset; end = start +PAGE_SIZE ; - min =min (min, start); - max =max (max, end); + min_off =min (min_off, start); + max_off =max (max_off, end); } -if (min >= max) +if (min_off >= max_off)return ; -drm_fb_helper_memory_range_to_clip (info, min, max - min, &damage_area); +/* +* As we can only track pages, we might reach beyond the end +* of the screen and account for non-existing scanlines. Hence, +* keep the covered memory area within the screen buffer. +*/ + max_off =min (max_off, info->screen_size); + +drm_fb_helper_memory_range_to_clip (info, min_off, max_off - min_off, &damage_area);drm_fb_helper_damage (info, damage_area.x1, damage_area.y1,drm_rect_width (&damage_area),drm_rect_height (&damage_area));