linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Vetter <daniel@ffwll.ch>
To: Sui Jingfeng <15330273260@189.cn>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>,
	Sui Jingfeng <suijingfeng@loongson.cn>, Li Yi <liyi@loongson.cn>,
	Helge Deller <deller@gmx.de>,
	Lucas De Marchi <lucas.demarchi@intel.com>,
	linux-kernel@vger.kernel.org, linux-fbdev@vger.kernel.org,
	dri-devel@lists.freedesktop.org,
	loongson-kernel@lists.loongnix.cn
Subject: Re: [PATCH] drm/fbdev-generic: fix potential out-of-bounds access
Date: Tue, 11 Apr 2023 16:53:01 +0200	[thread overview]
Message-ID: <ZDV0Te65tSh4Q/vc@phenom.ffwll.local> (raw)
In-Reply-To: <20230409132110.494630-1-15330273260@189.cn>

On Sun, Apr 09, 2023 at 09:21:10PM +0800, Sui Jingfeng wrote:
> From: Sui Jingfeng <suijingfeng@loongson.cn>
> 
> 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:
>    <TASK>
>    ? 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
>    </TASK>
>   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.

Nice catch!

> 
> Signed-off-by: Sui Jingfeng <suijingfeng@loongson.cn>
> ---
>  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);

So for additional robustness I think it'd be good if we change the entire
computation here to use drm_framebuffer data and not fb_info data, because
fundamentally that's what the drm kms code consumes. It should all match
anyway, but I think it makes the code more obviously correct.

So in the entire function instead of looking at fb_info->fix we should
probably look at

	struct drm_fb_helper *helper = info->par;

And then helper->fb->pitches[0] and helper->fb->height.

If you agree would be great if you can please respin with that (and the
commit message augmented to explain why we do the change)?
>  
>  	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;

I guess you forgot to remove this line here? Also I'm not understanding
why this matters, I think you're fix only needs the above chunk, not this
one? If I got this right then please drop this part, there's drivers which
only use drm_fb_helper.c but not drm_fbdev_generic.c, and from what I can
tell they all still set the gem buffer size here.

If otoh we need this too, then there's a few more places that need to be
fixed.

> +	screen_size = sizes->surface_height * buffer->fb->pitches[0];
> +
>  	screen_buffer = vzalloc(screen_size);
>  	if (!screen_buffer) {
>  		ret = -ENOMEM;

Cheers, Daniel

> -- 
> 2.25.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

  reply	other threads:[~2023-04-11 14:53 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-09 13:21 [PATCH] drm/fbdev-generic: fix potential out-of-bounds access Sui Jingfeng
2023-04-11 14:53 ` Daniel Vetter [this message]
2023-04-12 17:13   ` Sui Jingfeng
2023-04-12 17:22     ` Sui Jingfeng
2023-04-12 17:44     ` Daniel Vetter
2023-04-13 15:35       ` Sui Jingfeng
2023-04-13 15:56         ` Daniel Vetter
2023-04-13 17:00           ` Sui Jingfeng
2023-04-13 18:56             ` Daniel Vetter
2023-04-13 19:20               ` Thomas Zimmermann
2023-04-13 20:01                 ` Daniel Vetter
2023-04-14  4:23                   ` Sui Jingfeng
2023-04-14  5:36                     ` Daniel Vetter
2023-04-14  7:34                       ` Thomas Zimmermann
2023-04-14  7:39                         ` Thomas Zimmermann
2023-04-14  7:56                         ` Daniel Vetter
2023-04-14 11:30                           ` Sui Jingfeng
2023-04-16  7:54                             ` Daniel Vetter
2023-04-17  7:17                           ` Thomas Zimmermann
2023-04-14  7:28                   ` Thomas Zimmermann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZDV0Te65tSh4Q/vc@phenom.ffwll.local \
    --to=daniel@ffwll.ch \
    --cc=15330273260@189.cn \
    --cc=airlied@gmail.com \
    --cc=deller@gmx.de \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=liyi@loongson.cn \
    --cc=loongson-kernel@lists.loongnix.cn \
    --cc=lucas.demarchi@intel.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mripard@kernel.org \
    --cc=suijingfeng@loongson.cn \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).