sometime probably you need to call some func in kernel space who has a user space pointer as its argument, e.g.:
ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos);
If you directly call vfs_read, kernel will find that your buf parameter is not a user space pointer, so it sucks! you can set task's addr_limit to KERNEL_DS to cheat the kernel, let it believe your buf parameter is safe. as follows:
mm_segment_t old_fs;
old_fs = get_fs();
set_fs(KERNEL_DS);
vfs_read(filp, your_buf, ..........);
set_fs(old_fs);
an example :
//fs/exec.c
int kernel_read(struct file *file, unsigned long offset, char *addr, unsigned long count) { mm_segment_t old_fs; loff_t pos = offset; int result;
old_fs = get_fs(); set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ result = vfs_read(file, (void __user *)addr, count, &pos); set_fs(old_fs); return result; } EXPORT_SYMBOL(kernel_read);
|
sxg
阅读(1526) | 评论(0) | 转发(0) |