<p dir="ltr">Hi Yann, thank you, as I said this isn't real code, I just use to show my case. Anyway I will take the considerations in account. Thank you so much! And this get_user_page is new to me, thanks for pointing me out, I will read about it.</p>
<p dir="ltr">The real thing is a driver to nrf24l01+ driver from Nordic. I may use this non copying aproach to exchange lot of frames without copying. This would improve driver's performance. :)</p>
<p dir="ltr">Best regards!<br>
-dhs</p>
<div class="gmail_quote">Em 28/09/2015 17:08, "Yann Droneaud" <<a href="mailto:ydroneaud@opteya.com">ydroneaud@opteya.com</a>> escreveu:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
Le lundi 28 septembre 2015 à 13:51 -0300, Daniel. a écrit :<br>
> Hi all, I have a doubt about using pointers inside structs that are<br>
> passed (as pointers) to ioctl argument. Since pointers passed from<br>
> userspace can't be trusted, I need to copy they to kernel before<br>
> accessing they. In this case I have a pointer inside a struct that is<br>
> passed to the ioctl call also as pointer. So I need to copy the whole<br>
> struct to kernel space and only then dereference the pointer. If this<br>
> is true, two copy_from_user is needed right?<br>
><br>
> Suppose I have a struct like this<br>
><br>
> struct myioctl_arg {<br>
> char *tx_buf;<br>
<br>
__u8 __user *tx_buf;<br>
<br>
> int tx_siz;<br>
<br>
__u32 tx_siz;<br>
<br>
> }<br>
><br>
> and this ioctl definition<br>
><br>
> #define MYIOCTL_TX _IOWR(MY_MAGIC, MY_BASE, struct myioctl_arg *);<br>
><br>
<br>
#define MYIOCTL_TX _IOWR(MY_MAGIC, MY_BASE, struct myioctl_arg);<br>
<br>
> At userspace program I do something like this:<br>
><br>
> struct myioctl_arg arg = { .tx_buf = somebuf, .tx_siz = 32 }<br>
> ioctl(fd, MYIOCTL_TX, &arg);<br>
><br>
> And in my ioclt implementation<br>
> static ioctl(struct file *fp, unsigned int cmd, unsigned long arg)<br>
> {<br>
> struct myioctl_arg karg;<br>
> char kbuf[100];<br>
> ...<br>
> case MYIOCTL_TX:<br>
> copy_from_user(&karg, arg, sizeof(karg));<br>
<br>
if (copy_from_user(&karg, (const void __user *)arg, sizeof(karg))<br>
return -EFAULT;<br>
<br>
if (!karg.tx_siz)<br>
return -EINVAL;<br>
<br>
if (karg.tx_siz > sizeof(kbuf))<br>
return -EINVAL;<br>
<br>
> copy_from_user(kbuf, karg.tx_buf, karg.tx_siz);<br>
<br>
if (copy_from_user(kbuf, karg.tx_buf, karg.tx_siz))<br>
return -EFAULT;<br>
<br>
> // now kbuf has the same contents of somebuf in userspace<br>
> ...<br>
> }<br>
><br>
><br>
> I'm in doubt if this is the right way to access the userspace tx_buf.<br>
> Since the .tx_buf from arg is a userspace pointer, accessible from<br>
> userspace pointer arg, I can't type arg->tx_buf directly, doing this<br>
> is dereferencing a userspace pointer inside kernel. So I need to copy<br>
> the whole struct and dereference from the kernel space copy of it. So<br>
> this two calls of copy_from_user() is the right way to do it? They are<br>
> needed at all or is there better way of doing it?<br>
><br>
<br>
They are needed. Add __user annotation, install sparse and build with<br>
make C=1.<br>
<br>
For the second one, if the tx_buf is large enough, you may be well using<br>
something like get_user_page() to pin userspace memory inside the kernel<br>
memory so that you don't have to copy the memory to access it.<br>
<br>
Regards.<br>
<br>
--<br>
Yann Droneaud<br>
OPTEYA<br>
<br>
<br>
</blockquote></div>