From patchwork Sun Apr 9 13:21:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sui Jingfeng <15330273260@189.cn> X-Patchwork-Id: 13205986 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F36A2C77B70 for ; Sun, 9 Apr 2023 13:21:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229552AbjDINVS (ORCPT ); Sun, 9 Apr 2023 09:21:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229462AbjDINVR (ORCPT ); Sun, 9 Apr 2023 09:21:17 -0400 Received: from 189.cn (ptr.189.cn [183.61.185.101]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7353B422F; Sun, 9 Apr 2023 06:21:15 -0700 (PDT) HMM_SOURCE_IP: 10.64.8.41:37240.250830095 HMM_ATTACHE_NUM: 0000 HMM_SOURCE_TYPE: SMTP Received: from clientip-114.242.206.180 (unknown [10.64.8.41]) by 189.cn (HERMES) with SMTP id 183631001F8; Sun, 9 Apr 2023 21:21:13 +0800 (CST) Received: from ([114.242.206.180]) by gateway-151646-dep-7b48884fd-bkw2h with ESMTP id dcd59a4b78b04d9ea815ada68b5e12f9 for maarten.lankhorst@linux.intel.com; Sun, 09 Apr 2023 21:21:14 CST X-Transaction-ID: dcd59a4b78b04d9ea815ada68b5e12f9 X-Real-From: 15330273260@189.cn X-Receive-IP: 114.242.206.180 X-MEDUSA-Status: 0 Sender: 15330273260@189.cn From: Sui Jingfeng <15330273260@189.cn> To: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , Sui Jingfeng , Li Yi , Helge Deller , Lucas De Marchi Cc: linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org, loongson-kernel@lists.loongnix.cn Subject: [PATCH] drm/fbdev-generic: fix potential out-of-bounds access Date: Sun, 9 Apr 2023 21:21:10 +0800 Message-Id: <20230409132110.494630-1-15330273260@189.cn> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org From: Sui Jingfeng We should setting the screen buffer size according to the screen's actual size, rather than the size of the GEM object backing the front framebuffer. The size of GEM buffer is page size aligned, while the size of active area of a specific screen is *NOT* necessarily page size aliged. For example, 1680x1050, 1600x900, 1440x900, 800x6000 etc. In those case, the damage rect computed by drm_fb_helper_memory_range_to_clip() goes out of bottom bounds of the display. Run fbdev test of IGT on a x86+ast2400 platform with 1680x1050 resolution will cause the system hang with the following call trace: Oops: 0000 [#1] PREEMPT SMP PTI [IGT] fbdev: starting subtest eof Workqueue: events drm_fb_helper_damage_work [drm_kms_helper] [IGT] fbdev: starting subtest nullptr RIP: 0010:memcpy_erms+0xa/0x20 RSP: 0018:ffffa17d40167d98 EFLAGS: 00010246 RAX: ffffa17d4eb7fa80 RBX: ffffa17d40e0aa80 RCX: 00000000000014c0 RDX: 0000000000001a40 RSI: ffffa17d40e0b000 RDI: ffffa17d4eb80000 RBP: ffffa17d40167e20 R08: 0000000000000000 R09: ffff89522ecff8c0 R10: ffffa17d4e4c5000 R11: 0000000000000000 R12: ffffa17d4eb7fa80 R13: 0000000000001a40 R14: 000000000000041a R15: ffffa17d40167e30 FS: 0000000000000000(0000) GS:ffff895257380000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffa17d40e0b000 CR3: 00000001eaeca006 CR4: 00000000001706e0 Call Trace: ? drm_fbdev_generic_helper_fb_dirty+0x207/0x330 [drm_kms_helper] drm_fb_helper_damage_work+0x8f/0x170 [drm_kms_helper] process_one_work+0x21f/0x430 worker_thread+0x4e/0x3c0 ? __pfx_worker_thread+0x10/0x10 kthread+0xf4/0x120 ? __pfx_kthread+0x10/0x10 ret_from_fork+0x2c/0x50 CR2: ffffa17d40e0b000 ---[ end trace 0000000000000000 ]--- We also add trival code in this patch to restrict the damage rect beyond the last line of the framebuffer. Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/drm_fb_helper.c | 2 +- drivers/gpu/drm/drm_fbdev_generic.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 64458982be40..a2b749372759 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -645,7 +645,7 @@ static void drm_fb_helper_memory_range_to_clip(struct fb_info *info, off_t off, u32 x1 = 0; u32 y1 = off / info->fix.line_length; u32 x2 = info->var.xres; - u32 y2 = DIV_ROUND_UP(end, info->fix.line_length); + u32 y2 = min_t(u32, DIV_ROUND_UP(end, info->fix.line_length), info->var.yres); if ((y2 - y1) == 1) { /* diff --git a/drivers/gpu/drm/drm_fbdev_generic.c b/drivers/gpu/drm/drm_fbdev_generic.c index 8e5148bf40bb..a6daecb5f640 100644 --- a/drivers/gpu/drm/drm_fbdev_generic.c +++ b/drivers/gpu/drm/drm_fbdev_generic.c @@ -95,6 +95,8 @@ static int drm_fbdev_generic_helper_fb_probe(struct drm_fb_helper *fb_helper, fb_helper->fb = buffer->fb; screen_size = buffer->gem->size; + screen_size = sizes->surface_height * buffer->fb->pitches[0]; + screen_buffer = vzalloc(screen_size); if (!screen_buffer) { ret = -ENOMEM;