Live data from Hacker News

Undefined behavior in C is a reading error

yodaiken.com

61–70 of 503 posts

Re: Undefined behavior in C is a reading error

#61
post #24

I think the real problem stems from the mismatch between modern processors and the processors C was originally designed for. C programmers want their code to be fast. Vanilla C no longer gives them the tools to do that on a modern processor. Either the language needs to be extended or the compiler needs to get more creative in interpreting the existing language. The latter is the least disruptive and it doesn't stop…

Even on modern processors, an ADD instruction does not corrupt memory. The C standard, in declaring that an integer overflow results in all-bets-are-off UB, is not enabling compilers to provide valuable optimizations.

Re: Undefined behavior in C is a reading error

#62

I'm not convinced. The argument seems to hinge to a very large extent on the sentence: > Permissible undefined behavior ranges from A, to B, to C. The observation that "Permissible" has a specific meaning is important and interesting. But what about "ranges from ... to ..."? The author reads this as "Permissible undefined behavior is either A or B or C.", but that seems like a stretch to me. (Unless ISO defines "rang…

The original intent was for signed overflow to be architecture-specific (not everything was 2s complement back then).

On x86, the correct behavior was previously (and obviously) “perform a 2s complement wraparound”.

To “ignore” the situation used to mean “delegate to a lower level”. It now means “silently generate code that violates the semantics of the target microarchitecture”

As the article argues, I think this has gone too far. For example, people are starting to claim that asm blocks are undefined behavior. They’re clearly implementation specific (so undefined by the spec), but also well defined by each implementation.

In current readings of the spec, compilers are free to ignore them completely. Doing so would break all known operating systems, and many user space programs, so they have not managed to do so yet.

Edit: for signed overflow, other architecture-specific behavior (such as optionally trapping floating point exceptions) would also have been permissible, assuming the architecture supported it.

Re: Undefined behavior in C is a reading error

#63
post #42

> license for the kinds of dramatic and unintuitive transformations we’ve seen from the compilers, and any indication that undefined behavior should be a vehicle for permitting optimizations. Does anyone have an example of a time where Clang or GCC actually did something bad upon witnessing undefined behavior, rather than simply doing nothing, as the standard proposes? I ask because every time I've seen people get ma…

What do you define as "bad"?

Arguably several.

I've seen cases of overflow checks that were implemented assuming signed overflow (which all relevant platforms implement!) getting optimized away. Correct, given "signed overflow is UB" and thus can be assumed to not happen. Problematic given for widespread such checks are, and given that there's no easy portable alternative.

Entire checks getting optimized away because of a presumed strict aliasing violation. IIRC between structure with a compatible layout. Pretty code, no. UB yes. Reasonable, IDK.

Re: Undefined behavior in C is a reading error

#64

I think the problem is cultural in the C community. C programmers have Stockholm Syndrome around UB optimizations. As TFA notes, "There is No Reliable Way to Determine if a Large Codebase Contains Undefined Behavior" https://blog.llvm.org/2011/05/what-every-c-programmer-should... That's because UB is a bug that occurs as your program runs (e.g. dereferencing a null pointer). You'd have to prove that your program is f…

The situation has gotten at least somewhat better since then. Ubsan and friends are not a guarantee, but make it much more realistic to find UB issues.

Re: Undefined behavior in C is a reading error

#65
post #62

I'm not convinced. The argument seems to hinge to a very large extent on the sentence: > Permissible undefined behavior ranges from A, to B, to C. The observation that "Permissible" has a specific meaning is important and interesting. But what about "ranges from ... to ..."? The author reads this as "Permissible undefined behavior is either A or B or C.", but that seems like a stretch to me. (Unless ISO defines "rang…

The original intent was for signed overflow to be architecture-specific (not everything was 2s complement back then). On x86, the correct behavior was previously (and obviously) “perform a 2s complement wraparound”. To “ignore” the situation used to mean “delegate to a lower level”. It now means “silently generate code that violates the semantics of the target microarchitecture” As the article argues, I think this ha…

> The original intent was for signed overflow to be architecture-specific (not everything was 2s complement back then).

The term for that is implementation-defined, not undefined. If it were to be architecture-specific, back in C89, they would have used the term implementation-defined, as they do for things like the size of pointers.

Re: Undefined behavior in C is a reading error

#66
post #62

I'm not convinced. The argument seems to hinge to a very large extent on the sentence: > Permissible undefined behavior ranges from A, to B, to C. The observation that "Permissible" has a specific meaning is important and interesting. But what about "ranges from ... to ..."? The author reads this as "Permissible undefined behavior is either A or B or C.", but that seems like a stretch to me. (Unless ISO defines "rang…

The original intent was for signed overflow to be architecture-specific (not everything was 2s complement back then). On x86, the correct behavior was previously (and obviously) “perform a 2s complement wraparound”. To “ignore” the situation used to mean “delegate to a lower level”. It now means “silently generate code that violates the semantics of the target microarchitecture” As the article argues, I think this ha…

There's "implementation defined" for the concept you describe.

Re: Undefined behavior in C is a reading error

#67
post #49

Earlier quoted context omitted.

I'm not sure why syscalls would be UB; it's just not something defined by the C standard. Edit: To clarify, I meant UB in the sense it is typically used in these discussions, where the standard more-or-less explicitly says "If you do X, the behavior is undefined." Not in the literal sense of "ISO C does not say anything about write(2), hence using write(2) is undefined behavior according to the C standard", which see…

So if it is behavior that is not defined by the C standard, would that not make it undefined behavior?

[deleted]

Re: Undefined behavior in C is a reading error

#68
post #42

> license for the kinds of dramatic and unintuitive transformations we’ve seen from the compilers, and any indication that undefined behavior should be a vehicle for permitting optimizations. Does anyone have an example of a time where Clang or GCC actually did something bad upon witnessing undefined behavior, rather than simply doing nothing, as the standard proposes? I ask because every time I've seen people get ma…

I've seen a real-world example something like this:

   int a[32] = {...};

   int flag = 1 
The "1 undefined behavior (!) when index is greater than 32 (on a platform with 32-bit integers), even if the result is never used!

The compiler inferred that index must always be less than 32, which allowed it to optimize out the array bounds check, which turns the code into a write-anywhere gadget.

Note that if the standard had not declared "n << 32" to be all-bets-are-off UB, but instead had said something like, "it results in some implementation-specific value, or maybe traps" -- as a rational person would presume -- then this would not turn into a security problem.

Re: Undefined behavior in C is a reading error

#69
post #4

The author seems to be missing this essential text: "the implementor may augment the language by providing a definition of the officially undefined behavior." Making a system call is undefined behavior in the C standard, but it's not undefined behavior in clang-on-FreeBSD, because the implementors of clang on FreeBSD have defined what those system calls do. Ditto for "asm" (UD unless/until you're running on a compile…

> all of the tricks which make "malloc" work,

What are those, exactly? AFAIK, you can safely track memory addresses by storing them as intptr_t/uintptr_t.

Re: Undefined behavior in C is a reading error

#70

I think the problem is cultural in the C community. C programmers have Stockholm Syndrome around UB optimizations. As TFA notes, "There is No Reliable Way to Determine if a Large Codebase Contains Undefined Behavior" https://blog.llvm.org/2011/05/what-every-c-programmer-should... That's because UB is a bug that occurs as your program runs (e.g. dereferencing a null pointer). You'd have to prove that your program is f…

Anecdotally, I find about as many bugs in my Java code at work, as I do in my hobby C code, including "dereferencing null pointers" aka NullPointerExceptions.
Post reply on HN