aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@parcelfarce.linux.theplanet.co.uk>2005-08-27 01:48:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-27 13:11:40 -0400
commit6a029a90f5b93e2b50bcbbaef05ef91fa0c1d6b3 (patch)
treeba62bf7de680c10c00224305d628b484494918a1
parent36676bcbf9f6bcbea9d06e67ee8d04eacde54952 (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>
-rw-r--r--arch/um/drivers/mmapper_kern.c41
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;
31static char *v_buf = NULL; 23static char *v_buf = NULL;
32 24
33static ssize_t 25static ssize_t
34mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos) 26mmapper_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
50static ssize_t 31static ssize_t
51mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 32mmapper_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;
94out: 72out:
95 unlock_kernel();
96 return ret; 73 return ret;
97} 74}
98 75