Hi,I am trying to understand the read sandboxing of NaCl x86-64 and I have a set of questions on it.1. In this research paper, authors stated that "For data references, stores are sandboxed on both systems. Note that reads of secret data are generally not an issue as the address space barrier between the NaCl module and the browser protects browser resources such as cookies." However it seems that the early version of NaCl does not have read sandboxing; it is added in recent versions as mentioned in this discussion. I am confused that are the phrase "address space barrier" and so called "read sandboxing" added in later version of NaCl actually the same or not?
2. I wonder whether my understanding of read sandboxing in NaCl is correct:-1)an address is loaded into a general purpose register-2)the most significant 32 bits are cleared-3)the value is added to the base of sandbox's address space to get the true address-4)read from that address
I tried to dump the assembly code of a test program and I found the idea is similar as the one above. However when I try to modify the file inSRC/gcc/gcc/config/i386.mdin order not to let the compiler add 2nd and 3rd operation to different "mov" instructions, the read is still sandboxed when I test an example program via the modified toolchain. So I wonder whether my understanding is correct.
Many thanks for the reply.Is it possible now to get an earlier version source code which contains only write sandboxing?
It seems that I cannot simply remove the read sandboxing by removing "%nacl" prefix because of the duplication you mentioned.
Even though the write sandboxing would also be broken.
--
You received this message because you are subscribed to the Google Groups "Native-Client-Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to native-client-di...@googlegroups.com.
To post to this group, send email to native-cli...@googlegroups.com.
Visit this group at http://groups.google.com/group/native-client-discuss.
For more options, visit https://groups.google.com/d/optout.
20280: 48
8b 9c 24 90 00 00 mov 0x90(%rsp),%rbx
20287: 00
20288: bf
1d 02 02 10 mov
$0x1002021d,%edi
2028d: 31
c0 xor %eax,%eax
2028f: 48
63 f3 movslq %ebx,%rsi
20292: 66
0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
20299: 00
00
2029b: e8
a0 24 00 00 callq 22740
<printf>
20280: 8b
9c 24 90 00 00 00 mov 0x90(%rsp),%ebx
20287: bf
1d 02 02 10 mov
$0x1002021d,%edi
2028c: 31
c0 xor %eax,%eax
2028e: 89
de mov %ebx,%esi
20290: 66
66 2e 0f 1f 84 00 data32 nopw
%cs:0x0(%rax,%rax,1)
20297: 00
00 00 00
2029b: e8
a0 24 00 00 callq 22740
<printf>
Many thanks for the great reply.After I removed the prefix, I wrote a simple test to compile and run by the customized toolchain. The program basically sends the address of a String in host thread (trusted, which creates a NaClApp) to the sandbox thread. That number can be printed out correctly at the sandbox side, while I still cannot read the String at sandbox side.Say the String is stored at 00007F2ED1CFF010, after I cast it into a char pointer the value then becomes D1CFF010 (forced to be 32 bit with the original toolchain). After I removed the prefix, I got 00000000D1CFF010 which is 64 bit but the most significant 32 bits disappeared.So I still cannot read outside the sandbox.A piece of dumped assembly:20280: 48 8b 9c 24 90 00 00 mov 0x90(%rsp),%rbx
20287: 00
20288: bf 1d 02 02 10 mov $0x1002021d,%edi
2028d: 31 c0 xor %eax,%eax
2028f: 48 63 f3 movslq %ebx,%rsi
20292: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
20299: 00 00
2029b: e8 a0 24 00 00 callq 22740 <printf>
---20280: 8b 9c 24 90 00 00 00 mov 0x90(%rsp),%ebx
20287: bf 1d 02 02 10 mov $0x1002021d,%edi
2028c: 31 c0 xor %eax,%eax
2028e: 89 de mov %ebx,%esi
20290: 66 66 2e 0f 1f 84 00 data32 nopw %cs:0x0(%rax,%rax,1)
20297: 00 00 00 00
2029b: e8 a0 24 00 00 callq 22740 <printf>
where the top part is modified while the bottom part is original. I guess the problem is at the red line because it seems that only the number in ebx (not rbx) is passed through. Also there is problem at the "mov" instruction because the modified version specifies the "mov" to copy 32 bit to 64 bit (movslq). Is there anything out of "read sandboxing" that prevent read out of sandbox?
But we are talking about security. From security POV words "correctly written program" are no something convincing. What'll happen if someone will do something crazy? Will take random number, convert it into pointer to function and call it? Then (depending on whether you are lucky or unlucky) you'll be able to reach out of the sandbox.
To prevent these bugs (intentional or inintentional) from being exploitable NaCl adds "write sandboxing" and/or "read sandboxing". Both are DOING NOTHING in correctly written program.
Many thanks for the reply.
Yes I am trying to remove the read sandbox. It will be very grateful for me if you could offer some help on modifying the source code. Currently I am doing with the GCC based NaCl toolchain but I think PNaCl is also good for me to understand in depth.
But we are talking about security. From security POV words "correctly written program" are no something convincing. What'll happen if someone will do something crazy? Will take random number, convert it into pointer to function and call it? Then (depending on whether you are lucky or unlucky) you'll be able to reach out of the sandbox.Sorry, I might have not clearly explained what I am trying to do. Basically it is not me who want to do the "crazy" things. The thing I am concerning is that if someone doing something crazy inside the NaCl sandbox, is that possible that he/she can read outside the sandbox (my credit card No.?)? So I had the previous naive test; if I am the crazy man and I get the address of the sensitive data, can I read it inside the sandbox?
To prevent these bugs (intentional or inintentional) from being exploitable NaCl adds "write sandboxing" and/or "read sandboxing". Both are DOING NOTHING in correctly written program.If I cannot read outside the sandbox even without the read sandboxing, I would like to have a version with it removed.
Previously you mentioned that the read sandboxing is mainly focusing on windows (have I misunderstood it?),
As I have now turned off the masking by removing %nacl prefix, I now wonder can I able to further disable the "base+offset" addressing model (as I presume they are the two which add the overhead). I am curious about the performance gain without the read sandboxing on Linux. According to your previous explanation, is it the case that this operation will also break the nacl LP32 model?
Could I ask further where could be possible to make change to use like rax instead to get the full address?
Hi Derek:I am also interested in this topic and I have try your suggestion.
Basically it works for removing registers masking when instruction might be "Load" (like move from memory to regs). However, I still have some problem to actually access physical memory address since now the instruction still using 32 bit registers as dst. As below:Then the program can not run somehow because access not correct place.
Could I ask further where could be possible to make change to use like rax instead to get the full address?
On Friday, 24 July 2015 17:51:01 UTC+1, Derek Schuff wrote:In PNaCl's LLVM sources in lib/Target/X86/X86NaClRewritePass.cpp on line 522 in X86NaClRewritePass::ApplyMemorySFI there's a check:if (!IsLoad(MI) && !IsStore(MI))
which decides whether an instruction should have its memory operands sandboxed. It should be sufficient to remove the IsLoad check, although I haven't tried it.For getting the sources and building the PNaCl toolchain, refer to https://www.chromium.org/nativeclient/pnacl/developing-pnacl (in particular the "Toolchain Development" section)In answer to your other question. If you remove the read sandboxing inserted by the compiler, (or more properly, if you skip validation or change the validator so that it accepts such programs), then the untrusted code will be able to read outside the sandbox. This means it can read anything in the NaCl process, including the trusted code's data and whatever the OS happens to inject into the process. Maybe that's acceptable to you, or maybe not, depending on what you're trying to do.On Fri, Jul 24, 2015 at 4:41 AM Tiancheng Yi <tianche...@gmail.com> wrote:Many thanks for the reply.Yes I am trying to remove the read sandbox. It will be very grateful for me if you could offer some help on modifying the source code. Currently I am doing with the GCC based NaCl toolchain but I think PNaCl is also good for me to understand in depth.in the LLVM source
--
Hi Bill,You're right, that change won't quite do it.Since the pointers are 32-bit we would still need to generate loads with r15 as a base register, like so:mov 4(%r15, %rax), %esi(This is what the RewritePass does).The only difference would be that you wouldn't need the mov %eax,%eax before it.To change that, look for HandleMemoryRefTruncation and/or its callers in lib/Target/X86/MCTargetDesc/X86MCNaCl.cpp. that would be a small and simple change.In principle, without the sandboxing restriction for loads, you could, e.g. calculate a full 64-bit pointer and do arbitrary things like:leaq (%r15, %rax), %raxmov (%rax), %esimov 4(%rax), %ediIn practice it would be pretty nontrivial to get the compiler to do things like that (especially with loads and stores being asymmetric).Also in the example you posted, it looks to me like all of the loads are sandboxed in the usual way.
On Thu, Jul 30, 2015 at 8:34 AM Bill Huang <s9424...@gmail.com> wrote:Hi Derek:I am also interested in this topic and I have try your suggestion. Basically it works for removing registers masking when instruction might be "Load" (like move from memory to regs). However, I still have some problem to actually access physical memory address since now the instruction still using 32 bit registers as dst. As below:Then the program can not run somehow because access not correct place.Could I ask further where could be possible to make change to use like rax instead to get the full address?
On Friday, 24 July 2015 17:51:01 UTC+1, Derek Schuff wrote:In PNaCl's LLVM sources in lib/Target/X86/X86NaClRewritePass.cpp on line 522 in X86NaClRewritePass::ApplyMemorySFI there's a check:if (!IsLoad(MI) && !IsStore(MI))
which decides whether an instruction should have its memory operands sandboxed. It should be sufficient to remove the IsLoad check, although I haven't tried it.For getting the sources and building the PNaCl toolchain, refer to https://www.chromium.org/nativeclient/pnacl/developing-pnacl (in particular the "Toolchain Development" section)In answer to your other question. If you remove the read sandboxing inserted by the compiler, (or more properly, if you skip validation or change the validator so that it accepts such programs), then the untrusted code will be able to read outside the sandbox. This means it can read anything in the NaCl process, including the trusted code's data and whatever the OS happens to inject into the process. Maybe that's acceptable to you, or maybe not, depending on what you're trying to do.On Fri, Jul 24, 2015 at 4:41 AM Tiancheng Yi <tianche...@gmail.com> wrote:Many thanks for the reply.Yes I am trying to remove the read sandbox. It will be very grateful for me if you could offer some help on modifying the source code. Currently I am doing with the GCC based NaCl toolchain but I think PNaCl is also good for me to understand in depth.in the LLVM source
--
Also in the example you posted, it looks to me like all of the loads are sandboxed in the usual way.They are sandboxed on the left and not sandboxed on the right. %r15 is also removed from the address thus the whole thing blew apart as expected.
In one word what I want is the difference of performance.
Originally I thought NaCl without read sandboxing is not that unacceptable as it was published as paper.
With masking and "base+offset" removed perhaps there would be better performance (although it would not be that safe as before).
To unsubscribe from this group and stop receiving emails from it, send an email to native-client-discuss+unsub...@googlegroups.com.
On Fri, Jul 31, 2015 at 7:19 PM, Tiancheng Yi <tianche...@gmail.com> wrote:In one word what I want is the difference of performance.If your goal is performance then why are you trying to access memory outside of sandbox? I'm confused.
On Friday, 31 July 2015 18:18:54 UTC+1, khim wrote:On Fri, Jul 31, 2015 at 7:19 PM, Tiancheng Yi <tianche...@gmail.com> wrote:In one word what I want is the difference of performance.If your goal is performance then why are you trying to access memory outside of sandbox? I'm confused.I am sorry for making this point confused. I do not want, but I would like to verify that I can able to do that to make sure I really get the version without read sandbox to play with.
To unsubscribe from this group and stop receiving emails from it, send an email to native-client-di...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to native-client-discuss+unsub...@googlegroups.com.