Skip to content

FORTIFY checks

_FORTIFY_SOURCE replaces unbounded libc calls (memcpy, sprintf, strcpy, …) with bounds-checked variants (__memcpy_chk, …) when the compiler can infer a buffer size. checksec reports this from several angles, so they get their own section.

See Understanding output for color meanings. The key under each heading is the report key used in JSON/YAML and with --fail-if.

Two different sources

FORTIFY (and its counts) is derived by comparing the binary's imported libc functions against the fortifiable set — it works on any binary. FORTIFY Lvl and GLIBCXX Assert come from annobin compiler notes, which are only present on annobin-enabled toolchains (RHEL/Fedora and derivatives). On other toolchains they report Unknown — see Unknown vs N/A.


FORTIFY

Key: fortify_source

Protects against: buffer overflows in common libc string/memory functions, by routing them through bounds-checked *_chk variants.

How checksec detects it: resolves the target's libc, builds the set of fortifiable functions and their fortified (*_chk) counterparts, and checks whether the binary imports any fortified variants.

Value Color Meaning
Yes green At least one fortified (*_chk) function is used.
No red No fortified functions, though fortifiable ones are imported.
N/A plain Nothing fortifiable (e.g. a static binary with no libc imports).

Enable:

gcc -O2 -D_FORTIFY_SOURCE=2     # or =3 for stricter checks (glibc 2.34+)

Note

_FORTIFY_SOURCE requires optimization (-O1 or higher) to take effect.


Fortified / Fortifiable

Keys: fortified, fortifiable

These two informational counts accompany the FORTIFY result:

Column Meaning
Fortified Number of fortified (*_chk) functions the binary uses.
Fortifiable Number of functions that could be fortified.

Both render as plain (informational) counts. A healthy binary has Fortified close to Fortifiable. Use checksec fortifyFile <file> for the per-function breakdown.


FORTIFY Lvl

Key: fortify_level

Protects against: the same overflows as FORTIFY — this reports the level the code was compiled at, which annobin records per translation unit.

How checksec detects it: reads the _FORTIFY_SOURCE numeric note from the .gnu.build.attributes (annobin) section and reports the lowest level across all translation units.

Value Color Meaning
Level 2 (or higher) green All units built with -D_FORTIFY_SOURCE=2+.
Level 1 yellow Built at level 1 — weaker checks.
Level 0 red Explicitly built with fortification off.
Unknown yellow No annobin notes — the level can't be determined.

Why does this say Unknown?

FORTIFY Lvl → Unknown is the most-asked-about value (it prompted issue #346). It means the binary was built without annobin, so the per-unit level wasn't recorded. It is not a failure — check the FORTIFY column for the symbol-based verdict, which works without annobin.

Enable:

# On an annobin-enabled toolchain (RHEL/Fedora):
gcc -O2 -D_FORTIFY_SOURCE=2 -fplugin=annobin


GLIBCXX assertions

Key: glibcxx_assert

Protects against: out-of-bounds and invalid-argument bugs in the C++ standard library, by enabling libstdc++ precondition assertions.

How checksec detects it: reads the GLIBCXX_ASSERTIONS annobin note.

Value Color Meaning
Enabled green Built with -D_GLIBCXX_ASSERTIONS.
Disabled red annobin notes show it was off.
Unknown yellow No annobin notes — can't determine (see above).

Enable:

g++ -D_GLIBCXX_ASSERTIONS