On 10/07/18 00:13, Jeff Law wrote:
> On 07/09/2018 10:38 AM, Richard Earnshaw wrote:
>>
>> The patches I posted earlier this year for mitigating against
>> CVE-2017-5753 (Spectre variant 1) attracted some useful feedback, from
>> which it became obvious that a rethink was needed.  This mail, and the
>> following patches attempt to address that feedback and present a new
>> approach to mitigating against this form of attack surface.
>>
>> There were two major issues with the original approach:
>>
>> - The speculation bounds were too tightly constrained - essentially
>>   they had to represent and upper and lower bound on a pointer, or a
>>   pointer offset.
>> - The speculation constraints could only cover the immediately preceding
>>   branch, which often did not fit well with the structure of the existing
>>   code.
>>
>> An additional criticism was that the shape of the intrinsic did not
>> fit particularly well with systems that used a single speculation
>> barrier that essentially had to wait until all preceding speculation
>> had to be resolved.
> Right.  I suggest the Intel and IBM reps chime in on the updated semantics.
> 

Yes, logically, this is a boolean tracker value.  In practice we use ~0
for true and 0 for false, so that we can simply use it as a mask
operation later.

I hope this intrinsic will be even more acceptable than the one that
Bill Schmidt acked previously, it's even simpler than the version we had
last time.

>>
>> To address all of the above, these patches adopt a new approach, based
>> in part on a posting by Chandler Carruth to the LLVM developers list
>> (https://lists.llvm.org/pipermail/llvm-dev/2018-March/122085.html),
>> but which we have extended to deal with inter-function speculation.
>> The patches divide the problem into two halves.
> We're essentially turning the control dependency into a value that we
> can then use to munge the pointer or the resultant data.
> 
>>
>> The first half is some target-specific code to track the speculation
>> condition through the generated code to provide an internal variable
>> which can tell us whether or not the CPU's control flow speculation
>> matches the data flow calculations.  The idea is that the internal
>> variable starts with the value TRUE and if the CPU's control flow
>> speculation ever causes a jump to the wrong block of code the variable
>> becomes false until such time as the incorrect control flow
>> speculation gets unwound.
> Right.
> 
> So one of the things that comes immediately to mind is you have to run
> this early enough that you can still get to all the control flow and
> build your predicates.  Otherwise you have do undo stuff like
> conditional move generation.

No, the opposite, in fact.  We want to run this very late, at least on
Arm systems (AArch64 or AArch32).  Conditional move instructions are
fine - they're data-flow operations, not control flow (in fact, that's
exactly what the control flow tracker instructions are).  By running it
late we avoid disrupting any of the earlier optimization passes as well.

> 
> On the flip side, the earlier you do this mitigation, the more you have
> to worry about what the optimizers are going to do to the code later in
> the pipeline.  It's almost guaranteed a naive implementation is going to
> muck this up since we can propagate the state of the condition into the
> arms which will make the predicate state a compile time constant.
> 
> In fact this seems to be running into the area of pointer providence and
> some discussions we had around atomic a few years back.
> 
> I also wonder if this could be combined with taint analysis to produce a
> much lower overhead solution in cases were developers have done analysis
> and know what objects are potentially under attacker control.  So
> instead of analyzing everything, we can have a much narrower focus.

Automatic application of the tracker to vulnerable variables would be
nice, but I haven't attempted to go there yet: at present I still rely
on the user to annotate code with the new intrinsic.

That doesn't mean that we couldn't extend the overall approach later to
include automatic tracking.

> 
> The pointer munging could well run afoul of alias analysis engines that
> don't expect to be seeing those kind of operations.

I think the pass runs late enough that it isn't a problem.

> 
> Anyway, just some initial high level thoughts.  I'm sure there'll be
> more as I read the implementation.
> 

Thanks for starting to look at this so quickly.

R.

> 
> Jeff
> 

Reply via email to