33

I have written an application in C, and I'm trying to understand what is the purpose of the -fno-stack-protector command when compiling. For my specific application, it makes no difference if I use this command or not in terms of protecting against buffer overflow.

I've read online that the -fstack-protector and -fno-stack-protector commands enable and disable respectively the stack-smashing protector, but if I'm compiling the application myself, how can the protector be enabled beforehand? Does the usage of the command maybe depend on what system the application is running on?

user157251
  • 64,489
  • 38
  • 208
  • 350
touvlo2000
  • 415
  • 1
  • 5
  • 9

5 Answers5

22

In the standard/stock GCC, stack protector is off by default. However, some Linux distributions have patched GCC to turn it on by default. In my opinion, this is rather harmful, as it breaks the ability to compile anything that's not linked against the standard userspace libraries unless the Makefile specifically disables stack protector. It would even break the Linux kernel build except that the distributions with this hack added additional hacks to GCC to detect that the kernel is being built and disable it.

R.. GitHub STOP HELPING ICE
  • 195,354
  • 31
  • 331
  • 669
  • 2
    Wouldn't, by definition, anything compiled on a system with stack protection on by default get linked against libraries built with stack protection, since they in turn would have been compiled on a system with stack protection turned on? – tbert May 23 '12 at 04:44
  • 1
    I assume you're dealing with the second part of my answer (the comments about why it's problematic) and if so, in that case the answer is no. Any code not intended to run as part of the host's userspace ecosystem is not going to be linked against any of the host's libraries. (For example, a kernel is not linked against any userspace libraries. Other examples would be bootloader code, modules intended to be read in and used as templates by a dynrec/JIT emulator, etc.) – R.. GitHub STOP HELPING ICE May 23 '12 at 13:02
  • Wasn't talking about kernel space, but userspace; JIT compilation isn't being done with the C compiler; so, I have to ask, what is the problem with turning on stack protection in userland, beyond maybe having to set "-fno-stack-protector" in the compile args for the linux kernel? – tbert May 23 '12 at 13:14
  • 1
    My JIT example was that one could, instead of writing code generation logic for each possible ISA, write the units of code that a JIT would use in C, compile to ELF `.o` files, and use them as as data to be assembled by the JIT with minimal ISA-specific knowledge. Maybe you don't like my example, but one could certainly come up with others. Basically, in any situation where you're using the compiler as a *freestanding implementation*, stack protector is wrong (although it could be made to work by omitting `-lssp` and providing your own `__stack_chk_fail`). – R.. GitHub STOP HELPING ICE May 23 '12 at 13:30
  • 1
    My point about what's broken is that it forces every program using the C compiler as a freestanding implementation to include logic to check whether ssp is on by default, and how to turn it off, to the build system. And the same issue will repeat next time distros come up with hacks to the default GCC config. If `-ffreestanding` prevented ssp from being turned on by default, then it wouldn't be such a problem. – R.. GitHub STOP HELPING ICE May 23 '12 at 13:31
  • *"... some Linux distributions have patched GCC to turn it on by default."* - Stack Protectors are a standard security feature now. While there may be some corner cases (like a custom distro using `-ffreestanding`), in general they should be enabled. Turning them off should trigger a security defect. – jww Sep 12 '14 at 12:57
17

If you compile with -fstack-protector, then there will be a little more space allocated on the stack and a little more overhead on entry to and return from a function while the code sets up the checks and then actually checks whether you've overwritten the stack while in the function.

It will make a difference to your application. If enabled, it will head off stack overflow attacks quickly. Only if you have no function calls in your code would it leave your program unaffected (and since you normally write main(), and that is a function which is called by the startup code, it would have an effect on your program). However, stack overflow attacks are not the only possible attacks that can be used, so it is not a panacea. But it is useful protection with a limited cost.

The protection does not depend on the system per se; it depends on the version of the compiler that you are using, but that's all.

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
  • 1
    `-fstack-protector` also re-arranges stack layout to make it easier to detect a smash. – jww Sep 12 '14 at 12:58
  • @jww Yes, I observed that memory for strings (char[]) is allocated before any other integer. Thus overflowing it would not overwrite the ints. – Hritik Jul 22 '20 at 09:42
2

The stack protector is code that is generated by the compiler and placed into your program. It's not an external program or system call that is called by your program.

Paul Richter
  • 5,666
  • 2
  • 17
  • 21
1

Times when an option that matches a default compiler setting can be useful include:

  • when you're using a build system that may have a complex configuration that you want to tweak. Instead of figuring out where in a maze of makefiles it might be choosing to use fstack-protector (for example), it may let you easily pass in additional options that simply get tacked on to the end of the list of options. If GCC sees both fstack-protector and fno-stack-protector in the set of options, the last one on the command line is the one that takes effect.

  • the other time this kind of thing might be handy (which doesn't seem to apply to -fstack-protector, however) is when you have an option that turns on a bunch of 'sub-options'. For example, setting -O2 turns on a slew of -fxxx optimization options,and you may want to use -O2 for the most part but don't want GCC's strict aliasing optimizations. So you can specify -fno-strict-aliasing to set that particular option back to its default setting. (Note: this case is really equivalent to the case above)

Michael Burr
  • 311,791
  • 49
  • 497
  • 724
1

There are three reasons why you may want to turn this off,

  • You're building a shared a library where this may matter and other functions make assumptions about the stack.
  • You're concerned about performance.
  • You want to build vulnerable software. This very frequently happens with Capture The Flag (CTFs) and the like, as in the case if you wanted to build Protostar to demonstrate an exploit that you wouldn't otherwise be vulnerable too.
user157251
  • 64,489
  • 38
  • 208
  • 350