Received: by 2002:a05:6358:9144:b0:117:f937:c515 with SMTP id r4csp421742rwr; Wed, 19 Apr 2023 08:14:01 -0700 (PDT) X-Google-Smtp-Source: AKy350ZBtmXD1JcvhSltDmT5akAbGBnqNmH/1lIeV3LneGdG9aFzpc+Zs2s97jictWWIiXZswZKq X-Received: by 2002:a17:902:e3d2:b0:1a1:bede:5e4a with SMTP id r18-20020a170902e3d200b001a1bede5e4amr4785974ple.49.1681917241236; Wed, 19 Apr 2023 08:14:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1681917241; cv=none; d=google.com; s=arc-20160816; b=gzGMnrgiY3srbgPdOE7SYMrTdbILsZWdbZIr55ya95zJWKI+hZXSwWXv0mq9TBwdl7 G/Dx0c+7SFqkxuvDTvhM7PcdSNOrtMYm8F1fqF4VLJgI9sT3BeAUMFDQ9cAkdDsc8xiv V6QmMe+QozIjJAxosGApab88018AGD/yOf+6HWjfC0S37KzwmxJ9DM2QejH2U5/BMMub +x8VRkaKVPvqKbZfqTzYvhj8ZD00xieC4tSH098XZvfi/hb+7KX5ThtgGUVVrt/PgFM5 qM8C/ZovChRQvzjwLLH+kvTbFedQBsCyjQIHa/55ziPg48e7g+UHXFEDQ5DXhpvziptk JUYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=vxz4WpDlv6wH199UsEqYfGj6F7utE5kHnU1NSqrYkEI=; b=JH5Lhz6IsJjp7k3oGjbDOzTEFl0deHcifRfE4JDdXuTlNd/ToMIf6OnS1r8od9J35s EZ7f4mgf8cqxS7ScJVvUnKR+Xk3JeFCPb/o+NlIftGDEIlcuXkhraIYWX23mlwW0f7kQ EiuctTImihUW3IMKKIuaQ9TS4sNEERjTYGQpue0I2TpKiQv2Ocn1h4ycdq7A4h8qt9tx wWLEg4JBYqOaUvslwI7HOoXOkiS7CP6hEDZism9cm4qQZGSKy5ok1Hec98Xo3NQyoHYf HdfnADnn8fJ3uOtt8h85tQnBefxjhWQ+UGI3AhH+EbIwSdOhFEgCC48m9gE0CmJHIJcN XCCw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=a3Xj8a4L; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n20-20020a170902d0d400b001a6463c81d9si16109730pln.352.2023.04.19.08.13.46; Wed, 19 Apr 2023 08:14:01 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=a3Xj8a4L; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232892AbjDSPJn (ORCPT + 99 others); Wed, 19 Apr 2023 11:09:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232593AbjDSPJl (ORCPT ); Wed, 19 Apr 2023 11:09:41 -0400 Received: from mail-oo1-xc32.google.com (mail-oo1-xc32.google.com [IPv6:2607:f8b0:4864:20::c32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89E624C1F for ; Wed, 19 Apr 2023 08:09:38 -0700 (PDT) Received: by mail-oo1-xc32.google.com with SMTP id 006d021491bc7-545d82e1a1bso684340eaf.2 for ; Wed, 19 Apr 2023 08:09:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; t=1681916978; x=1684508978; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=vxz4WpDlv6wH199UsEqYfGj6F7utE5kHnU1NSqrYkEI=; b=a3Xj8a4LitxGLjzfNfiSrOOIuEUFh4CTav04xvB0rDBxTRMVcIg6pyUQJp/xAlLnQe 0Ur3qYeBmDt51R0iqSb2KTCKZsmfGorpAbGVYGJlNS6YiCIx6y+TLeTMXEUQRTHSpwWa /WT4J20/Q8d4ghyuY3j04x56N9IvmiEUFMNLE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1681916978; x=1684508978; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=vxz4WpDlv6wH199UsEqYfGj6F7utE5kHnU1NSqrYkEI=; b=HY9H35vtXxlgRh2IJCTq9ATTyVB4D6xCGRThwyaChRL2ZOv5QoQbrFhVEOFBbRJ+7L CB5D+6BFcqbqB056DBcwbXouDvXNqwLDrcsi50DCj3d1V1sca3K9n/lgolJZTPo1dc2T 1P/UeFGmEyy55o0H10Lw1X7JMQFHIzDP/aCp8Otgoet1MAvX7uhcp/QLr1+i0cXGiDsf 9+R2eULM00NZaJ+zE0xrgaWBGVm+Dvtuyrd6fsIEN16otUuvTyt5GqRMoIalZn8Fya8k GstdYBOVXdQzBuJVu3AHn2nZT/+202Bxg1S/mskyt526/Ow8fAALcpPwoMAtt9unMe9i kW5w== X-Gm-Message-State: AAQBX9cN/fH17ElcgYutflfIq9vG9O+S+5nM/F3lqEUKdV7cEDIo6VyI 1JZS2DEXfdSDy87Ud/KN1T/SH+bH2Q5dSRAsq8je+Q== X-Received: by 2002:aca:df87:0:b0:384:2019:c201 with SMTP id w129-20020acadf87000000b003842019c201mr1706947oig.8.1681916977741; Wed, 19 Apr 2023 08:09:37 -0700 (PDT) MIME-Version: 1.0 References: <20230417113219.1354078-1-suijingfeng@loongson.cn> <139c9398-488d-df19-9ae2-2b4b47ef64f4@189.cn> <86a8b262-cbf2-b75f-9972-491f557edf74@189.cn> In-Reply-To: <86a8b262-cbf2-b75f-9972-491f557edf74@189.cn> From: Daniel Vetter Date: Wed, 19 Apr 2023 17:09:26 +0200 Message-ID: Subject: Re: [PATCH v3] drm/fbdev-generic: prohibit potential out-of-bounds access To: Sui Jingfeng <15330273260@189.cn> Cc: Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Li Yi , Helge Deller , Lucas De Marchi , linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org, loongson-kernel@lists.loongnix.cn Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, 18 Apr 2023 at 20:16, Sui Jingfeng <15330273260@189.cn> wrote: > > Hi, > > On 2023/4/19 01:52, Sui Jingfeng wrote: > > Hi, > > > > On 2023/4/18 16:32, Daniel Vetter wrote: > >> On Mon, Apr 17, 2023 at 07:32:19PM +0800, Sui Jingfeng wrote: > >>> The fbdev test of IGT may write after EOF, which lead to out-of-bound > >>> access for the drm drivers using fbdev-generic. For example, on a x86 > >>> + aspeed bmc card platform, with a 1680x1050 resolution display, > >>> running > >>> fbdev test if IGT will cause the linux kernel 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 ]--- > >>> > >>> The direct reason is that damage rectange computed by > >>> drm_fb_helper_memory_range_to_clip() does not guaranteed to be > >>> in-bound. > >>> It is already results in workaround code populate to elsewhere. Another > >>> reason is that exposing a larger buffer size than the actual needed > >>> help > >>> to trigger this bug intrinsic in drm_fb_helper_memory_range_to_clip(). > >>> > >>> Others fbdev emulation solutions write to the GEM buffer directly, they > >>> won't reproduce this bug because the .fb_dirty function callback do not > >>> being hooked, so no chance is given to > >>> drm_fb_helper_memory_range_to_clip() > >>> to generate a out-of-bound when drm_fb_helper_sys_write() is called. > >>> > >>> This patch break the trigger condition of this bug by shrinking the > >>> shadow > >>> buffer size to sizes->surface_height * buffer->fb->pitches[0]. > >>> > >>> Fixes: '8fbc9af55de0 ("drm/fbdev-generic: Set screen size to size of > >>> GEM > >>> buffer")' > >>> > >>> Signed-off-by: Sui Jingfeng > >>> --- > >>> drivers/gpu/drm/drm_fbdev_generic.c | 2 +- > >>> 1 file changed, 1 insertion(+), 1 deletion(-) > >>> > >>> diff --git a/drivers/gpu/drm/drm_fbdev_generic.c > >>> b/drivers/gpu/drm/drm_fbdev_generic.c > >>> index 8e5148bf40bb..b057cfbba938 100644 > >>> --- a/drivers/gpu/drm/drm_fbdev_generic.c > >>> +++ b/drivers/gpu/drm/drm_fbdev_generic.c > >>> @@ -94,7 +94,7 @@ static int > >>> drm_fbdev_generic_helper_fb_probe(struct drm_fb_helper *fb_helper, > >>> fb_helper->buffer = buffer; > >>> fb_helper->fb = buffer->fb; > >>> - screen_size = buffer->gem->size; > >>> + screen_size = sizes->surface_height * buffer->fb->pitches[0]; > >> So I read core some more and stumbled over drm_fb_helper_deferred_io(). > >> Which has all the code and comments about this, including limiting. > >> > >> I think it would be clearer if we fix the issue there, instead of > >> passing > >> limits around in obscure places that then again get broken? > > > > No, it is more obscure doing that way... > > > > > > As the size of the shadow screen buffer will be exposed to userspace. > > > > The size 'helper->fb->height * helper->fb->pitches[0]' is a > > exactly(best) fit, > > > > You are guaranteed to waste at lease one byte by increasing one byte, > > > > and can not store all pixels by decreasing one byte (In the case where > > `helper->fb->pitches[0] = helper->fb->width * 4`). > > > > It implicitly tell the userspace do not go beyond that boundary. > > > > although userspace program can still choose to write after EOF, > > > > But it is for test purpose, to test the kernel if it can return a > > -EFBIG or not. > > > >> The thing is, > >> Thomas both authored the limit checks in drm_fb_helper_deferred_io() and > >> the patch which broken them again, so clearly this isn't very > >> obvious. I'm > >> thinking of something like this: > >> > >> > >> diff --git a/drivers/gpu/drm/drm_fb_helper.c > >> b/drivers/gpu/drm/drm_fb_helper.c > >> index ef4eb8b12766..726dab67c359 100644 > >> --- a/drivers/gpu/drm/drm_fb_helper.c > >> +++ b/drivers/gpu/drm/drm_fb_helper.c > >> @@ -697,10 +697,7 @@ void drm_fb_helper_deferred_io(struct fb_info > >> *info, struct list_head *pagerefli > >> * of the screen and account for non-existing scanlines. Hence, > >> * keep the covered memory area within the screen buffer. > >> */ > >> - if (info->screen_size) > >> - total_size = info->screen_size; > >> - else > >> - total_size = info->fix.smem_len; > >> + total_size = helper->fb->height * helper->fb->pitches[0]; > > > > This is just to mitigate the mistakes already has been made, > > > > because it do not do a good splitting between the *clip* part and the > > *damage update* part. > > > > An ideal clipping do not obscure its updating backend with a > > out-of-bound damage rectangle. > > > > Why did the drm_fb_helper_memory_range_to_clip() can not do a good job > > in all case > > > > to pass its backend a always meaningful damage rect ? > > > >> max_off = min(max_off, total_size); > >> if (min_off < max_off) { > >> > >> > >> I think that would make it utmost clear on what we're doing and why. > >> Otherwise we're just going to re-create the same bug again, like we've > >> done already :-) > > > > No, we create no bugs, we fix one. > > > > Thanks. > > > But honestly I do not have strong feel toward this, I just type what I'm > understand without seeing you resend a V3. > > It's OK in overall, I will help to test this tomorrow. :-) Apologies for making you jump around all the time and doing different versions of the same bugfix :-/ I think this one here is ok to merge, I just thought when looking at the history that we revert the exact patch without any other changes or comments, and usually that means someone will come up with the same cleanup idea again, and then we'll have a bug again. So maybe a comment or a WARN_ON or something else would be good. I guess we could also do your patch, but put a WARN_ON that the computed total_size is never bigger than the drm_fb size into drm_fb_helper_deferred_io()? That would also make sure that this bug doesn't get resurrected again. -Daniel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch