[gentoo-user] Re: Spectre-NG

2018-05-09 Thread Martin Vaeth
Rich Freeman  wrote:
> On Wed, May 9, 2018 at 2:18 PM Martin Vaeth  wrote:
>
>> Which would be the horribly slow case I mentioned above.
>
> I'm saying that high-level languages can be made safe.
>
> You're saying that making high-level languages safe comes at a performance
> cost.

A performance cost which is as high as in C, because you simply
have to protect *every* access.
And no, for the same reason as in C, it is not sufficient to do
this only for the array access case; you need to avoid speculative
execution for every conditional, every loop etc.
As a simple example, assume that you have read a password file
into a string of your language and now access a single password.
No matter, how you mark the end of the password (fixed-length, \0, \n,
...) speculative execution might always access the next password(s)
unless you prevent it globally. Whether it is exploitable depends
of course on other things. There is no difference to C.

> lot of C programmers do the same with manual bounds
> checks or equivalent functions like strncpy.

As mentioned above: It plays absolutely no role whether you
know the length a-priori, are looking for a symbol etc.
If you are copying, and the necessary conditional for the end
of the loop is not protected against speculative exection, your
code might be vulnerable to some spectre-type attack.
Actually, in case of short constant length, C is safer here than
most other languages, because it might unroll the loop and thus
avoid the conditional.

>> If slowness is not the issue, one could fix the C compiler in the same way
>> by avoiding speculative exection for every conditional jump.
>
> Sure, but that is way more overhead than necessary.

Also for languages with bound-checks an memory management you need
exactly the same overhead as well if you want to be safe:
Avoiding speculative execution in everything which is compiled into
a conditional.
Of course, in both cases a very careful flow analysis (or instead
requiring hints from the coder in some way) might prevent "safe"
cases. Like in C. There is simply no difference.

> We only need to sterilize these for data passed from an untrusted source

No, unless you know that after the end there cannot be stored
data you need to protect. If a language has means to mark these
data, a compiler might take care of this. But I would count these
cases to "very careful flow analysis or requiring hints from the coder":
One would need language features which are particularly designed
for spectre and which are not useful for much else.
I do not claim that one could not develop such a language.
Maybe there are some languages for which this is not too hard.
However, I think you were speaking about currently existing/used
langauges.

> A high-level language has access to more context and can probably
> more reliably determine which ones need protection.

If you mean by "high-level" a language which is so restrictive
for every conditional that a complete flow-analysis of the
code is trivial, you are right. I do not know such a language,
and I doubt that it could be a Turing-complete one.

> I think that in general language features that more clearly
> separate trusted vs untrusted data would probably help here.

For spectre, the necessary difference is not trusted vs. untrusted,
but worth-to-protect vs. irrelevant-for-every-attacker.
And even then it depends on details of the processor how
far after the end of the string accessed by an unprotected loop
data still is "protected" against spectre.




[gentoo-user] Re: Spectre-NG

2018-05-09 Thread Ian Zimmerman
On 2018-05-09 20:04, Wols Lists wrote:

> > As mentioned, I wonder why gcc/clang do not yet support this
> > horribly slow but spectre-safe option. It can't be that hard to
> > implement in the actual code-producing back-end.
> 
> Given the response by the gcc team to security people complaining that
> gcc was optimising out security-sensitive code (namely, a two-fingered
> salute near enough), I doubt the gcc team would have any interest in
> optimisations that SLOWED DOWN the resultant code.
> 
> I suspect that might be one of the forces driving the kernel towards
> CLANG - a development team that is not obsessed with performance at
> the expense of breaking any code that uses undefined features.

I'm afraid I side with the gcc people in this interminable flamewar.

Code may be "security-sensitive" but buggy.  Is the compiler writer
really responsible for guessing what the programmer meant to accomplish
with buggy code?  It would of course be preferable if the compiler could
just abort with an error when it detects UB, but that turns out to be
very hard to impossible in the case of C.  That's just a built in
problem with the language.

Further, I don't think the llvm/clang position on these cases is all
that different, although there may be a difference in emotional
attitude.

> Unfortunately, when dealing with hardware, one is forced to rely on
> undefined features. A strong point of C, until the compiler decides to
> go "rogue" on you ...

I don't understand what you mean here.  In the disputed cases there was
always a well-defined way (slightly more verbose but not prohibitively
so) to code the desired behavior.

-- 
Please don't Cc: me privately on mailing lists and Usenet,
if you also post the followup to the list or newsgroup.
To reply privately _only_ on Usenet and on broken lists
which rewrite From, fetch the TXT record for no-use.mooo.com.



Re: [gentoo-user] Re: Spectre-NG

2018-05-09 Thread Rich Freeman
On Wed, May 9, 2018 at 2:18 PM Martin Vaeth  wrote:

> Rich Freeman  wrote:
> > On Tue, May 8, 2018 at 4:19 AM Martin Vaeth  wrote:
> >
> >> Rich Freeman  wrote:
> >> >
> >> > Higher-level languages will probably become nearly immune to Spectre
> > just
> >> > as most are nearly immune to buffer overflows.
> >
> >> Quite the opposite: Higher-level languages *always* do some checks
> >> for array-length etc, and it is the _checks_ which are vulnerable.
> >> You can only make them non-vulnerable by making them horribly slow
> >> (by omitting speculative execution completely for the corresponding
> >> conditionals).
> >
> > Sure, but my point is that you CAN make them non-vulnerable by changing
the
> > compiler.

> Which would be the horribly slow case I mentioned above.

I'm saying that high-level languages can be made safe.

You're saying that making high-level languages safe comes at a performance
cost.

These are not in contradiction.  In fact the whole reason low-level
languages still exist to this day (besides legacy code) is that most of the
benefits of high-level languages come at a performance cost. Safety is just
one of them.

This is just as true for buffer overflows and memory management.  If you
take a lot of care, you can avoid the need for bounds checks on every array
access. If you get it wrong, it can go horribly wrong.  High-level
languages tend to compensate by doing bounds checks even when they might
not be needed.  A lot of C programmers do the same with manual bounds
checks or equivalent functions like strncpy.  Again, I'm using buffer
overflows as a more familiar analogy for others - I fully understand that
bounds checks actually make Spectre worse.

> If slowness is not the issue, one could fix the C compiler in the same way
> by avoiding speculative exection for every conditional jump.

Sure, but that is way more overhead than necessary.  We only need to
sterilize these for data passed from an untrusted source (I think).  If a
function declares an internal variable as a loop counter you don't need to
disable speculative execution every time you increment and check the
counter, and a loop is obviously exactly where you want to make this
distinction.

A low level language needs to use heuristics to try to figure out if a
conditional jump is safe to speculatively execute (probably at compile
time).  A high-level language has access to more context and can probably
more reliably determine which ones need protection.  On the other hand it
will probably do a lot more bounds-checking in general.  I'm not sure which
would end up costing more to make reliably safe.

I think that in general language features that more clearly separate
trusted vs untrusted data would probably help here.

-- 
Rich



Re: [gentoo-user] Re: Spectre-NG

2018-05-09 Thread Wols Lists
On 09/05/18 19:18, Martin Vaeth wrote:
> As mentioned, I wonder why gcc/clang do not yet support this
> horribly slow but spectre-safe option. It can't be that hard to
> implement in the actual code-producing back-end. 

Given the response by the gcc team to security people complaining that
gcc was optimising out security-sensitive code (namely, a two-fingered
salute near enough), I doubt the gcc team would have any interest in
optimisations that SLOWED DOWN the resultant code.

I suspect that might be one of the forces driving the kernel towards
CLANG - a development team that is not obsessed with performance at the
expense of breaking any code that uses undefined features.
Unfortunately, when dealing with hardware, one is forced to rely on
undefined features. A strong point of C, until the compiler decides to
go "rogue" on you ...

Cheers,
Wol



[gentoo-user] Re: Spectre-NG

2018-05-09 Thread Martin Vaeth
Rich Freeman  wrote:
> On Tue, May 8, 2018 at 4:19 AM Martin Vaeth  wrote:
>
>> Rich Freeman  wrote:
>> >
>> > Higher-level languages will probably become nearly immune to Spectre
> just
>> > as most are nearly immune to buffer overflows.
>
>> Quite the opposite: Higher-level languages *always* do some checks
>> for array-length etc, and it is the _checks_ which are vulnerable.
>> You can only make them non-vulnerable by making them horribly slow
>> (by omitting speculative execution completely for the corresponding
>> conditionals).
>
> Sure, but my point is that you CAN make them non-vulnerable by changing the
> compiler.

Which would be the horribly slow case I mentioned above.

> On the other hand, if somebody manually does a range check in C the only
> way to fix it is to either fix the source code

If slowness is not the issue, one could fix the C compiler in the same way
by avoiding speculative exection for every conditional jump.

As mentioned, I wonder why gcc/clang do not yet support this
horribly slow but spectre-safe option. It can't be that hard to
implement in the actual code-producing back-end. Only possible
optimization of that code (catching unnecessary cases or
preferring alternative code-paths if there are two many bad
cases) might be tricky, but perhaps this could be postponed
in a first implementation: safety first.