Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
"Strong" stack protection for GCC (lwn.net)
74 points by robrenaud on Feb 13, 2014 | hide | past | favorite | 28 comments



I know everyone is a bit tired of hearing about the new Mill CPU, but one of the things we've done with the architecture is to have the hardware track return addresses. This is not only much faster and efficient; it is also immune to these kinds of attacks.

There's an upcoming "Security" talk which will cover lots of other ways we've worked to improve the fundamental protection offered by the CPU, but the stack is covered in the Memory talk: http://ootbcomp.com/topic/memory/ and ootbcomp.com/topic/introduction-to-the-mill-cpu-programming-model-2/


I know everyone is a bit tired of hearing about the new Mill CPU

Well, damn, I must be late to the party. The Mill just caught my attention a week ago, and I'm far from being tired of hearing about it.

Thank you for sharing what you can.


Agree -- I've seen only one article on it so far and found it fascinating.


Check out http://ootbcomp.com/docs/ if you want more on the Mill.


Knuth's MMIX[0] architecture also has a "hardware" stack (scare quotes because it isn't implemented in real hardware)

[0]http://en.wikipedia.org/wiki/MMIX


As has been pointed out on the LWN thread, buffer overflows even on the stack can also leave you vulnerable by overwriting other automatic variables, e.g. a variable that indicates whether a client is authenticated as an administrator.


Yes this is completely true.

I meant particularly the return-to-libc type of attacks that the canary (to some extent) protects against, when I claimed immunity (and improved performance).

We have some stuff to talk about on the protecting authentication flags and things front too, but I'm afraid that'll have to wait for the Security talk.

One other security-related aspect that we have already presented is how stack debris is not readable once returned, so malicious code can't go looking at it.

We've also talked a little bit about how we don't have rings, and we have very cheap syscalls across protection boundaries. So there are some hints of stuff to come.


ROP chains.


On the conceptual level, ROP and return into libc are the same thing. You need to start them by overwriting an address somewhere, and the return address is a natural candidate.


Yes, the Security talk will cover ROP too :). Stay tuned.

The Mill is far from exploit-free, but vast swathes of attacks can be stopped or mitigated and we do our best.


I am not, I love to learn about new architectures.


I wish all distros will start compiling all its packages with a consistent policy to enable at least some level of stack protection (like Ubuntu and unlike Debian).


Can you elaborate? Debian has infrastructure for hardening their builds (look on their wiki), but each package has to make sure to use it. Unless Ubuntu patches each package source (which they don't), then they have the same hardening status as Debian. Where did I go wrong?


Doesn't Ubuntu take most of their packages from Debian?


Ubuntu uses the packages that have been maintained and integrated by Debian, but they don't necessarily take the binaries. They compile it themselves, and that means they can specify whatever compile options they want.


How would the computing world be, if compiler and OS vendors weren't required to keep on fixing the issues caused by C's widespread into the industry?


If C did not exist, it would be necessary to invent it.

There is CPU-bound code out there, where every cycle saved in an inner loop equates to hours of improved runtime or thousands of additional client transactions/second. Safer languages have made great strides in the kinds of dynamic profiling and optimization that can equal the performance of optimized C/C++, but there remain real penalties in startup and profiling time.


I think some things like null terminated strings etc are not inevitable in a fast language like C. There were definitely design mistakes that cost security and don't directly affect performance significantly.


If anything, null-terminated strings are bad for performance as often as good for it. One example that comes up reasonably often: comparing strings that have different lengths but common prefixes is fast with length-tagged (Pascal-style) strings, but expensive with C-style strings, because you have to scan both strings until you find either a string end, or a difference. So instead of quickly answering "not equal" after one integer comparison, you could end up doing hundreds (or thousands) of byte comparisons in degenerate cases. Anything that calls strlen() also ends up doing extra work.


Well, as far as kernel is concerned strings aren't a problem. Outside VFS they don't exist. Inside VFS everything is chopped into usually short pathname components which are hashed for dcache consumption. On x86_64 hashing is not byte-by-byte anymore.

Fixing pathetic macro system and type system (if that qualifies at all) would get rid of many many bugs.


It affects performance more on old, register poor, slow CPUs. Memory latency dominates processing time now, but it used to be a real issue.


Sure, but we always had the option to switch off bound checking on the code spots where it really made a difference.


How about Ocaml or Rust? They are both safer than C and are almost as fast.

I don't think we'd reinvent C on modern machines, which have millions of times more memory than K&R had to work with on their PDP-7.


You just made me smile.

I have done systems programming in Assembly, BASIC dialects, Pascal dialects, Modula-2, Ada, Oberon, without writing a single line of C.

There was a time C was confined to UNIX System V at some university labs and the world at large had other sytems languages to choose from.

Interest in C raised, because we wanted to have at home some kind of compiler for homework and while at the same time UNIX variants started to spread into the industry.

I know kids these days, raised in the VM golden age, think many of the current language features are only possible in a VM based environment, it wasn't like that 20 years ago.

There are hardly any feature ANSI/ISO C has over other systems languages, other than having 30+ years of investment into compiler backends and complaining other languages tend to be a bit more verbose.


There were systems languages before C, and there will be systems languages after it. Saving a cycle or two is not the strong point of C, either.


Isn't this the same as what the OpenBSD guys added to their GCC fork? I think it was called ProPolice.


According to http://en.wikipedia.org/wiki/Buffer_overflow_protection#GNU_..., it was IBM that developed ProPolice, and this is an evolution of a reimplementation by RedHat.


Gotcha - thanks for the correction. Checked my sources and it was W^X they implemented at the same time as ProPolice and indeed it was IBM who built that.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: