<p dir="ltr">Hi Yann, thank you, as I said this isn&#39;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&#39;s performance. :)</p>
<p dir="ltr">Best regards!<br>
-dhs</p>
<div class="gmail_quote">Em 28/09/2015 17:08, &quot;Yann Droneaud&quot; &lt;<a href="mailto:ydroneaud@opteya.com">ydroneaud@opteya.com</a>&gt; 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>
&gt; Hi all, I have a doubt about using pointers inside structs that are<br>
&gt; passed (as pointers) to ioctl argument. Since pointers passed from<br>
&gt; userspace can&#39;t be trusted, I need to copy they to kernel before<br>
&gt; accessing they. In this case I have a pointer inside a struct that is<br>
&gt; passed to the ioctl call also as pointer. So I need to copy the whole<br>
&gt; struct to kernel space and only then dereference the pointer. If this<br>
&gt; is true, two copy_from_user is needed right?<br>
&gt;<br>
&gt; Suppose I have a struct like this<br>
&gt;<br>
&gt; struct myioctl_arg {<br>
&gt;     char *tx_buf;<br>
<br>
__u8 __user *tx_buf;<br>
<br>
&gt;     int tx_siz;<br>
<br>
__u32 tx_siz;<br>
<br>
&gt; }<br>
&gt;<br>
&gt; and this ioctl definition<br>
&gt;<br>
&gt; #define MYIOCTL_TX _IOWR(MY_MAGIC, MY_BASE, struct myioctl_arg *);<br>
&gt;<br>
<br>
#define MYIOCTL_TX _IOWR(MY_MAGIC, MY_BASE, struct myioctl_arg);<br>
<br>
&gt; At userspace program I do something like this:<br>
&gt;<br>
&gt; struct myioctl_arg arg = { .tx_buf = somebuf, .tx_siz = 32 }<br>
&gt; ioctl(fd, MYIOCTL_TX, &amp;arg);<br>
&gt;<br>
&gt; And in my ioclt implementation<br>
&gt; static ioctl(struct file *fp, unsigned int cmd, unsigned long arg)<br>
&gt; {<br>
&gt;     struct myioctl_arg karg;<br>
&gt;     char   kbuf[100];<br>
&gt;     ...<br>
&gt;     case MYIOCTL_TX:<br>
&gt;           copy_from_user(&amp;karg, arg, sizeof(karg));<br>
<br>
        if (copy_from_user(&amp;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 &gt; sizeof(kbuf))<br>
                return -EINVAL;<br>
<br>
&gt;           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>
&gt;           // now kbuf has the same contents of somebuf in userspace<br>
&gt;    ...<br>
&gt; }<br>
&gt;<br>
&gt;<br>
&gt; I&#39;m in doubt if this is the right way to access the userspace tx_buf.<br>
&gt; Since the .tx_buf from arg is a userspace pointer, accessible from<br>
&gt; userspace pointer arg, I can&#39;t type arg-&gt;tx_buf directly, doing this<br>
&gt; is dereferencing a userspace pointer inside kernel. So I need to copy<br>
&gt; the whole struct and dereference from the kernel space copy of it. So<br>
&gt; this two calls of copy_from_user() is the right way to do it? They are<br>
&gt; needed at all or is there better way of doing it?<br>
&gt;<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&#39;t have to copy the memory to access it.<br>
<br>
Regards.<br>
<br>
--<br>
Yann Droneaud<br>
OPTEYA<br>
<br>
<br>
</blockquote></div>