On 2012-09-18 11:09, Dan Carpenter wrote:
On Tue, Sep 18, 2012 at 10:24:55AM +0100, Ian Abbott wrote:
On 2012-09-18 01:17, H Hartley Sweeten wrote:
The 'chanlist' in the comedi_cmd struct is an unsigned int __user
pointer.
The do_cmd_ioctl() and do_cmdtest_ioctl() functions in comedi_fops
do a copy_from_user() to move the data from user space to kernel
space before passing the comedi_cmd to the comedi drivers.
Unfortunately, the drivers then think 'chanlist' is still a
__user pointer since thats how the struct is defined.
Make the 'chanlist' a union of both a __user and kernel pointer.
The do_cmd_*_ioctl() functions are the only ones that use the
__user pointer. All the drivers then use the kernel pointer to
access the chanlist.
Personally, I'd rather get rid of the __user pointers in comedi.h
and do the appropriate casting in the comedi core.
(I came up with a macro a while ago to make the casting less ugly,
but I need to test that with `sparse` to make sure it doesn't get
confused.)
I didn't like that macro at all. :( Casting away user pointers
should be something that is only done rarely and it's good if it's
something you have to think about.
I can't remember the original email, but the macro I was thinking of was
along the lines of:
#define user_ptr(p) ((typeof(*(p)) __user *)(p))
to recast a kernel pointer as a user pointer. So it wasn't so much
casting the __user away as casting it in!
--
-=( Ian Abbott @ MEV Ltd. E-mail: <abbotti@xxxxxxxxx> )=-
-=( Tel: +44 (0)161 477 1898 FAX: +44 (0)161 718 3587 )=-
_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel