Re: [RFC PATCH] asm/generic: introduce if_nospec and nospec_barrier

Dan Williams
2018-01-04T23:12:03Z

On Thu, Jan 4, 2018 at 2:44 PM, Pavel Machek <pavel@ucw.cz> wrote:
> Hi!
>
>> >> > What should one be looking for. Do you have a typical example?
>> >> >
>> >>
>> >> See "Exploiting Conditional Branch Misprediction" from the paper [1].
>> >>
>> >> The typical example is an attacker controlled index used to trigger a
>> >> dependent read near a branch. Where an example of "near" from the
>> >> paper is "up to 188 simple instructions inserted in the source code
>> >> between the ‘if’ statement and the line accessing array...".
>> >>
>> >> if (attacker_controlled_index < bound)
>> >> val = array[attacker_controlled_index];
>> >> else
>> >> return error;
>> >>
>> >> ...when the cpu speculates that the 'index < bound' branch is taken it
>> >> reads index and uses that value to read array[index]. The result of an
>> >> 'array' relative read is potentially observable in the cache.
>> >
>> > You still need
>> >
>> > (void) array2[val];
>> >
>> > after that to get something observable, right?
>>
>> As far as I understand the presence of array2[val] discloses more
>> information, but in terms of the cpu taking an action that it is
>> observable in the cache that's already occurred when "val =
>> array[attacker_controlled_index];" is speculated. Lets err on the
>
> Well yes, attacker can observe val =
> array[attacker_controlled_index]; . But that's not something he's
> interested in. So the CPU cheats and attacker has a proof. But he knew
> that before.
>
>>side
>> of caution and shut down all the observable actions that are already
>> explicitly gated by an input validation check. In other words, a low
>> bandwidth information leak is still a leak.
>
> What did it leak? Nothing. Attacker had to know
> array+attacker_controlled_index, and he now knows
> (array+attacker_controlled_index)%CACHELINE_SIZE.
>
> With (void) array2[val];, the attack gets interesting -- I now know
> *(array+attacker_controlled_index) % CACHELINE_SIZE ... allowing me to
> get information from arbitrary place in memory -- which is useful for
> .. reading ssh keys, for example.

Right, but how far away from "val = array[attacker_controlled_index];"
in the instruction stream do you need to look before you're
comfortable there's no 'val' dependent reads in the speculation window
on all possible architectures. Until we have variable annotations and
compiler help my guess is that static analysis has an easier time
pointing us to the first potentially bad speculative access.