RE: [PATCH 1/1] video: hyperv_fb: Fix validation of screen resolution

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> -----Original Message-----
> From: Michael Kelley (LINUX) <mikelley@xxxxxxxxxxxxx>
> Sent: Sunday, January 16, 2022 2:19 PM
> To: KY Srinivasan <kys@xxxxxxxxxxxxx>; Haiyang Zhang <haiyangz@xxxxxxxxxxxxx>; Stephen
> Hemminger <sthemmin@xxxxxxxxxxxxx>; wei.liu@xxxxxxxxxx; Wei Hu <weh@xxxxxxxxxxxxx>; Dexuan
> Cui <decui@xxxxxxxxxxxxx>; drawat.floss@xxxxxxxxx; hhei <hhei@xxxxxxxxxx>; linux-
> kernel@xxxxxxxxxxxxxxx; linux-hyperv@xxxxxxxxxxxxxxx; linux-fbdev@xxxxxxxxxxxxxxx; dri-
> devel@xxxxxxxxxxxxxxxxxxxxx
> Cc: Michael Kelley (LINUX) <mikelley@xxxxxxxxxxxxx>
> 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@xxxxxxxxxxxxx>
> ---
>  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@xxxxxxxxxxxxx>





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux