Rich Freeman <ri...@gentoo.org> wrote:
> On Wed, May 9, 2018 at 2:18 PM Martin Vaeth <mar...@mvath.de> 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.


Reply via email to