Live data from Hacker News

Clang vs. Clang

blog.cr.yp.to

41–50 of 405 posts

Re: Clang vs. Clang

#41
post #3

Earlier quoted context omitted.

Optimizing compilers that don't allow disabling all optimizations makes it impossible to write secure code with them. Must do it with assembly.

If your "secure" code is not secure because of a compiler optimization it is fundamentally incorrect and broken.

There is a fundamental difference of priorities between the two worlds. For most general application code any optimization is fine as long as the output is correct. In security critical code information leakage from execution time and resource usage on the chip matters but that essentially means you need to get away from data-dependent memory access patterns and flow control.

Re: Clang vs. Clang

#42
post #24
post #3

Earlier quoted context omitted.

Optimizing compilers that don't allow disabling all optimizations makes it impossible to write secure code with them. Must do it with assembly.

Disabling all optimizations isn't even enough- fundamentally what you need is a much narrower specification for how the source language maps to its output. Even -O0 doesn't give you that, and in fact will often be counterproductive (e.g. you'll get branches in places that the optimizer would have removed them). The problem with this is that no general purpose compiler wants to tie its own hands behind its back in thi…

> You almost may as well just design a new language, at that point.

Forget “almost”.

Go compile this C code:

    void foo(int *ptr)
    {
        free(ptr);
        *ptr = 42;
    }
This is UB. And it has nothing whatsoever to do with optimizations — any sensible translation to machine code is a use-after-free, and an attacker can probably find a way to exploit that machine code to run arbitrary code and format your disk.

If you don’t like this, use a language without UB.

But djb wants something different, I think: a way to tell the compiler not to introduce timing dependencies on certain values. This is a nice idea, but it needs hardware support! Your CPU may well implement ALU instructions with data-dependent timing. Intel, for example, reserves the right to do this unless you set an MSR to tell it not to. And you cannot set that MSR from user code, so what exactly is a compiler supposed to do?

https://www.intel.com/content/www/us/en/developer/articles/t...

Re: Clang vs. Clang

#43
What I'd really like is a way to express code in a medium/high level language, and provide hand-optimized assembly code alongside it (for as many target architectures as you need). For a first-pass, you could machine-generate that assembly, and then manually verify that it's constant time (for example) and perform additional optimizations over the top of that, by hand.

The "compiler"'s job would then be to assert that the behaviour of the source matches the behaviour of the provided assembly. (This is probably a hard/impossible problem to solve in the general case, but I think it'd be solvable in enough cases to be useful)

To me this would offer the best of both worlds - readable, auditable source code, alongside high-performance assembly that you know won't randomly break in a future compiler update.

Re: Clang vs. Clang

#44
post #15

> The bugs admitted in the compiler changelogs are just the tip of the iceberg. Whenever possible, compiler writers refuse to take responsibility for the bugs they introduced, even though the compiled code worked fine before the "optimizations". This makes it difficult to read the rest of the article. Really? All compiler authors, as a blanket statement, act in bad faith? Whenever possible? > As a cryptographic examp…

> This makes it difficult to read the rest of the article. Really? All compiler authors, as a blanket statement, act in bad faith? Whenever possible? When I saw the link was to DJB’s site, I figured the post would contain a vitriolic and hyperbolic rant. It’s pretty on-brand for him (although, to be fair, he’s usually right.)

I don't think DJB is right here, but I do think he is one of the few "ugh compilers taking advantage of UB" people who is actually serious about it. DJB wants absolute certainty in predicting the compiled code so that he can make significantly stronger guarantees about his programs than almost anybody else needs.

The bad news for him is that the bulk of clang users aren't writing core cryptographic primitives and really DJB just needs a different language and compiler stack for his specific goals.

Re: Clang vs. Clang

#45
It’s worth noting that, on Intel CPUs, neither clang nor anything else can possibly generate correct code, because correct code does not exist in user mode.

https://www.intel.com/content/www/us/en/developer/articles/t...

Look at DOITM in that document — it is simply impossible for a userspace crypto library to set the required bit.

Re: Clang vs. Clang

#46
post #3

Earlier quoted context omitted.

Optimizing compilers that don't allow disabling all optimizations makes it impossible to write secure code with them. Must do it with assembly.

If your "secure" code is not secure because of a compiler optimization it is fundamentally incorrect and broken.

The problem is that preventing timing attacks often means you have to implement something in constant time. And most language specifications and implementations don't give you any guarantees that any operations hapen in constant time and can't be optimized.

So the only possible way to ensure things like string comparison don't have data-dependent timing is often to implement it in assembly, which is not great.

What we really need is intrinsics that are guaranteed to have the desired timing properties , and/or a way to disable optimization, or at least certain kinds of optimization for an area of code.

Re: Clang vs. Clang

#47

Compile your code with `-O0` and shut up already.

Unfortunately GCC’s codegen for GCC’s x86 intrinsics headers is really remarkably awful at -O0, particularly around constant loads and broadcasts, because those usually use code that’s as naïve as possible and rely on compiler optimizations to actually turn it into a broadcast, immediate, or whatever. (I haven’t checked Clang.)

"Unfortunately GCC’s codegen for GCC’s x86 intrinsics headers is really remarkably awful at -O0" - but that kind of seems to be what is asked for..

Re: Clang vs. Clang

#48

> [..] whenever possible, compiler writers refuse to take responsibility for the bugs they introduced I have seldomly seen someone discredit their expertise that fast in a blog post. (Especially if you follow the link and realized it's just basic fundamental C stuff of UB not meaning it produces an "arbitrary" value.)

I think the author knows very well what UB is and means. But he’s thinking critically about the whole system.

UB is meant to add value. It’s possible to write a language without it, so why do we have any UB at all? We do because of portability and because it gives flexibility to compilers writers.

The post is all about whether this flexibility is worth it when compared with the difficulty of writing programs without UB.

The author makes the case that (1) there seem to be more money lost on bugs than money saved on faster bytecode and (2) there’s an unwillingness to do something about it because compiler writers have a lot of weight when it comes to what goes into language standards.

Re: Clang vs. Clang

#49

Compile your code with `-O0` and shut up already.

Unfortunately GCC’s codegen for GCC’s x86 intrinsics headers is really remarkably awful at -O0, particularly around constant loads and broadcasts, because those usually use code that’s as naïve as possible and rely on compiler optimizations to actually turn it into a broadcast, immediate, or whatever. (I haven’t checked Clang.)

Clang tends to put everything on the stack at -O0 and actually try to do register allocation only as an optimization.

Re: Clang vs. Clang

#50
> It would be interesting to study what percentage of security failures can be partly or entirely attributed to compiler "optimizations".

I bet it's roughly none.

Post reply on HN