Since recent versions (>= 4.0, maybe before), gcc (and ld) has some nice security features. Debian has created a wrapper for the toolchain, to make the use of these features easy.

To install the wrapper, run:

apt-get install hardening-wrapper

To enable the hardening features, you have to export the environment variable:


The features include additional checks for printf-like functions, stack protector, using address-space layout randomization (ASLR), marking ELF-sections as read-only after loading when possible, etc.

Please note that you must compile with *-02* if you want the checks to be effective

DEB_BUILD_HARDENING_FORMAT (gcc/g++ -Wformat -Wformat-security)

Ask gcc to make additional checks on format strings, to prevent attacks.

The following code, for ex:


will result in a warning:

[home ~/harden] DEB_BUILD_HARDENING=1 make
gcc     bad.c   -o bad
bad.c: In function ‘main’:
bad.c:10: warning: format not a string literal and no format arguments

Why is this code vulnerable ? Because the buffer (buf) could contain format characters like %s, and the printf function will interpret these characters to pop arguments from the stack, and can result in the execution of arbitrary code.


  • Replace previous code by
  • Remember this is also true for other functions like syslog()
  • Tell gcc to help ! You can mark your own printf-like functions using gcc attributes, for ex:
void out_log(int level,const char *fmt,...)#ifdef __GNUC__  __attribute__((__format__(printf,2,3)))#endif;


When loading a program (which is handled by, many ELF sections are written and so marked as read-write. However, most of them could be turned read-onlyafter. This options tells the linker to mark as much sections as possible read-only.

[home ~/harden] objdump -x bad | grep RELRO
[home ~/harden] DEB_BUILD_HARDENING=1 make
[home ~/harden] objdump -x bad | grep RELRO
  RELRO off    0x0000000000000df0 vaddr 0x0000000000200df0 paddr 0x0000000000200df0 align 2**