lkml.org 
[lkml]   [2022]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRE: [PATCH 1/1] video: hyperv_fb: Fix validation of screen resolution
Date


> -----Original Message-----
> From: Michael Kelley (LINUX) <mikelley@microsoft.com>
> Sent: Sunday, January 16, 2022 2:19 PM
> To: KY Srinivasan <kys@microsoft.com>; Haiyang Zhang <haiyangz@microsoft.com>; Stephen
> Hemminger <sthemmin@microsoft.com>; wei.liu@kernel.org; Wei Hu <weh@microsoft.com>; Dexuan
> Cui <decui@microsoft.com>; drawat.floss@gmail.com; hhei <hhei@redhat.com>; linux-
> kernel@vger.kernel.org; linux-hyperv@vger.kernel.org; linux-fbdev@vger.kernel.org; dri-
> devel@lists.freedesktop.org
> Cc: Michael Kelley (LINUX) <mikelley@microsoft.com>
> Subject: [PATCH 1/1] video: hyperv_fb: Fix validation of screen resolution
>
> In the WIN10 version of the Synthetic Video protocol with Hyper-V,
> Hyper-V reports a list of supported resolutions as part of the protocol
> negotiation. The driver calculates the maximum width and height from
> the list of resolutions, and uses those maximums to validate any screen
> resolution specified in the video= option on the kernel boot line.
>
> This method of validation is incorrect. For example, the list of
> supported resolutions could contain 1600x1200 and 1920x1080, both of
> which fit in an 8 Mbyte frame buffer. But calculating the max width
> and height yields 1920 and 1200, and 1920x1200 resolution does not fit
> in an 8 Mbyte frame buffer. Unfortunately, this resolution is accepted,
> causing a kernel fault when the driver accesses memory outside the
> frame buffer.
>
> Instead, validate the specified screen resolution by calculating
> its size, and comparing against the frame buffer size. Delete the
> code for calculating the max width and height from the list of
> resolutions, since these max values have no use. Also add the
> frame buffer size to the info message to aid in understanding why
> a resolution might be rejected.
>
> Fixes: 67e7cdb4829d ("video: hyperv: hyperv_fb: Obtain screen resolution from Hyper-V
> host")
> Signed-off-by: Michael Kelley <mikelley@microsoft.com>
> ---
> drivers/video/fbdev/hyperv_fb.c | 16 +++-------------
> 1 file changed, 3 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
> index 23999df..c8e0ea2 100644
> --- a/drivers/video/fbdev/hyperv_fb.c
> +++ b/drivers/video/fbdev/hyperv_fb.c
> @@ -287,8 +287,6 @@ struct hvfb_par {
>
> static uint screen_width = HVFB_WIDTH;
> static uint screen_height = HVFB_HEIGHT;
> -static uint screen_width_max = HVFB_WIDTH;
> -static uint screen_height_max = HVFB_HEIGHT;
> static uint screen_depth;
> static uint screen_fb_size;
> static uint dio_fb_size; /* FB size for deferred IO */
> @@ -582,7 +580,6 @@ static int synthvid_get_supported_resolution(struct hv_device *hdev)
> int ret = 0;
> unsigned long t;
> u8 index;
> - int i;
>
> memset(msg, 0, sizeof(struct synthvid_msg));
> msg->vid_hdr.type = SYNTHVID_RESOLUTION_REQUEST;
> @@ -613,13 +610,6 @@ static int synthvid_get_supported_resolution(struct hv_device *hdev)
> goto out;
> }
>
> - for (i = 0; i < msg->resolution_resp.resolution_count; i++) {
> - screen_width_max = max_t(unsigned int, screen_width_max,
> - msg->resolution_resp.supported_resolution[i].width);
> - screen_height_max = max_t(unsigned int, screen_height_max,
> - msg->resolution_resp.supported_resolution[i].height);
> - }
> -
> screen_width =
> msg->resolution_resp.supported_resolution[index].width;
> screen_height =
> @@ -941,7 +931,7 @@ static void hvfb_get_option(struct fb_info *info)
>
> if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN ||
> (synthvid_ver_ge(par->synthvid_version, SYNTHVID_VERSION_WIN10) &&
> - (x > screen_width_max || y > screen_height_max)) ||
> + (x * y * screen_depth / 8 > screen_fb_size)) ||
> (par->synthvid_version == SYNTHVID_VERSION_WIN8 &&
> x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8) ||
> (par->synthvid_version == SYNTHVID_VERSION_WIN7 &&
> @@ -1194,8 +1184,8 @@ static int hvfb_probe(struct hv_device *hdev,
> }
>
> hvfb_get_option(info);
> - pr_info("Screen resolution: %dx%d, Color depth: %d\n",
> - screen_width, screen_height, screen_depth);
> + pr_info("Screen resolution: %dx%d, Color depth: %d, Frame buffer size: %d\n",
> + screen_width, screen_height, screen_depth, screen_fb_size);
>
> ret = hvfb_getmem(hdev, info);
> if (ret) {

Thank you!

Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>

\
 
 \ /
  Last update: 2022-01-16 22:54    [W:0.158 / U:0.068 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site