LWN: Comments on "Comparing GCC and Clang security features" https://lwn.net/Articles/798913/ This is a special feed containing comments posted to the individual LWN article titled "Comparing GCC and Clang security features". en-us Sun, 07 Sep 2025 13:08:57 +0000 Sun, 07 Sep 2025 13:08:57 +0000 https://www.rssboard.org/rss-specification lwn@lwn.net Comparing GCC and Clang security features https://lwn.net/Articles/800585/ https://lwn.net/Articles/800585/ anton INTO is not in AMD64. It has been replaced with one of the REX prefixes. However, a JO with a single-byte offset is also pretty small. Wed, 25 Sep 2019 20:38:57 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/800233/ https://lwn.net/Articles/800233/ robert_s <div class="FormattedComment"> If we're really being paranoid, I'd be more interested in zeroing entire stack frames on return. Many functions leave a lot of potentially useful (or sensitive) values lying around that could be read-beyond-bounds into.<br> </div> Sat, 21 Sep 2019 12:52:46 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/800062/ https://lwn.net/Articles/800062/ kmweber <div class="FormattedComment"> As is typically the case, the person who resorted to merely shouting "fallacy" rather than substantively explaining the alleged error in the argument has failed to understand both the argument they're responding to and the fallacy they're inaccurately name-dropping.<br> <p> There's a difference between "we don't know with certainty that this is a safe state, so there is a chance that this is unsafe so let's not take any chances" (which is the argument actually being made) and "we dony know it's safe; therefore it is definitely unsafe" (which would indeed be an argument to ignorance).<br> </div> Fri, 20 Sep 2019 01:46:38 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799919/ https://lwn.net/Articles/799919/ jschrod <div class="FormattedComment"> Proof by example. No, proof by simple example.<br> <p> How valuable.<br> </div> Thu, 19 Sep 2019 11:28:59 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799911/ https://lwn.net/Articles/799911/ dvdeug <div class="FormattedComment"> Pseudo-paranoia cuts both ways. But real paranoia has to follow patterns. It's hard to justify that register clean up makes some future attack easier; all it's doing is providing less information to the other functions. It's easy to imagine cases where the register clean up makes some future attack harder; the example rweikusat2 shows how string functions can leave pointers to strings in registers, and if that's working on sensitive information and something calls it and returns without sanitizing its own registers, it would return that information in registers. The expectation from a programmer that the only thing returned is what is explicitly returned would be violated.<br> </div> Thu, 19 Sep 2019 10:39:21 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799465/ https://lwn.net/Articles/799465/ foom <div class="FormattedComment"> While that can be true in general, it won't be for an integer wrapping type. There is no reason to write a custom move/copy constructor, or destructor, for such a type.<br> <p> Additionally, if you're ok using a compiler extension, Clang has an attribute that can be used to force trivial abi, if you do have a type which can be passed in registers despite having non-trivial constructors/destructors: <a href="https://clang.llvm.org/docs/AttributeReference.html#trivial-abi">https://clang.llvm.org/docs/AttributeReference.html#trivi...</a><br> </div> Tue, 17 Sep 2019 13:10:52 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799369/ https://lwn.net/Articles/799369/ roc <div class="FormattedComment"> C++ isn't ideal for implementing wrappers around integer types. It's too easy for your wrapper type to be "non-trivial for the purposes of calls" (<a href="http://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-trivial">http://itanium-cxx-abi.github.io/cxx-abi/abi.html#non-tri...</a>), in which case function parameters and results of that type must be passed by reference instead of by value, imposing significant performance penalties in some cases.<br> </div> Tue, 17 Sep 2019 02:48:00 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799357/ https://lwn.net/Articles/799357/ nybble41 <div class="FormattedComment"> In the "unsigned char" case there is no overflow (technically) because the unsigned conversion is defined to use modulo arithmetic. For "signed char", however, you would put the assignment inside, i.e.:<br> <p> signed char x, y, z;<br> __builtin_wrapv(x = y + z);<br> </div> Mon, 16 Sep 2019 22:04:23 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799344/ https://lwn.net/Articles/799344/ rgmoore <blockquote>Maybe it would be even better to think of them as attributes of the assignment.</blockquote> <p>This sounds like a million bugs waiting to happen. When I use an integer in a context where an overflow might result in a bug, I want a guarantee that the integer hasn't overflowed. Assigning an overflow type to the integer when you declare it provides that guarantee. Requiring the overflow type to the assignment means you can only guarantee the integer hasn't overflowed by going back and checking every assignment to make sure they're of the correct type. <p>More generally, when would you ever want the same variable to have different overflow behavior in different assignments? Why, for example, would you ever want to have one assignment saturate and another one wrap? I can't think of an example for when that would be sensible, so giving you the power to do it at the expense of removing the utility of the overflow types in guaranteeing that a given value will behave predictably seems like a terrible mistake. Mon, 16 Sep 2019 17:54:46 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799342/ https://lwn.net/Articles/799342/ excors <div class="FormattedComment"> I think that would behave very unintuitively, because of integer promotions. In code like "unsigned char x = __builtin_wrapv((unsigned char)0x80 + (unsigned char)0x80);", the '+' operator converts its arguments to int and returns an int, so there is no overflow inside the __builtin_wrapv. The assignment converts it to unsigned char, which may overflow, but that's outside the wrapv and will still have implementation-defined behaviour.<br> <p> The rules for promotion and conversion mean that arithmetic in C is already pretty confusing, so I'm not sure it's a good idea to make it many times more complex with a whole new set of types or operators or magic evaluation contexts.<br> <p> (Incidentally it looks like you can change the overflow behaviour at function scope with "#pragma GCC optimize("-ftrapv")" etc, which seems slightly less confusing than trying to change it at expression scope. Except it doesn't detect the overflow if e.g. the function gets inlined and evaluated at compile time, so -ftrapv is not actually useful for security.)<br> </div> Mon, 16 Sep 2019 17:10:42 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799334/ https://lwn.net/Articles/799334/ jgh <div class="FormattedComment"> For uninitialized variables, how about hardware support for a poison bit?<br> <p> Registers and stack locs would be written with a poisoned value at function head, and similar to an FP NaN, this should propagate on copies; it should trap on arithmetic or indirection use. It would be silently overwritten by a valid value.<br> <p> For best protection the full memory hierachy would support it (the DRAM layer, eg, could use a know-bad ECC). A cpu-chip-only implementation could get partial protection by not writing farther out than the last-level cache.<br> </div> Mon, 16 Sep 2019 15:04:46 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799335/ https://lwn.net/Articles/799335/ nybble41 <div class="FormattedComment"> Or rather than defining a bunch of new assignment operators, how about __builtin_wrapv(expr) evaluates expr in a context where signed overflow wraps, and __builtin_trapv(expr) does the same but in a context where signed overflow generates an exception? (For lexically scoped operations only, of course—code in other functions shouldn't be affected even if expr includes a function call.) The effect would be the same as if expr were compiled with the -fwrapv or -ftrapv option, respectively.<br> </div> Mon, 16 Sep 2019 14:56:13 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799256/ https://lwn.net/Articles/799256/ neilbrown <div class="FormattedComment"> <font class="QuotedText">&gt; Really compilers should just support the keywords __wrap, __trap, __saturate, __overflow and allow to</font><br> <font class="QuotedText">&gt; declare each integer type separately</font><br> <p> These attributes are attributes of the integer operation, not of the integer itself - a bit like 'volatile' which Linus has ranted about.<br> <p> Maybe it would be even better to think of them as attributes of the assignment.<br> <p> a = b + c<br> <p> traps on overflow.<br> <p> a @= b+c <br> <p> wraps if b+c overflowed (the symbol has a wrapping around it)<br> <p> a #= b + c <br> <p> saturates on overflow (the remnant of the real value gets hashed out)<br> <p> if you try (b + c) * x you always get a trap, because overflow is mostly bad.<br> Of course, you could always do<br> (_tmp @= b+ c) * x<br> if you really want to wrap a nested expression.<br> <p> </div> Mon, 16 Sep 2019 07:10:47 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799248/ https://lwn.net/Articles/799248/ dvdeug <div class="FormattedComment"> Ada's plethora of integer types don't seem to have been a great success; programmers write a lot of casts between integer types, and more recent languages haven't emulated it. Also, Ada has a lot of builtin support for such things, including type overloading depending on the result (i.e. in x := f(5), which f is called can depend on the type of x.) In C, without function overloading, if they're separate types, we need to add, in addition to abs, labs, llabs, imaxabs, wabs, wlabs, wllabs, sabs, slabs, sllabs, tabs, tlabs, tllabs, oabs, olabs, and ollabs. And they're going to have to be different types, since the most negative integer (-2,147,483,648) needs to trap on tabs and go to the most positive integer (2,147,483,647) on sabs.<br> <p> I'm not even sure you can have these types for short int, given the type extension rules in C. This type of thing is easy to say, but hard to clearly define, and even if defined, feels like would have been an overcomplex mess.<br> </div> Mon, 16 Sep 2019 05:57:01 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799243/ https://lwn.net/Articles/799243/ mjg59 <div class="FormattedComment"> You're able to guarantee which registers a compiler will use without manual inspection of the output?<br> </div> Sun, 15 Sep 2019 21:11:01 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799241/ https://lwn.net/Articles/799241/ Cyberax <div class="FormattedComment"> Nope, it's on point exactly.<br> <p> It doesn't seem that you understand the issue. It's possible to guarantee that ONE particular and easy function has no adverse effects from clobbered registers, it's not possible to prove that ALL functions are equally safe.<br> </div> Sun, 15 Sep 2019 21:06:01 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799240/ https://lwn.net/Articles/799240/ rweikusat2 <div class="FormattedComment"> As usual, your wild speculations about me are impolite, untrue and besides the point.<br> <p> <p> </div> Sun, 15 Sep 2019 21:00:04 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799239/ https://lwn.net/Articles/799239/ flussence <div class="FormattedComment"> <font class="QuotedText">&gt; This is a deliberately simplistic analysis, taking one sentence and turning it in to an independent logical proposition.</font><br> <p> And IIRC, doing so is such a tired logical fallacy that it even has its own pretentious latin label.<br> </div> Sun, 15 Sep 2019 20:47:06 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799237/ https://lwn.net/Articles/799237/ ballombe <div class="FormattedComment"> Or maybe the register clean up code can make some future attack easier.<br> Paranoia cuts both way.<br> </div> Sun, 15 Sep 2019 20:34:01 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799235/ https://lwn.net/Articles/799235/ Cyberax <div class="FormattedComment"> So all the software you're writing consists of newline stripping? No other functions whatsoever?<br> <p> That... explains things.<br> </div> Sun, 15 Sep 2019 20:14:44 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799233/ https://lwn.net/Articles/799233/ ken <div class="FormattedComment"> I must say I'm really skeptical about cleaning out caller saved registers. If you are cleaning up all registered used inside a called function on return you could potentially need to clear like 10-16 of them depending on what architecture you run on. <br> <p> And without even a single example of when that would have help it does sound a bit excessive. <br> </div> Sun, 15 Sep 2019 20:09:35 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799230/ https://lwn.net/Articles/799230/ rweikusat2 For a practical example. This ARM64 (mnemonical) machine code for a function supposed to strip trailing newlines from a string. <pre> 46b710: 8b214001 add x1, x0, w1, uxtw 46b714: eb01001f cmp x0, x1 46b718: 540000a3 b.cc 46b72c 46b71c: 14000007 b 46b738 46b720: d1000421 sub x1, x1, #0x1 46b724: eb01001f cmp x0, x1 46b728: 540000c0 b.eq 46b740 46b72c: 385ff022 ldurb w2, [x1,#-1] 46b730: 7100285f cmp w2, #0xa 46b734: 54ffff60 b.eq 46b720 46b738: 3900003f strb wzr, [x1] 46b73c: d65f03c0 ret 46b740: aa0003e1 mov x1, x0 46b744: 3900003f strb wzr, [x1] 46b748: d65f03c0 ret </pre> This is called with a pointer to the string in x0 and its length in w1. After the function has finished, x1 points to a null byte written over the the first trailing newline or immediately behind the string if there were no newlines. w2 contains the rightmost character which wasn't a newline or 10 if there were only newlines in the string. There's no information in these registers which isn't already available at the call site, hence, there's absolutely no point in changing the values of these two registers before returning from the function. Sun, 15 Sep 2019 19:53:42 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799228/ https://lwn.net/Articles/799228/ rweikusat2 <div class="FormattedComment"> That's definitely not a known fact as an exploit this 'feature' is supposed to 'defend' against would otherwise need to exist, ie, nobody would have to resort to "we don't what will happen in future" as reason for "why is this of value".<br> <p> <p> <p> </div> Sun, 15 Sep 2019 19:37:51 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799197/ https://lwn.net/Articles/799197/ mpr22 <div class="FormattedComment"> <font class="QuotedText">&gt; What do you get if you add a __trap and __saturate integer?</font><br> <p> There are two outcomes that for me would honour the principle of least astonishment:<br> <p> Defined behaviour "compile-time error" as ballombe suggests, or in the alternative, defined behaviour "always follow the overflow semantics of the left-hand operand and ignore the overflow semantics of the right-hand operand".<br> </div> Sat, 14 Sep 2019 17:34:59 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799194/ https://lwn.net/Articles/799194/ ballombe <div class="FormattedComment"> <font class="QuotedText">&gt; What do you get if you add a __trap and __saturate integer? What if they're different sizes? </font><br> <p> compilation error.<br> </div> Sat, 14 Sep 2019 16:53:38 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799165/ https://lwn.net/Articles/799165/ alonz That's quite different: switching to Rust implies a full rewrite of relevant code. Switching the kernel to compile as C++ is expected to be several orders of magnitude easier - at least in theory, much of the code should just compile as-is, and much of the rest can be fixed mechanically. <p>(I agree that Rust would provide more value&mdash;but at a hugely higher cost.) Sat, 14 Sep 2019 08:49:14 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799161/ https://lwn.net/Articles/799161/ pbonzini <div class="FormattedComment"> Call it paranoia if you want, but it is certainly not ignorance. It is definitely a known fact that even the smallest knowledge of register contents has in the past been turned into exploits<br> </div> Sat, 14 Sep 2019 07:06:23 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799157/ https://lwn.net/Articles/799157/ willy <div class="FormattedComment"> Rather than C++, Rust has its advocates:<br> <p> <a href="https://github.com/fishinabarrel/linux-kernel-module-rust">https://github.com/fishinabarrel/linux-kernel-module-rust</a><br> <p> (click the link to the LSSNA presentation for some of their reasoning)<br> <p> </div> Sat, 14 Sep 2019 02:23:52 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799155/ https://lwn.net/Articles/799155/ rweikusat2 <div class="FormattedComment"> <a href="https://ses.edu/logical-fallacies-101-ad-ignorantiam/">https://ses.edu/logical-fallacies-101-ad-ignorantiam/</a><br> <p> Nothing follows from ignorance.<br> </div> Sat, 14 Sep 2019 00:49:13 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799152/ https://lwn.net/Articles/799152/ Paf <div class="FormattedComment"> This is a deliberately simplistic analysis, taking one sentence and turning it in to an independent logical proposition.<br> <p> I’ll expand the sentence in to the context you know exists and you can tell me if it’s still “arguing from ignorance”.<br> <p> “Many récent security vulnerabilities have come from leaking internal state that was not previously recognized as important. Therefore, it is worth scrubbing potential sources of this internal state information, even without specific attacks identified for that particular vector.”<br> </div> Fri, 13 Sep 2019 22:14:57 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799151/ https://lwn.net/Articles/799151/ Cyberax <div class="FormattedComment"> No. This is a valid reasoning from the past experience.<br> </div> Fri, 13 Sep 2019 20:42:12 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799149/ https://lwn.net/Articles/799149/ rweikusat2 <div class="FormattedComment"> No. That's invalid reasoning aka invalid reasoning, and nothing else.<br> <p> <p> </div> Fri, 13 Sep 2019 20:11:41 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799146/ https://lwn.net/Articles/799146/ rahulsundaram <div class="FormattedComment"> <font class="QuotedText">&gt; This is an appeal to ignorance (logical fallacy).</font><br> <p> Aka proactive security? What about this one?<br> <p> "The kernel is now free of implicit fall-throughs; of the roughly 500 patches fixing fall-through warnings in the last year, Cook said, about 10% turned out to be addressing real bugs in the code."<br> <p> <p> </div> Fri, 13 Sep 2019 18:41:26 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799143/ https://lwn.net/Articles/799143/ rweikusat2 <div class="FormattedComment"> <font class="QuotedText">&gt; Cook responded that there is value in bringing the architecture to a known state at function return; it may not block a specific </font><br> <font class="QuotedText">&gt; attack right now, but "we don't know what is coming next".</font><br> <p> This is an appeal to ignorance (logical fallacy).<br> <p> </div> Fri, 13 Sep 2019 17:38:52 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799142/ https://lwn.net/Articles/799142/ mathstuf <div class="FormattedComment"> That means you have even more hard-to-understand implicit conversion rules. What do you get if you add a __trap and __saturate integer? What if they're different sizes? Different signedness? Better to add all the variants of the operators as functions to the standard library. That would also make upcasts explicit (e.g., sataddu64(somei64, someu8)) while you're at it too.<br> <p> Oh, you also might want __extend where operations return the next larger integer size to guarantee that the result fits.<br> </div> Fri, 13 Sep 2019 17:20:35 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799131/ https://lwn.net/Articles/799131/ sami <div class="FormattedComment"> <font class="QuotedText">&gt; A good intermediate state might be able to rule out indirect calls to functions whose address is never taken</font><br> <p> Clang's CFI implementation does exactly this.<br> </div> Fri, 13 Sep 2019 15:40:49 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799095/ https://lwn.net/Articles/799095/ eru <div class="FormattedComment"> So using debug information is not an option? (Maybe that takes even more space).<br> How about something like what coverage instrumentation does? (Which includes adding some initialized constant data structures for each function).<br> For every function you would store the name, and an array mapping from the offsets of the overflow checks to line numbers. Not very much data there, since not every line needs to be mapped. I assume that after the trap there is some way to figure out the function where it happened and then find the map.<br> <p> </div> Fri, 13 Sep 2019 13:31:54 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799094/ https://lwn.net/Articles/799094/ ballombe <div class="FormattedComment"> Really compilers should just support the keywords __wrap, __trap, __saturate, __overflow and allow to <br> declare each integer type separately<br> __wrap long int i;<br> __saturate unsigned long int j;<br> __overflow short int k;<br> etc.<br> instead of having a global setting.<br> <p> </div> Fri, 13 Sep 2019 13:22:46 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799093/ https://lwn.net/Articles/799093/ nix <div class="FormattedComment"> The code bloat here isn't really caused the overflow checks: those are fairly cheap. The problem is printing useful errors (including the locus of the problem) on error. Just a printf call is a lot bigger than the overflow checks, and the error-locus strings right now really explode the number of constant strings in the program.<br> </div> Fri, 13 Sep 2019 13:01:27 +0000 Comparing GCC and Clang security features https://lwn.net/Articles/799092/ https://lwn.net/Articles/799092/ eru <div class="FormattedComment"> Back when compilers that checked things at run-time were popular, Intel included the single byte instruction INTO (interrupt if overflow flag set) into the x86 instruction set. I think it is still there. Using that the checking would have almost no effect on code size, if you can handle the resulting signal smartly.<br> <p> </div> Fri, 13 Sep 2019 12:49:10 +0000