<div dir="ltr"><div>Hi,</div><div>Yeah, now I understand the problem here. Thanks.</div><div>But I too have another doubt in "Bounds check bypass store"</div><div><br></div><div>In this example in the Speculative load hardening : <br></div><div><pre><span class="gmail-n">unsigned</span> <span class="gmail-n">char</span> <span class="gmail-n">local_buffer</span><span class="gmail-p">[</span><span class="gmail-mi">4</span><span class="gmail-p">];</span>
<span class="gmail-n">unsigned</span> <span class="gmail-n">char</span> <span class="gmail-o">*</span><span class="gmail-n">untrusted_data_from_caller</span> <span class="gmail-o">=</span> <span class="gmail-o">...</span><span class="gmail-p">;</span>
<span class="gmail-n">unsigned</span> <span class="gmail-n">long</span> <span class="gmail-n">untrusted_size_from_caller</span> <span class="gmail-o">=</span> <span class="gmail-o">...</span><span class="gmail-p">;</span>
<span class="gmail-k">if</span> <span class="gmail-p">(</span><span class="gmail-n">untrusted_size_from_caller</span> <span class="gmail-o"><</span> <span class="gmail-n">sizeof</span><span class="gmail-p">(</span><span class="gmail-n">local_buffer</span><span class="gmail-p">))</span> <span class="gmail-p">{</span>
  <span class="gmail-o">//</span> <span class="gmail-n">Speculative</span> <span class="gmail-n">execution</span> <span class="gmail-n">enters</span> <span class="gmail-n">here</span> <span class="gmail-k">with</span> <span class="gmail-n">a</span> <span class="gmail-n">too</span><span class="gmail-o">-</span><span class="gmail-n">large</span> <span class="gmail-n">size</span><span class="gmail-o">.</span>
  <span class="gmail-n">memcpy</span><span class="gmail-p">(</span><span class="gmail-n">local_buffer</span><span class="gmail-p">,</span> <span class="gmail-n">untrusted_data_from_caller</span><span class="gmail-p">,</span>
         <span class="gmail-n">untrusted_size_from_caller</span><span class="gmail-p">);</span>
  <span class="gmail-o">//</span> <span class="gmail-n">The</span> <span class="gmail-n">stack</span> <span class="gmail-n">has</span> <span class="gmail-n">now</span> <span class="gmail-n">been</span> <span class="gmail-n">smashed</span><span class="gmail-p">,</span> <span class="gmail-n">writing</span> <span class="gmail-n">an</span> <span class="gmail-n">attacker</span><span class="gmail-o">-</span><span class="gmail-n">controlled</span>
  <span class="gmail-o">//</span> <span class="gmail-n">address</span> <span class="gmail-n">over</span> <span class="gmail-n">the</span> <span class="gmail-k">return</span> <span class="gmail-n">address</span><span class="gmail-o">.</span>
  <span class="gmail-n">minor_processing</span><span class="gmail-p">(</span><span class="gmail-n">local_buffer</span><span class="gmail-p">);</span>
  <span class="gmail-k">return</span><span class="gmail-p">;</span>
  <span class="gmail-o">//</span> <span class="gmail-n">Control</span> <span class="gmail-n">will</span> <span class="gmail-n">speculate</span> <span class="gmail-n">to</span> <span class="gmail-n">the</span> <span class="gmail-n">attacker</span><span class="gmail-o">-</span><span class="gmail-n">written</span> <span class="gmail-n">address</span><span class="gmail-o">.</span>
<span class="gmail-p">}<br></span></pre><pre><span style="font-family:arial,sans-serif"><span class="gmail-p"><br></span></span></pre><pre><span class="gmail-p"><font face="arial,sans-serif"><span style="font-family:arial,sans-serif">During speculative execution, it stores an arbitrary data in the stack memory (architectural state, I guess). <br>Doesn't that change the architectural state of the processor? I learned that all stores are written to  register files first and then if the speculative <br>execution is correct then it written back into memory, if not those register files are reverted back. But in the above case the return address <br>is loaded from the (stack) memory, for which the contents have to be written to the memory first during the speculative execution. It contradicts <br>my assumptions about the store operation in speculative execution.</span><br><br></font></span></pre><pre><span class="gmail-p"><font face="arial,sans-serif">Am I wrong here? <br></font></span></pre></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 17 Sep 2019 at 21:30, Craig Topper <<a href="mailto:craig.topper@gmail.com" target="_blank">craig.topper@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div dir="auto">The reverting of state doesn’t occur when the condition is available. The processor has to “execute” the branch uop and see that it was mispredicted. This occurs at least one cycle after the condition is available. The conditional move on the predicate state can execute at the same time as the branch. Or it can execute before it if the branch unit is busy. The load can do the same.</div></div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Sep 17, 2019 at 7:57 AM Praveen Velliengiri via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi,<br></div><div>Thanks for your email, I understand that the execution stalls until the predicated state is computed, then we mask pointers with all_zeros_mask if there is a mis-prediction. But I understand that as soon as the condition value is available, the processor can check about it's assumptions and revert back.<br></div><div><br></div><div>That is, <br></div><div>If the branch prediction is correct during speculation, we mask with all_ones, the processor can follow the predicted branch to retire. <br></div><div>But if the processor mispredicted the branch, it will revert back as soon as condition become available if this is the case then we don't execute speculatively the operations : pointer1 &= predicate_state - (if branch) and *pointer2 & predicted_state - (else branch) right? Or out-of-processor's allow such access?</div><div><br></div><div>Plus, why we are masking with all_zeros_mask during mis-prediction. Is there any reason for choosing all_zeros_mask? <br></div><div><br></div><div>Cheers,</div><div>Praveen <br></div><div><br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 17 Sep 2019 at 17:08, Jeremy Lakeman <<a href="mailto:Jeremy.Lakeman@gmail.com" target="_blank">Jeremy.Lakeman@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>There's a difference between control flow speculation and data flow. <br></div><div>By entangling the control flow & data, the cpu should stall the memory load until the condition is known, since the pointer value also isn't known.</div><div><br></div><div>I assume that actual experts (not me) tested this, and / or asked intel if this was sufficient to prevent the speculative memory load, given how speculation is actually implemented.<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 17 Sep 2019 at 02:04, Praveen Velliengiri via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi all,</div><div><br></div><div>I understand how the speculative information flow attack works. I'm trying get my head around the spectre v1 mitigation of LLVM.</div><div>In the design document here : <a href="https://llvm.org/docs/SpeculativeLoadHardening.html#speculative-load-hardening" target="_blank">https://llvm.org/docs/SpeculativeLoadHardening.html#speculative-load-hardening.</a></div><div><br></div><div>Example: <br></div><div><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">void</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">leak</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">(</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-nb">int</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">data</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">);</span>
<span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">void</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">example</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">(</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-nb">int</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o">*</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">pointer1</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">,</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-nb">int</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o">*</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">pointer2</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">)</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">{</span>
  <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-k">if</span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">(</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">condition</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">)</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o"></span>
    <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">leak</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">(</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o">*</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">pointer1</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">);</span>
 <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"></span> <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-k">else</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n"></span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o"></span>
    <span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">leak</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">(</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-o">*</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-n">pointer2</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">);</span><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"></span>
<span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">}<br></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p">After the applying the mitigation the code resembles like:<br><br>void leak(int data);<br>void example(int* pointer1, int* pointer2) {
  uintptr_t predicate_state = all_ones_mask;
  if (condition) {
    predicate_state = !condition ? all_zeros_mask : predicate_state;
    pointer1 &= predicate_state;
    leak(*pointer1);
  } else {
    int value2 = *pointer2 & predicate_state;
    leak(value2);
  }
}<br></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"><span style="font-family:arial,sans-serif">Let's assume that the branch is mispredicted and if body is taken. The value predicate_state mask is depend on the "result of the condition" but which is not yet available </span>hence<font face="arial,sans-serif"> <br></font></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"><font face="arial,sans-serif">speculative execution. My question whether the value of predicate_state is also guessed by the processor? If it is correct, then the value of predicate_state will be <br>predicate_state, if the processor mis-predicts the condition as true. Is my assumption is correct? i.e predicate_state = ! 1 ? all_zeros_mask : predicate_state, where processor predicts <br>condition as true. <br><br>Or Whether the execution stalls at "predicate_state = !condition ? all_zeros_mask : predicate_state until the result of condition became available? If this is true, why we have to <br></font></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"><font face="arial,sans-serif">harden the pointers in the first place, because after the condition is actually computed, the processors will revert back right the execution trace of mis-prediction. <br><br></font></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"><font face="arial,sans-serif">I know that I'm missing something fundamental here, I would highly appreciate your help on this? Please let me know if you more info!<br><br></font></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"><font face="arial,sans-serif">Cheeers,<br></font></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"><font face="arial,sans-serif">Praveen<br></font></span></pre><pre><span class="gmail-m_4157921557040794526gmail-m_-5631710115781457301m_4010757841521279094gmail-m_-5397961809883743755gmail-m_7769756769736594767gmail-p"><font face="arial,sans-serif"><br></font></span></pre></div></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>
</blockquote></div>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div>-- <br><div dir="ltr" class="gmail-m_4157921557040794526gmail-m_-5631710115781457301gmail_signature">~Craig</div>
</blockquote></div>