<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, Apr 5, 2018 at 2:07 AM Kristof Beyls <<a href="mailto:Kristof.Beyls@arm.com">Kristof.Beyls@arm.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



<div style="word-wrap:break-word">
<span>Hi Chandler,</span>
<div><br>
<div><span>Thank you very much for sharing this!</span></div>
<div><span><br>
</span><span>The RFC is pretty lengthy but the far majority of it makes sense to me. I’m sure I’m forgetting to react to some aspects below, but I thought I’d summarize some initial thoughts and questions I had after reading the RFC end-to-end.</span></div>
<div><br>
* I believe the same high-level principles you outline can also be used to implement the same protection on the Arm instruction sets (AArch64 and AArch32). The technique you describe is dependent on being able to do an “<span style="color:rgb(34,34,34)">unpredicted
 conditional update of a register's value"</span>. For the Arm architecture, the guarantee for the conditional update to be unpredicted can come from using the new CSDB instruction – see documentation at <a href="https://developer.arm.com/support/security-update/download-the-" target="_blank">https://developer.arm.com/support/security-update/download-the-</a>whitepaper.</div></div></div></blockquote><div><br></div><div>I think even without this the practical guarantee can be met. But let's discuss that off line and in more depth as it doesn't have *too* much to do with the compiler side of this and is really just an ARM architecture question.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>
<div><span><br>
</span><span>* It seems you suggest 2 ways to protect against side-channel attacks leaking speculatively-loaded secret data: either protect by zero-ing out address bits that may represent secret data, or zero-ing out loaded data. In the first case
 (zero-ing out address bits) – wouldn’t you have to apply that to addresses used in stores too, next to addresses used in loads?</span></div></div></div></blockquote><div><br></div><div>Stores don't intrinsically leak data. Specifically, if you have never loaded secret data, nothing you store can leak secret data.</div><div>1) You can't be storing the secret data itself, you never loaded it.</div><div>2) You can't be storing to an address influenced by the secret data, that too would require loading it.</div><div><br></div><div>So once loads are hardened, stores shouldn't matter.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>
<div><span><br>
</span><span>* IIUC, you state that constant-offset stack locations and global variables don’t need protection. For option 1 (zero-ing out the address bit that may represent secret data) – I can understand the rationale for why constant offset stack
 locations and global variables don’t need protection. But I’m wondering what the detailed rationale is for not needing protection on option 2 (zero-ing out the value loaded): what guarantees that no secret info can be located on the stack or in a global variable?
 Or did I misunderstand the proposal?</span></div></div></div></blockquote><div><br></div><div>It isn't that we don't *need* protection. It is that e don't *provide* protection and insist programs keep their secret data elsewhere. This will certainly require changes to software to achieve. But without this, the performance becomes much worse because of reloads of spilled registers and such being impacted. Plus, it would preclude the address based approach.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>
<div><span><br>
</span><span>* For x86 specifically, you explain how the low 2gb and high 2gb of address space should be protected by the OS. I wonder if this +-2gb range could be reduced sharply by letting the compiler not generate 32 bit constant offsets in address
 calculations, but at most a much smaller constant offset? I assume limiting that may have only a very small effect on code quality – and might potentially ease the requirements on the OS?<br></span></div></div></div></blockquote><div><br></div><div>Yes. Specifically, this seems like the only viable path for 32-bit architectures. I freely admit my only focus was on a 64-bit architecture and so I didn't really spend any time on this.</div><div><br></div><div>For a 64-bit architecture, 2gb is as easy to protect as a smaller region, so it seems worth keeping the performance.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><span>
</span><span> </span></div>
<div><span><br>
</span><span>Thanks!</span></div></div></div><div style="word-wrap:break-word"><div><div><span><br>
<br>
</span><span>Kristof<br>
<br>
</span><span><br>
</span>
</div></div></div><div style="word-wrap:break-word"><div><div><div><blockquote type="cite">
<div>On 23 Mar 2018, at 11:56, Chandler Carruth via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:</div>
<br class="m_5485575218133091241Apple-interchange-newline">
</blockquote></div></div></div></div><div style="word-wrap:break-word"><div><div><div><blockquote type="cite"><div><div dir="ltr">Hello all,
<div><br>
</div>
<div>I've been working for the last month or so on a comprehensive mitigation approach to variant #1 of Spectre. There are a bunch of reasons why this is desirable:</div>
<div>- Critical software that is unlikely to be easily hand-mitigated (or where the performance tradeoff isn't worth it) will have a compelling option.</div>
<div>- It gives us a baseline on performance for hand-mitigation.</div>
<div>- Combined with opt-in or opt-out, it may give simpler hand-mitigation.</div>
<div>- It is instructive to see *how* to mitigate code patterns.</div>
<div><br>
</div>
<div>A detailed design document is available for commenting here:</div>
<div><a href="https://docs.google.com/document/d/1wwcfv3UV9ZnZVcGiGuoITT_61e_Ko3TmoCS3uXLcJR0/edit" target="_blank">https://docs.google.com/document/d/1wwcfv3UV9ZnZVcGiGuoITT_61e_Ko3TmoCS3uXLcJR0/edit</a></div>
<div>(I pasted this in markdown format at the bottom of the email as well.)<br>
</div>
<div><br>
</div>
<div>I have also published a very early prototype patch that implements this design:</div>
<div><a href="https://reviews.llvm.org/D44824" target="_blank">https://reviews.llvm.org/D44824</a></div>
<div>This is the patch I've used to collect the performance data on the approach. It should be fairly functional but is a long way from being ready to review in detail, much less land. I'm posting so folks can start seeing the overall approach and
 can play with it if they want. Grab it here:</div>
<div><br>
</div>
<div>Comments are very welcome! I'd like to keep the doc and this thread focused on discussion of the high-level technique for hardening, and the code review thread for discussion of the techniques used to implement this in LLVM.</div>
<div><br>
</div>
<div>Thanks all!</div>
<div>-Chandler</div>
</div></div></blockquote></div></div></div></div><div style="word-wrap:break-word"><div><div><div><blockquote type="cite"><div><div dir="ltr"><div>
<div>….</div>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</div>

</blockquote></div></div>