Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[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>

authored by

Al Viro and committed by
Linus Torvalds
6a029a90 36676bcb

+9 -32
+9 -32
arch/um/drivers/mmapper_kern.c
··· 9 9 * 10 10 */ 11 11 12 - #include <linux/types.h> 13 - #include <linux/kdev_t.h> 14 - #include <linux/time.h> 15 - #include <linux/devfs_fs_kernel.h> 12 + #include <linux/init.h> 16 13 #include <linux/module.h> 17 14 #include <linux/mm.h> 18 - #include <linux/slab.h> 19 - #include <linux/init.h> 20 - #include <linux/smp_lock.h> 21 15 #include <linux/miscdevice.h> 22 16 #include <asm/uaccess.h> 23 - #include <asm/irq.h> 24 - #include <asm/pgtable.h> 25 17 #include "mem_user.h" 26 18 #include "user_util.h" 27 19 ··· 23 31 static char *v_buf = NULL; 24 32 25 33 static ssize_t 26 - mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos) 34 + mmapper_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 27 35 { 28 - if(*ppos > mmapper_size) 29 - return -EINVAL; 30 - 31 - if(count + *ppos > mmapper_size) 32 - count = count + *ppos - mmapper_size; 33 - 34 - if(count < 0) 35 - return -EINVAL; 36 - 37 - copy_to_user(buf,&v_buf[*ppos],count); 38 - 39 - return count; 36 + return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size); 40 37 } 41 38 42 39 static ssize_t 43 - mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos) 40 + mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 44 41 { 45 - if(*ppos > mmapper_size) 42 + if (*ppos > mmapper_size) 46 43 return -EINVAL; 47 44 48 - if(count + *ppos > mmapper_size) 49 - count = count + *ppos - mmapper_size; 45 + if (count > mmapper_size - *ppos) 46 + count = mmapper_size - *ppos; 50 47 51 - if(count < 0) 52 - return -EINVAL; 53 - 54 - copy_from_user(&v_buf[*ppos],buf,count); 48 + if (copy_from_user(&v_buf[*ppos], buf, count)) 49 + return -EFAULT; 55 50 56 51 return count; 57 52 } ··· 56 77 int ret = -EINVAL; 57 78 int size; 58 79 59 - lock_kernel(); 60 80 if (vma->vm_pgoff != 0) 61 81 goto out; 62 82 ··· 70 92 goto out; 71 93 ret = 0; 72 94 out: 73 - unlock_kernel(); 74 95 return ret; 75 96 } 76 97