Live data from Hacker News

Clang vs. Clang

blog.cr.yp.to

131–140 of 405 posts

Re: Clang vs. Clang

#131
post #96
post #90

Earlier quoted context omitted.

I think you're replying to a strawman. Here's the full quote: > The excuse for not taking responsibility is that there are "language standards" saying that these bugs should be blamed on millions of programmers writing code that bumps into "undefined behavior", rather than being blamed on the much smaller group of compiler writers subsequently changing how this code behaves. These "language standards" are written by…

Perhaps the solution is also to reign in the language standard to support stricter use cases. For example, what if there was a constant-time { ... }; block in the same way you have extern "C" { ... }; . Not only would it allow you to have optimizations outside of the block, it would also force the compiler to ensure that a given block of code is always constant-time (as a security check done by the compiler).

> Perhaps the solution is also to reign in the language standard to support stricter use cases.

Here's a nine-year-old comment from the author asking for exactly that:

https://groups.google.com/g/boring-crypto/c/48qa1kWignU/m/o8...

Re: Clang vs. Clang

#132
post #54

> compiler writers refuse to take responsibility for the bugs they introduced, even though the compiled code worked fine before the "optimizations". The excuse for not taking responsibility is that there are "language standards" saying that these bugs should be blamed on millions of programmers writing code that bumps into "undefined behavior" But that's not an excuse for having a bug; it's the exact evidence that it…

The problem is that c and c++ have a ridiculous amount of undefined behavior, and it is extremely difficult to avoid all of it. One of the advantages of rust is it confines any potential UB to unsafe blocks. But even in rust, which has defined behavior in a lot of places that are UB in c, if you venture into unsafe code, it is remarkable easy to accidentally run into subtle UB issues.

I think the biggest problem is people conflating "undefined" with "unknowable". They act like because C doesn't define the behavior you can't expect certain compilers to behave a certain way. GCC handles signed overflows consistently, even though the concept is undefined at a language level; as goes many other UBs. And the big compilers are all pretty consistent with each other.

Is it annoying if you want to make sure your code compiles the same in different compiler sets? Sure, but that's part of the the issue with the standards body and the compiler developers existing independent of each other. Especially considering plenty of times C/C++ have tried to enforce certain niche behaviors and GCC/ICC/Clang/etc have decided to go their own ways.

Re: Clang vs. Clang

#133
post #17
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 you have ub then you have a bug and there is some system that will show it. It isn't hard to write code without ub.

Do you know what UBSAN is? Have you used it?

Re: Clang vs. Clang

#134

> compiler writers refuse to take responsibility for the bugs they introduced, even though the compiled code worked fine before the "optimizations". The excuse for not taking responsibility is that there are "language standards" saying that these bugs should be blamed on millions of programmers writing code that bumps into "undefined behavior" But that's not an excuse for having a bug; it's the exact evidence that it…

There are only two models of UB that are useful to compiler users:

1) This is a bad idea and refuse to compile.

2) Do something sensible and stable.

Silently fail and generate impossible to predict code is a third model that is only of use to compiler writers. Hiding behind the spec benefits no actual user.

Re: Clang vs. Clang

#135
post #33

Earlier quoted context omitted.

People write buffer overflows because and memory leaks they are not coreful. The rest of ub are things I have never seen despite running sanitizers and a large codebase.

Perhaps you’re not looking all that hard.

Sanitizers are very good at finding ub.

Re: Clang vs. Clang

#136
post #133
post #17

Earlier quoted context omitted.

If you have ub then you have a bug and there is some system that will show it. It isn't hard to write code without ub.

Do you know what UBSAN is? Have you used it?

yes, my ci system runs it with a comprehensive test suite.

Re: Clang vs. Clang

#137
post #134

> compiler writers refuse to take responsibility for the bugs they introduced, even though the compiled code worked fine before the "optimizations". The excuse for not taking responsibility is that there are "language standards" saying that these bugs should be blamed on millions of programmers writing code that bumps into "undefined behavior" But that's not an excuse for having a bug; it's the exact evidence that it…

There are only two models of UB that are useful to compiler users: 1) This is a bad idea and refuse to compile. 2) Do something sensible and stable. Silently fail and generate impossible to predict code is a third model that is only of use to compiler writers. Hiding behind the spec benefits no actual user.

I think this is a point of view that seems sensible, but probably hasn't really thought through how this works. For example

  some_array[i]
What should the compiler emit here? Should it emit a bounds check? In the event the bounds check fails, what should it do? It is only through the practice of undefined behavior that the compiler can consistently generate code that avoids the bounds check. (We don't need it, because if `i` is out-of-bounds then it's undefined behavior and illegal).

If you think this is bad, then you're arguing against memory unsafe languages in general. A sane position is the one the Rust takes, which is by default, yes indeed you should always generate the bounds check (unless you can prove it always succeeds). But there will likely always be hot inner loops where we need to discharge the bounds checks statically. Ideally that would be done with some kind of formal reasoning support, but the industry is far that atm.

For a more in depth read: https://blog.regehr.org/archives/213

Re: Clang vs. Clang

#138
post #124

Earlier quoted context omitted.

What's the alternative?

An instruction prefix that makes instructions constant time. A code segment bit (ugly but would work). Different instructions. Making constant time the default. A control register that’s a user register.

since we already have some reasons to sign in an enclave, why not just design a cryptographic processor which is highly unoptimized and highly predictable. since the majority of codes benefit immensely from the optimizations, it doesn't seem reasonable to cripple them.

Re: Clang vs. Clang

#139
post #71

Earlier quoted context omitted.

That's an interesting note. I wonder why they claim this. As far as I know, `[[gnu::optimize("-fno-tree-loop-distribute-patterns")]]` (or the equivalent #pragma) is required for implementing a memcpy function in C unless you do something funky with the build system.

Maybe that's applied to the TU that defines it? I don't see it in the glibc sources.

It's indeed used:

Definition of macro: https://sourceware.org/git/?p=glibc.git;a=blob;f=include/lib...

Use: https://sourceware.org/git/?p=glibc.git;a=blob;f=string/memm...

For a bunch of other places -fno-builtin-* seems to be used.

Re: Clang vs. Clang

#140

Earlier quoted context omitted.

No, he’s wrong. What you’re talking about is completely different than what you are: your code doesn’t work because Apple changes the behavior of their frameworks, which has nothing to do with what compiler you’re using. There’s a different contract there than what a C compiler gives you.

It’s not quite that simple in Swift-land. There is a significant overlap between what’s compiler and what’s runtime. I’m supposedly linking against the same libraries, but changing the host platform changes the output binaries. Same code, same linked libraries, different host platform, different codegen. Mine isn’t security critical, but the result is similarly unexpected.

It’s really not the same thing. Your complaint is about Apple’s complex framework API management, not about the compiler optimization/undefined behavior.

Swift frameworks sometimes blur the line the way I think you mean by being able to be back-deployed to earlier OS releases through embedding in your binary. Apple’s documentation is poor (and has been since the NeXT takeover in 1997), but, again, that’s not a compiler issue as such.

Post reply on HN