diff options
author | Al Viro <viro@parcelfarce.linux.theplanet.co.uk> | 2005-08-27 01:48:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-08-27 13:11:40 -0400 |
commit | 6a029a90f5b93e2b50bcbbaef05ef91fa0c1d6b3 (patch) | |
tree | ba62bf7de680c10c00224305d628b484494918a1 /arch/um/drivers | |
parent | 36676bcbf9f6bcbea9d06e67ee8d04eacde54952 (diff) |
[PATCH] mmaper_kern.c fixes [buffer overruns]
- copy_from_user() can fail; ->write() must check its return value.
- severe buffer overruns both in ->read() and ->write() - lseek to the
end (i.e. to mmapper_size) and
if (count + *ppos > mmapper_size)
count = count + *ppos - mmapper_size;
will do absolutely nothing. Then it will call
copy_to_user(buf,&v_buf[*ppos],count);
with obvious results (similar for ->write()).
Fixed by turning read to simple_read_from_buffer() and by doing
normal limiting of count in ->write().
- gratitious lock_kernel() in ->mmap() - it's useless there.
- lots of gratuitous includes.
Signed-off-by: Al Viro <viro@parcelfarce.linux.theplanet.co.uk>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/drivers')
-rw-r--r-- | arch/um/drivers/mmapper_kern.c | 41 |
1 files changed, 9 insertions, 32 deletions
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index a37a5ac13c22..022f67bb6873 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c | |||
@@ -9,19 +9,11 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/init.h> |
13 | #include <linux/kdev_t.h> | ||
14 | #include <linux/time.h> | ||
15 | #include <linux/devfs_fs_kernel.h> | ||
16 | #include <linux/module.h> | 13 | #include <linux/module.h> |
17 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/miscdevice.h> | 15 | #include <linux/miscdevice.h> |
22 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
23 | #include <asm/irq.h> | ||
24 | #include <asm/pgtable.h> | ||
25 | #include "mem_user.h" | 17 | #include "mem_user.h" |
26 | #include "user_util.h" | 18 | #include "user_util.h" |
27 | 19 | ||
@@ -31,35 +23,22 @@ static unsigned long p_buf = 0; | |||
31 | static char *v_buf = NULL; | 23 | static char *v_buf = NULL; |
32 | 24 | ||
33 | static ssize_t | 25 | static ssize_t |
34 | mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos) | 26 | mmapper_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) |
35 | { | 27 | { |
36 | if(*ppos > mmapper_size) | 28 | return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size); |
37 | return -EINVAL; | ||
38 | |||
39 | if(count + *ppos > mmapper_size) | ||
40 | count = count + *ppos - mmapper_size; | ||
41 | |||
42 | if(count < 0) | ||
43 | return -EINVAL; | ||
44 | |||
45 | copy_to_user(buf,&v_buf[*ppos],count); | ||
46 | |||
47 | return count; | ||
48 | } | 29 | } |
49 | 30 | ||
50 | static ssize_t | 31 | static ssize_t |
51 | mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos) | 32 | mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
52 | { | 33 | { |
53 | if(*ppos > mmapper_size) | 34 | if (*ppos > mmapper_size) |
54 | return -EINVAL; | 35 | return -EINVAL; |
55 | 36 | ||
56 | if(count + *ppos > mmapper_size) | 37 | if (count > mmapper_size - *ppos) |
57 | count = count + *ppos - mmapper_size; | 38 | count = mmapper_size - *ppos; |
58 | |||
59 | if(count < 0) | ||
60 | return -EINVAL; | ||
61 | 39 | ||
62 | copy_from_user(&v_buf[*ppos],buf,count); | 40 | if (copy_from_user(&v_buf[*ppos], buf, count)) |
41 | return -EFAULT; | ||
63 | 42 | ||
64 | return count; | 43 | return count; |
65 | } | 44 | } |
@@ -77,7 +56,6 @@ mmapper_mmap(struct file *file, struct vm_area_struct * vma) | |||
77 | int ret = -EINVAL; | 56 | int ret = -EINVAL; |
78 | int size; | 57 | int size; |
79 | 58 | ||
80 | lock_kernel(); | ||
81 | if (vma->vm_pgoff != 0) | 59 | if (vma->vm_pgoff != 0) |
82 | goto out; | 60 | goto out; |
83 | 61 | ||
@@ -92,7 +70,6 @@ mmapper_mmap(struct file *file, struct vm_area_struct * vma) | |||
92 | goto out; | 70 | goto out; |
93 | ret = 0; | 71 | ret = 0; |
94 | out: | 72 | out: |
95 | unlock_kernel(); | ||
96 | return ret; | 73 | return ret; |
97 | } | 74 | } |
98 | 75 | ||