Security-hardening drift¶
A library upgrade can be perfectly ABI-compatible yet silently weaken the
security hardening of the shipped binary — full RELRO downgraded to partial,
the stack canary dropped, _FORTIFY_SOURCE disabled, or a writable+executable
segment introduced. None of these break existing consumers, so a normal
compatibility gate stays green. abicheck captures a checksec-equivalent
surface from the ELF and reports a weakening transition as a deployment risk.
What is captured¶
For every ELF, the snapshot records:
| Property | Source | Meaning |
|---|---|---|
relro |
PT_GNU_RELRO + BIND_NOW |
none / partial / full RELRO |
bind_now |
DT_BIND_NOW, DF_BIND_NOW, DF_1_NOW |
eager binding (whole GOT read-only) |
is_pie |
ET_DYN + DF_1_PIE |
position-independent executable |
has_stack_canary |
__stack_chk_fail / __stack_chk_guard references |
-fstack-protector |
has_fortify_source |
*_chk wrapper references |
_FORTIFY_SOURCE |
has_writable_executable_segment |
PT_LOAD with PF_W and PF_X |
W^X violation |
has_executable_stack |
PT_GNU_STACK with PF_X |
NX disabled |
Change kinds¶
A regression (and only a regression — improvements are never findings) emits:
relro_weakened— full→partial or →none RELROpie_disabled— PIE executable became non-PIEstack_canary_removed—-fstack-protectorno longer referencedfortify_source_weakened—_FORTIFY_SOURCEwrappers no longer referencedwritable_executable_segment— a W^X segment was introducedexecutable_stack— executable stack introduced (regression)
All of these are COMPATIBLE_WITH_RISK by default, so they surface in the
report without failing a standard compatibility gate.
The opposite, improving transition — removing an executable stack — is reported
as the distinct executable_stack_removed kind (COMPATIBLE, informational).
Keeping the two directions as separate kinds is what lets the security policy
gate the regression (executable_stack) without ever failing a hardening
improvement.
Turnkey gating: the shipped security policy¶
abicheck ships a built-in policy that promotes the hardening kinds to hard breaks. Reference it by name — no file to author:
--policy-file security resolves to the packaged
abicheck/policies/security.yaml.
It uses base_policy: strict_abi and gates relro_weakened, pie_disabled,
stack_canary_removed, fortify_source_weakened, writable_executable_segment
and executable_stack to break, and rpath_changed / runpath_changed to
warn. To customize, copy it and pass your own path.
Example¶
$ abicheck compare libfoo.so.1 libfoo.so.2 --policy-file security
BREAKING
relro_weakened GNU_RELRO RELRO weakened: full → none
stack_canary_removed __stack_chk_fail Stack canary removed: -fstack-protector no longer referenced
Without the policy the same comparison reports COMPATIBLE_WITH_RISK and the
two findings appear under the deployment-risk section.
Scope¶
This covers the ELF hardening surface. Non-ELF hardening (PE /GS,
/DYNAMICBASE; macOS hardened runtime) is out of scope for now.