Source Fortification (The GNU C Library)

### D.2 Fortification of function calls ¶

This section contains implementation details of the GNU C Library and may not remain stable across releases.

The `_FORTIFY_SOURCE` macro may be defined by users to control hardening of calls into some functions in the GNU C Library. The definition should be at the top of the source file before any headers are included or at the pre-processor commandline using the `-D` switch. The hardening primarily focuses on accesses to buffers passed to the functions but may also include checks for validity of other inputs to the functions.

When the `_FORTIFY_SOURCE` macro is defined, it enables code that validates inputs passed to some functions in the GNU C Library to determine if they are safe. If the compiler is unable to determine that the inputs to the function call are safe, the call may be replaced by a call to its hardened variant that does additional safety checks at runtime. Some hardened variants need the size of the buffer to perform access validation and this is provided by the `__builtin_object_size` or the `__builtin_dynamic_object_size` builtin functions. `_FORTIFY_SOURCE` also enables additional compile time diagnostics, such as unchecked return values from some functions, to encourage developers to add error checking for those functions.

At runtime, if any of those safety checks fail, the program will terminate with a `SIGABRT` signal. `_FORTIFY_SOURCE` may be defined to one of the following values:

- 1: This enables buffer bounds checking using the value returned by the `__builtin_object_size` compiler builtin function. If the function returns `(size_t) -1`, the function call is left untouched. Additionally, this level also enables validation of flags to the `open`, `open64`, `openat` and `openat64` functions.
- 2: This behaves like 1, with the addition of some checks that may trap code that is conforming but unsafe, e.g. accepting `%n` only in read-only format strings.
- 3: This enables buffer bounds checking using the value returned by the `__builtin_dynamic_object_size` compiler builtin function. If the function returns `(size_t) -1`, the function call is left untouched. Fortification at this level may have a impact on program performance if the function call that is fortified is frequently encountered and the size expression returned by `__builtin_dynamic_object_size` is complex.

In general, the fortified variants of the function calls use the name of the function with a `__` prefix and a `_chk` suffix. There are some exceptions, e.g. the `printf` family of functions where, depending on the architecture, one may also see fortified variants have the `_chkieee128` suffix or the `__nldbl___` prefix to their names.

Another exception is the `open` family of functions, where their fortified replacements have the `__` prefix and a `_2` suffix. The `FD_SET`, `FD_CLR` and `FD_ISSET` macros use the `__fdelt_chk` function on fortification.

The following functions and macros are fortified in the GNU C Library:

- `asprintf`
- `confstr`
- `dprintf`
- `explicit_bzero`
- `FD_SET`
- `FD_CLR`
- `FD_ISSET`
- `fgets`
- `fgets_unlocked`
- `fgetws`
- `fgetws_unlocked`
- `fprintf`
- `fread`
- `fread_unlocked`
- `fwprintf`
- `getcwd`
- `getdomainname`
- `getgroups`
- `gethostname`
- `getlogin_r`
- `gets`
- `getwd`
- `inet_ntop`
- `inet_pton`
- `longjmp`
- `mbsnrtowcs`
- `mbsrtowcs`
- `mbstowcs`
- `memcpy`
- `memmove`
- `mempcpy`
- `memset`
- `memset_explicit`
- `mq_open`
- `obstack_printf`
- `obstack_vprintf`
- `open`
- `open64`
- `openat`
- `openat64`
- `poll`
- `ppoll64`
- `ppoll`
- `pread64`
- `pread`
- `printf`
- `ptsname_r`
- `read`
- `readlinkat`
- `readlink`
- `realpath`
- `recv`
- `recvfrom`
- `snprintf`
- `sprintf`
- `stpcpy`
- `stpncpy`
- `strcat`
- `strcpy`
- `strlcat`
- `strlcpy`
- `strncat`
- `strncpy`
- `swprintf`
- `syslog`
- `ttyname_r`
- `vasprintf`
- `vdprintf`
- `vfprintf`
- `vfwprintf`
- `vprintf`
- `vsnprintf`
- `vsprintf`
- `vswprintf`
- `vsyslog`
- `vwprintf`
- `wcpcpy`
- `wcpncpy`
- `wcrtomb`
- `wcscat`
- `wcscpy`
- `wcslcat`
- `wcslcpy`
- `wcsncat`
- `wcsncpy`
- `wcsnrtombs`
- `wcsrtombs`
- `wcstombs`
- `wctomb`
- `wmemcpy`
- `wmemmove`
- `wmempcpy`
- `wmemset`
- `wprintf`