Re: [PATCH v2] drm/log: Batch vmap/vunmap and flush for record drawing

[email protected]
Newsgroups org.freedesktop.lists.dri-devel
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Unconditional clearing of lines 0, 1, and 2 can write past the end of the framebuffer if `scanout->rows` is less than 3.
--

--- Patch [1]: [PATCH v2] drm/log: Batch vmap/vunmap and flush for record drawing ---
commit 59469456017da9a89a891c48422d122f14da3c7a
Author: Shixiong Ou <[email protected]>

drm/log: Batch vmap/vunmap and flush for record drawing

This commit refactors drm_log_clear_line and drm_log_draw_line to accept a
pre-mapped iosys_map by value, removing the per-line vmap/vunmap/flush
calls. The single vmap/vunmap pair and flush are moved to
drm_log_draw_new_line.

> diff --git a/drivers/gpu/drm/clients/drm_log.c b/drivers/gpu/drm/clients/drm_log.c
> index e3e02c84a4cfe..97eddae3973f3 100644
> --- a/drivers/gpu/drm/clients/drm_log.c
> +++ b/drivers/gpu/drm/clients/drm_log.c

[ ... ]

> @@ -134,21 +125,40 @@ static void drm_log_draw_line(struct drm_log_scanout *scanout, const char *s,
>  	scanout->line++;
>  	if (scanout->line >= scanout->rows)
>  		scanout->line = 0;
> -	drm_client_buffer_vunmap_local(scanout->buffer);
> -	drm_client_buffer_flush(scanout->buffer, &r);
>  }
>  
>  static void drm_log_draw_new_line(struct drm_log_scanout *scanout,
> -				  const char *s, unsigned int len, unsigned int prefix_len)
> +				  const char *s, unsigned int len,
> +				  unsigned int prefix_len)
>  {
> +	struct iosys_map map;
> +	struct drm_framebuffer *fb = scanout->buffer->fb;
> +	u32 height = scanout->scaled_font_h;
> +	u32 line = scanout->line;
> +	u32 y2;
> +	struct drm_rect dirty;
> +
> +	if (drm_client_buffer_vmap_local(scanout->buffer, &map))
> +		return;
> +
>  	if (scanout->line == 0) {
> -		drm_log_clear_line(scanout, 0);
> -		drm_log_clear_line(scanout, 1);
> -		drm_log_clear_line(scanout, 2);
> +		drm_log_clear_line(scanout, 0, map);
> +		drm_log_clear_line(scanout, 1, map);
> +		drm_log_clear_line(scanout, 2, map);

[Severity: High]
This is a pre-existing issue, but can unconditionally clearing lines 0, 1,
and 2 write past the end of the framebuffer if scanout->rows is less than 3?

If the display has a very small vertical resolution, or if the scale module
parameter is set to a large value, scanout->rows can be less than 3.

When scanout->line == 0, drm_log_draw_new_line unconditionally clears line 2.
This calls drm_log_clear_line, which does:

static void drm_log_clear_line(struct drm_log_scanout *scanout, u32 line,
                               struct iosys_map map)
{
        ...
        iosys_map_memset(&map, line * height * fb->pitches[0], 0, height * fb->pitches[0]);
}

If line * height exceeds the actual framebuffer height, does this result in
an out-of-bounds memory write that could corrupt adjacent kernel memory?

> +		y2 = min(3, scanout->rows) * height;
> +	} else if (scanout->line + 2 < scanout->rows) {
> -		drm_log_clear_line(scanout, scanout->line + 2);
> +		drm_log_clear_line(scanout, scanout->line + 2, map);
> +		y2 = (line + 3) * height;
> +	} else {
> +		y2 = (line + 1) * height;
> +	}
> +
> -	drm_log_draw_line(scanout, s, len, prefix_len);
> +	drm_log_draw_line(scanout, s, len, prefix_len, map);
> +
> +	drm_client_buffer_vunmap_local(scanout->buffer);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.