google / safeside

Understand and mitigate software-observable side-channels
BSD 3-Clause "New" or "Revised" License
493 stars 53 forks source link

ForceRead call clarification. #24

Closed asteinha closed 4 years ago

asteinha commented 4 years ago

As advised by Devin.

mmdriley commented 4 years ago

For the broader audience: the concern here was that using operator[] signified an eager dereference, whereas we want the semantics to be "calculate an offset to pass to ForceRead".

I'm ambivalent here -- I don't find the new version more readable -- but I'll defer to @ssbr

ssbr commented 4 years ago

The issue I have is that x[i] is a dereference, and semantically not distinguishable from any other in C++, even if you don't use the value and instead take the address immediately. For example, this is undefined behavior:

int* x= nullptr;
int* y = &x[0];

But this is defined behavior:

int* x= nullptr;
int* y = x + 0;

So here, I think it's clearer to avoid the whole issue of executing dereferences in favor of pure address computation. If there is ever any UB from actually loading that address, let it happen in ForceRead, where we can force it to be defined behavior instead (via e.g. inline assembly, etc.)

I do admit this is not a very important point though. :) For example, x + 2 is just as much UB as &x[2] is. However, that is a surprising fact to basically every C++ programmer, and not avoidable. I'd at least prefer we limit the axes on which we need to worry about UB to the minimum possible.

(This reminds me that there's another source of UB I want to eliminate.)