[gentoo-user] Re: Spectre-NG
Rich Freemanwrote: > 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
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
On Wed, May 9, 2018 at 2:18 PM Martin Vaethwrote: > 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
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
Rich Freemanwrote: > 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.