summaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c48
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},