diff options
-rw-r--r-- | drivers/video/fbdev/core/fb_sys_fops.c | 24 | ||||
-rw-r--r-- | drivers/video/fbdev/core/fbmem.c | 15 |
2 files changed, 24 insertions, 15 deletions
diff --git a/drivers/video/fbdev/core/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c index ff275d7f3eaf..cefb77b9546d 100644 --- a/drivers/video/fbdev/core/fb_sys_fops.c +++ b/drivers/video/fbdev/core/fb_sys_fops.c @@ -19,7 +19,8 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, unsigned long p = *ppos; void *src; int err = 0; - unsigned long total_size; + unsigned long total_size, c; + ssize_t ret; if (info->state != FBINFO_STATE_RUNNING) return -EPERM; @@ -43,13 +44,14 @@ ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, if (info->fbops->fb_sync) info->fbops->fb_sync(info); - if (copy_to_user(buf, src, count)) + c = copy_to_user(buf, src, count); + if (c) err = -EFAULT; + ret = count - c; - if (!err) - *ppos += count; + *ppos += ret; - return (err) ? err : count; + return ret ? ret : err; } EXPORT_SYMBOL_GPL(fb_sys_read); @@ -59,7 +61,8 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, unsigned long p = *ppos; void *dst; int err = 0; - unsigned long total_size; + unsigned long total_size, c; + size_t ret; if (info->state != FBINFO_STATE_RUNNING) return -EPERM; @@ -89,13 +92,14 @@ ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, if (info->fbops->fb_sync) info->fbops->fb_sync(info); - if (copy_from_user(dst, buf, count)) + c = copy_from_user(dst, buf, count); + if (c) err = -EFAULT; + ret = count - c; - if (!err) - *ppos += count; + *ppos += ret; - return (err) ? err : count; + return ret ? ret : err; } EXPORT_SYMBOL_GPL(fb_sys_write); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 875541ff185b..9c79fb076c6d 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -766,7 +766,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) u8 *buffer, *dst; u8 __iomem *src; int c, cnt = 0, err = 0; - unsigned long total_size; + unsigned long total_size, trailing; if (!info || ! info->screen_base) return -ENODEV; @@ -808,10 +808,13 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) dst += c; src += c; - if (copy_to_user(buf, buffer, c)) { + trailing = copy_to_user(buf, buffer, c); + if (trailing == c) { err = -EFAULT; break; } + c -= trailing; + *ppos += c; buf += c; cnt += c; @@ -820,7 +823,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) kfree(buffer); - return (err) ? err : cnt; + return cnt ? cnt : err; } static ssize_t @@ -831,7 +834,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) u8 *buffer, *src; u8 __iomem *dst; int c, cnt = 0, err = 0; - unsigned long total_size; + unsigned long total_size, trailing; if (!info || !info->screen_base) return -ENODEV; @@ -876,10 +879,12 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) c = (count > PAGE_SIZE) ? PAGE_SIZE : count; src = buffer; - if (copy_from_user(src, buf, c)) { + trailing = copy_from_user(src, buf, c); + if (trailing == c) { err = -EFAULT; break; } + c -= trailing; fb_memcpy_tofb(dst, src, c); dst += c; |