<div dir="ltr">The particular non-C binary that I&#39;m using is rust with musl support, so that I can statically compile the binary in order to eliminate all library dependencies and then run it on a buildroot based linux.</div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 16, 2016 at 1:32 PM, Kenneth Adam Miller <span dir="ltr">&lt;<a href="mailto:kennethadammiller@gmail.com" target="_blank">kennethadammiller@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Wait, are you assuming that I&#39;m using the latest kernel? Because I&#39;m using 3.14.56...</div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 16, 2016 at 1:31 PM, Mike Krinkin <span dir="ltr">&lt;<a href="mailto:krinkin.m.u@gmail.com" target="_blank">krinkin.m.u@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On Sat, Jan 16, 2016 at 01:16:42PM -0500, Kenneth Adam Miller wrote:<br>
&gt; Ok, so you think that the format of the binary would influence the kernel<br>
&gt; to change the permissions on the user&#39;s behalf? There&#39;s not much prose<br>
&gt; explanation here, and I don&#39;t understand why the kernel would do something<br>
&gt; like this.<br>
<br>
</span>That personality falg was introduced here with quite a detail explanation<br>
(which i don&#39;t understand though):<br>
<a href="http://lwn.net/Articles/94068/" rel="noreferrer" target="_blank">http://lwn.net/Articles/94068/</a><br>
<span><br>
&gt; I just wanted to use a static binary to eliminate library<br>
&gt; dependency issues between my host machine and the target machine. I had no<br>
&gt; idea that settings like this would carry over to my task at hand.<br>
<br>
</span>I compiled simple hello world with -static flag, and GNU_STACK in the binary<br>
has no executable flag set, so static has probably nothing to do with this.<br>
<div><div><br>
&gt;<br>
&gt; On Sat, Jan 16, 2016 at 1:08 PM, Mike Krinkin &lt;<a href="mailto:krinkin.m.u@gmail.com" target="_blank">krinkin.m.u@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; &gt; On Sat, Jan 16, 2016 at 12:45:17PM -0500, Kenneth Adam Miller wrote:<br>
&gt; &gt; &gt; I got the strace output of my non-C binary (I filtered the noise out of<br>
&gt; &gt; the<br>
&gt; &gt; &gt; output for you):<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; mmap(NULL, 8192, PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1,<br>
&gt; &gt; 0)<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; I also have readelf -l output:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Elf file type is EXEC (Executable file)<br>
&gt; &gt; &gt; Entry point 0x401311<br>
&gt; &gt; &gt; There are 7 program headers, starting at offset 64<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Program Headers:<br>
&gt; &gt; &gt;   Type           Offset             VirtAddr           PhysAddr<br>
&gt; &gt; &gt;                  FileSiz            MemSiz              Flags  Align<br>
&gt; &gt; &gt;   LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000<br>
&gt; &gt; &gt;                  0x00000000000db604 0x00000000000db604  R E    1000<br>
&gt; &gt; &gt;   LOAD           0x00000000000dc1c0 0x00000000004dd1c0 0x00000000004dd1c0<br>
&gt; &gt; &gt;                  0x0000000000006220 0x00000000000091dc  RW     1000<br>
&gt; &gt; &gt;   NOTE           0x00000000000001c8 0x00000000004001c8 0x00000000004001c8<br>
&gt; &gt; &gt;                  0x0000000000000024 0x0000000000000024  R      4<br>
&gt; &gt; &gt;   GNU_EH_FRAME   0x00000000000d5680 0x00000000004d5680 0x00000000004d5680<br>
&gt; &gt; &gt;                  0x0000000000005f84 0x0000000000005f84  R      4<br>
&gt; &gt; &gt;   GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000<br>
&gt; &gt; &gt;                  0x0000000000000000 0x0000000000000000  RWE    0<br>
&gt; &gt;<br>
&gt; &gt; Well, probably this is a bit more relevant:<br>
&gt; &gt; <a href="http://lxr.free-electrons.com/source/mm/mmap.c#L1281" rel="noreferrer" target="_blank">http://lxr.free-electrons.com/source/mm/mmap.c#L1281</a><br>
&gt; &gt;<br>
&gt; &gt; As far as i can see, kernel sets READ_IMPLIES_EXEC flag here:<br>
&gt; &gt; <a href="http://lxr.free-electrons.com/source/fs/binfmt_elf.c#L844" rel="noreferrer" target="_blank">http://lxr.free-electrons.com/source/fs/binfmt_elf.c#L844</a><br>
&gt; &gt;<br>
&gt; &gt; if executable_stack != EXSTACK_DISABLE_X, and executable_stack initialized<br>
&gt; &gt; here:<br>
&gt; &gt; <a href="http://lxr.free-electrons.com/source/fs/binfmt_elf.c#L781" rel="noreferrer" target="_blank">http://lxr.free-electrons.com/source/fs/binfmt_elf.c#L781</a><br>
&gt; &gt;<br>
&gt; &gt; if GNU_STACK has an executable flag set (and i suppose, that RWE means,<br>
&gt; &gt; that<br>
&gt; &gt; in your case GNU_STACK indeed has exectuable flag set).<br>
&gt; &gt;<br>
&gt; &gt; It may be a reason, i&#39;m not shure though. May be this can help:<br>
&gt; &gt; <a href="http://man7.org/linux/man-pages/man2/personality.2.html" rel="noreferrer" target="_blank">http://man7.org/linux/man-pages/man2/personality.2.html</a><br>
&gt; &gt;<br>
&gt; &gt;<br>
&gt; &gt; &gt;   TLS            0x00000000000dc1c0 0x00000000004dd1c0 0x00000000004dd1c0<br>
&gt; &gt; &gt;                  0x0000000000000100 0x0000000000000100  R      10<br>
&gt; &gt; &gt;   GNU_RELRO      0x00000000000dc1c0 0x00000000004dd1c0 0x00000000004dd1c0<br>
&gt; &gt; &gt;                  0x0000000000005e40 0x0000000000005e40  RW     20<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt;  Section to Segment mapping:<br>
&gt; &gt; &gt;   Segment Sections...<br>
&gt; &gt; &gt;    00     .note.gnu.build-id .init .text .fini .gcc_except_table .rodata<br>
&gt; &gt; &gt; .debug_gdb_scripts .eh_frame .eh_frame_hdr<br>
&gt; &gt; &gt;    01     .tdata .data.rel.ro.local .<a href="http://data.rel.ro" rel="noreferrer" target="_blank">data.rel.ro</a> .init_array .got<br>
&gt; &gt; .got.plt<br>
&gt; &gt; &gt; .data .bss<br>
&gt; &gt; &gt;    02     .note.gnu.build-id<br>
&gt; &gt; &gt;    03     .eh_frame_hdr<br>
&gt; &gt; &gt;    04<br>
&gt; &gt; &gt;    05     .tdata<br>
&gt; &gt; &gt;    06     .tdata .data.rel.ro.local .<a href="http://data.rel.ro" rel="noreferrer" target="_blank">data.rel.ro</a> .init_array .got<br>
&gt; &gt; .got.plt<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; Some notes:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; As a test, I changed the non-C binary&#39;s target device file to /dev/zero,<br>
&gt; &gt; &gt; and then I could see that the non-C mmap attempt would succeed just fine.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; After further verification and debugging based on guidance from another<br>
&gt; &gt; &gt; forum, I have convinced that the vm_flags change must be occuring<br>
&gt; &gt; somewhere<br>
&gt; &gt; &gt; in kernel land after control flow has left user land. Now I need to<br>
&gt; &gt; figure<br>
&gt; &gt; &gt; out how to use a kernel debugger or kprobes to walk through the execution<br>
&gt; &gt; &gt; of mmap callback delegation and see where the flags parameter is being<br>
&gt; &gt; &gt; changed.<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; I was pointed out to this:<br>
&gt; &gt; &gt; <a href="http://lxr.free-electrons.com/source/mm/mmap.c#L1312" rel="noreferrer" target="_blank">http://lxr.free-electrons.com/source/mm/mmap.c#L1312</a><br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; But why would my vm_flags be changed by the kernel? And what can I do to<br>
&gt; &gt; &gt; get this to stop? Why is the kernel changing the vm_flags for a non-C<br>
&gt; &gt; &gt; binary using my device file, but not for either a C binary using my<br>
&gt; &gt; device<br>
&gt; &gt; &gt; file or any type of binary that&#39;s not using my device file?<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; On Thu, Jan 14, 2016 at 12:28 PM, Kenneth Adam Miller &lt;<br>
&gt; &gt; &gt; <a href="mailto:kennethadammiller@gmail.com" target="_blank">kennethadammiller@gmail.com</a>&gt; wrote:<br>
&gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; On Thu, Jan 14, 2016 at 12:00 PM, Mike Krinkin &lt;<a href="mailto:krinkin.m.u@gmail.com" target="_blank">krinkin.m.u@gmail.com</a>&gt;<br>
&gt; &gt; &gt; &gt; wrote:<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;&gt; Hi, i have a couple of questions to clarify, if you don&#39;t mind<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;&gt; On Thu, Jan 14, 2016 at 11:04:28AM -0500, Kenneth Adam Miller wrote:<br>
&gt; &gt; &gt; &gt;&gt; &gt; I have a custom drive and userland program pair that I&#39;m using for a<br>
&gt; &gt; &gt; &gt;&gt; very<br>
&gt; &gt; &gt; &gt;&gt; &gt; special use case at my workplace where we are mapping specific<br>
&gt; &gt; physical<br>
&gt; &gt; &gt; &gt;&gt; &gt; address ranges into userland memory with a mmap callback. Everything<br>
&gt; &gt; &gt; &gt;&gt; works<br>
&gt; &gt; &gt; &gt;&gt; &gt; together well with a C userland program that calls into our driver&#39;s<br>
&gt; &gt; &gt; &gt;&gt; ioctl<br>
&gt; &gt; &gt; &gt;&gt; &gt; and mmap definitions, but for our case we are using an alternative<br>
&gt; &gt; &gt; &gt;&gt; systems<br>
&gt; &gt; &gt; &gt;&gt; &gt; language just for the userland program.<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;&gt; So you have userland app written in C, and another not written in C?<br>
&gt; &gt; &gt; &gt;&gt; The former works well while the latter doesn&#39;t, am i right?<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; Yes, the former works in so much as mmap completes successfully. I&#39;ve<br>
&gt; &gt; &gt; &gt; verified that the<br>
&gt; &gt; &gt; &gt; parameters are identical in the non-C program. The issue of just using<br>
&gt; &gt; the<br>
&gt; &gt; &gt; &gt; C only program<br>
&gt; &gt; &gt; &gt; is that the actual implementation of interest is in the non-C program,<br>
&gt; &gt; and<br>
&gt; &gt; &gt; &gt; that&#39;s because<br>
&gt; &gt; &gt; &gt; that language facilitates other features that are *required* on our<br>
&gt; &gt; end.<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;&gt; &gt; That mmap call is failing (properly<br>
&gt; &gt; &gt; &gt;&gt; &gt; as we want) out from the driver&#39;s mmap implementation due to the<br>
&gt; &gt; fact<br>
&gt; &gt; &gt; &gt;&gt; that<br>
&gt; &gt; &gt; &gt;&gt; &gt; the vm_flags have the VM_EXEC flag set. We do not want users to be<br>
&gt; &gt; able<br>
&gt; &gt; &gt; &gt;&gt; to<br>
&gt; &gt; &gt; &gt;&gt; &gt; map the memory range as executable, so the driver should check for<br>
&gt; &gt; this<br>
&gt; &gt; &gt; &gt;&gt; as<br>
&gt; &gt; &gt; &gt;&gt; &gt; it does. The issue is in the fact that somewhere between where mmap<br>
&gt; &gt; is<br>
&gt; &gt; &gt; &gt;&gt; &gt; called and when the parameters are given to the driver, the<br>
&gt; &gt; &gt; &gt;&gt; vma-&gt;vm_flags<br>
&gt; &gt; &gt; &gt;&gt; &gt; are being set to 255. I&#39;ve manually checked the values being given<br>
&gt; &gt; to<br>
&gt; &gt; &gt; &gt;&gt; the<br>
&gt; &gt; &gt; &gt;&gt; &gt; mmap call in our non-C binary, and they are *equivalent* in value to<br>
&gt; &gt; &gt; &gt;&gt; that<br>
&gt; &gt; &gt; &gt;&gt; &gt; of the C program.<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;&gt; By &quot;manually&quot; do you mean strace? Could you show strace output for<br>
&gt; &gt; &gt; &gt;&gt; both apps? And also could you show readelf -l output for both<br>
&gt; &gt; binaries?<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt; By manually, I mean with a print call just before the mmap call in<br>
&gt; &gt; each of<br>
&gt; &gt; &gt; &gt; the<br>
&gt; &gt; &gt; &gt; programs. Right now, I&#39;m working on getting a strace output, but I<br>
&gt; &gt; have to<br>
&gt; &gt; &gt; &gt; run that in qemu.<br>
&gt; &gt; &gt; &gt; To be able to run it in qemu in order to isolate the driver and all<br>
&gt; &gt; from<br>
&gt; &gt; &gt; &gt; my host, I have to build<br>
&gt; &gt; &gt; &gt; with buildroot. So I&#39;ll email that when I get it, but it&#39;ll be a while.<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;&gt; &gt;<br>
&gt; &gt; &gt; &gt;&gt; &gt; My question is, is there anything that can cause the vma-&gt;vm_flags<br>
&gt; &gt; to be<br>
&gt; &gt; &gt; &gt;&gt; &gt; changed in the trip between when the user land program calls mmap<br>
&gt; &gt; and<br>
&gt; &gt; &gt; &gt;&gt; when<br>
&gt; &gt; &gt; &gt;&gt; &gt; control is delivered to the mmap callback?<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;&gt; &gt; _______________________________________________<br>
&gt; &gt; &gt; &gt;&gt; &gt; Kernelnewbies mailing list<br>
&gt; &gt; &gt; &gt;&gt; &gt; <a href="mailto:Kernelnewbies@kernelnewbies.org" target="_blank">Kernelnewbies@kernelnewbies.org</a><br>
&gt; &gt; &gt; &gt;&gt; &gt; <a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies" rel="noreferrer" target="_blank">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;&gt;<br>
&gt; &gt; &gt; &gt;<br>
&gt; &gt;<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>