Re: [PATCH v2] fbdev: core: Clamp total_size to smem_len in read/write functions

Helge Deller <[email protected]> Sat, 25 Jul 2026 17:29:58 +0200
Newsgroups org.kernel.vger.linux-fbdev,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On 7/21/26 09:15, Mingyu Wang wrote:
> Some legacy fbdev drivers may incorrectly set info->screen_size to a
> value larger than the actual mapped framebuffer size (info->fix.smem_len=
)
> during mode switches. This could allow out-of-bounds I/O and system
> memory accesses in fb_io_read(), fb_io_write(), fb_sys_read(), and
> fb_sys_write().
>=20
> Prevent this by clamping total_size to smem_len when smem_len is non-zer=
o.
> Virtual framebuffers (smem_len =3D=3D 0) are unaffected.
>=20
> This is a hardening measure; no specific crash is fixed by this patch.
>=20
> Signed-off-by: Mingyu Wang <[email protected]>
> ---
> v2:
>   - Apply the clamp to fb_sys_read() and fb_sys_write() as well to preve=
nt
>     similar OOB accesses in system memory framebuffers (Reported by Sash=
iko).
>   - Update commit message to clearly state this is a hardening measure.
> ---
>   drivers/video/fbdev/core/fb_io_fops.c  | 16 ++++++++++++++++
>   drivers/video/fbdev/core/fb_sys_fops.c | 16 ++++++++++++++++
>   2 files changed, 32 insertions(+)

Sounds reasonable.
I've added it to fbdev git tree for wider testing.

Thanks!
Helge


 =20
> diff --git a/drivers/video/fbdev/core/fb_io_fops.c b/drivers/video/fbdev=
/core/fb_io_fops.c
> index 6ab60fcd0050..335f16d2cc23 100644
> --- a/drivers/video/fbdev/core/fb_io_fops.c
> +++ b/drivers/video/fbdev/core/fb_io_fops.c
> @@ -24,6 +24,14 @@ ssize_t fb_io_read(struct fb_info *info, char __user =
*buf, size_t count, loff_t
>   	if (total_size =3D=3D 0)
>   		total_size =3D info->fix.smem_len;
>  =20
> +	/*
> +	 * Security Hardening: Defend against buggy legacy drivers that may
> +	 * calculate a malformed screen_size. Clamp total_size to the actual
> +	 * hardware mapped memory limit (smem_len) to prevent OOB access.
> +	 */
> +	if (info->fix.smem_len && total_size > info->fix.smem_len)
> +		total_size =3D info->fix.smem_len;
> +
>   	if (p >=3D total_size)
>   		return 0;
>  =20
> @@ -88,6 +96,14 @@ ssize_t fb_io_write(struct fb_info *info, const char =
__user *buf, size_t count,
>   	if (total_size =3D=3D 0)
>   		total_size =3D info->fix.smem_len;
>  =20
> +	/*
> +	 * Security Hardening: Defend against buggy legacy drivers that may
> +	 * calculate a malformed screen_size. Clamp total_size to the actual
> +	 * hardware mapped memory limit (smem_len) to prevent OOB access.
> +	 */
> +	if (info->fix.smem_len && total_size > info->fix.smem_len)
> +		total_size =3D info->fix.smem_len;
> +
>   	if (p > total_size)
>   		return -EFBIG;
>  =20
> diff --git a/drivers/video/fbdev/core/fb_sys_fops.c b/drivers/video/fbde=
v/core/fb_sys_fops.c
> index be96b3b3942e..e97cf02f7c70 100644
> --- a/drivers/video/fbdev/core/fb_sys_fops.c
> +++ b/drivers/video/fbdev/core/fb_sys_fops.c
> @@ -35,6 +35,14 @@ ssize_t fb_sys_read(struct fb_info *info, char __user=
 *buf, size_t count,
>   	if (total_size =3D=3D 0)
>   		total_size =3D info->fix.smem_len;
>  =20
> +	/*
> +	 * Security Hardening: Defend against buggy legacy drivers that may
> +	 * calculate a malformed screen_size. Clamp total_size to the actual
> +	 * hardware mapped memory limit (smem_len) to prevent OOB access.
> +	 */
> +	if (info->fix.smem_len && total_size > info->fix.smem_len)
> +		total_size =3D info->fix.smem_len;
> +
>   	if (p >=3D total_size)
>   		return 0;
>  =20
> @@ -80,6 +88,14 @@ ssize_t fb_sys_write(struct fb_info *info, const char=
 __user *buf,
>   	if (total_size =3D=3D 0)
>   		total_size =3D info->fix.smem_len;
>  =20
> +	/*
> +	 * Security Hardening: Defend against buggy legacy drivers that may
> +	 * calculate a malformed screen_size. Clamp total_size to the actual
> +	 * hardware mapped memory limit (smem_len) to prevent OOB access.
> +	 */
> +	if (info->fix.smem_len && total_size > info->fix.smem_len)
> +		total_size =3D info->fix.smem_len;
> +
>   	if (p > total_size)
>   		return -EFBIG;
>  =20