diff options
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r-- | drivers/char/mem.c | 48 |
1 files changed, 20 insertions, 28 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 29c41f4418c0..66719f9d294c 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -88,21 +88,15 @@ static inline int uncached_access(struct file *file, unsigned long addr) } #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE -static inline int valid_phys_addr_range(unsigned long addr, size_t *count) +static inline int valid_phys_addr_range(unsigned long addr, size_t count) { - unsigned long end_mem; - - end_mem = __pa(high_memory); - if (addr >= end_mem) + if (addr + count > __pa(high_memory)) return 0; - if (*count > end_mem - addr) - *count = end_mem - addr; - return 1; } -static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t *size) +static inline int valid_mmap_phys_addr_range(unsigned long addr, size_t size) { return 1; } @@ -119,7 +113,7 @@ static ssize_t read_mem(struct file * file, char __user * buf, ssize_t read, sz; char *ptr; - if (!valid_phys_addr_range(p, &count)) + if (!valid_phys_addr_range(p, count)) return -EFAULT; read = 0; #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED @@ -177,7 +171,7 @@ static ssize_t write_mem(struct file * file, const char __user * buf, unsigned long copied; void *ptr; - if (!valid_phys_addr_range(p, &count)) + if (!valid_phys_addr_range(p, count)) return -EFAULT; written = 0; @@ -216,11 +210,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf, copied = copy_from_user(ptr, buf, sz); if (copied) { - ssize_t ret; - - ret = written + (sz - copied); - if (ret) - return ret; + written += sz - copied; + if (written) + break; return -EFAULT; } buf += sz; @@ -251,7 +243,7 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma) { size_t size = vma->vm_end - vma->vm_start; - if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, &size)) + if (!valid_mmap_phys_addr_range(vma->vm_pgoff << PAGE_SHIFT, size)) return -EINVAL; vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff, @@ -456,11 +448,9 @@ do_write_kmem(void *p, unsigned long realp, const char __user * buf, copied = copy_from_user(ptr, buf, sz); if (copied) { - ssize_t ret; - - ret = written + (sz - copied); - if (ret) - return ret; + written += sz - copied; + if (written) + break; return -EFAULT; } buf += sz; @@ -514,11 +504,10 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, if (len) { written = copy_from_user(kbuf, buf, len); if (written) { - ssize_t ret; - + if (wrote + virtr) + break; free_page((unsigned long)kbuf); - ret = wrote + virtr + (len - written); - return ret ? ret : -EFAULT; + return -EFAULT; } } len = vwrite(kbuf, (char *)p, len); @@ -563,8 +552,11 @@ static ssize_t write_port(struct file * file, const char __user * buf, return -EFAULT; while (count-- > 0 && i < 65536) { char c; - if (__get_user(c, tmp)) + if (__get_user(c, tmp)) { + if (tmp > buf) + break; return -EFAULT; + } outb(c,i); i++; tmp++; @@ -907,7 +899,7 @@ static const struct { unsigned int minor; char *name; umode_t mode; - struct file_operations *fops; + const struct file_operations *fops; } devlist[] = { /* list of minor devices */ {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, |