Skip to content

Commit 3f8974f

Browse files
committed
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: Thomas Zimmermann <tzimmermann@suse.de> Tested-by: Sui Jingfeng <suijingfeng@loongson.cn> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Acked-by: Helge Deller <deller@gmx.de> Link: https://patchwork.freedesktop.org/patch/msgid/20230428122452.4856-18-tzimmermann@suse.de
1 parent 453bd91 commit 3f8974f

11 files changed

Lines changed: 43 additions & 4 deletions

File tree

drivers/media/pci/ivtv/ivtvfb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
378378
unsigned long dma_size;
379379
u16 lead = 0, tail = 0;
380380

381+
if (!info->screen_base)
382+
return -ENODEV;
383+
381384
total_size = info->screen_size;
382385

383386
if (total_size == 0)

drivers/video/fbdev/arcfb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,9 @@ static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
451451
struct arcfb_par *par;
452452
unsigned int xres;
453453

454+
if (!info->screen_buffer)
455+
return -ENODEV;
456+
454457
p = *ppos;
455458
par = info->par;
456459
xres = info->var.xres;

drivers/video/fbdev/broadsheetfb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,9 @@ static ssize_t broadsheetfb_write(struct fb_info *info, const char __user *buf,
10131013
int err = 0;
10141014
unsigned long total_size;
10151015

1016+
if (!info->screen_buffer)
1017+
return -ENODEV;
1018+
10161019
total_size = info->fix.smem_len;
10171020

10181021
if (p > total_size)

drivers/video/fbdev/cobalt_lcdfb.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ static ssize_t cobalt_lcdfb_read(struct fb_info *info, char __user *buf,
129129
unsigned long pos;
130130
int len, retval = 0;
131131

132+
if (!info->screen_base)
133+
return -ENODEV;
134+
132135
pos = *ppos;
133136
if (pos >= LCD_CHARS_MAX || count == 0)
134137
return 0;
@@ -175,6 +178,9 @@ static ssize_t cobalt_lcdfb_write(struct fb_info *info, const char __user *buf,
175178
unsigned long pos;
176179
int len, retval = 0;
177180

181+
if (!info->screen_base)
182+
return -ENODEV;
183+
178184
pos = *ppos;
179185
if (pos >= LCD_CHARS_MAX || count == 0)
180186
return 0;

drivers/video/fbdev/core/fb_sys_fops.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
2222
unsigned long total_size, c;
2323
ssize_t ret;
2424

25+
if (!info->screen_buffer)
26+
return -ENODEV;
27+
2528
total_size = info->screen_size;
2629

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

67+
if (!info->screen_buffer)
68+
return -ENODEV;
69+
6470
total_size = info->screen_size;
6571

6672
if (total_size == 0)

drivers/video/fbdev/core/fbmem.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
768768
int c, cnt = 0, err = 0;
769769
unsigned long total_size, trailing;
770770

771-
if (!info || ! info->screen_base)
771+
if (!info)
772772
return -ENODEV;
773773

774774
if (info->state != FBINFO_STATE_RUNNING)
@@ -777,6 +777,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
777777
if (info->fbops->fb_read)
778778
return info->fbops->fb_read(info, buf, count, ppos);
779779

780+
if (!info->screen_base)
781+
return -ENODEV;
782+
780783
total_size = info->screen_size;
781784

782785
if (total_size == 0)
@@ -836,7 +839,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
836839
int c, cnt = 0, err = 0;
837840
unsigned long total_size, trailing;
838841

839-
if (!info || !info->screen_base)
842+
if (!info)
840843
return -ENODEV;
841844

842845
if (info->state != FBINFO_STATE_RUNNING)
@@ -845,6 +848,9 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
845848
if (info->fbops->fb_write)
846849
return info->fbops->fb_write(info, buf, count, ppos);
847850

851+
if (!info->screen_base)
852+
return -ENODEV;
853+
848854
total_size = info->screen_size;
849855

850856
if (total_size == 0)

drivers/video/fbdev/hecubafb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf,
163163
int err = 0;
164164
unsigned long total_size;
165165

166+
if (!info->screen_buffer)
167+
return -ENODEV;
168+
166169
total_size = info->fix.smem_len;
167170

168171
if (p > total_size)

drivers/video/fbdev/metronomefb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,9 @@ static ssize_t metronomefb_write(struct fb_info *info, const char __user *buf,
523523
int err = 0;
524524
unsigned long total_size;
525525

526+
if (!info->screen_buffer)
527+
return -ENODEV;
528+
526529
total_size = info->fix.smem_len;
527530

528531
if (p > total_size)

drivers/video/fbdev/pvr2fb.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,9 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
647647
struct page **pages;
648648
int ret, i;
649649

650+
if (!info->screen_base)
651+
return -ENODEV;
652+
650653
nr_pages = (count + PAGE_SIZE - 1) >> PAGE_SHIFT;
651654

652655
pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);

drivers/video/fbdev/sm712fb.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ static ssize_t smtcfb_read(struct fb_info *info, char __user *buf,
10281028
int c, i, cnt = 0, err = 0;
10291029
unsigned long total_size;
10301030

1031-
if (!info || !info->screen_base)
1031+
if (!info->screen_base)
10321032
return -ENODEV;
10331033

10341034
total_size = info->screen_size;
@@ -1091,7 +1091,7 @@ static ssize_t smtcfb_write(struct fb_info *info, const char __user *buf,
10911091
int c, i, cnt = 0, err = 0;
10921092
unsigned long total_size;
10931093

1094-
if (!info || !info->screen_base)
1094+
if (!info->screen_base)
10951095
return -ENODEV;
10961096

10971097
total_size = info->screen_size;

0 commit comments

Comments
 (0)