Commit 3f8974f6 authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

fbdev: Validate info->screen_{base, buffer} in fb_ops implementations



Push the test for info->screen_base from fb_read() and fb_write() into
the implementations of struct fb_ops.{fb_read,fb_write}. In cases where
the driver operates on info->screen_buffer, test this field instead.

While bothi fields, screen_base and screen_buffer, are stored in the
same location, they refer to different address spaces. For correctness,
we want to test each field in exactly the code that uses it.

v2:
	* also test screen_base in pvr2fb (Geert)
	* also test screen_buffer in ivtvfb, arcfb, broadsheetfb,
	  hecubafb, metronomefb and ssd1307fb (Geert)
	* give a rational for the change (Geert)

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Tested-by: default avatarSui Jingfeng <suijingfeng@loongson.cn>
Reviewed-by: default avatarJavier Martinez Canillas <javierm@redhat.com>
Acked-by: default avatarHelge Deller <deller@gmx.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20230428122452.4856-18-tzimmermann@suse.de
parent 453bd913
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -378,6 +378,9 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
	unsigned long dma_size;
	u16 lead = 0, tail = 0;

	if (!info->screen_base)
		return -ENODEV;

	total_size = info->screen_size;

	if (total_size == 0)
+3 −0
Original line number Diff line number Diff line
@@ -451,6 +451,9 @@ static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
	struct arcfb_par *par;
	unsigned int xres;

	if (!info->screen_buffer)
		return -ENODEV;

	p = *ppos;
	par = info->par;
	xres = info->var.xres;
+3 −0
Original line number Diff line number Diff line
@@ -1013,6 +1013,9 @@ static ssize_t broadsheetfb_write(struct fb_info *info, const char __user *buf,
	int err = 0;
	unsigned long total_size;

	if (!info->screen_buffer)
		return -ENODEV;

	total_size = info->fix.smem_len;

	if (p > total_size)
+6 −0
Original line number Diff line number Diff line
@@ -129,6 +129,9 @@ static ssize_t cobalt_lcdfb_read(struct fb_info *info, char __user *buf,
	unsigned long pos;
	int len, retval = 0;

	if (!info->screen_base)
		return -ENODEV;

	pos = *ppos;
	if (pos >= LCD_CHARS_MAX || count == 0)
		return 0;
@@ -175,6 +178,9 @@ static ssize_t cobalt_lcdfb_write(struct fb_info *info, const char __user *buf,
	unsigned long pos;
	int len, retval = 0;

	if (!info->screen_base)
		return -ENODEV;

	pos = *ppos;
	if (pos >= LCD_CHARS_MAX || count == 0)
		return 0;
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
	unsigned long total_size, c;
	ssize_t ret;

	if (!info->screen_buffer)
		return -ENODEV;

	total_size = info->screen_size;

	if (total_size == 0)
@@ -61,6 +64,9 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
	unsigned long total_size, c;
	size_t ret;

	if (!info->screen_buffer)
		return -ENODEV;

	total_size = info->screen_size;

	if (total_size == 0)
Loading