1 |
Rich Freeman <rich0@g.o> wrote: |
2 |
> On Wed, May 9, 2018 at 2:18 PM Martin Vaeth <martin@×××××.de> wrote: |
3 |
> |
4 |
>> Which would be the horribly slow case I mentioned above. |
5 |
> |
6 |
> I'm saying that high-level languages can be made safe. |
7 |
> |
8 |
> You're saying that making high-level languages safe comes at a performance |
9 |
> cost. |
10 |
|
11 |
A performance cost which is as high as in C, because you simply |
12 |
have to protect *every* access. |
13 |
And no, for the same reason as in C, it is not sufficient to do |
14 |
this only for the array access case; you need to avoid speculative |
15 |
execution for every conditional, every loop etc. |
16 |
As a simple example, assume that you have read a password file |
17 |
into a string of your language and now access a single password. |
18 |
No matter, how you mark the end of the password (fixed-length, \0, \n, |
19 |
...) speculative execution might always access the next password(s) |
20 |
unless you prevent it globally. Whether it is exploitable depends |
21 |
of course on other things. There is no difference to C. |
22 |
|
23 |
> lot of C programmers do the same with manual bounds |
24 |
> checks or equivalent functions like strncpy. |
25 |
|
26 |
As mentioned above: It plays absolutely no role whether you |
27 |
know the length a-priori, are looking for a symbol etc. |
28 |
If you are copying, and the necessary conditional for the end |
29 |
of the loop is not protected against speculative exection, your |
30 |
code might be vulnerable to some spectre-type attack. |
31 |
Actually, in case of short constant length, C is safer here than |
32 |
most other languages, because it might unroll the loop and thus |
33 |
avoid the conditional. |
34 |
|
35 |
>> If slowness is not the issue, one could fix the C compiler in the same way |
36 |
>> by avoiding speculative exection for every conditional jump. |
37 |
> |
38 |
> Sure, but that is way more overhead than necessary. |
39 |
|
40 |
Also for languages with bound-checks an memory management you need |
41 |
exactly the same overhead as well if you want to be safe: |
42 |
Avoiding speculative execution in everything which is compiled into |
43 |
a conditional. |
44 |
Of course, in both cases a very careful flow analysis (or instead |
45 |
requiring hints from the coder in some way) might prevent "safe" |
46 |
cases. Like in C. There is simply no difference. |
47 |
|
48 |
> We only need to sterilize these for data passed from an untrusted source |
49 |
|
50 |
No, unless you know that after the end there cannot be stored |
51 |
data you need to protect. If a language has means to mark these |
52 |
data, a compiler might take care of this. But I would count these |
53 |
cases to "very careful flow analysis or requiring hints from the coder": |
54 |
One would need language features which are particularly designed |
55 |
for spectre and which are not useful for much else. |
56 |
I do not claim that one could not develop such a language. |
57 |
Maybe there are some languages for which this is not too hard. |
58 |
However, I think you were speaking about currently existing/used |
59 |
langauges. |
60 |
|
61 |
> A high-level language has access to more context and can probably |
62 |
> more reliably determine which ones need protection. |
63 |
|
64 |
If you mean by "high-level" a language which is so restrictive |
65 |
for every conditional that a complete flow-analysis of the |
66 |
code is trivial, you are right. I do not know such a language, |
67 |
and I doubt that it could be a Turing-complete one. |
68 |
|
69 |
> I think that in general language features that more clearly |
70 |
> separate trusted vs untrusted data would probably help here. |
71 |
|
72 |
For spectre, the necessary difference is not trusted vs. untrusted, |
73 |
but worth-to-protect vs. irrelevant-for-every-attacker. |
74 |
And even then it depends on details of the processor how |
75 |
far after the end of the string accessed by an unprotected loop |
76 |
data still is "protected" against spectre. |