]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
fbdev: Validate info->screen_{base, buffer} in fb_ops implementations
authorThomas Zimmermann <tzimmermann@suse.de>
Fri, 28 Apr 2023 12:24:50 +0000 (14:24 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Mon, 8 May 2023 13:28:34 +0000 (15:28 +0200)
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
drivers/media/pci/ivtv/ivtvfb.c
drivers/video/fbdev/arcfb.c
drivers/video/fbdev/broadsheetfb.c
drivers/video/fbdev/cobalt_lcdfb.c
drivers/video/fbdev/core/fb_sys_fops.c
drivers/video/fbdev/core/fbmem.c
drivers/video/fbdev/hecubafb.c
drivers/video/fbdev/metronomefb.c
drivers/video/fbdev/pvr2fb.c
drivers/video/fbdev/sm712fb.c
drivers/video/fbdev/ssd1307fb.c

index 22123a25daea9cb02642070b97eba9a7c307d32d..0aeb9daaee4cbeddd2800d8b90723fe8e3a48af6 100644 (file)
@@ -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)
index 088c4b30fd314d19629289ae3917bb47dba8cdb0..7750e020839ecd91fb736db5495c9ffd92d30eb1 100644 (file)
@@ -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;
index 691de5df581b896d132f3cbe5bb6b59fd6c7975a..e9c5d5c04062bd6b41ee6be1111d9f623da3e60b 100644 (file)
@@ -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)
index 5f8b6324d2e8cc13498f59519c4a48f27a53c213..26dbd1c78195cb40fece7f6e75cd7fc1bcba727e 100644 (file)
@@ -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;
index 7dee5d3c7fb1477bc040ab3f60622cfdbad60195..0cb0989abda61c5f4e3d0cb32b105bf6848a419c 100644 (file)
@@ -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)
index 9c79fb076c6d9059027e8293eb18b9cd18306638..bf5a0780457e19cd5721836d3d7e1c39bd68ba94 100644 (file)
@@ -768,7 +768,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        int c, cnt = 0, err = 0;
        unsigned long total_size, trailing;
 
-       if (!info || ! info->screen_base)
+       if (!info)
                return -ENODEV;
 
        if (info->state != FBINFO_STATE_RUNNING)
@@ -777,6 +777,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
        if (info->fbops->fb_read)
                return info->fbops->fb_read(info, buf, count, ppos);
 
+       if (!info->screen_base)
+               return -ENODEV;
+
        total_size = info->screen_size;
 
        if (total_size == 0)
@@ -836,7 +839,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
        int c, cnt = 0, err = 0;
        unsigned long total_size, trailing;
 
-       if (!info || !info->screen_base)
+       if (!info)
                return -ENODEV;
 
        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)
        if (info->fbops->fb_write)
                return info->fbops->fb_write(info, buf, count, ppos);
 
+       if (!info->screen_base)
+               return -ENODEV;
+
        total_size = info->screen_size;
 
        if (total_size == 0)
index a2996d39f918cfd50e01c4d099001383284596cc..72308d4e0c22d05c60f4477d6602da373a58d49b 100644 (file)
@@ -163,6 +163,9 @@ static ssize_t hecubafb_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)
index 2bb068cadac63c9dc0ce3f48ff4be52841f30b9c..7fc59466fe6c923bb7225194205b9385f8ea8db2 100644 (file)
@@ -523,6 +523,9 @@ static ssize_t metronomefb_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)
index 6888127a5eb8859437432abdf43cfbf936cfd1ff..550fdb5b4d41e4c6042e286ef09d63d8bf1ae1d2 100644 (file)
@@ -647,6 +647,9 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
        struct page **pages;
        int ret, i;
 
+       if (!info->screen_base)
+               return -ENODEV;
+
        nr_pages = (count + PAGE_SIZE - 1) >> PAGE_SHIFT;
 
        pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
index 6f852cd756c5fe06410721a7ea6d45108b014022..b7ad3c644e138db5a76c09ac15acd79ec8c78034 100644 (file)
@@ -1028,7 +1028,7 @@ static ssize_t smtcfb_read(struct fb_info *info, char __user *buf,
        int c, i, cnt = 0, err = 0;
        unsigned long total_size;
 
-       if (!info || !info->screen_base)
+       if (!info->screen_base)
                return -ENODEV;
 
        total_size = info->screen_size;
@@ -1091,7 +1091,7 @@ static ssize_t smtcfb_write(struct fb_info *info, const char __user *buf,
        int c, i, cnt = 0, err = 0;
        unsigned long total_size;
 
-       if (!info || !info->screen_base)
+       if (!info->screen_base)
                return -ENODEV;
 
        total_size = info->screen_size;
index 046b9990d27cd92c1a26b16bf9f6c05713a65dda..a8f2975de76bebb104f36fecc01e7030b86e7ed5 100644 (file)
@@ -301,6 +301,9 @@ static ssize_t ssd1307fb_write(struct fb_info *info, const char __user *buf,
        void *dst;
        int ret;
 
+       if (!info->screen_buffer)
+               return -ENODEV;
+
        total_size = info->fix.smem_len;
 
        if (p > total_size)