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.