tested can be controlled via command line options, but the default is to
test for all of them.
+ The tool was originally built to assist in the implementation of
+security features for Fedora, although it does now check for more things
+than are described in that document:
+<https://fedoraproject.org/wiki/Security_Features>
+
New tests can be added to the HARDENED checker by adding an entry in
the TESTS array defined in 'hardened.c' and then creating the necessary
code to support the test. There is more information on this process in
* Menu:
* Test bind now:: The bind-now test
-* Test gnu stack:: The gnu-stack test
-* Test writable got:: The writable-got test
-* Test rwx seg:: The rwx-seg test
-* Test textrel:: The textrel test
-* Test run path:: The run-path test
+* Test branch protection:: The branch-protection test
* Test cf protection:: The cf-protection test
-* Test optimization:: The optimization test
-* Test stack prot:: The stack-prot test
-* Test stack clash:: The stack-clash test
-* Test fortify:: The fortify test
-* Test notes:: The notes test
-* Test gnu relro:: The gnu relro test
-* Test pie:: The pie test
-* Test pic:: The pic test
* Test dynamic segment:: The dynamic-segment test
* Test dynamic tags:: The dynamic-tags test
-* Test not dynamic tags:: The not-dynamic-tags test
-* Test branch protection:: The branch-protection test
+* Test entry:: The entry test
+* Test fortify:: The fortify test
+* Test glibcxx assertions:: The glibcxx-assertions test
+* Test gnu relro:: The gnu relro test
+* Test gnu stack:: The gnu-stack test
+* Test go revision:: The go revision test
+* Test instrumentation:: The instrumentation test
+* Test lto:: The lto test
* Test not branch protection:: The not-branch-protection test
-* Test short enums:: The short-enums test
-* Test stack realign:: The stack-realign test
+* Test not dynamic tags:: The not-dynamic-tags test
+* Test notes:: The notes test
+* Test only go:: The only go test
+* Test optimization:: The optimization test
+* Test pic:: The pic test
+* Test pie:: The pie test
* Test production:: The production test
-* Test lto:: The lto test
* Test property note:: The property note test
+* Test run path:: The run-path test
+* Test rwx seg:: The rwx-seg test
+* Test short enums:: The short-enums test
+* Test stack clash:: The stack-clash test
+* Test stack prot:: The stack-prot test
+* Test stack realign:: The stack-realign test
+* Test textrel:: The textrel test
* Test threads:: The threads test
-* Test glibcxx assertions:: The glibcxx-assertions test
-* Test entry:: The entry test
-* Test go revision:: The go revision test
-* Test only go:: The only go test
* Test warnings:: The warnings test
-* Test instrumentation:: The instrumentation test
+* Test writable got:: The writable-got test
The HARDENED tool does support some command line options of its own
as well.
* Waiving Hardened Results:: How to ignore specific hardening tests.
\1f
-File: annobin.info, Node: Test bind now, Next: Test gnu stack, Up: Hardened
+File: annobin.info, Node: Test bind now, Next: Test branch protection, Up: Hardened
4.2.1 The bind-now test
-----------------------
'--skip-bind-now' option and re-enabled by the '--test-bind-now' option.
\1f
-File: annobin.info, Node: Test gnu stack, Next: Test writable got, Prev: Test bind now, Up: Hardened
-
-4.2.2 The gnu-stack test
-------------------------
-
- Problem: An attacker could place code on the stack and then run it
- Fix By: Updating compiler, assembler sources and/or linker scripts
- Waive If: The application *really* needs to be able to dynamically create and execute code
-
- Example: FAIL: gnu-stack test because the .stack section has incorrect permissions
- Example: FAIL: gnu-stack test because the .note.GNU-stack section has execute permission
- Example: FAIL: gnu-stack test because the GNU stack segment has execute permission
- Example: FAIL: gnu-stack test because the GNU stack segment does not have both read & write permissions
- Example: FAIL: gnu-stack test because no .note.GNU-stack section found
- Example: MAYB: gnu-stack test because multiple stack sections detected
-
- This test checks that it is not possible to place code onto the stack
-and then execute it. Normally the stack just holds data and addresses,
-but never instructions. A favourite tactic of attackers however is to
-discover a buffer overrun bug that addresses the stack and then place
-instructions there before forcing the processor to execute them.
-
- The test actually checks several different parts of a binary file in
-order to determine that its stack is safe, which is why there are
-several different potential failure messages.
-
- Most applications will have a section inserted into them by the
-compiler called .NOTE.GNU-STACK. The section has no contents, but the
-read, write, and execute attributes of the section reflect the needs of
-the application's stack.
-
- Ordinary compiled code should never see this problem, but the test
-failure can be triggered by programs built with an old compiler which
-does not support the .NOTE-GNU-STACK section, or if the program contains
-some assembler source files or linked with a custom made linker map.
-
- To fix the problem either the compiler needs to be upgraded or the
-linker map needs to be updated or the assembler sources need to be
-extended to add the .NOTE-GNU-STACK section by adding code like this:
-
- .section .note.GNU-stack,"",%progbits
-
- If necessary the test can be disabled via the '--skip-gnu-stack'
-option and re-enabled via the '--test-gnu-stack' option.
-
-\1f
-File: annobin.info, Node: Test writable got, Next: Test rwx seg, Prev: Test gnu stack, Up: Hardened
-
-4.2.3 The writable-got test
----------------------------
-
- Problem: An attacker could intercept and redirect shared library function calls
- Fix By: Link with -Wl,--secure-plt
- Waive If: No shared libraries are used
-
- Example: FAIL: writable-got test because the GOT/PLT relocs are writable
-
- This test checks that the instructions to set up the GOT and PLT
-tables in a dynamic executable cannot be altered by an outside source.
-
- Dynamic executables use two tables to help them connect to shared
-libraries. These tables - the GOT and the PLT - are set up when the
-program runs, based upon instructions held in special sections in the
-file. If these sections are writable then an attacker could change
-their contents and thus cause the program to call the wrong functions in
-the shared libraries.
-
- Under normal circumstances this test should never fail. If it does
-then something unusual is going on. One possible cure is to add the
-'-Wl,--secure-plt' option to the final link command line.
-
- If necessary the test can be disabled via the '--skip-writable-got'
-option and re-enabled via the '--test-writable-got' option.
-
-\1f
-File: annobin.info, Node: Test rwx seg, Next: Test textrel, Prev: Test writable got, Up: Hardened
-
-4.2.4 The rwx-seg test
-----------------------
-
- Problem: An attacker could add their own code to an executable
- Fix By: Changing the linker script used to create the binary
- Waive If: Don't.
-
- Example: FAIL: rwx-seg test because segment has Read, Write and eXecute flags set
-
- This test checks that the file does not have any segments that have
-all three of the READ, WRITE and EXECUTE permissions. Code segments
-should have read and execute permissions, but they should not be
-writable as otherwise an attacker can overwrite the code. Data segments
-should have read permission, and possibly write permission as well, but
-never execute permission as otherwise an attacker might be able to
-create their own code in a data area.
-
- The linker will normally never create a binary file with a segment
-with all three permissions, but it is possible to force it to do so by
-using a custom linker script. If this flaw is detected then whatever
-linker script is being used should be corrected to remove the problem.
-
- If necessary the test can be disabled via the '--skip-rwx-seg' option
-and re-enabled via the '--test-rwx-seg' option.
-
-\1f
-File: annobin.info, Node: Test textrel, Next: Test run path, Prev: Test rwx seg, Up: Hardened
-
-4.2.5 The textrel test
-----------------------
-
- Problem: An attacker could change the code in an executable
- Fix By: Compiling with -fPIC enabled
- Waive If: The code _must_ be static
-
- Example: FAIL: textrel test because the DT_TEXTREL tag was detected
-
- This test checks to make sure that a binary file does not contain any
-relocations that alter the contents of a code section. Relocations are
-special instructions that the program loader uses to alter pieces of a
-application when it starts up. Normally these relocations are
-restricted to altering the application's data, but if any of them alter
-its code then an attacker might be able to exploit this to change the
-program.
+File: annobin.info, Node: Test branch protection, Next: Test cf protection, Prev: Test bind now, Up: Hardened
- This problem usually only arises when a binary is built to execute at
-a fixed address. Such binaries need text relocations to help them run
-at the address chosen. The safest solution therefore is to compile the
-binary to be position independent by using the '-fPIC' or '-fPIE'
-compiler command line options.
+4.2.2 The branch-protection test
+--------------------------------
- If necessary the test can be disabled via the '--skip-textrel' option
-and re-enabled via the '--test-textrel' option.
+ Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
+ Fix By: Compile with -mbranch-protection=standard
+ Waive If: Not running on AArch64
+ Waive If: The application will not run on Fedora 35 or later.
+ Waive If: The application will not run on newer AArch64 cores.
-\1f
-File: annobin.info, Node: Test run path, Next: Test cf protection, Prev: Test textrel, Up: Hardened
+ Example: FAIL: branch protection test because not enabled
+ Example: FAIL: branch protection test because only partially enabled
+ Example: FAIL: branch protection test because .note.gnu.property section not found (it is needed for branch protection support)
+ Example: FAIL: branch protection test because the -mbranch-protection option was not used
-4.2.6 The run-path test
------------------------
+ AArch64 processors are vulnerable to a class of attack known as ROP
+and JOP style attacks. Preventing this kind of exploit requires
+assistance from the hardware itself, in the form of new instructions
+that need to be inserted by the compiler, and new bits in the core's
+status that need to be set.
- Problem: An attacker could cause an application to use a corrupted shared library
- Fix By: Compiling with -Wl,--enable-new-dtags or moving the shared libraries needed to a proper location
- Waive If: The application uses shared libraries held in non-standard locations
- Waive If: The linker does not support --enable-new-dtags
+ This test checks to see if the compile time option to enable the
+security feature was used. There are four levels of security available,
+ranging from none through partial (some functions are protected others
+are not) to full. The test checks that full security has been enabled.
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag is corrupt
- Example: MAYB: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag exists but is empty
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag contains a path that does not start with /usr
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has a path that contains '..'
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has $ORIGIN after a non-$ORIGIN path
- Example: MAYB: run-path test because the RPATH dynamic tag is deprecated. Link with --enable-new-dtags to use RUNPATH instead
+ The security feature is enabled by compiling with the
+'-mbranch-protection=standard' gcc command line option.
- An application that uses shared libraries contains information on how
-to locate those libraries. This information is a list of directories
-which should be searched for the libraries. The test checks that the
-list is secure.
+ Note - these security features are only found on newer versions of
+the AArch64 architecture, and they need a compiler and a loader that
+will support them. Currently this means Fedora 35 or later, but not
+RHEL.
- The test actually covers several different aspects, such as all
-directory paths must be absolute, start with /USR and must not contain
-... If any of these rules are broken then an attacker might be able to
-exploit the search paths to force the application to load their own,
-corrupted version of a shared library.
+ Note - this test is the inverse of the *note Test not branch
+protection:: test and directly related to the *note Test dynamic tags::
+test.
- Normally this test will only be triggered if an application is linked
-by an old linker which does not support the generation of the new format
-DT_RUNPATH search paths. Or if it is linked against shared libraries
-which do not reside in standard locations. Fixing the test depends upon
-whether these issues can be solved.
+ Note - this test is automatically enabled if the '--profile-rawhide'
+options are used.
- If necessary the test can be disabled via the '--skip-run-path'
-option and re-enabled via the '--test-run-path' option.
+ If necessary the test can be disabled via the
+'--skip-branch-protection' option and re-enabled via the
+'--test-branch-protection' option.
\1f
-File: annobin.info, Node: Test cf protection, Next: Test optimization, Prev: Test run path, Up: Hardened
+File: annobin.info, Node: Test cf protection, Next: Test dynamic segment, Prev: Test branch protection, Up: Hardened
-4.2.7 The cf-protection test
+4.2.3 The cf-protection test
----------------------------
Problem: An attacker could compromise an unprotected binary
option and re-enabled via the '--test-cf-protection' option.
\1f
-File: annobin.info, Node: Test optimization, Next: Test stack prot, Prev: Test cf protection, Up: Hardened
+File: annobin.info, Node: Test dynamic segment, Next: Test dynamic tags, Prev: Test cf protection, Up: Hardened
-4.2.8 The optimization test
----------------------------
-
- Problem: Insufficient optimization prevents security features from working
- Fix By: Compiling with -O2
- Waive If: The application does not use string/memory functions
+4.2.4 The dynamic-segment test
+------------------------------
- Example: FAIL: optimization test because optimization level too low
- Example: FAIL: optimization test because level too low
- Example: MAYB: optimization test because no valid notes found regarding this test
+ Problem: Programs with more than one dynamic section will not be loaded properly
+ Fix By: Fix assembler source code and/or linker script
+ Waive If: Don't.
- This test checks that the application was compiled with sufficient
-optimization enabled.
+ Example: FAIL: dynamic segment test because multiple dynamic sections detected
- The C library security hardening features enabled via the
-'-D_FORTIFY_SOURCE=2' or '-D_FORTIFY_SOURCE=3' preprocessor command line
-options will only work properly if the compiler is run at an
-optimization level of at least '-O2'. Hence this test checks to make
-sure that this level (or higher) has been used.
+ Dynamic executables must have a dynamic section which contains
+information that is used by the loader at program startup. The loader
+however only expects there to be one dynamic section in a program, and
+it does not cope it there are more than one. Normally this is not an
+issue however as the linker will ensure that there is only one dynamic
+section. It is possible however to use a custom linker script to create
+more than one dynamic section, or to write some assembler code
+specifically designed to create multiple dynamic sections.
- Normally the only reason for not using '-O2' or higher is because the
-application is space sensitive and needs to be compiled with '-Os' or
-the compilation process is so time intensive that using '-O0' is the
-only way to obtain reasonable build times.
-
- If necessary the test can be disabled via the '--skip-optimization'
-option and re-enabled via the '--test-optimization' option.
+ If necessary the test can be disabled via the
+'--skip-dynamic-segment' option and re-enabled via the
+'--test-dynamic-segment' option.
\1f
-File: annobin.info, Node: Test stack prot, Next: Test stack clash, Prev: Test optimization, Up: Hardened
+File: annobin.info, Node: Test dynamic tags, Next: Test entry, Prev: Test dynamic segment, Up: Hardened
-4.2.9 The stack-prot test
--------------------------
+4.2.5 The dynamic-tags test
+---------------------------
- Problem: Attackers exploiting stack overrun bugs can gain control of an application
- Fix By: Compiling with -fstack-protector-strong
- Waive If: Don't
+ Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
+ Fix By: Compile with -mbranch-protection=standard
+ Waive If: Not running on AArch64
+ Waive If: The application will not run on Fedora 35 or later.
+ Waive If: The application will not run on newer AArch64 cores.
- Example: FAIL: stack-prot test because insufficient protection enabled
- Example: FAIL: stack-prot test because stack protection deliberately disabled
- Example: FAIL: stack-prot test because only some functions protected
- Example: FAIL: stack-prot test because insufficient Stack Safe sanitization
+ Example: FAIL: dynamic tags test because BTI_PLT and PAC_PLT flags missing from the dynamic tags
+ Example: FAIL: dynamic tags test because BTI_PLT flag is missing from the dynamic tags
+ Example: FAIL: dynamic tags test because PAC_PLT flag is missing from the dynamic tags
+ Example: FAIL: dynamic tags test because no dynamic tags found
- This test checks that the application has been compiled with stack
-protection enabled. For gcc this means using the
-'-fstack-protector-strong' option and for Clang the
-'-fsanitize=safe-stack' option. The gcc option does have some levels of
-protection other than STRONG, but STRONG is the only one that provides
-full protection.
+ AArch64 processors are vulnerable to a class of attack known as ROP
+and JOP style attacks. Preventing this kind of exploit requires
+assistance from the hardware itself, in the form of new instructions
+that need to be inserted by the compiler, and new bits in the core's
+status that need to be set.
- The stack protection feature adds checks to compiled code that
-attempt to detect buffer overflows for local buffers. These are often a
-source of vulnerability that can be exploited by an attacker.
+ This test checks to see if executable binaries have been marked as
+supporting the necessary security features to prevent this kind of
+attack. If they are marked then the runtime loader can enable the
+features in the processor core. This marking is done by setting flags
+in the tags found in the dynamic section of the executable. If the
+flags are missing then the executable is considered to be unprotected.
- If necessary the test can be disabled via the '--skip-stack-prot'
-option and re-enabled via the '--test-stack-prot' option.
+ The security features are enabled by compiling with the
+'-mbranch-protection=standard' gcc command line option.
-\1f
-File: annobin.info, Node: Test stack clash, Next: Test fortify, Prev: Test stack prot, Up: Hardened
+ Note - these security features are only found on newer versions of
+the AArch64 architecture, and they need a compiler and a loader that
+will support them. Currently this means Fedora 35 or later, but not
+RHEL.
-4.2.10 The stack-clash test
----------------------------
+ Note - this test is the inverse of the *note Test not dynamic tags::
+test and directly related to the *note Test branch protection:: test.
- Problem: Attackers exploiting stack overrun bugs can gain control of an application
- Fix By: Compiling with -fstack-clash-protection
- Waive If: Don't
+ Note - this test is automatically enabled if the '--profile-rawhide'
+options are used.
- Example: FAIL: stack-clash test because -fstack-clash-protection not enabled
+ If necessary the test can be disabled via the '--skip-dynamic-tags'
+option and re-enabled via the '--test-dynamic-tags' option.
- This test checks that the application has been compiled with stack
-clash protection enabled. If this feature is not enabled then an
-attacker could trick the application into overlapping its heap and
-stack, allowing them to alter both.
+\1f
+File: annobin.info, Node: Test entry, Next: Test fortify, Prev: Test dynamic tags, Up: Hardened
- For a full explanation of this topic see these blogs:
+4.2.6 The entry test
+--------------------
- <https://developers.redhat.com/blog/2017/09/25/stack-clash-mitigation-gcc-background>
+ Problem: Intel's CET security feature requires that the first instruction in a program be ENDBR
+ Fix By: Compile statup code with -fcf-protection
+ Waive If: The application will not run on the latest Intel hardware
- <https://developers.redhat.com/blog/2019/04/30/stack-clash-mitigation-in-gcc-why-fstack-check-is-not-the-answer>
+ Example: FAIL: entry test because instruction at entry is not ENDBR32
+ Example: FAIL: entry test because instruction at entry is not ENDBR64
- <https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3>
+ This test checks to make sure that the first instruction in a program
+for the x86 or x86_64 architectures is ENDBR. This is needed as part of
+Intel's CET security feature. (See *note Test cf protection:: for more
+details on CET).
- If necessary the test can be disabled via the '--skip-stack-clash'
-option and re-enabled via the '--test-stack-clash' option.
+ If necessary the test can be disabled via the '--skip-entry' option
+and re-enabled via the '--test-entry' option.
\1f
-File: annobin.info, Node: Test fortify, Next: Test notes, Prev: Test stack clash, Up: Hardened
+File: annobin.info, Node: Test fortify, Next: Test glibcxx assertions, Prev: Test entry, Up: Hardened
-4.2.11 The fortify test
------------------------
+4.2.7 The fortify test
+----------------------
Problem: Buffer overruns in string/memory library functions can be exploited by an attacker
Fix By: Compiling with -D_FORTIFY_SOURCE=2
and re-enabled via the '--test-fortify' option.
\1f
-File: annobin.info, Node: Test notes, Next: Test gnu relro, Prev: Test fortify, Up: Hardened
-
-4.2.12 The notes test
----------------------
-
- Problem: Lack of annobin notes in a binary means that other tests will not work properly
- Fix By: Compiling with -fplugin=annobin
- Waive If: The annobin plugin is not available
-
- Example: FAIL: notes test because gaps were detected in the annobin coverage
- Example: MAYB: notes test because not all of the .text section is covered by notes
- Example: FAIL: notes test because annobin notes were not found
+File: annobin.info, Node: Test glibcxx assertions, Next: Test gnu relro, Prev: Test fortify, Up: Hardened
- Example: MAYB: lto test because no indication that LTO was used
- Example: MAYB: stack-clash test because no notes found regarding this test
- Example: FAIL: fortify test because no indication that the necessary option was used (and a C compiler was detected)
- Example: FAIL: warnings test because no indication that the necessary option was used (and a C compiler was detected)
- Example: FAIL: stack-realign test because stack realign support is mandatory
- Example: FAIL: branch-protection test because the -mbranch-protection option was not used
+4.2.8 The glibcxx-assertions test
+---------------------------------
- This test checks that there are annobin notes covering all of the
-file. Annobin notes are generated by the compiler and describe the
-security features that have been enabled. The notes contain range
-information, so that it is possible to determine if all of an
-application has been covered by the notes, or if there are parts that
-are missing notes.
+ Problem: Compiled C++ code might contain bugs that could have been detected and fixed
+ Fix By: Compile with -D_GLIBCXX_ASSERTIONS
+ Waive If: Not compiling C++
+ Waive If: Not using functions from libstdc++
- If annobin notes are missing from a file then some of the other
-checks run by the HARDENED checker will not work, which can trigger FAIL
-or MAYB results for those tests.
+ Example: FAIL: glibcxx-assertions test because compiled without -D_GLIBCXX_ASSERTIONS
- Annobin notes are normally produced by a compiler plugin which can be
-enabled via the '-fplugin=annobin' option for gcc or Clang, and the
-'-fpass-plugin=annobin' option for LLVM. (Note for pre version-13 of
-LLVM the '-Xclang -load -Xclang annobin' option should be used instead).
+ This test checks to make sure that the '-D_GLIBCXX_ASSERTIONS' g+=
+compiler command line option was used when building binaries. This
+option is one of several supported by the LIBSTDC++ library and it is
+used to enable various NULL pointer and bounds checking security
+features. For more information see:
- Annobin notes can be generated for assembler sources by using the
-'-Wa,--generate-missing-build-notes=yes' option.
+ <https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html>
- If necessary the test can be disabled via the '--skip-notes' and
-'--ignore-gaps' options and re-enabled via the '--test-notes' and
-'--report-gaps' options.
+ If necessary the test can be disabled via the
+'--skip-glibcxx-assertions' option and re-enabled via the
+'--test-glibcxx-assertions' option.
\1f
-File: annobin.info, Node: Test gnu relro, Next: Test pie, Prev: Test notes, Up: Hardened
+File: annobin.info, Node: Test gnu relro, Next: Test gnu stack, Prev: Test glibcxx assertions, Up: Hardened
-4.2.13 The gnu-relro test
--------------------------
+4.2.9 The gnu-relro test
+------------------------
Problem: An attacker could alter how an applications interacts with shared libraries
Fix By: Link with -Wl,-z,relro,-z,now
option and re-enabled via the '--test-gnu-relro' option.
\1f
-File: annobin.info, Node: Test pie, Next: Test pic, Prev: Test gnu relro, Up: Hardened
+File: annobin.info, Node: Test gnu stack, Next: Test go revision, Prev: Test gnu relro, Up: Hardened
-4.2.14 The pie test
--------------------
+4.2.10 The gnu-stack test
+-------------------------
- Problem: Static binaries are more vulnerable to attacks
- Fix By: Link with -Wl,-pie
- Waive If: Don't
+ Problem: An attacker could place code on the stack and then run it
+ Fix By: Updating compiler, assembler sources and/or linker scripts
+ Waive If: The application *really* needs to be able to dynamically create and execute code
- Example: FAIL: pie test because not built with '-Wl,-pie' (gcc/clang) or '-buildmode pie' (go)
+ Example: FAIL: gnu-stack test because the .stack section has incorrect permissions
+ Example: FAIL: gnu-stack test because the .note.GNU-stack section has execute permission
+ Example: FAIL: gnu-stack test because the GNU stack segment has execute permission
+ Example: FAIL: gnu-stack test because the GNU stack segment does not have both read & write permissions
+ Example: FAIL: gnu-stack test because no .note.GNU-stack section found
+ Example: MAYB: gnu-stack test because multiple stack sections detected
- Programs can be compiled to either load at a fixed address in memory
-(STATIC programs) or at a random address assigned at startup time
-(DYNAMIC programs). Static programs are more vulnerable to exploits
-because an attacker will know exactly where every part of the program is
-located. Thus building dynamic executables is recommended.
+ This test checks that it is not possible to place code onto the stack
+and then execute it. Normally the stack just holds data and addresses,
+but never instructions. A favourite tactic of attackers however is to
+discover a buffer overrun bug that addresses the stack and then place
+instructions there before forcing the processor to execute them.
- This test checks that the appropriate linker option ('-pie') has been
-used to generate dynamic executables. The option is only needed for
-linking executables, not shared libraries.
+ The test actually checks several different parts of a binary file in
+order to determine that its stack is safe, which is why there are
+several different potential failure messages.
- Note - this check is related to the *note Test pic:: test. This test
-checks that the correct linker option has been used. That test checks
-that the correct compile time option has been used.
+ Most applications will have a section inserted into them by the
+compiler called .NOTE.GNU-STACK. The section has no contents, but the
+read, write, and execute attributes of the section reflect the needs of
+the application's stack.
- If necessary the test can be disabled via the '--skip-pie' option and
-re-enabled via the '--test-pie' option.
+ Ordinary compiled code should never see this problem, but the test
+failure can be triggered by programs built with an old compiler which
+does not support the .NOTE-GNU-STACK section, or if the program contains
+some assembler source files or linked with a custom made linker map.
-\1f
-File: annobin.info, Node: Test pic, Next: Test dynamic segment, Prev: Test pie, Up: Hardened
+ To fix the problem either the compiler needs to be upgraded or the
+linker map needs to be updated or the assembler sources need to be
+extended to add the .NOTE-GNU-STACK section by adding code like this:
-4.2.15 The pic test
--------------------
+ .section .note.GNU-stack,"",%progbits
- Problem: Static binaries are more vulnerable to attacks
- Fix By: Compile with -fPIC or -fPIE
- Waive If: Don't.
+ If necessary the test can be disabled via the '--skip-gnu-stack'
+option and re-enabled via the '--test-gnu-stack' option.
- Example: FAIL: pic test because -fpic/-fpie not enabled
+\1f
+File: annobin.info, Node: Test go revision, Next: Test instrumentation, Prev: Test gnu stack, Up: Hardened
- Programs can be compiled to either load at a fixed address in memory
-(STATIC programs) or at a random address assigned at startup time
-(DYNAMIC programs). Static programs are more vulnerable to exploits
-because an attacker will know exactly where every part of the program is
-located. Thus building dynamic executables is recommended.
+4.2.11 The go-revision test
+---------------------------
- This test checks that the appropriate compiler option has been used
-to generate dynamic code. For shared libraries this is the '-fPIE'
-option should be used. For dynamic executables the '-fPIC' option
-should be used. Note - there are lower case alternatives of these
-options (ie '-fpie' and '-fpic') which can also be used. The difference
-between the lower case and upper case versions is architecture
-dependent, but usually the lower case version will only work with
-smaller programs, wheres the upper case version works for all program
-sizes.
+ Problem: Using old versions of the GO compiler looses out on security enhacements
+ Fix By: Using a newer GO compiler
+ Waive If: No new GO compiler is available
- Note - this check is related to the *note Test pie:: test. This test
-checks that the correct compile time option has been used. That test
-checks that the correct link time option has been used.
+ Example: FAIL: go-revision test because GO revision must be >= 14
+ Example: FAIL: go-revision test because multiple, different GO version strings found
+ Example: FAIL: go-revision test because no Go compiler revision information found
- If necessary the test can be disabled via the '--skip-pic' option and
-re-enabled via the '--test-pic' option.
+ This test checks to see that GO code has been compiled by at least a
+revision 14 compiler. Earlier versions of the compiler do not have all
+the bug fixes and security enhancements of later versions.
+
+ Note - it is likely that the minimum revision of the GO compiler will
+be increased in the future.
+
+ If necessary the test can be disabled via the '--skip-go-revision'
+option and re-enabled via the '--test-go-revision' option.
\1f
-File: annobin.info, Node: Test dynamic segment, Next: Test dynamic tags, Prev: Test pic, Up: Hardened
+File: annobin.info, Node: Test instrumentation, Next: Test lto, Prev: Test go revision, Up: Hardened
-4.2.16 The dynamic-segment test
+4.2.12 The instrumentation test
-------------------------------
- Problem: Programs with more than one dynamic section will not be loaded properly
- Fix By: Fix assembler source code and/or linker script
- Waive If: Don't.
+ Problem: Instrumented binaries are bigger and slower than regular binaries
+ Fix By: Removing instrumentation options from compiler command line
+ Waive If: Instrumentation is needed.
- Example: FAIL: dynamic segment test because multiple dynamic sections detected
+ Example: WARN: Instrumentation enabled - this is probably a mistake for production binaries
- Dynamic executables must have a dynamic section which contains
-information that is used by the loader at program startup. The loader
-however only expects there to be one dynamic section in a program, and
-it does not cope it there are more than one. Normally this is not an
-issue however as the linker will ensure that there is only one dynamic
-section. It is possible however to use a custom linker script to create
-more than one dynamic section, or to write some assembler code
-specifically designed to create multiple dynamic sections.
+ This test checks to see if any of gcc's instrumentation command line
+options have been used when the binary built. These options are:
+'_fsanitize', '-finstrument-functions', '-p', '-pg', and
+'-fprofile-arcs'.
- If necessary the test can be disabled via the
-'--skip-dynamic-segment' option and re-enabled via the
-'--test-dynamic-segment' option.
+ There is no way to disable this test.
\1f
-File: annobin.info, Node: Test dynamic tags, Next: Test not dynamic tags, Prev: Test dynamic segment, Up: Hardened
+File: annobin.info, Node: Test lto, Next: Test not branch protection, Prev: Test instrumentation, Up: Hardened
-4.2.17 The dynamic-tags test
-----------------------------
+4.2.13 The lto test
+-------------------
- Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
- Fix By: Compile with -mbranch-protection=standard
- Waive If: Not running on AArch64
- Waive If: The application will not run on Fedora 35 or later.
- Waive If: The application will not run on newer AArch64 cores.
+ Problem: Mixed use of LTO and non-LTO binaries indicates a problem with the build system
+ Fix By: Using -flto consistently
+ Waive If: LTO building is not wanted
- Example: FAIL: dynamic tags test because BTI_PLT and PAC_PLT flags missing from the dynamic tags
- Example: FAIL: dynamic tags test because BTI_PLT flag is missing from the dynamic tags
- Example: FAIL: dynamic tags test because PAC_PLT flag is missing from the dynamic tags
- Example: FAIL: dynamic tags test because no dynamic tags found
+ Example: FAIL: lto test because compiled with both -flto and -fno-lto
- AArch64 processors are vulnerable to a class of attack known as ROP
-and JOP style attacks. Preventing this kind of exploit requires
-assistance from the hardware itself, in the form of new instructions
-that need to be inserted by the compiler, and new bits in the core's
-status that need to be set.
+ This test checks to see if the '-flto' compiler command line option
+was used. Whilst this option can produce better code, its use is not
+essential, hence this test currently only checks to see if both the
+'-flto' and the '-fno-lto' options were used together.
- This test checks to see if executable binaries have been marked as
-supporting the necessary security features to prevent this kind of
-attack. If they are marked then the runtime loader can enable the
-features in the processor core. This marking is done by setting flags
-in the tags found in the dynamic section of the executable. If the
-flags are missing then the executable is considered to be unprotected.
+ If necessary the test can be disabled via the '--skip-lto' option and
+re-enabled via the '--test-lto' option.
- The security features are enabled by compiling with the
-'-mbranch-protection=standard' gcc command line option.
+\1f
+File: annobin.info, Node: Test not branch protection, Next: Test not dynamic tags, Prev: Test lto, Up: Hardened
- Note - these security features are only found on newer versions of
-the AArch64 architecture, and they need a compiler and a loader that
-will support them. Currently this means Fedora 35 or later, but not
-RHEL.
+4.2.14 The not-branch-protection test
+-------------------------------------
- Note - this test is the inverse of the *note Test not dynamic tags::
-test and directly related to the *note Test branch protection:: test.
+ Problem: Protecting AArch64 binaries needs newer versions of AArch64 cores
+ Fix By: Compile with -mbranch-protection=none
+ Waive If: Not running on AArch64
+ Waive If: The application will run on Fedora 35 or later.
+ Waive If: The application will not run on newer AArch64 cores.
- Note - this test is automatically enabled if the '--profile-rawhide'
-options are used.
+ Example: FAIL: not branch protection test because protection enabled
+ Example: FAIL: not branch protection test because only partially disabled
- If necessary the test can be disabled via the '--skip-dynamic-tags'
-option and re-enabled via the '--test-dynamic-tags' option.
+ Note - this test is the inverse of the *note Test branch protection::
+test and directly related to the *note Test not dynamic tags:: test.
+
+ This test checks to see if the compile time option to enable the
+AArch64 branch protection security feature was used. This feature is
+only supported on newer versions of AArch64 core, and will not work on
+older cores. Hence this test checks to make sure that the option was
+not used, or was used but was set to disable the feature.
+
+ The security features can be disabled by compiling with the
+'-mbranch-protection=none' gcc command line option.
+
+ Note - this test is automatically enabled if the '--profile-el7' or
+'--profile-el9' options are used.
+
+ If necessary the test can be disabled via the
+'--skip-not-branch-protection' option and re-enabled via the
+'--test-not-branch-protection' option.
\1f
-File: annobin.info, Node: Test not dynamic tags, Next: Test branch protection, Prev: Test dynamic tags, Up: Hardened
+File: annobin.info, Node: Test not dynamic tags, Next: Test notes, Prev: Test not branch protection, Up: Hardened
-4.2.18 The not-dynamic-tags test
+4.2.15 The not-dynamic-tags test
--------------------------------
Problem: Protecting AArch64 binaries needs newer versions of AArch64 cores
'--test-not-dynamic-tags' option.
\1f
-File: annobin.info, Node: Test branch protection, Next: Test not branch protection, Prev: Test not dynamic tags, Up: Hardened
+File: annobin.info, Node: Test notes, Next: Test only go, Prev: Test not dynamic tags, Up: Hardened
-4.2.19 The branch-protection test
----------------------------------
+4.2.16 The notes test
+---------------------
- Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
- Fix By: Compile with -mbranch-protection=standard
- Waive If: Not running on AArch64
- Waive If: The application will not run on Fedora 35 or later.
- Waive If: The application will not run on newer AArch64 cores.
+ Problem: Lack of annobin notes in a binary means that other tests will not work properly
+ Fix By: Compiling with -fplugin=annobin
+ Waive If: The annobin plugin is not available
- Example: FAIL: branch protection test because not enabled
- Example: FAIL: branch protection test because only partially enabled
- Example: FAIL: branch protection test because .note.gnu.property section not found (it is needed for branch protection support)
- Example: FAIL: branch protection test because the -mbranch-protection option was not used
+ Example: FAIL: notes test because gaps were detected in the annobin coverage
+ Example: MAYB: notes test because not all of the .text section is covered by notes
+ Example: FAIL: notes test because annobin notes were not found
- AArch64 processors are vulnerable to a class of attack known as ROP
-and JOP style attacks. Preventing this kind of exploit requires
-assistance from the hardware itself, in the form of new instructions
-that need to be inserted by the compiler, and new bits in the core's
-status that need to be set.
+ Example: MAYB: lto test because no indication that LTO was used
+ Example: MAYB: stack-clash test because no notes found regarding this test
+ Example: FAIL: fortify test because no indication that the necessary option was used (and a C compiler was detected)
+ Example: FAIL: warnings test because no indication that the necessary option was used (and a C compiler was detected)
+ Example: FAIL: stack-realign test because stack realign support is mandatory
+ Example: FAIL: branch-protection test because the -mbranch-protection option was not used
- This test checks to see if the compile time option to enable the
-security feature was used. There are four levels of security available,
-ranging from none through partial (some functions are protected others
-are not) to full. The test checks that full security has been enabled.
+ This test checks that there are annobin notes covering all of the
+file. Annobin notes are generated by the compiler and describe the
+security features that have been enabled. The notes contain range
+information, so that it is possible to determine if all of an
+application has been covered by the notes, or if there are parts that
+are missing notes.
- The security feature is enabled by compiling with the
-'-mbranch-protection=standard' gcc command line option.
+ If annobin notes are missing from a file then some of the other
+checks run by the HARDENED checker will not work, which can trigger FAIL
+or MAYB results for those tests.
- Note - these security features are only found on newer versions of
-the AArch64 architecture, and they need a compiler and a loader that
-will support them. Currently this means Fedora 35 or later, but not
-RHEL.
+ Annobin notes are normally produced by a compiler plugin which can be
+enabled via the '-fplugin=annobin' option for gcc or Clang, and the
+'-fpass-plugin=annobin' option for LLVM. (Note for pre version-13 of
+LLVM the '-Xclang -load -Xclang annobin' option should be used instead).
- Note - this test is the inverse of the *note Test not branch
-protection:: test and directly related to the *note Test dynamic tags::
-test.
+ Annobin notes can be generated for assembler sources by using the
+'-Wa,--generate-missing-build-notes=yes' option.
- Note - this test is automatically enabled if the '--profile-rawhide'
-options are used.
+ If necessary the test can be disabled via the '--skip-notes' and
+'--ignore-gaps' options and re-enabled via the '--test-notes' and
+'--report-gaps' options.
- If necessary the test can be disabled via the
-'--skip-branch-protection' option and re-enabled via the
-'--test-branch-protection' option.
+\1f
+File: annobin.info, Node: Test only go, Next: Test optimization, Prev: Test notes, Up: Hardened
+
+4.2.17 The only-go test
+-----------------------
+
+ Problem: Mixing GO and C is unsafe on x86 platforms
+ Fix By: Using a new GO compiler
+ Waive If: Always
+
+ Example: FAIL: only-go test because combining GO and non-GO object files on x86 systems is not safe - it disables CET
+
+ Note - this test is currently disabled. The GO compiler's lack of
+support for CET is a known issue that cannot be addressed by package
+maintainers. Hence there is no point in issuing an error message.
+
+ This test checks to see if GO and C are being used together in the
+same program. This is a problem for code that is going to run on x86
+architectures as the GO compiler does not support Intel's CET
+technology. (See *note Test cf protection:: for more details on CET).
+The GO language is inheritantly safer than C, but if the two are mixed,
+then the C parts will be missing out on the protection offered by CET.
+
+ If necessary the test can be disabled via the '--skip-only-go' option
+and re-enabled via the '--test-only-go' option.
\1f
-File: annobin.info, Node: Test not branch protection, Next: Test short enums, Prev: Test branch protection, Up: Hardened
+File: annobin.info, Node: Test optimization, Next: Test pic, Prev: Test only go, Up: Hardened
-4.2.20 The not-branch-protection test
--------------------------------------
+4.2.18 The optimization test
+----------------------------
- Problem: Protecting AArch64 binaries needs newer versions of AArch64 cores
- Fix By: Compile with -mbranch-protection=none
- Waive If: Not running on AArch64
- Waive If: The application will run on Fedora 35 or later.
- Waive If: The application will not run on newer AArch64 cores.
+ Problem: Insufficient optimization prevents security features from working
+ Fix By: Compiling with -O2
+ Waive If: The application does not use string/memory functions
- Example: FAIL: not branch protection test because protection enabled
- Example: FAIL: not branch protection test because only partially disabled
+ Example: FAIL: optimization test because optimization level too low
+ Example: FAIL: optimization test because level too low
+ Example: MAYB: optimization test because no valid notes found regarding this test
- Note - this test is the inverse of the *note Test branch protection::
-test and directly related to the *note Test not dynamic tags:: test.
+ This test checks that the application was compiled with sufficient
+optimization enabled.
- This test checks to see if the compile time option to enable the
-AArch64 branch protection security feature was used. This feature is
-only supported on newer versions of AArch64 core, and will not work on
-older cores. Hence this test checks to make sure that the option was
-not used, or was used but was set to disable the feature.
+ The C library security hardening features enabled via the
+'-D_FORTIFY_SOURCE=2' or '-D_FORTIFY_SOURCE=3' preprocessor command line
+options will only work properly if the compiler is run at an
+optimization level of at least '-O2'. Hence this test checks to make
+sure that this level (or higher) has been used.
- The security features can be disabled by compiling with the
-'-mbranch-protection=none' gcc command line option.
+ Normally the only reason for not using '-O2' or higher is because the
+application is space sensitive and needs to be compiled with '-Os' or
+the compilation process is so time intensive that using '-O0' is the
+only way to obtain reasonable build times.
- Note - this test is automatically enabled if the '--profile-el7' or
-'--profile-el9' options are used.
+ If necessary the test can be disabled via the '--skip-optimization'
+option and re-enabled via the '--test-optimization' option.
- If necessary the test can be disabled via the
-'--skip-not-branch-protection' option and re-enabled via the
-'--test-not-branch-protection' option.
+\1f
+File: annobin.info, Node: Test pic, Next: Test pie, Prev: Test optimization, Up: Hardened
+
+4.2.19 The pic test
+-------------------
+
+ Problem: Static binaries are more vulnerable to attacks
+ Fix By: Compile with -fPIC or -fPIE
+ Waive If: Don't.
+
+ Example: FAIL: pic test because -fpic/-fpie not enabled
+
+ Programs can be compiled to either load at a fixed address in memory
+(STATIC programs) or at a random address assigned at startup time
+(DYNAMIC programs). Static programs are more vulnerable to exploits
+because an attacker will know exactly where every part of the program is
+located. Thus building dynamic executables is recommended.
+
+ This test checks that the appropriate compiler option has been used
+to generate dynamic code. For shared libraries this is the '-fPIE'
+option should be used. For dynamic executables the '-fPIC' option
+should be used. Note - there are lower case alternatives of these
+options (ie '-fpie' and '-fpic') which can also be used. The difference
+between the lower case and upper case versions is architecture
+dependent, but usually the lower case version will only work with
+smaller programs, wheres the upper case version works for all program
+sizes.
+
+ Note - this check is related to the *note Test pie:: test. This test
+checks that the correct compile time option has been used. That test
+checks that the correct link time option has been used.
+
+ If necessary the test can be disabled via the '--skip-pic' option and
+re-enabled via the '--test-pic' option.
+
+\1f
+File: annobin.info, Node: Test pie, Next: Test production, Prev: Test pic, Up: Hardened
+
+4.2.20 The pie test
+-------------------
+
+ Problem: Static binaries are more vulnerable to attacks
+ Fix By: Link with -Wl,-pie
+ Waive If: Don't
+
+ Example: FAIL: pie test because not built with '-Wl,-pie' (gcc/clang) or '-buildmode pie' (go)
+
+ Programs can be compiled to either load at a fixed address in memory
+(STATIC programs) or at a random address assigned at startup time
+(DYNAMIC programs). Static programs are more vulnerable to exploits
+because an attacker will know exactly where every part of the program is
+located. Thus building dynamic executables is recommended.
+
+ This test checks that the appropriate linker option ('-pie') has been
+used to generate dynamic executables. The option is only needed for
+linking executables, not shared libraries.
+
+ Note - this check is related to the *note Test pic:: test. This test
+checks that the correct linker option has been used. That test checks
+that the correct compile time option has been used.
+
+ If necessary the test can be disabled via the '--skip-pie' option and
+re-enabled via the '--test-pie' option.
+
+\1f
+File: annobin.info, Node: Test production, Next: Test property note, Prev: Test pie, Up: Hardened
+
+4.2.21 The production test
+--------------------------
+
+ Problem: Shipping code generated by an experimental compiler is bad
+ Fix By: Compile with a production ready compiler
+ Waive If: The code is never going to be shipped
+
+ Example: FAIL: production test because a production-ready compiler was not used to build the binary
+
+ This test checks to make sure that the binary was not produced by an
+experimental compiler. Experimental compilers can be detected by
+examining their version information, which will include the string
+NOT_FOR_PRODUCTION.
+
+ If necessary the test can be disabled via the '--skip-production'
+option and re-enabled via the '--test-production' option.
+
+\1f
+File: annobin.info, Node: Test property note, Next: Test run path, Prev: Test production, Up: Hardened
+
+4.2.22 The property-note test
+-----------------------------
+
+ Problem: Badly formed or missing GNU property notes can compromise an application at runtime
+ Fix By: Investigate and fix the creation of the notes
+ Waive If: Using old tools that do not generate the notes
+
+ Example: FAIL: property-note test because there is more than one GNU Property note
+ Example: FAIL: property-note test because the property note does not have expected name
+ Example: FAIL: property-note test because the property note data has the wrong size
+ Example: FAIL: property-note test because the note section is present but empty
+ Example: FAIL: property-note test because the property note data has an invalid size
+ Example: FAIL: property-note test because the IBT property is not enabled
+ Example: FAIL: property-note test because the SHSTK property is not enabled
+ Example: FAIL: property-note test because unexpected property note type
+ Example: FAIL: property-note test because the BTI property is not enabled
+ Example: FAIL: property-note test because the GNU Property note segment not 8 byte aligned
+ Example: FAIL: property-note test because there is more than one GNU Property note in the note segment
+ Example: FAIL: property-note test because .note.gnu.property section not found (it is needed for branch protection support
+ Example: FAIL: property-note test because no .note.gnu.property section = no control flow information
+ Example: FAIL: property-note test because control flow protection is not enabled
+
+ GNU property notes are special markers in binary files that provide
+information about the program to the runtime loader. This information
+is architecture specific and it often includes details about any
+security features that were enabled when the program was compiled.
+
+ This test checks that the property note is present - if needed for
+the particular architcture - and that it is properly formatted.
+
+ Problems with property notes are usually related to other security
+options being missing, or the use of assembler source files which do not
+contain their own instructions for creating property notes.
+
+ If necessary the test can be disabled via the '--skip-property-note'
+option and re-enabled via the '--test-property-note' option.
+
+\1f
+File: annobin.info, Node: Test run path, Next: Test rwx seg, Prev: Test property note, Up: Hardened
+
+4.2.23 The run-path test
+------------------------
+
+ Problem: An attacker could cause an application to use a corrupted shared library
+ Fix By: Compiling with -Wl,--enable-new-dtags or moving the shared libraries needed to a proper location
+ Waive If: The application uses shared libraries held in non-standard locations
+ Waive If: The linker does not support --enable-new-dtags
+
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag is corrupt
+ Example: MAYB: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag exists but is empty
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag contains a path that does not start with /usr
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has a path that contains '..'
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has $ORIGIN after a non-$ORIGIN path
+ Example: MAYB: run-path test because the RPATH dynamic tag is deprecated. Link with --enable-new-dtags to use RUNPATH instead
+
+ An application that uses shared libraries contains information on how
+to locate those libraries. This information is a list of directories
+which should be searched for the libraries. The test checks that the
+list is secure.
+
+ The test actually covers several different aspects, such as all
+directory paths must be absolute, start with /USR and must not contain
+... If any of these rules are broken then an attacker might be able to
+exploit the search paths to force the application to load their own,
+corrupted version of a shared library.
+
+ Normally this test will only be triggered if an application is linked
+by an old linker which does not support the generation of the new format
+DT_RUNPATH search paths. Or if it is linked against shared libraries
+which do not reside in standard locations. Fixing the test depends upon
+whether these issues can be solved.
+
+ If necessary the test can be disabled via the '--skip-run-path'
+option and re-enabled via the '--test-run-path' option.
+
+\1f
+File: annobin.info, Node: Test rwx seg, Next: Test short enums, Prev: Test run path, Up: Hardened
+
+4.2.24 The rwx-seg test
+-----------------------
+
+ Problem: An attacker could add their own code to an executable
+ Fix By: Changing the linker script used to create the binary
+ Waive If: Don't.
+
+ Example: FAIL: rwx-seg test because segment has Read, Write and eXecute flags set
+
+ This test checks that the file does not have any segments that have
+all three of the READ, WRITE and EXECUTE permissions. Code segments
+should have read and execute permissions, but they should not be
+writable as otherwise an attacker can overwrite the code. Data segments
+should have read permission, and possibly write permission as well, but
+never execute permission as otherwise an attacker might be able to
+create their own code in a data area.
+
+ The linker will normally never create a binary file with a segment
+with all three permissions, but it is possible to force it to do so by
+using a custom linker script. If this flaw is detected then whatever
+linker script is being used should be corrected to remove the problem.
+
+ If necessary the test can be disabled via the '--skip-rwx-seg' option
+and re-enabled via the '--test-rwx-seg' option.
\1f
-File: annobin.info, Node: Test short enums, Next: Test stack realign, Prev: Test not branch protection, Up: Hardened
+File: annobin.info, Node: Test short enums, Next: Test stack clash, Prev: Test rwx seg, Up: Hardened
-4.2.21 The short-enums test
+4.2.25 The short-enums test
---------------------------
Problem: Compiler options can change the size of enums
option and re-enabled via the '--test-short-enums' option.
\1f
-File: annobin.info, Node: Test stack realign, Next: Test production, Prev: Test short enums, Up: Hardened
+File: annobin.info, Node: Test stack clash, Next: Test stack prot, Prev: Test short enums, Up: Hardened
+
+4.2.26 The stack-clash test
+---------------------------
+
+ Problem: Attackers exploiting stack overrun bugs can gain control of an application
+ Fix By: Compiling with -fstack-clash-protection
+ Waive If: Don't
+
+ Example: FAIL: stack-clash test because -fstack-clash-protection not enabled
+
+ This test checks that the application has been compiled with stack
+clash protection enabled. If this feature is not enabled then an
+attacker could trick the application into overlapping its heap and
+stack, allowing them to alter both.
+
+ For a full explanation of this topic see these blogs:
+
+ <https://developers.redhat.com/blog/2017/09/25/stack-clash-mitigation-gcc-background>
+
+ <https://developers.redhat.com/blog/2019/04/30/stack-clash-mitigation-in-gcc-why-fstack-check-is-not-the-answer>
+
+ <https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3>
+
+ If necessary the test can be disabled via the '--skip-stack-clash'
+option and re-enabled via the '--test-stack-clash' option.
+
+\1f
+File: annobin.info, Node: Test stack prot, Next: Test stack realign, Prev: Test stack clash, Up: Hardened
+
+4.2.27 The stack-prot test
+--------------------------
+
+ Problem: Attackers exploiting stack overrun bugs can gain control of an application
+ Fix By: Compiling with -fstack-protector-strong
+ Waive If: Don't
+
+ Example: FAIL: stack-prot test because insufficient protection enabled
+ Example: FAIL: stack-prot test because stack protection deliberately disabled
+ Example: FAIL: stack-prot test because only some functions protected
+ Example: FAIL: stack-prot test because insufficient Stack Safe sanitization
+
+ This test checks that the application has been compiled with stack
+protection enabled. For gcc this means using the
+'-fstack-protector-strong' option and for Clang the
+'-fsanitize=safe-stack' option. The gcc option does have some levels of
+protection other than STRONG, but STRONG is the only one that provides
+full protection.
+
+ The stack protection feature adds checks to compiled code that
+attempt to detect buffer overflows for local buffers. These are often a
+source of vulnerability that can be exploited by an attacker.
+
+ If necessary the test can be disabled via the '--skip-stack-prot'
+option and re-enabled via the '--test-stack-prot' option.
+
+\1f
+File: annobin.info, Node: Test stack realign, Next: Test textrel, Prev: Test stack prot, Up: Hardened
-4.2.22 The stack-realign test
+4.2.28 The stack-realign test
-----------------------------
Problem: Legacy x86 code is incompatible with SSE instructions
option and re-enabled via the '--test-stack-realign' option.
\1f
-File: annobin.info, Node: Test production, Next: Test lto, Prev: Test stack realign, Up: Hardened
-
-4.2.23 The production test
---------------------------
-
- Problem: Shipping code generated by an experimental compiler is bad
- Fix By: Compile with a production ready compiler
- Waive If: The code is never going to be shipped
-
- Example: FAIL: production test because a production-ready compiler was not used to build the binary
-
- This test checks to make sure that the binary was not produced by an
-experimental compiler. Experimental compilers can be detected by
-examining their version information, which will include the string
-NOT_FOR_PRODUCTION.
-
- If necessary the test can be disabled via the '--skip-production'
-option and re-enabled via the '--test-production' option.
-
-\1f
-File: annobin.info, Node: Test lto, Next: Test property note, Prev: Test production, Up: Hardened
-
-4.2.24 The lto test
--------------------
-
- Problem: Mixed use of LTO and non-LTO binaries indicates a problem with the build system
- Fix By: Using -flto consistently
- Waive If: LTO building is not wanted
-
- Example: FAIL: lto test because compiled with both -flto and -fno-lto
-
- This test checks to see if the '-flto' compiler command line option
-was used. Whilst this option can produce better code, its use is not
-essential, hence this test currently only checks to see if both the
-'-flto' and the '-fno-lto' options were used together.
-
- If necessary the test can be disabled via the '--skip-lto' option and
-re-enabled via the '--test-lto' option.
-
-\1f
-File: annobin.info, Node: Test property note, Next: Test threads, Prev: Test lto, Up: Hardened
-
-4.2.25 The property-note test
------------------------------
+File: annobin.info, Node: Test textrel, Next: Test threads, Prev: Test stack realign, Up: Hardened
- Problem: Badly formed or missing GNU property notes can compromise an application at runtime
- Fix By: Investigate and fix the creation of the notes
- Waive If: Using old tools that do not generate the notes
+4.2.29 The textrel test
+-----------------------
- Example: FAIL: property-note test because there is more than one GNU Property note
- Example: FAIL: property-note test because the property note does not have expected name
- Example: FAIL: property-note test because the property note data has the wrong size
- Example: FAIL: property-note test because the note section is present but empty
- Example: FAIL: property-note test because the property note data has an invalid size
- Example: FAIL: property-note test because the IBT property is not enabled
- Example: FAIL: property-note test because the SHSTK property is not enabled
- Example: FAIL: property-note test because unexpected property note type
- Example: FAIL: property-note test because the BTI property is not enabled
- Example: FAIL: property-note test because the GNU Property note segment not 8 byte aligned
- Example: FAIL: property-note test because there is more than one GNU Property note in the note segment
- Example: FAIL: property-note test because .note.gnu.property section not found (it is needed for branch protection support
- Example: FAIL: property-note test because no .note.gnu.property section = no control flow information
- Example: FAIL: property-note test because control flow protection is not enabled
+ Problem: An attacker could change the code in an executable
+ Fix By: Compiling with -fPIC enabled
+ Waive If: The code _must_ be static
- GNU property notes are special markers in binary files that provide
-information about the program to the runtime loader. This information
-is architecture specific and it often includes details about any
-security features that were enabled when the program was compiled.
+ Example: FAIL: textrel test because the DT_TEXTREL tag was detected
- This test checks that the property note is present - if needed for
-the particular architcture - and that it is properly formatted.
+ This test checks to make sure that a binary file does not contain any
+relocations that alter the contents of a code section. Relocations are
+special instructions that the program loader uses to alter pieces of a
+application when it starts up. Normally these relocations are
+restricted to altering the application's data, but if any of them alter
+its code then an attacker might be able to exploit this to change the
+program.
- Problems with property notes are usually related to other security
-options being missing, or the use of assembler source files which do not
-contain their own instructions for creating property notes.
+ This problem usually only arises when a binary is built to execute at
+a fixed address. Such binaries need text relocations to help them run
+at the address chosen. The safest solution therefore is to compile the
+binary to be position independent by using the '-fPIC' or '-fPIE'
+compiler command line options.
- If necessary the test can be disabled via the '--skip-property-note'
-option and re-enabled via the '--test-property-note' option.
+ If necessary the test can be disabled via the '--skip-textrel' option
+and re-enabled via the '--test-textrel' option.
\1f
-File: annobin.info, Node: Test threads, Next: Test glibcxx assertions, Prev: Test property note, Up: Hardened
+File: annobin.info, Node: Test threads, Next: Test warnings, Prev: Test textrel, Up: Hardened
-4.2.26 The threads test
+4.2.30 The threads test
-----------------------
Problem: Programs that do not support exceptions are more vulnerable to attacks
and re-enabled via the '--test-threads' option.
\1f
-File: annobin.info, Node: Test glibcxx assertions, Next: Test entry, Prev: Test threads, Up: Hardened
-
-4.2.27 The glibcxx-assertions test
-----------------------------------
-
- Problem: Compiled C++ code might contain bugs that could have been detected and fixed
- Fix By: Compile with -D_GLIBCXX_ASSERTIONS
- Waive If: Not compiling C++
- Waive If: Not using functions from libstdc++
-
- Example: FAIL: glibcxx-assertions test because compiled without -D_GLIBCXX_ASSERTIONS
-
- This test checks to make sure that the '-D_GLIBCXX_ASSERTIONS' g+=
-compiler command line option was used when building binaries. This
-option is one of several supported by the LIBSTDC++ library and it is
-used to enable various NULL pointer and bounds checking security
-features. For more information see:
-
- <https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html>
-
- If necessary the test can be disabled via the
-'--skip-glibcxx-assertions' option and re-enabled via the
-'--test-glibcxx-assertions' option.
-
-\1f
-File: annobin.info, Node: Test entry, Next: Test go revision, Prev: Test glibcxx assertions, Up: Hardened
-
-4.2.28 The entry test
----------------------
-
- Problem: Intel's CET security feature requires that the first instruction in a program be ENDBR
- Fix By: Compile statup code with -fcf-protection
- Waive If: The application will not run on the latest Intel hardware
-
- Example: FAIL: entry test because instruction at entry is not ENDBR32
- Example: FAIL: entry test because instruction at entry is not ENDBR64
-
- This test checks to make sure that the first instruction in a program
-for the x86 or x86_64 architectures is ENDBR. This is needed as part of
-Intel's CET security feature. (See *note Test cf protection:: for more
-details on CET).
-
- If necessary the test can be disabled via the '--skip-entry' option
-and re-enabled via the '--test-entry' option.
-
-\1f
-File: annobin.info, Node: Test go revision, Next: Test only go, Prev: Test entry, Up: Hardened
-
-4.2.29 The go-revision test
----------------------------
-
- Problem: Using old versions of the GO compiler looses out on security enhacements
- Fix By: Using a newer GO compiler
- Waive If: No new GO compiler is available
-
- Example: FAIL: go-revision test because GO revision must be >= 14
- Example: FAIL: go-revision test because multiple, different GO version strings found
- Example: FAIL: go-revision test because no Go compiler revision information found
-
- This test checks to see that GO code has been compiled by at least a
-revision 14 compiler. Earlier versions of the compiler do not have all
-the bug fixes and security enhancements of later versions.
-
- Note - it is likely that the minimum revision of the GO compiler will
-be increased in the future.
-
- If necessary the test can be disabled via the '--skip-go-revision'
-option and re-enabled via the '--test-go-revision' option.
-
-\1f
-File: annobin.info, Node: Test only go, Next: Test warnings, Prev: Test go revision, Up: Hardened
-
-4.2.30 The only-go test
------------------------
-
- Problem: Mixing GO and C is unsafe on x86 platforms
- Fix By: Using a new GO compiler
- Waive If: Always
-
- Example: FAIL: only-go test because combining GO and non-GO object files on x86 systems is not safe - it disables CET
-
- Note - this test is currently disabled. The GO compiler's lack of
-support for CET is a known issue that cannot be addressed by package
-maintainers. Hence there is no point in issuing an error message.
-
- This test checks to see if GO and C are being used together in the
-same program. This is a problem for code that is going to run on x86
-architectures as the GO compiler does not support Intel's CET
-technology. (See *note Test cf protection:: for more details on CET).
-The GO language is inheritantly safer than C, but if the two are mixed,
-then the C parts will be missing out on the protection offered by CET.
-
- If necessary the test can be disabled via the '--skip-only-go' option
-and re-enabled via the '--test-only-go' option.
-
-\1f
-File: annobin.info, Node: Test warnings, Next: Test instrumentation, Prev: Test only go, Up: Hardened
+File: annobin.info, Node: Test warnings, Next: Test writable got, Prev: Test threads, Up: Hardened
4.2.31 The warnings test
------------------------
option and re-enabled via the '--test-warnings' option.
\1f
-File: annobin.info, Node: Test instrumentation, Next: Hardened Command Line Options, Prev: Test warnings, Up: Hardened
+File: annobin.info, Node: Test writable got, Next: Hardened Command Line Options, Prev: Test warnings, Up: Hardened
-4.2.32 The instrumentation test
--------------------------------
+4.2.32 The writable-got test
+----------------------------
- Problem: Instrumented binaries are bigger and slower than regular binaries
- Fix By: Removing instrumentation options from compiler command line
- Waive If: Instrumentation is needed.
+ Problem: An attacker could intercept and redirect shared library function calls
+ Fix By: Link with -Wl,--secure-plt
+ Waive If: No shared libraries are used
- Example: WARN: Instrumentation enabled - this is probably a mistake for production binaries
+ Example: FAIL: writable-got test because the GOT/PLT relocs are writable
- This test checks to see if any of gcc's instrumentation command line
-options have been used when the binary built. These options are:
-'_fsanitize', '-finstrument-functions', '-p', '-pg', and
-'-fprofile-arcs'.
+ This test checks that the instructions to set up the GOT and PLT
+tables in a dynamic executable cannot be altered by an outside source.
- There is no way to disable this test.
+ Dynamic executables use two tables to help them connect to shared
+libraries. These tables - the GOT and the PLT - are set up when the
+program runs, based upon instructions held in special sections in the
+file. If these sections are writable then an attacker could change
+their contents and thus cause the program to call the wrong functions in
+the shared libraries.
+
+ Under normal circumstances this test should never fail. If it does
+then something unusual is going on. One possible cure is to add the
+'-Wl,--secure-plt' option to the final link command line.
+
+ If necessary the test can be disabled via the '--skip-writable-got'
+option and re-enabled via the '--test-writable-got' option.
\1f
-File: annobin.info, Node: Hardened Command Line Options, Next: Waiving Hardened Results, Prev: Test instrumentation, Up: Hardened
+File: annobin.info, Node: Hardened Command Line Options, Next: Waiving Hardened Results, Prev: Test writable got, Up: Hardened
4.2.33 Command line options specific to the hardened tool
---------------------------------------------------------
Node: Annocheck\7f21775
Node: Built By\7f25665
Node: Hardened\7f27168
-Node: Test bind now\7f30682
-Node: Test gnu stack\7f32225
-Node: Test writable got\7f34620
-Node: Test rwx seg\7f35888
-Node: Test textrel\7f37158
-Node: Test run path\7f38408
-Node: Test cf protection\7f40603
-Node: Test optimization\7f44551
-Node: Test stack prot\7f45937
-Node: Test stack clash\7f47266
-Node: Test fortify\7f48413
-Node: Test notes\7f49835
-Node: Test gnu relro\7f52111
-Node: Test pie\7f53828
-Node: Test pic\7f55029
-Node: Test dynamic segment\7f56577
-Node: Test dynamic tags\7f57700
-Node: Test not dynamic tags\7f59988
-Node: Test branch protection\7f61620
-Node: Test not branch protection\7f63818
-Node: Test short enums\7f65350
-Node: Test stack realign\7f66383
-Node: Test production\7f67657
-Node: Test lto\7f68470
-Node: Test property note\7f69258
-Node: Test threads\7f71727
-Node: Test glibcxx assertions\7f72559
-Node: Test entry\7f73595
-Node: Test go revision\7f74502
-Node: Test only go\7f75538
-Node: Test warnings\7f76691
-Node: Test instrumentation\7f77529
-Node: Hardened Command Line Options\7f78282
-Node: Waiving Hardened Results\7f81477
-Node: Notes\7f82861
-Node: Size\7f83497
-Node: Timing\7f85640
-Node: Configure Options\7f86279
-Node: Legacy Scripts\7f88618
-Node: Who Built Me\7f89393
-Node: ABI Checking\7f92153
-Node: Hardening Checks\7f94269
-Node: Checking Archives\7f98355
-Node: GNU FDL\7f100776
+Node: Test bind now\7f30912
+Node: Test branch protection\7f32463
+Node: Test cf protection\7f34643
+Node: Test dynamic segment\7f38603
+Node: Test dynamic tags\7f39734
+Node: Test entry\7f42009
+Node: Test fortify\7f42904
+Node: Test glibcxx assertions\7f44331
+Node: Test gnu relro\7f45369
+Node: Test gnu stack\7f47103
+Node: Test go revision\7f49500
+Node: Test instrumentation\7f50548
+Node: Test lto\7f51283
+Node: Test not branch protection\7f52084
+Node: Test not dynamic tags\7f53607
+Node: Test notes\7f55236
+Node: Test only go\7f57519
+Node: Test optimization\7f58670
+Node: Test pic\7f60045
+Node: Test pie\7f61590
+Node: Test production\7f62792
+Node: Test property note\7f63605
+Node: Test run path\7f66082
+Node: Test rwx seg\7f68279
+Node: Test short enums\7f69551
+Node: Test stack clash\7f70568
+Node: Test stack prot\7f71719
+Node: Test stack realign\7f73051
+Node: Test textrel\7f74321
+Node: Test threads\7f75578
+Node: Test warnings\7f76394
+Node: Test writable got\7f77229
+Node: Hardened Command Line Options\7f78515
+Node: Waiving Hardened Results\7f81707
+Node: Notes\7f83091
+Node: Size\7f83727
+Node: Timing\7f85870
+Node: Configure Options\7f86509
+Node: Legacy Scripts\7f88848
+Node: Who Built Me\7f89623
+Node: ABI Checking\7f92383
+Node: Hardening Checks\7f94499
+Node: Checking Archives\7f98585
+Node: GNU FDL\7f101006
\1f
End Tag Table
@menu
* Test bind now:: The bind-now test
-* Test gnu stack:: The gnu-stack test
-* Test writable got:: The writable-got test
-* Test rwx seg:: The rwx-seg test
-* Test textrel:: The textrel test
-* Test run path:: The run-path test
+* Test branch protection:: The branch-protection test
* Test cf protection:: The cf-protection test
-* Test optimization:: The optimization test
-* Test stack prot:: The stack-prot test
-* Test stack clash:: The stack-clash test
-* Test fortify:: The fortify test
-* Test notes:: The notes test
-* Test gnu relro:: The gnu relro test
-* Test pie:: The pie test
-* Test pic:: The pic test
* Test dynamic segment:: The dynamic-segment test
* Test dynamic tags:: The dynamic-tags test
-* Test not dynamic tags:: The not-dynamic-tags test
-* Test branch protection:: The branch-protection test
+* Test entry:: The entry test
+* Test fortify:: The fortify test
+* Test glibcxx assertions:: The glibcxx-assertions test
+* Test gnu relro:: The gnu relro test
+* Test gnu stack:: The gnu-stack test
+* Test go revision:: The go revision test
+* Test instrumentation:: The instrumentation test
+* Test lto:: The lto test
* Test not branch protection:: The not-branch-protection test
-* Test short enums:: The short-enums test
-* Test stack realign:: The stack-realign test
+* Test not dynamic tags:: The not-dynamic-tags test
+* Test notes:: The notes test
+* Test only go:: The only go test
+* Test optimization:: The optimization test
+* Test pic:: The pic test
+* Test pie:: The pie test
* Test production:: The production test
-* Test lto:: The lto test
* Test property note:: The property note test
+* Test run path:: The run-path test
+* Test rwx seg:: The rwx-seg test
+* Test short enums:: The short-enums test
+* Test stack clash:: The stack-clash test
+* Test stack prot:: The stack-prot test
+* Test stack realign:: The stack-realign test
+* Test textrel:: The textrel test
* Test threads:: The threads test
-* Test glibcxx assertions:: The glibcxx-assertions test
-* Test entry:: The entry test
-* Test go revision:: The go revision test
-* Test only go:: The only go test
* Test warnings:: The warnings test
-* Test instrumentation:: The instrumentation test
+* Test writable got:: The writable-got test
@end menu
The @var{hardened} tool does support some command line options of its
@option{--test-bind-now} option.
@c -----------------------------------------------------------------
-@node Test gnu stack
-@subsection The gnu-stack test
+@node Test branch protection
+@subsection The branch-protection test
@smallexample
- Problem: An attacker could place code on the stack and then run it
- Fix By: Updating compiler, assembler sources and/or linker scripts
- Waive If: The application *really* needs to be able to dynamically create and execute code
-
- Example: FAIL: gnu-stack test because the .stack section has incorrect permissions
- Example: FAIL: gnu-stack test because the .note.GNU-stack section has execute permission
- Example: FAIL: gnu-stack test because the GNU stack segment has execute permission
- Example: FAIL: gnu-stack test because the GNU stack segment does not have both read & write permissions
- Example: FAIL: gnu-stack test because no .note.GNU-stack section found
- Example: MAYB: gnu-stack test because multiple stack sections detected
-@end smallexample
-
-This test checks that it is not possible to place code onto the stack
-and then execute it. Normally the stack just holds data and
-addresses, but never instructions. A favourite tactic of attackers
-however is to discover a buffer overrun bug that addresses the stack
-and then place instructions there before forcing the processor to
-execute them.
-
-The test actually checks several different parts of a binary file in
-order to determine that its stack is safe, which is why there are
-several different potential failure messages.
-
-Most applications will have a section inserted into them by the
-compiler called @var{.note.GNU-stack}. The section has no contents,
-but the read, write, and execute attributes of the section reflect the
-needs of the application's stack.
-
-Ordinary compiled code should never see this problem, but the test
-failure can be triggered by programs built with an old compiler which
-does not support the @var{.note-GNU-stack} section, or if the program
-contains some assembler source files or linked with a custom made
-linker map.
-
-To fix the problem either the compiler needs to be upgraded or the
-linker map needs to be updated or the assembler sources need to be
-extended to add the @var{.note-GNU-stack} section by adding code like
-this:
+ Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
+ Fix By: Compile with -mbranch-protection=standard
+ Waive If: Not running on AArch64
+ Waive If: The application will not run on Fedora 35 or later.
+ Waive If: The application will not run on newer AArch64 cores.
-@smallexample
- .section .note.GNU-stack,"",%progbits
+ Example: FAIL: branch protection test because not enabled
+ Example: FAIL: branch protection test because only partially enabled
+ Example: FAIL: branch protection test because .note.gnu.property section not found (it is needed for branch protection support)
+ Example: FAIL: branch protection test because the -mbranch-protection option was not used
@end smallexample
-If necessary the test can be disabled via the
-@option{--skip-gnu-stack} option and re-enabled via the
-@option{--test-gnu-stack} option.
+AArch64 processors are vulnerable to a class of attack known as
+@var{ROP} and @var{JOP} style attacks. Preventing this kind of
+exploit requires assistance from the hardware itself, in the form of
+new instructions that need to be inserted by the compiler, and new
+bits in the core's status that need to be set.
-@c -----------------------------------------------------------------
-@node Test writable got
-@subsection The writable-got test
+This test checks to see if the compile time option to enable the
+security feature was used. There are four levels of security
+available, ranging from none through partial (some functions are
+protected others are not) to full. The test checks that full security
+has been enabled.
-@smallexample
- Problem: An attacker could intercept and redirect shared library function calls
- Fix By: Link with -Wl,--secure-plt
- Waive If: No shared libraries are used
-
- Example: FAIL: writable-got test because the GOT/PLT relocs are writable
-@end smallexample
+The security feature is enabled by compiling with the
+@option{-mbranch-protection=standard} gcc command line option.
-This test checks that the instructions to set up the @var{GOT} and
-@var{PLT} tables in a dynamic executable cannot be altered by an
-outside source.
+Note - these security features are only found on newer versions of the
+AArch64 architecture, and they need a compiler and a loader that will
+support them. Currently this means Fedora 35 or later, but not RHEL.
-Dynamic executables use two tables to help them connect to shared
-libraries. These tables - the @var{GOT} and the @var{PLT} - are set
-up when the program runs, based upon instructions held in special
-sections in the file. If these sections are writable then an
-attacker could change their contents and thus cause the program to
-call the wrong functions in the shared libraries.
+Note - this test is the inverse of the @ref{Test not branch protection}
+test and directly related to the @ref{Test dynamic tags} test.
-Under normal circumstances this test should never fail. If it does
-then something unusual is going on. One possible cure is to add the
-@option{-Wl,--secure-plt} option to the final link command line.
+Note - this test is automatically enabled if the
+@option{--profile-rawhide} options are used.
If necessary the test can be disabled via the
-@option{--skip-writable-got} option and re-enabled via the
-@option{--test-writable-got} option.
-
-@c -----------------------------------------------------------------
-@node Test rwx seg
-@subsection The rwx-seg test
-
-@smallexample
- Problem: An attacker could add their own code to an executable
- Fix By: Changing the linker script used to create the binary
- Waive If: Don't.
-
- Example: FAIL: rwx-seg test because segment has Read, Write and eXecute flags set
-@end smallexample
-
-This test checks that the file does not have any segments that have
-all three of the @var{read}, @var{write} and @var{execute}
-permissions. Code segments should have read and execute permissions,
-but they should not be writable as otherwise an attacker can
-overwrite the code. Data segments should have read permission, and
-possibly write permission as well, but never execute permission
-as otherwise an attacker might be able to create their own code in a
-data area.
-
-The linker will normally never create a binary file with a segment
-with all three permissions, but it is possible to force it to do so by
-using a custom linker script. If this flaw is detected then whatever
-linker script is being used should be corrected to remove the problem.
-
-If necessary the test can be disabled via the @option{--skip-rwx-seg}
-option and re-enabled via the @option{--test-rwx-seg} option.
-
-@c -----------------------------------------------------------------
-@node Test textrel
-@subsection The textrel test
-
-@smallexample
- Problem: An attacker could change the code in an executable
- Fix By: Compiling with -fPIC enabled
- Waive If: The code @emph{must} be static
-
- Example: FAIL: textrel test because the DT_TEXTREL tag was detected
-@end smallexample
-
-This test checks to make sure that a binary file does not contain any
-relocations that alter the contents of a code section. Relocations
-are special instructions that the program loader uses to alter pieces
-of a application when it starts up. Normally these relocations are
-restricted to altering the application's data, but if any of them
-alter its code then an attacker might be able to exploit this to
-change the program.
-
-This problem usually only arises when a binary is built to execute at
-a fixed address. Such binaries need text relocations to help them run
-at the address chosen. The safest solution therefore is to compile
-the binary to be position independent by using the @option{-fPIC} or
-@option{-fPIE} compiler command line options.
-
-If necessary the test can be disabled via the @option{--skip-textrel}
-option and re-enabled via the @option{--test-textrel} option.
-
-@c -----------------------------------------------------------------
-@node Test run path
-@subsection The run-path test
-
-@smallexample
- Problem: An attacker could cause an application to use a corrupted shared library
- Fix By: Compiling with -Wl,--enable-new-dtags or moving the shared libraries needed to a proper location
- Waive If: The application uses shared libraries held in non-standard locations
- Waive If: The linker does not support --enable-new-dtags
-
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag is corrupt
- Example: MAYB: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag exists but is empty
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag contains a path that does not start with /usr
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has a path that contains '..'
- Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has $ORIGIN after a non-$ORIGIN path
- Example: MAYB: run-path test because the RPATH dynamic tag is deprecated. Link with --enable-new-dtags to use RUNPATH instead
-@end smallexample
-
-An application that uses shared libraries contains information on how
-to locate those libraries. This information is a list of directories
-which should be searched for the libraries. The test checks that the
-list is secure.
-
-The test actually covers several different aspects, such as all
-directory paths must be absolute, start with @var{/usr} and must not
-contain @var{..}. If any of these rules are broken then an attacker
-might be able to exploit the search paths to force the application to
-load their own, corrupted version of a shared library.
-
-Normally this test will only be triggered if an application is linked
-by an old linker which does not support the generation of the new
-format @var{DT_RUNPATH} search paths. Or if it is linked against
-shared libraries which do not reside in standard locations. Fixing
-the test depends upon whether these issues can be solved.
-
-If necessary the test can be disabled via the @option{--skip-run-path}
-option and re-enabled via the @option{--test-run-path} option.
+@option{--skip-branch-protection} option and re-enabled via the
+@option{--test-branch-protection} option.
@c -----------------------------------------------------------------
@node Test cf protection
option and re-enabled via the @option{--test-cf-protection} option.
@c -----------------------------------------------------------------
-@node Test optimization
-@subsection The optimization test
+@node Test dynamic segment
+@subsection The dynamic-segment test
@smallexample
- Problem: Insufficient optimization prevents security features from working
- Fix By: Compiling with -O2
- Waive If: The application does not use string/memory functions
-
- Example: FAIL: optimization test because optimization level too low
- Example: FAIL: optimization test because level too low
- Example: MAYB: optimization test because no valid notes found regarding this test
-@end smallexample
-
-This test checks that the application was compiled with sufficient
-optimization enabled.
+ Problem: Programs with more than one dynamic section will not be loaded properly
+ Fix By: Fix assembler source code and/or linker script
+ Waive If: Don't.
-The C library security hardening features enabled via the
-@option{-D_FORTIFY_SOURCE=2} or @option{-D_FORTIFY_SOURCE=3}
-preprocessor command line options will only work properly if the
-compiler is run at an optimization level of at least @option{-O2}.
-Hence this test checks to make sure that this level (or higher) has
-been used.
+ Example: FAIL: dynamic segment test because multiple dynamic sections detected
+@end smallexample
-Normally the only reason for not using @option{-O2} or higher is
-because the application is space sensitive and needs to be compiled
-with @option{-Os} or the compilation process is so time intensive that
-using @option{-O0} is the only way to obtain reasonable build times.
+Dynamic executables must have a dynamic section which contains
+information that is used by the loader at program startup. The loader
+however only expects there to be one dynamic section in a program, and
+it does not cope it there are more than one. Normally this is not an
+issue however as the linker will ensure that there is only one dynamic
+section. It is possible however to use a custom linker script to
+create more than one dynamic section, or to write some assembler code
+specifically designed to create multiple dynamic sections.
-If necessary the test can be disabled via the @option{--skip-optimization}
-option and re-enabled via the @option{--test-optimization} option.
+If necessary the test can be disabled via the @option{--skip-dynamic-segment}
+option and re-enabled via the @option{--test-dynamic-segment} option.
@c -----------------------------------------------------------------
-@node Test stack prot
-@subsection The stack-prot test
+@node Test dynamic tags
+@subsection The dynamic-tags test
@smallexample
- Problem: Attackers exploiting stack overrun bugs can gain control of an application
- Fix By: Compiling with -fstack-protector-strong
- Waive If: Don't
-
- Example: FAIL: stack-prot test because insufficient protection enabled
- Example: FAIL: stack-prot test because stack protection deliberately disabled
- Example: FAIL: stack-prot test because only some functions protected
- Example: FAIL: stack-prot test because insufficient Stack Safe sanitization
+ Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
+ Fix By: Compile with -mbranch-protection=standard
+ Waive If: Not running on AArch64
+ Waive If: The application will not run on Fedora 35 or later.
+ Waive If: The application will not run on newer AArch64 cores.
+
+ Example: FAIL: dynamic tags test because BTI_PLT and PAC_PLT flags missing from the dynamic tags
+ Example: FAIL: dynamic tags test because BTI_PLT flag is missing from the dynamic tags
+ Example: FAIL: dynamic tags test because PAC_PLT flag is missing from the dynamic tags
+ Example: FAIL: dynamic tags test because no dynamic tags found
@end smallexample
-This test checks that the application has been compiled with stack
-protection enabled. For gcc this means using the
-@option{-fstack-protector-strong} option and for Clang the
-@option{-fsanitize=safe-stack} option. The gcc option does have some
-levels of protection other than @var{strong}, but @var{strong} is the
-only one that provides full protection.
+AArch64 processors are vulnerable to a class of attack known as
+@var{ROP} and @var{JOP} style attacks. Preventing this kind of
+exploit requires assistance from the hardware itself, in the form of
+new instructions that need to be inserted by the compiler, and new
+bits in the core's status that need to be set.
-The stack protection feature adds checks to compiled code that attempt
-to detect buffer overflows for local buffers. These are often a
-source of vulnerability that can be exploited by an attacker.
+This test checks to see if executable binaries have been marked as
+supporting the necessary security features to prevent this kind of
+attack. If they are marked then the runtime loader can enable the
+features in the processor core. This marking is done by setting flags
+in the tags found in the dynamic section of the executable. If the
+flags are missing then the executable is considered to be unprotected.
-If necessary the test can be disabled via the @option{--skip-stack-prot}
-option and re-enabled via the @option{--test-stack-prot} option.
+The security features are enabled by compiling with the
+@option{-mbranch-protection=standard} gcc command line option.
-@c -----------------------------------------------------------------
-@node Test stack clash
-@subsection The stack-clash test
+Note - these security features are only found on newer versions of the
+AArch64 architecture, and they need a compiler and a loader that will
+support them. Currently this means Fedora 35 or later, but not RHEL.
-@smallexample
- Problem: Attackers exploiting stack overrun bugs can gain control of an application
- Fix By: Compiling with -fstack-clash-protection
- Waive If: Don't
-
- Example: FAIL: stack-clash test because -fstack-clash-protection not enabled
-@end smallexample
+Note - this test is the inverse of the @ref{Test not dynamic tags}
+test and directly related to the @ref{Test branch protection} test.
-This test checks that the application has been compiled with stack
-clash protection enabled. If this feature is not enabled then an
-attacker could trick the application into overlapping its heap and
-stack, allowing them to alter both.
+Note - this test is automatically enabled if the
+@option{--profile-rawhide} options are used.
-For a full explanation of this topic see these blogs:
+If necessary the test can be disabled via the @option{--skip-dynamic-tags}
+option and re-enabled via the @option{--test-dynamic-tags} option.
-@url{https://developers.redhat.com/blog/2017/09/25/stack-clash-mitigation-gcc-background}
+@c -----------------------------------------------------------------
+@node Test entry
+@subsection The entry test
-@url{https://developers.redhat.com/blog/2019/04/30/stack-clash-mitigation-in-gcc-why-fstack-check-is-not-the-answer}
+@smallexample
+ Problem: Intel's CET security feature requires that the first instruction in a program be ENDBR
+ Fix By: Compile statup code with -fcf-protection
+ Waive If: The application will not run on the latest Intel hardware
-@url{https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3}
+ Example: FAIL: entry test because instruction at entry is not ENDBR32
+ Example: FAIL: entry test because instruction at entry is not ENDBR64
+@end smallexample
-If necessary the test can be disabled via the @option{--skip-stack-clash}
-option and re-enabled via the @option{--test-stack-clash} option.
+This test checks to make sure that the first instruction in a program
+for the x86 or x86_64 architectures is @var{ENDBR}. This is needed as
+part of Intel's @var{CET} security feature. (See @ref{Test cf
+protection} for more details on @var{CET}).
+
+If necessary the test can be disabled via the
+@option{--skip-entry} option and re-enabled via the
+@option{--test-entry} option.
@c -----------------------------------------------------------------
@node Test fortify
option and re-enabled via the @option{--test-fortify} option.
@c -----------------------------------------------------------------
-@node Test notes
-@subsection The notes test
+@node Test glibcxx assertions
+@subsection The glibcxx-assertions test
@smallexample
- Problem: Lack of annobin notes in a binary means that other tests will not work properly
- Fix By: Compiling with -fplugin=annobin
- Waive If: The annobin plugin is not available
-
- Example: FAIL: notes test because gaps were detected in the annobin coverage
- Example: MAYB: notes test because not all of the .text section is covered by notes
- Example: FAIL: notes test because annobin notes were not found
+ Problem: Compiled C++ code might contain bugs that could have been detected and fixed
+ Fix By: Compile with -D_GLIBCXX_ASSERTIONS
+ Waive If: Not compiling C++
+ Waive If: Not using functions from libstdc++
- Example: MAYB: lto test because no indication that LTO was used
- Example: MAYB: stack-clash test because no notes found regarding this test
- Example: FAIL: fortify test because no indication that the necessary option was used (and a C compiler was detected)
- Example: FAIL: warnings test because no indication that the necessary option was used (and a C compiler was detected)
- Example: FAIL: stack-realign test because stack realign support is mandatory
- Example: FAIL: branch-protection test because the -mbranch-protection option was not used
+ Example: FAIL: glibcxx-assertions test because compiled without -D_GLIBCXX_ASSERTIONS
@end smallexample
-This test checks that there are annobin notes covering all of the
-file. Annobin notes are generated by the compiler and describe the
-security features that have been enabled. The notes contain range
-information, so that it is possible to determine if all of an
-application has been covered by the notes, or if there are parts that
-are missing notes.
-
-If annobin notes are missing from a file then some of the other checks
-run by the @var{hardened} checker will not work, which can trigger
-FAIL or MAYB results for those tests.
-
-Annobin notes are normally produced by a compiler plugin which can be
-enabled via the @option{-fplugin=annobin} option for gcc or Clang, and
-the @option{-fpass-plugin=annobin} option for LLVM. (Note for pre
-version-13 of LLVM the @option{-Xclang -load -Xclang annobin} option
-should be used instead).
+This test checks to make sure that the @option{-D_GLIBCXX_ASSERTIONS}
+g+= compiler command line option was used when building binaries.
+This option is one of several supported by the @var{libstdc++} library
+and it is used to enable various NULL pointer and bounds checking
+security features. For more information see:
-Annobin notes can be generated for assembler sources by using the
-@option{-Wa,--generate-missing-build-notes=yes} option.
+@url{https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html}
-If necessary the test can be disabled via the @option{--skip-notes}
-and @option{--ignore-gaps} options and re-enabled via the
-@option{--test-notes} and @option{--report-gaps} options.
+If necessary the test can be disabled via the
+@option{--skip-glibcxx-assertions} option and re-enabled via the
+@option{--test-glibcxx-assertions} option.
@c -----------------------------------------------------------------
@node Test gnu relro
@option{--test-gnu-relro} option.
@c -----------------------------------------------------------------
-@node Test pie
-@subsection The pie test
+@node Test gnu stack
+@subsection The gnu-stack test
@smallexample
- Problem: Static binaries are more vulnerable to attacks
- Fix By: Link with -Wl,-pie
- Waive If: Don't
-
- Example: FAIL: pie test because not built with '-Wl,-pie' (gcc/clang) or '-buildmode pie' (go)
+ Problem: An attacker could place code on the stack and then run it
+ Fix By: Updating compiler, assembler sources and/or linker scripts
+ Waive If: The application *really* needs to be able to dynamically create and execute code
+
+ Example: FAIL: gnu-stack test because the .stack section has incorrect permissions
+ Example: FAIL: gnu-stack test because the .note.GNU-stack section has execute permission
+ Example: FAIL: gnu-stack test because the GNU stack segment has execute permission
+ Example: FAIL: gnu-stack test because the GNU stack segment does not have both read & write permissions
+ Example: FAIL: gnu-stack test because no .note.GNU-stack section found
+ Example: MAYB: gnu-stack test because multiple stack sections detected
@end smallexample
-Programs can be compiled to either load at a fixed address in memory
-(@var{static} programs) or at a random address assigned at startup
-time (@var{dynamic} programs). Static programs are more vulnerable to
-exploits because an attacker will know exactly where every part of the
-program is located. Thus building dynamic executables is
-recommended.
+This test checks that it is not possible to place code onto the stack
+and then execute it. Normally the stack just holds data and
+addresses, but never instructions. A favourite tactic of attackers
+however is to discover a buffer overrun bug that addresses the stack
+and then place instructions there before forcing the processor to
+execute them.
-This test checks that the appropriate linker option (@option{-pie})
-has been used to generate dynamic executables. The option is only
-needed for linking executables, not shared libraries.
+The test actually checks several different parts of a binary file in
+order to determine that its stack is safe, which is why there are
+several different potential failure messages.
-Note - this check is related to the @ref{Test pic} test. This test
-checks that the correct linker option has been used. That test
-checks that the correct compile time option has been used.
+Most applications will have a section inserted into them by the
+compiler called @var{.note.GNU-stack}. The section has no contents,
+but the read, write, and execute attributes of the section reflect the
+needs of the application's stack.
-If necessary the test can be disabled via the @option{--skip-pie}
-option and re-enabled via the @option{--test-pie} option.
+Ordinary compiled code should never see this problem, but the test
+failure can be triggered by programs built with an old compiler which
+does not support the @var{.note-GNU-stack} section, or if the program
+contains some assembler source files or linked with a custom made
+linker map.
+
+To fix the problem either the compiler needs to be upgraded or the
+linker map needs to be updated or the assembler sources need to be
+extended to add the @var{.note-GNU-stack} section by adding code like
+this:
+
+@smallexample
+ .section .note.GNU-stack,"",%progbits
+@end smallexample
+
+If necessary the test can be disabled via the
+@option{--skip-gnu-stack} option and re-enabled via the
+@option{--test-gnu-stack} option.
@c -----------------------------------------------------------------
-@node Test pic
-@subsection The pic test
+@node Test go revision
+@subsection The go-revision test
@smallexample
- Problem: Static binaries are more vulnerable to attacks
- Fix By: Compile with -fPIC or -fPIE
- Waive If: Don't.
+ Problem: Using old versions of the GO compiler looses out on security enhacements
+ Fix By: Using a newer GO compiler
+ Waive If: No new GO compiler is available
- Example: FAIL: pic test because -fpic/-fpie not enabled
+ Example: FAIL: go-revision test because GO revision must be >= 14
+ Example: FAIL: go-revision test because multiple, different GO version strings found
+ Example: FAIL: go-revision test because no Go compiler revision information found
@end smallexample
-Programs can be compiled to either load at a fixed address in memory
-(@var{static} programs) or at a random address assigned at startup
-time (@var{dynamic} programs). Static programs are more vulnerable to
-exploits because an attacker will know exactly where every part of the
-program is located. Thus building dynamic executables is
-recommended.
+This test checks to see that GO code has been compiled by at least a
+revision 14 compiler. Earlier versions of the compiler do not have
+all the bug fixes and security enhancements of later versions.
-This test checks that the appropriate compiler option has been used to
-generate dynamic code. For shared libraries this is the
-@option{-fPIE} option should be used. For dynamic executables the
-@option{-fPIC} option should be used. Note - there are lower case
-alternatives of these options (ie @option{-fpie} and @option{-fpic})
-which can also be used. The difference between the lower case and
-upper case versions is architecture dependent, but usually the lower
-case version will only work with smaller programs, wheres the upper
-case version works for all program sizes.
+Note - it is likely that the minimum revision of the GO compiler will
+be increased in the future.
-Note - this check is related to the @ref{Test pie} test. This test
-checks that the correct compile time option has been used. That test
-checks that the correct link time option has been used.
+If necessary the test can be disabled via the
+@option{--skip-go-revision} option and re-enabled via the
+@option{--test-go-revision} option.
-If necessary the test can be disabled via the @option{--skip-pic}
-option and re-enabled via the @option{--test-pic} option.
+@c -----------------------------------------------------------------
+@node Test instrumentation
+@subsection The instrumentation test
+
+@smallexample
+ Problem: Instrumented binaries are bigger and slower than regular binaries
+ Fix By: Removing instrumentation options from compiler command line
+ Waive If: Instrumentation is needed.
+
+ Example: WARN: Instrumentation enabled - this is probably a mistake for production binaries
+@end smallexample
+
+This test checks to see if any of gcc's instrumentation command line
+options have been used when the binary built. These options are:
+@option{_fsanitize}, @option{-finstrument-functions}, @option{-p},
+@option{-pg}, and @option{-fprofile-arcs}.
+
+There is no way to disable this test.
@c -----------------------------------------------------------------
-@node Test dynamic segment
-@subsection The dynamic-segment test
+@node Test lto
+@subsection The lto test
@smallexample
- Problem: Programs with more than one dynamic section will not be loaded properly
- Fix By: Fix assembler source code and/or linker script
- Waive If: Don't.
+ Problem: Mixed use of LTO and non-LTO binaries indicates a problem with the build system
+ Fix By: Using -flto consistently
+ Waive If: LTO building is not wanted
- Example: FAIL: dynamic segment test because multiple dynamic sections detected
+ Example: FAIL: lto test because compiled with both -flto and -fno-lto
@end smallexample
-Dynamic executables must have a dynamic section which contains
-information that is used by the loader at program startup. The loader
-however only expects there to be one dynamic section in a program, and
-it does not cope it there are more than one. Normally this is not an
-issue however as the linker will ensure that there is only one dynamic
-section. It is possible however to use a custom linker script to
-create more than one dynamic section, or to write some assembler code
-specifically designed to create multiple dynamic sections.
+This test checks to see if the @option{-flto} compiler command line
+option was used. Whilst this option can produce better code, its use
+is not essential, hence this test currently only checks to see if both
+the @option{-flto} and the @option{-fno-lto} options were used together.
-If necessary the test can be disabled via the @option{--skip-dynamic-segment}
-option and re-enabled via the @option{--test-dynamic-segment} option.
+If necessary the test can be disabled via the
+@option{--skip-lto} option and re-enabled via the
+@option{--test-lto} option.
@c -----------------------------------------------------------------
-@node Test dynamic tags
-@subsection The dynamic-tags test
+@node Test not branch protection
+@subsection The not-branch-protection test
@smallexample
- Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
- Fix By: Compile with -mbranch-protection=standard
+ Problem: Protecting AArch64 binaries needs newer versions of AArch64 cores
+ Fix By: Compile with -mbranch-protection=none
Waive If: Not running on AArch64
- Waive If: The application will not run on Fedora 35 or later.
+ Waive If: The application will run on Fedora 35 or later.
Waive If: The application will not run on newer AArch64 cores.
- Example: FAIL: dynamic tags test because BTI_PLT and PAC_PLT flags missing from the dynamic tags
- Example: FAIL: dynamic tags test because BTI_PLT flag is missing from the dynamic tags
- Example: FAIL: dynamic tags test because PAC_PLT flag is missing from the dynamic tags
- Example: FAIL: dynamic tags test because no dynamic tags found
+ Example: FAIL: not branch protection test because protection enabled
+ Example: FAIL: not branch protection test because only partially disabled
@end smallexample
-AArch64 processors are vulnerable to a class of attack known as
-@var{ROP} and @var{JOP} style attacks. Preventing this kind of
-exploit requires assistance from the hardware itself, in the form of
-new instructions that need to be inserted by the compiler, and new
-bits in the core's status that need to be set.
-
-This test checks to see if executable binaries have been marked as
-supporting the necessary security features to prevent this kind of
-attack. If they are marked then the runtime loader can enable the
-features in the processor core. This marking is done by setting flags
-in the tags found in the dynamic section of the executable. If the
-flags are missing then the executable is considered to be unprotected.
-
-The security features are enabled by compiling with the
-@option{-mbranch-protection=standard} gcc command line option.
+Note - this test is the inverse of the @ref{Test branch protection} test
+and directly related to the @ref{Test not dynamic tags} test.
-Note - these security features are only found on newer versions of the
-AArch64 architecture, and they need a compiler and a loader that will
-support them. Currently this means Fedora 35 or later, but not RHEL.
+This test checks to see if the compile time option to enable the
+AArch64 branch protection security feature was used. This feature
+is only supported on newer versions of AArch64 core, and will not work
+on older cores. Hence this test checks to make sure that the option
+was not used, or was used but was set to disable the feature.
-Note - this test is the inverse of the @ref{Test not dynamic tags}
-test and directly related to the @ref{Test branch protection} test.
+The security features can be disabled by compiling with the
+@option{-mbranch-protection=none} gcc command line option.
Note - this test is automatically enabled if the
-@option{--profile-rawhide} options are used.
+@option{--profile-el7} or @option{--profile-el9} options are used.
-If necessary the test can be disabled via the @option{--skip-dynamic-tags}
-option and re-enabled via the @option{--test-dynamic-tags} option.
+If necessary the test can be disabled via the
+@option{--skip-not-branch-protection} option and re-enabled via the
+@option{--test-not-branch-protection} option.
@c -----------------------------------------------------------------
@node Test not dynamic tags
option and re-enabled via the @option{--test-not-dynamic-tags} option.
@c -----------------------------------------------------------------
-@node Test branch protection
-@subsection The branch-protection test
+@node Test notes
+@subsection The notes test
@smallexample
- Problem: Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
- Fix By: Compile with -mbranch-protection=standard
- Waive If: Not running on AArch64
- Waive If: The application will not run on Fedora 35 or later.
- Waive If: The application will not run on newer AArch64 cores.
+ Problem: Lack of annobin notes in a binary means that other tests will not work properly
+ Fix By: Compiling with -fplugin=annobin
+ Waive If: The annobin plugin is not available
- Example: FAIL: branch protection test because not enabled
- Example: FAIL: branch protection test because only partially enabled
- Example: FAIL: branch protection test because .note.gnu.property section not found (it is needed for branch protection support)
- Example: FAIL: branch protection test because the -mbranch-protection option was not used
+ Example: FAIL: notes test because gaps were detected in the annobin coverage
+ Example: MAYB: notes test because not all of the .text section is covered by notes
+ Example: FAIL: notes test because annobin notes were not found
+
+ Example: MAYB: lto test because no indication that LTO was used
+ Example: MAYB: stack-clash test because no notes found regarding this test
+ Example: FAIL: fortify test because no indication that the necessary option was used (and a C compiler was detected)
+ Example: FAIL: warnings test because no indication that the necessary option was used (and a C compiler was detected)
+ Example: FAIL: stack-realign test because stack realign support is mandatory
+ Example: FAIL: branch-protection test because the -mbranch-protection option was not used
@end smallexample
-AArch64 processors are vulnerable to a class of attack known as
-@var{ROP} and @var{JOP} style attacks. Preventing this kind of
-exploit requires assistance from the hardware itself, in the form of
-new instructions that need to be inserted by the compiler, and new
-bits in the core's status that need to be set.
+This test checks that there are annobin notes covering all of the
+file. Annobin notes are generated by the compiler and describe the
+security features that have been enabled. The notes contain range
+information, so that it is possible to determine if all of an
+application has been covered by the notes, or if there are parts that
+are missing notes.
-This test checks to see if the compile time option to enable the
-security feature was used. There are four levels of security
-available, ranging from none through partial (some functions are
-protected others are not) to full. The test checks that full security
-has been enabled.
+If annobin notes are missing from a file then some of the other checks
+run by the @var{hardened} checker will not work, which can trigger
+FAIL or MAYB results for those tests.
-The security feature is enabled by compiling with the
-@option{-mbranch-protection=standard} gcc command line option.
+Annobin notes are normally produced by a compiler plugin which can be
+enabled via the @option{-fplugin=annobin} option for gcc or Clang, and
+the @option{-fpass-plugin=annobin} option for LLVM. (Note for pre
+version-13 of LLVM the @option{-Xclang -load -Xclang annobin} option
+should be used instead).
-Note - these security features are only found on newer versions of the
-AArch64 architecture, and they need a compiler and a loader that will
-support them. Currently this means Fedora 35 or later, but not RHEL.
+Annobin notes can be generated for assembler sources by using the
+@option{-Wa,--generate-missing-build-notes=yes} option.
-Note - this test is the inverse of the @ref{Test not branch protection}
-test and directly related to the @ref{Test dynamic tags} test.
+If necessary the test can be disabled via the @option{--skip-notes}
+and @option{--ignore-gaps} options and re-enabled via the
+@option{--test-notes} and @option{--report-gaps} options.
-Note - this test is automatically enabled if the
-@option{--profile-rawhide} options are used.
+@c -----------------------------------------------------------------
+@node Test only go
+@subsection The only-go test
+
+@smallexample
+ Problem: Mixing GO and C is unsafe on x86 platforms
+ Fix By: Using a new GO compiler
+ Waive If: Always
+
+ Example: FAIL: only-go test because combining GO and non-GO object files on x86 systems is not safe - it disables CET
+@end smallexample
+
+Note - this test is currently disabled. The GO compiler's lack of
+support for @var{CET} is a known issue that cannot be addressed by
+package maintainers. Hence there is no point in issuing an error
+message.
+
+This test checks to see if GO and C are being used together in the
+same program. This is a problem for code that is going to run on x86
+architectures as the GO compiler does not support Intel's @var{CET}
+technology. (See @ref{Test cf protection} for more details on
+@var{CET}). The GO language is inheritantly safer than C, but if the
+two are mixed, then the C parts will be missing out on the protection
+offered by @var{CET}.
If necessary the test can be disabled via the
-@option{--skip-branch-protection} option and re-enabled via the
-@option{--test-branch-protection} option.
+@option{--skip-only-go} option and re-enabled via the
+@option{--test-only-go} option.
@c -----------------------------------------------------------------
-@node Test not branch protection
-@subsection The not-branch-protection test
+@node Test optimization
+@subsection The optimization test
@smallexample
- Problem: Protecting AArch64 binaries needs newer versions of AArch64 cores
- Fix By: Compile with -mbranch-protection=none
- Waive If: Not running on AArch64
- Waive If: The application will run on Fedora 35 or later.
- Waive If: The application will not run on newer AArch64 cores.
+ Problem: Insufficient optimization prevents security features from working
+ Fix By: Compiling with -O2
+ Waive If: The application does not use string/memory functions
+
+ Example: FAIL: optimization test because optimization level too low
+ Example: FAIL: optimization test because level too low
+ Example: MAYB: optimization test because no valid notes found regarding this test
+@end smallexample
- Example: FAIL: not branch protection test because protection enabled
- Example: FAIL: not branch protection test because only partially disabled
+This test checks that the application was compiled with sufficient
+optimization enabled.
+
+The C library security hardening features enabled via the
+@option{-D_FORTIFY_SOURCE=2} or @option{-D_FORTIFY_SOURCE=3}
+preprocessor command line options will only work properly if the
+compiler is run at an optimization level of at least @option{-O2}.
+Hence this test checks to make sure that this level (or higher) has
+been used.
+
+Normally the only reason for not using @option{-O2} or higher is
+because the application is space sensitive and needs to be compiled
+with @option{-Os} or the compilation process is so time intensive that
+using @option{-O0} is the only way to obtain reasonable build times.
+
+If necessary the test can be disabled via the @option{--skip-optimization}
+option and re-enabled via the @option{--test-optimization} option.
+
+@c -----------------------------------------------------------------
+@node Test pic
+@subsection The pic test
+
+@smallexample
+ Problem: Static binaries are more vulnerable to attacks
+ Fix By: Compile with -fPIC or -fPIE
+ Waive If: Don't.
+
+ Example: FAIL: pic test because -fpic/-fpie not enabled
@end smallexample
-Note - this test is the inverse of the @ref{Test branch protection} test
-and directly related to the @ref{Test not dynamic tags} test.
+Programs can be compiled to either load at a fixed address in memory
+(@var{static} programs) or at a random address assigned at startup
+time (@var{dynamic} programs). Static programs are more vulnerable to
+exploits because an attacker will know exactly where every part of the
+program is located. Thus building dynamic executables is
+recommended.
-This test checks to see if the compile time option to enable the
-AArch64 branch protection security feature was used. This feature
-is only supported on newer versions of AArch64 core, and will not work
-on older cores. Hence this test checks to make sure that the option
-was not used, or was used but was set to disable the feature.
+This test checks that the appropriate compiler option has been used to
+generate dynamic code. For shared libraries this is the
+@option{-fPIE} option should be used. For dynamic executables the
+@option{-fPIC} option should be used. Note - there are lower case
+alternatives of these options (ie @option{-fpie} and @option{-fpic})
+which can also be used. The difference between the lower case and
+upper case versions is architecture dependent, but usually the lower
+case version will only work with smaller programs, wheres the upper
+case version works for all program sizes.
-The security features can be disabled by compiling with the
-@option{-mbranch-protection=none} gcc command line option.
+Note - this check is related to the @ref{Test pie} test. This test
+checks that the correct compile time option has been used. That test
+checks that the correct link time option has been used.
-Note - this test is automatically enabled if the
-@option{--profile-el7} or @option{--profile-el9} options are used.
+If necessary the test can be disabled via the @option{--skip-pic}
+option and re-enabled via the @option{--test-pic} option.
+
+@c -----------------------------------------------------------------
+@node Test pie
+@subsection The pie test
+
+@smallexample
+ Problem: Static binaries are more vulnerable to attacks
+ Fix By: Link with -Wl,-pie
+ Waive If: Don't
+
+ Example: FAIL: pie test because not built with '-Wl,-pie' (gcc/clang) or '-buildmode pie' (go)
+@end smallexample
+
+Programs can be compiled to either load at a fixed address in memory
+(@var{static} programs) or at a random address assigned at startup
+time (@var{dynamic} programs). Static programs are more vulnerable to
+exploits because an attacker will know exactly where every part of the
+program is located. Thus building dynamic executables is
+recommended.
+
+This test checks that the appropriate linker option (@option{-pie})
+has been used to generate dynamic executables. The option is only
+needed for linking executables, not shared libraries.
+
+Note - this check is related to the @ref{Test pic} test. This test
+checks that the correct linker option has been used. That test
+checks that the correct compile time option has been used.
+
+If necessary the test can be disabled via the @option{--skip-pie}
+option and re-enabled via the @option{--test-pie} option.
+
+@c -----------------------------------------------------------------
+@node Test production
+@subsection The production test
+
+@smallexample
+ Problem: Shipping code generated by an experimental compiler is bad
+ Fix By: Compile with a production ready compiler
+ Waive If: The code is never going to be shipped
+
+ Example: FAIL: production test because a production-ready compiler was not used to build the binary
+@end smallexample
+
+This test checks to make sure that the binary was not produced by an
+experimental compiler. Experimental compilers can be detected by
+examining their version information, which will include the string
+@var{NOT_FOR_PRODUCTION}.
If necessary the test can be disabled via the
-@option{--skip-not-branch-protection} option and re-enabled via the
-@option{--test-not-branch-protection} option.
+@option{--skip-production} option and re-enabled via the
+@option{--test-production} option.
+
+@c -----------------------------------------------------------------
+@node Test property note
+@subsection The property-note test
+
+@smallexample
+ Problem: Badly formed or missing GNU property notes can compromise an application at runtime
+ Fix By: Investigate and fix the creation of the notes
+ Waive If: Using old tools that do not generate the notes
+
+ Example: FAIL: property-note test because there is more than one GNU Property note
+ Example: FAIL: property-note test because the property note does not have expected name
+ Example: FAIL: property-note test because the property note data has the wrong size
+ Example: FAIL: property-note test because the note section is present but empty
+ Example: FAIL: property-note test because the property note data has an invalid size
+ Example: FAIL: property-note test because the IBT property is not enabled
+ Example: FAIL: property-note test because the SHSTK property is not enabled
+ Example: FAIL: property-note test because unexpected property note type
+ Example: FAIL: property-note test because the BTI property is not enabled
+ Example: FAIL: property-note test because the GNU Property note segment not 8 byte aligned
+ Example: FAIL: property-note test because there is more than one GNU Property note in the note segment
+ Example: FAIL: property-note test because .note.gnu.property section not found (it is needed for branch protection support
+ Example: FAIL: property-note test because no .note.gnu.property section = no control flow information
+ Example: FAIL: property-note test because control flow protection is not enabled
+@end smallexample
+
+GNU property notes are special markers in binary files that provide
+information about the program to the runtime loader. This information
+is architecture specific and it often includes details about any
+security features that were enabled when the program was compiled.
+
+This test checks that the property note is present - if needed for the
+particular architcture - and that it is properly formatted.
+
+Problems with property notes are usually related to other security
+options being missing, or the use of assembler source files which do
+not contain their own instructions for creating property notes.
+
+If necessary the test can be disabled via the
+@option{--skip-property-note} option and re-enabled via the
+@option{--test-property-note} option.
+
+@c -----------------------------------------------------------------
+@node Test run path
+@subsection The run-path test
+
+@smallexample
+ Problem: An attacker could cause an application to use a corrupted shared library
+ Fix By: Compiling with -Wl,--enable-new-dtags or moving the shared libraries needed to a proper location
+ Waive If: The application uses shared libraries held in non-standard locations
+ Waive If: The linker does not support --enable-new-dtags
+
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag is corrupt
+ Example: MAYB: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag exists but is empty
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag contains a path that does not start with /usr
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has a path that contains '..'
+ Example: FAIL: run-path test because the DT_RPATH/DT_RUNPATH dynamic tag has $ORIGIN after a non-$ORIGIN path
+ Example: MAYB: run-path test because the RPATH dynamic tag is deprecated. Link with --enable-new-dtags to use RUNPATH instead
+@end smallexample
+
+An application that uses shared libraries contains information on how
+to locate those libraries. This information is a list of directories
+which should be searched for the libraries. The test checks that the
+list is secure.
+
+The test actually covers several different aspects, such as all
+directory paths must be absolute, start with @var{/usr} and must not
+contain @var{..}. If any of these rules are broken then an attacker
+might be able to exploit the search paths to force the application to
+load their own, corrupted version of a shared library.
+
+Normally this test will only be triggered if an application is linked
+by an old linker which does not support the generation of the new
+format @var{DT_RUNPATH} search paths. Or if it is linked against
+shared libraries which do not reside in standard locations. Fixing
+the test depends upon whether these issues can be solved.
+
+If necessary the test can be disabled via the @option{--skip-run-path}
+option and re-enabled via the @option{--test-run-path} option.
+
+@c -----------------------------------------------------------------
+@node Test rwx seg
+@subsection The rwx-seg test
+
+@smallexample
+ Problem: An attacker could add their own code to an executable
+ Fix By: Changing the linker script used to create the binary
+ Waive If: Don't.
+
+ Example: FAIL: rwx-seg test because segment has Read, Write and eXecute flags set
+@end smallexample
+
+This test checks that the file does not have any segments that have
+all three of the @var{read}, @var{write} and @var{execute}
+permissions. Code segments should have read and execute permissions,
+but they should not be writable as otherwise an attacker can
+overwrite the code. Data segments should have read permission, and
+possibly write permission as well, but never execute permission
+as otherwise an attacker might be able to create their own code in a
+data area.
+
+The linker will normally never create a binary file with a segment
+with all three permissions, but it is possible to force it to do so by
+using a custom linker script. If this flaw is detected then whatever
+linker script is being used should be corrected to remove the problem.
+
+If necessary the test can be disabled via the @option{--skip-rwx-seg}
+option and re-enabled via the @option{--test-rwx-seg} option.
@c -----------------------------------------------------------------
@node Test short enums
Example: FAIL: short-enum test because both short and long enums supported
@end smallexample
-The @option{-fshort-enums} gcc compiler option can be used to reduce
-code size by storing enums in a @var{short} instead of an @var{int}.
-But if the code passes enums between functions compiled in different
-files then the @option{-fshort-enums} option must be used consistently
-or there could be problems.
+The @option{-fshort-enums} gcc compiler option can be used to reduce
+code size by storing enums in a @var{short} instead of an @var{int}.
+But if the code passes enums between functions compiled in different
+files then the @option{-fshort-enums} option must be used consistently
+or there could be problems.
+
+This test checks that either all files in an application were compiled
+with the @option{-fshort-enums} option, or that the option was never
+used.
+
+If necessary the test can be disabled via the
+@option{--skip-short-enums} option and re-enabled via the
+@option{--test-short-enums} option.
+
+@c -----------------------------------------------------------------
+@node Test stack clash
+@subsection The stack-clash test
+
+@smallexample
+ Problem: Attackers exploiting stack overrun bugs can gain control of an application
+ Fix By: Compiling with -fstack-clash-protection
+ Waive If: Don't
+
+ Example: FAIL: stack-clash test because -fstack-clash-protection not enabled
+@end smallexample
+
+This test checks that the application has been compiled with stack
+clash protection enabled. If this feature is not enabled then an
+attacker could trick the application into overlapping its heap and
+stack, allowing them to alter both.
+
+For a full explanation of this topic see these blogs:
+
+@url{https://developers.redhat.com/blog/2017/09/25/stack-clash-mitigation-gcc-background}
+
+@url{https://developers.redhat.com/blog/2019/04/30/stack-clash-mitigation-in-gcc-why-fstack-check-is-not-the-answer}
+
+@url{https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3}
+
+If necessary the test can be disabled via the @option{--skip-stack-clash}
+option and re-enabled via the @option{--test-stack-clash} option.
+
+@c -----------------------------------------------------------------
+@node Test stack prot
+@subsection The stack-prot test
+
+@smallexample
+ Problem: Attackers exploiting stack overrun bugs can gain control of an application
+ Fix By: Compiling with -fstack-protector-strong
+ Waive If: Don't
+
+ Example: FAIL: stack-prot test because insufficient protection enabled
+ Example: FAIL: stack-prot test because stack protection deliberately disabled
+ Example: FAIL: stack-prot test because only some functions protected
+ Example: FAIL: stack-prot test because insufficient Stack Safe sanitization
+@end smallexample
+
+This test checks that the application has been compiled with stack
+protection enabled. For gcc this means using the
+@option{-fstack-protector-strong} option and for Clang the
+@option{-fsanitize=safe-stack} option. The gcc option does have some
+levels of protection other than @var{strong}, but @var{strong} is the
+only one that provides full protection.
-This test checks that either all files in an application were compiled
-with the @option{-fshort-enums} option, or that the option was never
-used.
+The stack protection feature adds checks to compiled code that attempt
+to detect buffer overflows for local buffers. These are often a
+source of vulnerability that can be exploited by an attacker.
-If necessary the test can be disabled via the
-@option{--skip-short-enums} option and re-enabled via the
-@option{--test-short-enums} option.
+If necessary the test can be disabled via the @option{--skip-stack-prot}
+option and re-enabled via the @option{--test-stack-prot} option.
@c -----------------------------------------------------------------
@node Test stack realign
@option{--test-stack-realign} option.
@c -----------------------------------------------------------------
-@node Test production
-@subsection The production test
-
-@smallexample
- Problem: Shipping code generated by an experimental compiler is bad
- Fix By: Compile with a production ready compiler
- Waive If: The code is never going to be shipped
-
- Example: FAIL: production test because a production-ready compiler was not used to build the binary
-@end smallexample
-
-This test checks to make sure that the binary was not produced by an
-experimental compiler. Experimental compilers can be detected by
-examining their version information, which will include the string
-@var{NOT_FOR_PRODUCTION}.
-
-If necessary the test can be disabled via the
-@option{--skip-production} option and re-enabled via the
-@option{--test-production} option.
-
-@c -----------------------------------------------------------------
-@node Test lto
-@subsection The lto test
-
-@smallexample
- Problem: Mixed use of LTO and non-LTO binaries indicates a problem with the build system
- Fix By: Using -flto consistently
- Waive If: LTO building is not wanted
-
- Example: FAIL: lto test because compiled with both -flto and -fno-lto
-@end smallexample
-
-This test checks to see if the @option{-flto} compiler command line
-option was used. Whilst this option can produce better code, its use
-is not essential, hence this test currently only checks to see if both
-the @option{-flto} and the @option{-fno-lto} options were used together.
-
-If necessary the test can be disabled via the
-@option{--skip-lto} option and re-enabled via the
-@option{--test-lto} option.
-
-@c -----------------------------------------------------------------
-@node Test property note
-@subsection The property-note test
+@node Test textrel
+@subsection The textrel test
@smallexample
- Problem: Badly formed or missing GNU property notes can compromise an application at runtime
- Fix By: Investigate and fix the creation of the notes
- Waive If: Using old tools that do not generate the notes
-
- Example: FAIL: property-note test because there is more than one GNU Property note
- Example: FAIL: property-note test because the property note does not have expected name
- Example: FAIL: property-note test because the property note data has the wrong size
- Example: FAIL: property-note test because the note section is present but empty
- Example: FAIL: property-note test because the property note data has an invalid size
- Example: FAIL: property-note test because the IBT property is not enabled
- Example: FAIL: property-note test because the SHSTK property is not enabled
- Example: FAIL: property-note test because unexpected property note type
- Example: FAIL: property-note test because the BTI property is not enabled
- Example: FAIL: property-note test because the GNU Property note segment not 8 byte aligned
- Example: FAIL: property-note test because there is more than one GNU Property note in the note segment
- Example: FAIL: property-note test because .note.gnu.property section not found (it is needed for branch protection support
- Example: FAIL: property-note test because no .note.gnu.property section = no control flow information
- Example: FAIL: property-note test because control flow protection is not enabled
+ Problem: An attacker could change the code in an executable
+ Fix By: Compiling with -fPIC enabled
+ Waive If: The code @emph{must} be static
+
+ Example: FAIL: textrel test because the DT_TEXTREL tag was detected
@end smallexample
-GNU property notes are special markers in binary files that provide
-information about the program to the runtime loader. This information
-is architecture specific and it often includes details about any
-security features that were enabled when the program was compiled.
-
-This test checks that the property note is present - if needed for the
-particular architcture - and that it is properly formatted.
+This test checks to make sure that a binary file does not contain any
+relocations that alter the contents of a code section. Relocations
+are special instructions that the program loader uses to alter pieces
+of a application when it starts up. Normally these relocations are
+restricted to altering the application's data, but if any of them
+alter its code then an attacker might be able to exploit this to
+change the program.
-Problems with property notes are usually related to other security
-options being missing, or the use of assembler source files which do
-not contain their own instructions for creating property notes.
+This problem usually only arises when a binary is built to execute at
+a fixed address. Such binaries need text relocations to help them run
+at the address chosen. The safest solution therefore is to compile
+the binary to be position independent by using the @option{-fPIC} or
+@option{-fPIE} compiler command line options.
-If necessary the test can be disabled via the
-@option{--skip-property-note} option and re-enabled via the
-@option{--test-property-note} option.
+If necessary the test can be disabled via the @option{--skip-textrel}
+option and re-enabled via the @option{--test-textrel} option.
@c -----------------------------------------------------------------
@node Test threads
@option{--skip-threads} option and re-enabled via the
@option{--test-threads} option.
-@c -----------------------------------------------------------------
-@node Test glibcxx assertions
-@subsection The glibcxx-assertions test
-
-@smallexample
- Problem: Compiled C++ code might contain bugs that could have been detected and fixed
- Fix By: Compile with -D_GLIBCXX_ASSERTIONS
- Waive If: Not compiling C++
- Waive If: Not using functions from libstdc++
-
- Example: FAIL: glibcxx-assertions test because compiled without -D_GLIBCXX_ASSERTIONS
-@end smallexample
-
-This test checks to make sure that the @option{-D_GLIBCXX_ASSERTIONS}
-g+= compiler command line option was used when building binaries.
-This option is one of several supported by the @var{libstdc++} library
-and it is used to enable various NULL pointer and bounds checking
-security features. For more information see:
-
-@url{https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html}
-
-If necessary the test can be disabled via the
-@option{--skip-glibcxx-assertions} option and re-enabled via the
-@option{--test-glibcxx-assertions} option.
-
-@c -----------------------------------------------------------------
-@node Test entry
-@subsection The entry test
-
-@smallexample
- Problem: Intel's CET security feature requires that the first instruction in a program be ENDBR
- Fix By: Compile statup code with -fcf-protection
- Waive If: The application will not run on the latest Intel hardware
-
- Example: FAIL: entry test because instruction at entry is not ENDBR32
- Example: FAIL: entry test because instruction at entry is not ENDBR64
-@end smallexample
-
-This test checks to make sure that the first instruction in a program
-for the x86 or x86_64 architectures is @var{ENDBR}. This is needed as
-part of Intel's @var{CET} security feature. (See @ref{Test cf
-protection} for more details on @var{CET}).
-
-If necessary the test can be disabled via the
-@option{--skip-entry} option and re-enabled via the
-@option{--test-entry} option.
-
-@c -----------------------------------------------------------------
-@node Test go revision
-@subsection The go-revision test
-
-@smallexample
- Problem: Using old versions of the GO compiler looses out on security enhacements
- Fix By: Using a newer GO compiler
- Waive If: No new GO compiler is available
-
- Example: FAIL: go-revision test because GO revision must be >= 14
- Example: FAIL: go-revision test because multiple, different GO version strings found
- Example: FAIL: go-revision test because no Go compiler revision information found
-@end smallexample
-
-This test checks to see that GO code has been compiled by at least a
-revision 14 compiler. Earlier versions of the compiler do not have
-all the bug fixes and security enhancements of later versions.
-
-Note - it is likely that the minimum revision of the GO compiler will
-be increased in the future.
-
-If necessary the test can be disabled via the
-@option{--skip-go-revision} option and re-enabled via the
-@option{--test-go-revision} option.
-
-@c -----------------------------------------------------------------
-@node Test only go
-@subsection The only-go test
-
-@smallexample
- Problem: Mixing GO and C is unsafe on x86 platforms
- Fix By: Using a new GO compiler
- Waive If: Always
-
- Example: FAIL: only-go test because combining GO and non-GO object files on x86 systems is not safe - it disables CET
-@end smallexample
-
-Note - this test is currently disabled. The GO compiler's lack of
-support for @var{CET} is a known issue that cannot be addressed by
-package maintainers. Hence there is no point in issuing an error
-message.
-
-This test checks to see if GO and C are being used together in the
-same program. This is a problem for code that is going to run on x86
-architectures as the GO compiler does not support Intel's @var{CET}
-technology. (See @ref{Test cf protection} for more details on
-@var{CET}). The GO language is inheritantly safer than C, but if the
-two are mixed, then the C parts will be missing out on the protection
-offered by @var{CET}.
-
-If necessary the test can be disabled via the
-@option{--skip-only-go} option and re-enabled via the
-@option{--test-only-go} option.
-
@c -----------------------------------------------------------------
@node Test warnings
@subsection The warnings test
@option{--test-warnings} option.
@c -----------------------------------------------------------------
-@node Test instrumentation
-@subsection The instrumentation test
+@node Test writable got
+@subsection The writable-got test
@smallexample
- Problem: Instrumented binaries are bigger and slower than regular binaries
- Fix By: Removing instrumentation options from compiler command line
- Waive If: Instrumentation is needed.
-
- Example: WARN: Instrumentation enabled - this is probably a mistake for production binaries
+ Problem: An attacker could intercept and redirect shared library function calls
+ Fix By: Link with -Wl,--secure-plt
+ Waive If: No shared libraries are used
+
+ Example: FAIL: writable-got test because the GOT/PLT relocs are writable
@end smallexample
-This test checks to see if any of gcc's instrumentation command line
-options have been used when the binary built. These options are:
-@option{_fsanitize}, @option{-finstrument-functions}, @option{-p},
-@option{-pg}, and @option{-fprofile-arcs}.
+This test checks that the instructions to set up the @var{GOT} and
+@var{PLT} tables in a dynamic executable cannot be altered by an
+outside source.
-There is no way to disable this test.
+Dynamic executables use two tables to help them connect to shared
+libraries. These tables - the @var{GOT} and the @var{PLT} - are set
+up when the program runs, based upon instructions held in special
+sections in the file. If these sections are writable then an
+attacker could change their contents and thus cause the program to
+call the wrong functions in the shared libraries.
+
+Under normal circumstances this test should never fail. If it does
+then something unusual is going on. One possible cure is to add the
+@option{-Wl,--secure-plt} option to the final link command line.
+
+If necessary the test can be disabled via the
+@option{--skip-writable-got} option and re-enabled via the
+@option{--test-writable-got} option.
@c -----------------------------------------------------------------
@node Hardened Command Line Options