File: annobin.info, Node: Top, Next: Introduction, Up: (dir)
Annotating Binaries: How Was Your Program Built ?
*************************************************
This manual describes the ANNOBIN plugin and the 'annocheck' program,
and how you can use them to determine what security features were used
when a program was built.
This manual is for 'annobin' (Annobin) version 11.0.
This document is distributed under the terms of the GNU Free
Documentation License version 1.3. A copy of the license is included in
the section entitled "GNU Free Documentation License".
* Menu:
* Introduction:: What is Binary Annotation ?
* Plugins:: How to add Binary Annotations to your application.
* Examining:: How to examine the information stored in the binary.
* Annocheck:: Analysing binary files.
* Libannocheck:: Allowing other programs to run security checks.
* Configure Options:: Configuring annobin and annocheck.
* Legacy Scripts:: Other ways to use the information stored in the binary.
* GNU FDL:: GNU Free Documentation License
File: annobin.info, Node: Introduction, Next: Plugins, Prev: Top, Up: Top
1 What is Binary Annotation ?
*****************************
Binary Annotation is a method for recording information about an
application inside the application itself. It is an implementation of
the 'Watermark' specification defined here:
<https://fedoraproject.org/wiki/Toolchain/Watermark>
Although mainly focused on recording security information, the system
can be used to record any kind of data, even data not related to the
application. One of the main goals of the system however is the ability
to specify the address range over which a given piece of information is
valid. So for example it is possible to specify that all of a program
was compiled with the '-O2' option except for one special function which
was compiled with '-O0' instead.
The range information is useful because it allows third parties to
examine the binary and find out if its construction was consistent. IE
that there are no gaps in the recorded information, and no special cases
where a required feature was not active.
The system works by adding special sections to the application
containing individual pieces of information along with an address range
for which the information is valid. (Some effort has gone into the
storing this information in a reasonably compact format).
The information is generated by a plugin that is attached to the
compiler. The plugin extracts information from the internals of
compiler and records them in the object file(s) being produced.
Note - the plugin method is just one way of generating the
information. Any interested party can create and add information to the
object file, providing that they follow the Watermark specification.
The information can be extracted from files via the use of tools like
'readelf' and 'objdump'. The 'annobin' package itself includes a
program called 'annocheck' which can can also examine this information.
Details on this program can be found elsewhere in this documentation.
File: annobin.info, Node: Plugins, Next: Examining, Prev: Introduction, Up: Top
2 How to add Binary Annotations to your application.
****************************************************
Normally the option to enable the recording of binary annotation notes
is enabled automatically by the build system, so no user intervention is
required. On Fedora and RHEL based systems this is handled by the
'redhat-rpm-config' package.
Currently the binary annotations are generated by a plugin to the
compiler ('GCC', 'clang' or 'llvm'). This does mean that files that are
not compiled by any of these compilers will not gain any annotations,
although there is an optional assembler switch to add some basic notes
if none are present in the input files.
If the build system being used does not automatically enable the
'annobin' plugin then it can be specifically added to the compiler
command line by adding the '-fplugin=annobin' (for gcc) or
'-fplugin=annobin-for-clang' (for clang) or '-fplugin=annobin-for-llvm'
(for LLVM) option. It may also be necessary to tell the compiler where
to find the plugin by adding the '-iplugindir=' option, although this
should only be necessary if the plugin is installed in an unusual place.
If it is desired to disable the recording of binary annotations then
the '-fplugin-arg-annobin-disable' (for 'gcc') or '-Xclang
-plugin-arg-annobin-disable' (for 'clang' or 'llvm') can be used. Note
- these options must be placed _after_ the '-fplugin=annobin' option.
On Fedora and RHEL systems the plugin can be disabled entirely for
all compilations in a package by adding '%undefine _annotated_build' to
the spec file.
The plugin accepts a small selection of command line arguments, all
accessed by passing '-fplugin-arg-annobin-<option>' (for 'gcc') or
'-Xclang -plugin-arg-annobin-<option>' (for 'clang' or 'llvm') on the
command line. These options must be placed on the command line after
the plugin itself is mentioned. Note - not all versions of the plugin
accept all of these options. The options are:
'disable'
'enable'
Either disable or enable the plugin. The default is for the plugin
to be enabled.
'help'
Display a list of supported options on the standard output. This
is in addition to whatever else the plugin has been instructed to
do.
'version'
Display the version of the plugin on the standard output. This is
in addition to whatever else the plugin has been instructed to do.
'verbose'
Report the actions that the plugin is taking. If invoked for a
second time on the command line the plugin will be very verbose.
'function-verbose'
Report the generation of function specific notes. This indicates
that the named function was compiled with different options from
those that were globally enabled.
'stack-size-notes'
'no-stack-size-notes'
Do, or do not, record information about the stack requirements of
functions in the executable. This feature is disabled by default
as these notes can take up a lot of extra room if the executable
contains a lot of functions.
'stack-threshold=N'
If stack size requirements are being recorded then this option sets
the minimum value to record. Functions which require less than 'N'
bytes of static stack space will not have their requirements
recorded. If not set, then 'N' defaults to 1024.
'global-file-syms'
'no-global-file-syms'
If enabled the 'global-file-syms' option will create globally
visible, unique symbols to mark the start and end of the compiled
code. This can be desirable if a program consists of multiple
source files with the same name, or if it links to a library that
was built with source files of the same name as the program itself.
The disadvantage of this feature however is that the unique names
are based upon the time of the build, so repeated builds of the
same source will have different symbol names inside it. This
breaks the functionality of the build-id system which is meant to
identify similar builds created at different times. This feature
is disabled by default, and if enabled can be disabled again via
the 'no-global-file-syms' option.
'attach'
'no-attach'
When gcc compiles code with the '-ffunction-sections' option active
it will place each function into its own section. When the
'annobin' 'attach' option is active the plugin will attempt to
attach the function section to a group containing the notes and
relocations for the function. In that way, if the linker decides
to discard the function, it will also know that it should discard
the notes and relocations as well.
The default is 'attach', but this can be disabled via the
'no-attach' option. Note however that if both 'attach' and
'link-order' are disabled then note generation for function
sections will not work properly.
'link-order'
'no-link-order'
As an alternative to using section groups and a special assembler
directive the plugin can use a feature of the ELF 'SHF_LINK_ORDER'
flag which tells the linker that it should discard a section if the
section it is linked to is also being discarded. This behaviour is
enabled by the 'link-order' option.
'rename'
Adds an extra prefix to the symbol names generated by the 'annobin'
plugin. This allows the plugin to be run twice on the same
executable, which can be useful for debugging and build testing.
'active-checks'
'no-active-checks'
The 'annobin' plugin will normally generate a warning message if it
detects that neither the '-D_FORTIFY_SOURCE=2' nor the
'-D_FORTIFY_SOURCE=3' options have been provided on the command
line and '-flto' has been enabled. This is because LTO compilation
hides preprocessor options, so information about them cannot be
passed on to the 'annocheck' tool.
The 'active-checks' option changes the warning message into an
error message, just as if '-Werror' had been specified.
The 'no-active-checks' option disables the warning message
entirely.
Note - in the future the 'annobin' plugin might be extended to
produce warning messages for other missing command line options.
Note - as a workaround for certain tests generated by the
'autoconf' tool the warning message will not be produced if the
input source filename starts with 'conftest.'. In these cases
autoconf is usually checking to see if a warning will be produced
for some other reason, and so the 'annobin' warning would get in
the way. If the 'active-checks' option has been enabled however,
an error message will still be generated.
'dynamic-notes'
'no-dynamic-notes'
'static-notes'
'no-static-notes'
These options are deprecated.
'ppc64-nops'
'no-ppc64-nops'
This option either enables or disables the insertion of NOP
instructions in the some of the code sections of PowerPC64
binaries. This is necessary to avoid problems with the 'elflint'
program which will complain about binaries built without this
option enabled. The option is enabled by default, but since it
does increase the size of compiled programs by a small amount, the
'no-ppc64-nops' is provided in order to turn it off.
The plugins record information appropriate to the compiler that is
running them. So the 'gcc' plugin records information about the
following options:
'-D_FORTIFY_SOURCE=[2|3]'
'-D_GLIBCXX_ASSERTIONS'
'-O'
'-Wall'
'-fPIC'
'-fPIE'
'-fcf-protection'
'-finstrument_functions'
'-flto'
'-fomit-frame-pointer'
'-fprofile'
'-fprofile-arcs'
'-fsanitize'
'-fshort-enums'
'-fstack-clash-protection'
'-fstack-protector'
'-g'
'-mbranch-protection (AArch64)'
'-mstack-realign (i386)'
'-mtls-size (PowerPC)'
The 'Clang' plugin records information on the following command line
options:
'-O'
'-Wall'
'-fPIC'
'-fPIE'
'-fcf-protection-branch'
'-fcf-protection-return'
'-fsanitize=cfi-cast-strict'
'-fsanitize=safe-stack'
'-fspeculative-load-hardening'
'-fstack-protector-strong'
Note - if LTO compilation is enabled (-flto) then any data recorded
by the Clang plugin is ignored when the object file is recompiled by the
LLVM backend. Hence when using LTO and Clang it is best to enable the
LLVM plugin.
The 'LLVM' plugin records information on the following command line
options:
'-D_FORTIFY_SOURCE=[2|3]'
'-O'
'-Wall'
'-flto'
'-fPIC'
'-fPIE'
'-fcf-protection-branch'
'-fcf-protection-return'
'-fsanitize=safe-stack'
'-fstack-protector-strong'
'-g'
File: annobin.info, Node: Examining, Next: Annocheck, Prev: Plugins, Up: Top
3 How to examine the information stored in the binary.
******************************************************
The information is stored in the ELF Note format in a special section
called '.gnu.build.attributes'. The 'readelf' program from the
'binutils' package can extract and display these notes when the
'--notes' option is provided. (Adding the '--wide' option is also
helpful). Here is an example of the output:
Displaying notes found in: .gnu.build.attributes
Owner Data size Description
GA$<version>3p3 0x00000010 OPEN Applies to region from 0x8a0 to 0x8c6 (hello.c)
GA$<tool>gcc 7.2.1 20170915 0x00000000 OPEN Applies to region from 0x8a0 to 0x8c6
GA*GOW:0x452b 0x00000000 OPEN Applies to region from 0x8a0 to 0x8c6
GA*<stack prot>strong 0x00000000 OPEN Applies to region from 0x8a0 to 0x8c6
GA*GOW:0x412b 0x00000010 func Applies to region from 0x8c0 to 0x8c6 (baz)
This shows various different pieces of information, including the
fact that the notes were produced using version 3 of the specification,
and version 3 of the plugin. The binary was built by gcc version 7.2.1
and the -fstack-protector-strong option was enabled on the command line.
The program was compiled with -O2 enabled except the baz() function
which was compiled with -O0 instead.
The most complicated part of the notes is the owner field. This is
used to encode the type of note as well as its value and possibly extra
data as well. The format of the field is explained in detail in the
Watermark specification, but it basically consists of the letters 'G'
and 'A' followed by an encoding character (one of '*$!+') and then a
type character and finally the value.
The notes are always four byte aligned, even on 64-bit systems. This
does mean that consumers of the notes may have to read 8-byte wide
values from 4-byte aligned addresses, and that producers of the notes
may have to generate unaligned relocs when creating them.
Most of the notes have a reasonably self explanatory name and value.
The exception are the 'version' and 'GOW' notes, which are included in
the table below.
* Menu:
* The Version Encoding:: Encoding Versions
* The STACK Encoding:: Encoding Stack Protection
* The PIC Encoding:: Encoding Position Independence
* The GOW Encoding:: Encoding Optimization and Debugging Levels
* The CF Encoding:: Encoding Control Flow Protection
* The ENUM Encoding:: Encoding the Size of Enumerations
* The INSTRUMENT Encoding:: Encoding Instrumentation Options
File: annobin.info, Node: The Version Encoding, Next: The STACK Encoding, Up: Examining
3.1 Encoding Protocol and Producer Versions
===========================================
The 'version' note encodes the version of the Watermark specification
used and the version of the tool used to generate the notes. Typically
the protocol version will be 3 and the plugin version will be 9. It
also encodes the tool used to generate the notes as a single character.
The following characters are used:
'L'
The notes have been produced by the Clang plugin.
'V'
The notes have been produced by the LLVM plugin.
'a'
The notes have been produced by the assembler.
'c'
The notes have been produced by the gcc plugin for the .text.cold
section.
'e'
The notes have been produced by the gcc plugin for the .text.exit
section.
'g'
The notes have been produced by the gcc plugin when running in LTO
mode.
'h'
The notes have been produced by the gcc plugin for the .text.hot
section.
'l'
The notes have been produced by the linker.
'p'
The notes have been produced by the gcc plugin.
's'
The notes have been produced by the gcc plugin for the
.text.startup section.
File: annobin.info, Node: The STACK Encoding, Next: The PIC Encoding, Prev: The Version Encoding, Up: Examining
3.2 Encoding Stack Protections
==============================
The stack protection note (value 2) encodes the setting of the
'-fstack-protector' option. Possible values are:
'0'
Not compiled with any setting of '-fstack-protector' (or the
setting is unknown).
'1'
Compiled with just '-fstack-protector'.
'2'
Compiled with '-fstack-protector-all'.
'3'
Compiled with '-fstack-protector-strong'.
'4'
Compiled with '-fstack-protector-explicit'.
File: annobin.info, Node: The PIC Encoding, Next: The GOW Encoding, Prev: The STACK Encoding, Up: Examining
3.3 Encoding Position Independence
==================================
The 'Position Independence Status' note encodes the setting of the
'-fpic'/'-fpie' used when compiling the program. The value of the note
can be
'0'
Static code, ie neither pic nor pie.
'1'
Compiled with '-fpic'.
'2'
Compiled with '-fPIC'.
'3'
Compiled with '-fpie'.
'4'
Compiled with '-fPIE'
If both 'pic' and 'pie' have been specified on the command line then
'pie' takes the precedence in the encoding.
File: annobin.info, Node: The GOW Encoding, Next: The CF Encoding, Prev: The PIC Encoding, Up: Examining
3.4 Encoding Optimization and Debugging Levels
==============================================
The 'GOW' note encodes the optimization level ('-O') and debugging level
('-g') used when compiling a binary. In order to save space this is
stored as a bit field with the bits having the following meanings:
'bits 0 - 2'
The debug type, ie DBX, DWARF, VMS or XCOFF. As specified by the
'-gstabs', '-gdwarf', '-gvms' and '-gxcoff' options.
'bit 3'
Set if GNU extensions to the debug type have been enabled.
'bits 4 - 5'
The debug info level ie TERSE, NORMAL or VERBOSE as set by the
'-g<level>' option.
'bits 6 - 8'
The DWARF version, if DWARF is being generated. Set by the
'-gdwarf-<version>' option.
'bits 9 - 10'
The optimization level as set by the '-O<number>' option. Levels
above 3 are treated as if they were 3.
'bit 11'
Set if the optimize-for-size option ('-Os') is enabled.
'bit 12'
Set if the inaccurate-but-fast optimization option ('-Ofast') has
been enabled.
'bit 13'
Set if the optimize-with-debugging option ('-Og') has been enabled.
'bit 14'
Set if the enable most warnings option ('-Wall') has been enabled.
'bit 15'
Set if the format security warning option ('-Wformat-security') has
been enabled.
'bit 16'
Set if LTO compilation has been enabled.
'bit 17'
Set if LTO compilation has been disabled. This bit is here so that
tools can detect notes created by earlier versions of annobin which
did not set any bits higher than 15.
'bits 18 - 19'
These bits are used to record the setting of gcc's
'-ftrivial-auto-var-init' command line option. If both bits are
clear then the option is not supported by the compiler. If bit 18
is clear but bit 19 is set, then the compiler supports the option,
but either it was not used, or it was used but the option's value
was 'skip'. Otherwise if bit 19 is clear then the option was used
but its value was set to 'pattern' (which is inappropriate for
production binaries) or if bit 19 is set then the option was used
and its value was set to 'zero'.
'bits 20 - 21'
These bits are used to record the setting of gcc's
'-fzero-call-used-regs' command line option. If both bits are
clear the option is not supported by the compiler. Otherwise if
bit 20 is clear (and bit 21 is set) then the option is supported
but it was not used, or it was used, but its value was set to
'skip'. Otherwise bit 20 is set and bit 21 is clear, indicating
that the option was used and a value other than 'skip' was used.
Currently setting both bots 20 and 21 is not supported although
this may change in the future.
The other bits are not currently used and should be set to zero so
they can be used in future extensions to the specification.
File: annobin.info, Node: The CF Encoding, Next: The ENUM Encoding, Prev: The GOW Encoding, Up: Examining
3.5 Encoding Control Flow Protection
====================================
Records the setting of the '-cf-protection' option. This is a bit mask
using the following bits, based upon the definition of the 'enum
cf_protection_level' from gcc's 'flag-types.h' header file:
'bit 0'
Branches are protected. (ie '-fcf-protection=branch').
'bit 1'
Returns are protected. (ie '-fcf-protection=return').
'bit 2'
If set, this indicates that the other bits were explicitly set by
an option on the gcc command line. Otherwise those bits were
implicitly set by either other options or the backend concerned.
If both bits 0 and 1 are set then this implies the
'-fcf-protection=full' option, and if neither are set then this implies
the '-fcf-protection=none' option.
Note - in order to avoid storing a value of 0 in the note (which can
be confused with a NUL-byte to indicate the end of a string), the value
stored is biased by 1.
File: annobin.info, Node: The ENUM Encoding, Next: The INSTRUMENT Encoding, Prev: The CF Encoding, Up: Examining
3.6 Encoding the Size of Enumerations
=====================================
Record the value of the '-fshort-enums' option. Possible values are:
'true'
The '-fshort-enums' option has been enabled.
'false'
The '-fshort-enums' option has not been enabled.
File: annobin.info, Node: The INSTRUMENT Encoding, Prev: The ENUM Encoding, Up: Examining
3.7 Encoding Instrumentation Options
====================================
Records the enablement of various code instrumentation options. Note -
this note is only produced if one or more of these options are enabled.
The note encodes four values, separate by the forward slash (/)
character. These values are:
'sanitization'
Enabled via a plethora of '-fsanitize=...' options these tell gcc
to add extra code to help with various different types of error
checking features.
'function instrumentation'
Enabled via gcc's '-finstrument-functions' option, this adds
special function calls at the entry and exit point of every normal
function.
'profiling'
Enabled via gcc's '-p' or '-pg' options, this adds instrumentation
to the compiled code that generates output suitable for analysis
via the 'prof' or 'gprof' programs.
'arc profiling'
Enabled via gcc's '-fprofile-arc' option, or one of the meta-
profiling options, this option adds code to record how many times
every branch and function call is executed.
Each value represents a setting of an internal gcc flag variable.
The exact meaning of the values is specific to gcc, but any non-zero
number means that the feature has been enabled in some way.
File: annobin.info, Node: Annocheck, Next: Libannocheck, Prev: Examining, Up: Top
4 Analysing binary files.
*************************
annocheck
[-h | -help]
[-help-TOOL]
[-version]
[-v | -verbose]
[-q | -quiet]
[-i | -ignore-unknown]
[-r | -report-unknown]
[-f | -follow-links]
[-I | -ignore-links]
[-debug-rpm=FILE]
[-dwarf-dir=DIR]
[-p TEXT | -prefix=TEXT]
[-t DIR | -tmpdir=DIR]
[-u | -use-debuginfod]
[-n | -no-use-debuginfod]
[-enable-TOOL]
[-disable-TOOL]
[-TOOL-OPTION]
FILE...
The 'annocheck' program can analyse binary files and report
information about them. It is designed to be modular, with a set of
self-contained tools providing the checking functionality. Currently
the following tools are implemented:
* Menu:
* Built By:: Which tool(s) were used to build the file(s) ?
* Hardened:: Were the file(s) built with the correct security options ?
* Notes:: What annobin notes are inside the file(s) ?
* Size:: What is the cumulative size of specific sections in the file(s) ?
* Timing:: How long did the checks take ?
The 'annocheck' program is able to scan inside rpm files and
libraries. It will automatically recurse into any directories that are
specified on the command line. In addition 'annocheck' knows how to
find debug information held in separate debug files, and it will search
for these whenever it needs the resources that they contain.
New tools can be added to the annocheck framework by creating a new
source file and including it in the 'Makefile' used to build
'annocheck'. The modular nature of 'annocheck' means that nothing else
needs to be updated.
New tools must fill out a 'struct checker' structure (defined in
'annocheck.h') and they must define a constructor function that calls
'annocheck_add_checker' to register their presence at program start-up.
The 'annocheck' program supports some generic command line options
that are used regardless of which tools are enabled.
'--debug-rpm=FILE'
Look in FILE for separate dwarf debug information.
'--dwarf-dir=DIR'
Look in DIR for separate dwarf debug information files.
'--help'
'-h'
Displays the generic annobin usage information and then exits.
'--help-TOOL'
Display the usage information for TOOL and then exits.
'--report-unknown'
'--ignore-unknown'
'-r'
'-i'
If enabled, unknown file types are reported when they are
encountered. This includes non-ELF format files, block devices and
so on. Directories are not considered to be unknown and are
automatically descended.
The default setting depends upon the file being processed. For rpm
files the default is to ignore unknowns, since these often contain
non-executable files. For other file types, including directories,
the default is to report unknown files.
'--ignore-links'
'--follow-links'
'-I'
'-f'
Specifies whether symbolic links should be followed or ignored.
The default setting depends upon the file being processed. For rpm
files the default is to ignore symbolic links, since these often
unresolveable. For other file types, including directories, the
default is to follow the links.
'--prefix=TEXT'
'-p TEXT'
Include TEXT in the output description.
'--quiet'
'-q'
Do not print anything, just return an exit status.
'--tmpdir=DIR'
'-t DIR'
Use DIR as a directory for holding temporary files.
'--verbose'
'-v'
Produce informational messages whilst working. Repeat for more
information.
'--version'
Report the version of the tool and then exit.
'--use-debuginfod'
'-u'
Enable the use of the debuginfod service to download debuginfo
rpms. This feature is enabled by default, but it is only active if
support for the debuginfod server has been compiled in to
annocheck.
'--no-use-debuginfod'
'-n'
Do not use the debuginfod service, even if it is available.
'--enable-TOOL'
Enable TOOL. Most tools are disabled by default and so need to be
enabled via this option before they will act.
'--disable-TOOL'
Disable TOOL. Normally used to disable the hardening checker,
which is enabled by default.
'--TOOL-OPTION'
Pass OPTION on to TOOL.
Any other command line options will be passed to the tools in turn in
order to give them a chance to claim and process them.
File: annobin.info, Node: Built By, Next: Hardened, Up: Annocheck
4.1 The builder checker.
========================
annocheck
-enable-builtby
[-all]
[-tool=NAME]
[-nottool=NAME]
FILE...
The BUILT-BY tool is disabled by default, but it can be enabled by
the command line option '--enable-builtby'. The tool checks the
specified files to see if any information is stored about how the file
was built.
Since the hardening checker is enabled by default it may also be
useful to add the '--disable-hardened' option to the command line.
The tool supports a few command line options to customise its
behaviour:
'--all'
Report all builder identification strings. The tool has several
different heuristics for determining the builder. By default it
will report the information return by the first successful
heuristic. If the '--all' option is enabled then all successful
results will be returned.
'--tool=NAME'
This option can be used to restrict the output to only those files
which were built by a specific tool. This can be useful when
scanning a directory full of files searching for those built by a
particular compiler.
'--nottool=NAME'
This option can be used to restrict the output to only those files
which were not built by a specific tool. This can be useful when
scanning a directory full of files searching for those that were
not built by a particular compiler.
File: annobin.info, Node: Hardened, Next: Notes, Prev: Built By, Up: Annocheck
4.2 The Hardened security checker.
==================================
annocheck
[-skip-NAME[=FUNCNAME]]
[-test-NAME]
[-skip-all]
[-test-all]
[-skip-future]
[-test-future]
[-test-unicode-all]
[-test-unicode-suspicious]
[-profile=RELEASE]
[-ignore-gaps]
[-report-gaps]
[-fixed-format-messages]
[-disable-colour]
[-enable-colour]
[-disable-hardened]
[-enable-hardened]
[-full-filenames]
[-base-filenames]
[-no-urls]
[-provide-urls]
FILE...
The HARDENED tool checks that the specified files were built with
specific security hardening features enabled. The features that are
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
this blog:
<https://developers.redhat.com/articles/2021/07/15/build-your-own-tool-search-code-sequences-binary-files>
Currently the HARDENED tool can run the following tests. Each test
listed here starts with a short section describing the reason for the
test, a probable solution to fix the test, criteria for when the test
can be ignored and some examples of the error messages that are produced
by annocheck when the test goes wrong.
* Menu:
* Test auto var init:: The auto-var-init test
* Test bind now:: The bind-now test
* Test branch protection:: The branch-protection test
* Test cf protection:: The cf-protection test
* Test dynamic segment:: The dynamic-segment test
* Test dynamic tags:: The dynamic-tags test
* Test entry:: The entry test
* Test fast:: The -Ofast test
* Test fortify:: The fortify test
* Test gaps:: The gaps 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 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 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 unicode:: The unicode test
* Test warnings:: The warnings test
* Test writable got:: The writable-got test
* Test zero call used regs:: The zero-call-used-regs test
The HARDENED tool does support some command line options of its own
as well.
* Menu:
* Hardened Command Line Options:: Command line options specific to the hardened tool
* Waiving Hardened Results:: How to ignore specific hardening tests.
* Absence of compiled code:: What to do if annocheck reports that it could not find compiled code.
File: annobin.info, Node: Test auto var init, Next: Test bind now, Up: Hardened
4.2.1 The auto-var-init test
----------------------------
Problem: An attacker could extract information from uninitialised locations on the stack
Fix By: Add -fauto-var-init=zero to the compiler command line
Waive If: The overhead of initializing auto variables is too high
Example: FAIL: auto-var-init test because -ftrivial-auto-var-init not used or set to 'uninitialized'
This is a future test. It is not enabled by default. It checks a
security feature that may not be widely available or enforced.
This test checks to make sure that programs have been compiled with
the '-ftrivial-auto-var-init=zero' command line option. This option
ensures that all local variables are initialised, even if they are not
used. This includes any padding between structure fields or unused
array entries. If this is not done then a potential attacker might be
able to access the unitialized memory and extract information.
The test can be enabled via the '--test-auto-var-init' option and
disabled by the '--skip-auto-var-init' option. It is also enabled if
the '--test-future' option is specified and disabled if the
'skip-future' option is specified.
File: annobin.info, Node: Test bind now, Next: Test branch protection, Prev: Test auto var init, Up: Hardened
4.2.2 The bind-now test
-----------------------
Problem: An attacker could intercept calls to shared library functions
Fix By: Add -Wl,-z,now to final link command line
Waive If: No shared libraries used
Example: FAIL: bind-now test because not linked with -Wl,-z,now
This test checks that lazy binding is not enabled in the binary.
Lazy binding can be used to delay resolving the links between an
application and any shared libraries that it uses:
<https://www.airs.com/blog/archives/41>
Using lazy binding provides a faster start-up for an application
since this resolving process is not performed until a function call is
made to a specific library. But it is also a security vulnerability
since an attacker could replace the binding with a link to their own
code. Hence for security purposes immediate binding rather than lazy
binding should be used.
The type of binding is selected via a linker command line option, and
on a compiler command line the secure version usually looks like
'-Wl,-z,now'. The lazy binding option is '-Wl,-z,lazy' although some
linkers are configured to use lazy binding by default, in which case
just the absence of the '-Wl,-z,now' option is enough to trigger this
test.
Whilst important, this test can be ignored if the binary does not use
any shared libraries.
Note - this test is automatically disabled if the '--profile=el7'
option is used.
The test can be disabled via the '--skip-bind-now' option and
re-enabled by the '--test-bind-now' option.
File: annobin.info, Node: Test branch protection, Next: Test cf protection, Prev: Test bind now, Up: Hardened
4.2.3 The branch-protection 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.
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
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 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.
The security feature is enabled by compiling with the
'-mbranch-protection=standard' gcc command line option.
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.
Note - this test is the inverse of the *note Test not branch
protection:: test and directly related to the *note Test dynamic tags::
test.
Note - this test is automatically enabled if the '--profile=rawhide'
option or '--profile=f36' option is used and disabled if the
'--profile=el7', '--profile=el8', '--profile=el9' or '--profile=f35'
options are used.
If necessary the test can be disabled via the
'--skip-branch-protection' option and re-enabled via the
'--test-branch-protection' option.
File: annobin.info, Node: Test cf protection, Next: Test dynamic segment, Prev: Test branch protection, Up: Hardened
4.2.4 The cf-protection test
----------------------------
Problem: An attacker could compromise an unprotected binary
Fix By: Compiling with -fcf-protection=full
Waive If: The application will not run on the latest Intel hardware
Waive If: The application is built by a compiler that does not support CET
Example: FAIL: cf-protection test because only branch protection enabled
Example: FAIL: cf-protection test because only return protection enabled
Example: FAIL: cf-protection test because no protection enabled
Example: FAIL: cf-protection test because insufficient Control Flow sanitization
Example: FAIL: cf-protection test because no .note.gnu.property section = no control flow information
Example: FAIL: cf-protection test because CET enabling note missing
Example: FAIL: cf-protection test because control flow protection is not enabled
Intel have introduced a new security feature called CET to their
Tiger Lake and newer cores:
<https://newsroom.intel.com/editorials/intel-cet-answers-call-protect-common-malware-threats/#gs.avhl8k>
This test checks to see that this feature is enabled. Normally this
is done by compiling the code with the '-fcf-protection=full' command
line option enabled. But if an application contains assembler code, or
it is linked against a library that has not been built with the
protection enabled, or it is built by a compiler that does not support
CET then this test can fail.
The feature has to be enabled in the compiler as it involves
inserting new instructions into the compiled code. The feature is also
an all-or-nothing type proposition for any process. Either all of the
code in the process must have been built to support CET - in which case
the feature can be enabled - or if even a single component does not
support CET then it must be disabled for the entire process.
In order to enforce this the compiler inserts a special note into
compiled object files (the .note.gnu.property section referred to
above). The note indicates that CET is supported, as well as details of
the minimum x86 architecture revision needed and so on.
Then when the object files are linked together to create the
executable the linker checks all of these notes, and if any object file
or library is missing one then it does not put a note in the output
executable. Alternatively if all of the object files (and libraries of
course) do have notes, but one or more of them do not have the
CET-is-enabled flag, then the linker copies the notes into the
executable, but always clears the CET-is-enabled flag.
Finally when a program is executed the run-time loader checks this
note and if the CET-is-enabled flag is present then it enables the CET
feature in the hardware.
Fixing this check either means enabling the '-fcf-protection=full'
(for gcc) or the '-fcf-protection-branch' and '-fcf-protection-return'
options (for Clang).
If an assembler source file is used as part of an application then it
too needs to be updated. Any location in the source code where an
indirect branch or function call can land must now have either ENDBR64
(for 64-bit assembler) or ENDBR32 (for 32-bit assembler) as the first
instruction executed.
In addition the assembler needs a note to indicate that it now
supports CET. This note can be added via including this code snippet in
the sources:
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
If necessary the test can be disabled via the '--skip-cf-protection'
option and re-enabled via the '--test-cf-protection' option.
For more information on CET see:
<https://www.intel.com/content/dam/develop/external/us/en/documents/catc17-introduction-intel-cet-844137.pdf>
File: annobin.info, Node: Test dynamic segment, Next: Test dynamic tags, Prev: Test cf protection, Up: Hardened
4.2.5 The dynamic-segment 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.
Example: FAIL: dynamic segment test because multiple dynamic sections detected
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
'--skip-dynamic-segment' option and re-enabled via the
'--test-dynamic-segment' option.
File: annobin.info, Node: Test dynamic tags, Next: Test entry, Prev: Test dynamic segment, Up: Hardened
4.2.6 The dynamic-tags 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.
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
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 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
'-mbranch-protection=standard' gcc command line option.
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.
Note - this test is the inverse of the *note Test not dynamic tags::
test and directly related to the *note Test branch protection:: test.
Note - this test is automatically enabled if the '--profile=rawhide'
option or '--profile=f36' option is used and disabled if the
'--profile=el7', '--profile=el8', '--profile=el9' or '--profile=f35'
options are used.
If necessary the test can be disabled via the '--skip-dynamic-tags'
option and re-enabled via the '--test-dynamic-tags' option.
File: annobin.info, Node: Test entry, Next: Test fast, Prev: Test dynamic tags, Up: Hardened
4.2.7 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.
File: annobin.info, Node: Test fast, Next: Test fortify, Prev: Test entry, Up: Hardened
4.2.8 The -Ofast test
---------------------
Problem: Combining code that is compiled with -Ofast with code that
is not results in inconsistent behaviour
Fix By: Compiling everything with -Ofast
Waive If: The application does not use maths functions
Example: FAIL: fast test because some parts of the program were compiled with -Ofast and some were not.
This test checks that if part of the application was compiled with
the '-Ofast' option, then all of it was compiled with this option. If
only some parts are compiled with -Ofast then the parts that are not may
not behave correctly as they will be expecting to receive accurate
results from mathematical functions. For more details on this problem
see: <https://bugzilla.redhat.com/show_bug.cgi?id=1248744>
If necessary the test can be disabled via the '--skip-fast' option
and re-enabled via the '--test-fast' option.
File: annobin.info, Node: Test fortify, Next: Test gaps, Prev: Test fast, Up: Hardened
4.2.9 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 or -D_FORTIFY_SOURCE=3
Waive If: The application does not use C library string/memory functions
Example: FAIL: fortify test because -D_FORTIFY_SOURCE=[2|3] was not present on the command line
Example: FAIL: fortify test because -O level is too low
Example: FAIL: fortify test because no indication that the necessary option was used (and a C compiler was detected)
This test checks that the application was compiled with either
'-D_FORTIFY_SOURCE=2' or '-D_FORTIFY_SOURCE=3' specified on the compiler
command line. Since these options need good optimization in order to
work properly the test also checks that '-O2' or higher was used.
The '_FORTIFY_SOURCE' define enables the use of secure version of
certain string and memory C library functions. For full details of what
it does, see this blog:
<https://access.redhat.com/blogs/766093/posts/1976213>
Any program that uses the string or memory functions in the GLIBC
library should have this define present on the compiler command line.
Programs that do not use these functions do not need the define, but it
will not hurt to have it present anyway.
Note - this test is automatically disabled if the '--profile=el7'
option is used.
If necessary the test can be disabled via the '--skip-fortify' option
and re-enabled via the '--test-fortify' option.
File: annobin.info, Node: Test gaps, Next: Test glibcxx assertions, Prev: Test fortify, Up: Hardened
4.2.10 The gaps test
--------------------
Problem: Without complete coverage of the compiled code, other tests can miss problems
Fix By: Compile with -fplugin=annobin
Waive If: Not compiling C or C++ code
Example: FAIL: gaps were detected in the annobin coverage
This test checks to make sure that there are no gaps in the annobin
data for the binary being checked. If gaps are present then this means
that some parts of the program might have problems which cannot be
detected by annocheck.
If necessary the test can be disabled via the '--skip-gaps' option
and re-enabled via the '--test-gaps' option.
File: annobin.info, Node: Test glibcxx assertions, Next: Test gnu relro, Prev: Test gaps, Up: Hardened
4.2.11 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.
File: annobin.info, Node: Test gnu relro, Next: Test gnu stack, Prev: Test glibcxx assertions, Up: Hardened
4.2.12 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
Waive If: The application runs in an space/time constrained environment
Example: FAIL: gnu relro test because not linked with -Wl,-z,relro
Some parts of an executable need to be modified when it starts, so
that it can access any shared libraries that it uses. This process is
called relocation, and once it is finished the altered code/data should
not be modified again. The GNU RELRO test checks that write permission
can be removed once the relocations have finished.
Enabling GNU RELRO increases the executable size on disk and in
memory, and depending upon the application it can also cause a slow
start time. It does not cause any significant execution time penalty,
and using pre-linking can eliminate the startup penalty.
For programs that do not need to be reloaded often, such as daemons
and servers, and on systems where disk and memory are relatively
abundant such as desktops and servers, the overhead of GNU RELRO is very
insignificant and highly recommended. For programs that need to be
reloaded often, the execution penalty of GNU RELRO can be eliminated by
using prelinking. For embedded systems where space is scarce, GNU RELRO
is not recommended due to its space overhead.
To turn on GNU RELRO compile with the gcc '-Wl,-z,relro,-z,now'
option.
If necessary the test can be disabled via the '--skip-gnu-relro'
option and re-enabled via the '--test-gnu-relro' option.
File: annobin.info, Node: Test gnu stack, Next: Test go revision, Prev: Test gnu relro, Up: Hardened
4.2.13 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.
File: annobin.info, Node: Test go revision, Next: Test instrumentation, Prev: Test gnu stack, Up: Hardened
4.2.14 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.
File: annobin.info, Node: Test instrumentation, Next: Test lto, Prev: Test go revision, Up: Hardened
4.2.15 The instrumentation 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.
Example: WARN: Instrumentation enabled - this is probably a mistake for production binaries
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-instrumentation' option and re-enabled via the
'--test-instrumentation' option.
File: annobin.info, Node: Test lto, Next: Test not branch protection, Prev: Test instrumentation, Up: Hardened
4.2.16 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.
Note - this test is automatically disabled if the '--profile=el7' or
'--profile=el8' option is used.
If necessary the test can be disabled via the '--skip-lto' option and
re-enabled via the '--test-lto' option.
File: annobin.info, Node: Test not branch protection, Next: Test not dynamic tags, Prev: Test lto, Up: Hardened
4.2.17 The not-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.
Example: FAIL: not branch protection test because protection enabled
Example: FAIL: not branch protection test because only partially disabled
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 disabled if the '--profile=rawhide'
or '--profile=f36' options are used and enabled if the '--profile=el7',
'--profile=el8', '--profile=el9' or '--profile=f35' 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.
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
--------------------------------
Problem: Protecting AArch64 binaries needs newer versions of AArch64 cores
Fix By: Compile with -mbranch-protection=off
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.
Example: FAIL: not dynamic tags test because BTI_PLT and PAC_PLT flags are present in the dynamic tags
Example: FAIL: not dynamic tags test because BTI_PLT flag is present in the dynamic tags
Example: FAIL: not dynamic tags test because PAC_PLT flag is present in the dynamic tags
Note - this test is the inverse of the *note Test dynamic tags:: test
and directly related to the *note Test not branch protection:: test.
This test checks to see if executable AArch64 binaries have been
marked as supporting the BTI and PAC security features. Such features
require the support of the run-time loader in order to work, and this
test is intended for environments where this support is missing. (Such
as RHEL or pre version-35 Fedora).
The security features can be disabled by compiling with the
'-mbranch-protection=none' gcc command line option.
Note - this test is automatically disabled if the '--profile=rawhide'
or '--profile=f36' options are used and enabled if the '--profile=el7',
'--profile=el8', '--profile=el9' or '--profile=f35' options are used.
If necessary the test can be disabled via the
'--skip-not-dynamic-tags' option and re-enabled via the
'--test-not-dynamic-tags' option.
File: annobin.info, Node: Test notes, Next: Test only go, Prev: Test not dynamic tags, Up: Hardened
4.2.19 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
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 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 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 '-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).
Annobin notes can be generated for assembler sources by using the
'-Wa,--generate-missing-build-notes=yes' option. Even better would be
to add extra code to the assembler sources to create annobin notes that
describe the security features supported by the assembler.
Compiling a simple C program with the '-S -fverbose-asm
-fplugin=annobin <security option>' options should provide an example of
how to encode an annobin note about _<security option>_.
If necessary the test can be disabled via the '--skip-notes' and
'--skip-gaps' options and re-enabled via the '--test-notes' and
'--test-gaps' options.
File: annobin.info, Node: Test only go, Next: Test optimization, Prev: Test notes, Up: Hardened
4.2.20 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.
File: annobin.info, Node: Test optimization, Next: Test pic, Prev: Test only go, Up: Hardened
4.2.21 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
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
This test checks that the application was compiled with sufficient
optimization enabled.
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.
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.
File: annobin.info, Node: Test pic, Next: Test pie, Prev: Test optimization, Up: Hardened
4.2.22 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.
File: annobin.info, Node: Test pie, Next: Test production, Prev: Test pic, Up: Hardened
4.2.23 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.
Note - this test is automatically disabled if the '--profile=el7'
option is used.
If necessary the test can be disabled via the '--skip-pie' option and
re-enabled via the '--test-pie' option.
File: annobin.info, Node: Test production, Next: Test property note, Prev: Test pie, Up: Hardened
4.2.24 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 or CROSS FROM.
If necessary the test can be disabled via the '--skip-production'
option and re-enabled via the '--test-production' option.
File: annobin.info, Node: Test property note, Next: Test run path, Prev: Test production, Up: Hardened
4.2.25 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.
File: annobin.info, Node: Test run path, Next: Test rwx seg, Prev: Test property note, Up: Hardened
4.2.26 The run-path test
------------------------
Problem: An attacker could cause an application to use a corrupted shared library
Fix By: 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
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.
In addition if the '--profile=rawhide' option has been enabled then
the presence of the DT_RPATH dynamic tag will generate a MAYB result,
since in Fedora the DT_RUNPATH tag is preferred. (The two tags only
differ in when they are evaluated by the program loader). The
DT_RUNPATH dynamic tag should be generated by default, if it is needed,
but in some cases it may be necessary to add the '--enable-new-dtags'
option to the linker command line, or the '-Wl,--enable-new-dtags'
option if you use gcc to drive the linker.
If necessary the test can be disabled via the '--skip-run-path'
option and re-enabled via the '--test-run-path' option.
File: annobin.info, Node: Test rwx seg, Next: Test short enums, Prev: Test run path, Up: Hardened
4.2.27 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 are
1. have all three of the READ, WRITE and EXECUTE permissions.
2. have a non-zero size
3. are resident in memory when the program runs
4. do not have an architecture/OS specific type
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.
File: annobin.info, Node: Test short enums, Next: Test stack clash, Prev: Test rwx seg, Up: Hardened
4.2.28 The short-enums test
---------------------------
Problem: Compiler options can change the size of enums
Fix By: Compile with consistent use of the -fshort-enum option
Waive If: Enums are not passed between different compilation units
Example: FAIL: short-enum test because both short and long enums supported
The '-fshort-enums' gcc compiler option can be used to reduce code
size by storing enums in a SHORT instead of an INT. But if the code
passes enums between functions compiled in different files then the
'-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 '-fshort-enums' option, or that the option was never
used.
If necessary the test can be disabled via the '--skip-short-enums'
option and re-enabled via the '--test-short-enums' option.
File: annobin.info, Node: Test stack clash, Next: Test stack prot, Prev: Test short enums, Up: Hardened
4.2.29 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 (either gcc's '-fstack-clash-protection' or
LLVM's 'SafeStack' attribute. 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 - if LTO compilation is enabled then this option needs to be
provided both when the object files are built and when they are linked
together.
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>
Note - this test is automatically disabled if the '--profile=el7'
option is used.
If necessary the test can be disabled via the '--skip-stack-clash'
option and re-enabled via the '--test-stack-clash' option.
File: annobin.info, Node: Test stack prot, Next: Test stack realign, Prev: Test stack clash, Up: Hardened
4.2.30 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.
File: annobin.info, Node: Test stack realign, Next: Test textrel, Prev: Test stack prot, Up: Hardened
4.2.31 The stack-realign test
-----------------------------
Problem: Legacy x86 code is incompatible with SSE instructions
Fix By: Compile with -mstackrealign
Waive If: The application is not going run in a 32-bit x86 environment
Waive If: The application will not use SSE (or later) instructions
Example: FAIL: stack-realign test because -mstack-realign not enabled
Example: FAIL: stack-realign test because stack realign support is mandatory
On the Intel 32-bit x86 architecture most instructions work with
4-byte aligned addresses. The SSE extension (and later) however need
16-byte aligned addresses. This causes problems for data that is held
on the stack, if the stack pointer is not aligned to a 16-byte address.
The '-mstackrealign' gcc command line option tells the compiler to
generate extra code at function entry which ensures that 16-byte
alignment is maintained.
This test checks to make sure that this option has been used when
compiling x86 binaries.
If necessary the test can be disabled via the '--skip-stack-realign'
option and re-enabled via the '--test-stack-realign' option.
File: annobin.info, Node: Test textrel, Next: Test threads, Prev: Test stack realign, Up: Hardened
4.2.32 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.
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-textrel' option
and re-enabled via the '--test-textrel' option.
File: annobin.info, Node: Test threads, Next: Test unicode, Prev: Test textrel, Up: Hardened
4.2.33 The threads test
-----------------------
Problem: Programs that do not support exceptions are more vulnerable to attacks
Fix By: Compile with -fexceptions
Waive If: Program size is an important issue
Example: FAIL: threads test because not compiled with -fexceptions
This test checks to make sure that the '-fexceptions' g++ command
line option was used when building the binary. The test is only
triggered if the binary uses the PTHREADS library as single threaded
applications can cleanly tidy up after themselves if an exception is
generated.
If necessary the test can be disabled via the '--skip-threads' option
and re-enabled via the '--test-threads' option.
File: annobin.info, Node: Test unicode, Next: Test warnings, Prev: Test threads, Up: Hardened
4.2.34 The unicode test
-----------------------
Problem: Symbols containing certain unicode characters can conceal their real name
Fix By: Replacing the unicode characters with other characters
Waive If: The unicode names are valid
Example: FAIL: unicode test because dangerous characters were found in a symbol name
This test checks to make sure that symbols in the binary do not
contain control characters or multibyte (aka unicode) characters.
Whilst unicode characters are technically allowed in symbol names, their
presence is suspect since they can be used maliciously.
The test looks for the following characters in symbol names:
'Any control character'
'The space and DEL characters'
'Any non-unicode multibyte character'
In addition if the '--test-unicode-all' option has been enabled
(either via the command line, or via selecting a RHEL profile with the
'--profile' option) then the test will fail is any multibyte character
is found.
On the other hand, if the opposite '--test-unicode-suspicious' option
has been enabled then the test looks for:
'Any character with zero width'
'Any character that changes the direction of the text'
Other suspicious multibyte characters may be added in the future.
If necessary the test can be disabled via the '--skip-unicode' option
and re-enabled via the '--test-unicode' option.
File: annobin.info, Node: Test warnings, Next: Test writable got, Prev: Test unicode, Up: Hardened
4.2.35 The warnings test
------------------------
Problem: Compiling without warnings enabled can result in poor code
Fix By: Add -Wall to the compiler command line
Waive If: There are known problems with using -Wall
Example: FAIL: warnings test because compiled without either -Wall or -Wformat-security
This test checks to see that a file has been compiled with either or
both of the '-Wall' and '-Wformat-security' options specified. Enabling
warnings - and then fixing the problems reported - results in better
quality code that is less likely to contain bugs.
If necessary the test can be disabled via the '--skip-warnings'
option and re-enabled via the '--test-warnings' option.
File: annobin.info, Node: Test writable got, Next: Test zero call used regs, Prev: Test warnings, Up: Hardened
4.2.36 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.
File: annobin.info, Node: Test zero call used regs, Next: Hardened Command Line Options, Prev: Test writable got, Up: Hardened
4.2.37 The zero-call-used-regs test
-----------------------------------
Problem: An attacker could extract information or use ROP style attacks if call used registers are not initialised
Fix By: Add -fzero-call-used-regs=all
Waive If: The overhead of initializing the registers is too high
Example: FAIL: zero-call-used-regs test because -fzero-call-used-regs not used or set to 'skip'
This is a future test. It is not enabled by default. It checks a
security feature that may not be widely available or enforced.
This test checks to make sure that programs have been compiled with
the '-fzero-call-used-regs=' command line option. This option ensures
that registers used in a function call are set to zero when the function
returns. If this is not done then a potential attacker might be able to
access information in the registers and/or use them in ROP style
attacks.
The test can be enabled via the '--test-zero-call-used-regs' option
and disabled by the '--skip-zero-call-used-regs' option. It is also
enabled if the '--test-future' option is specified and disabled if the
'skip-future' option is specified.
File: annobin.info, Node: Hardened Command Line Options, Next: Waiving Hardened Results, Prev: Test zero call used regs, Up: Hardened
4.2.38 Command line options specific to the hardened tool
---------------------------------------------------------
'--skip-TEST[=FUNCNAME]'
Disable the test called TEST. If the optional FUNCNAME argument is
supplied then the test is only disabled for the named function (and
by implication it is enabled for other functions). This extended
version of the option can be used multiple times to allow the test
to be skipped for multiple functions.
'--skip-all'
Disable all tests. Not really useful unless followed by...
'--test-NAME'
Enable test NAME.
'--test-all'
Enable all the tests.
'--test-future'
'--skip-future'
Report _future fail_ tests. These are tests for security features
which are not yet implemented or widely adopted, but which are
planned for the future. The '--skip-future' option can be used to
restore the default behaviour of skipping these tests.
'--test-unicode-all'
'--test-unicode-suspicious'
The '--test-unicode' test checks for the presence of multibyte
characters in symbol names, which are unusual and potentially
dangerous. The test has two modes of operation. In one mode,
enabled by '--test-unicode-all', any multibyte character is
considered suspicious. This mode is good for code bases where
multibyte characters are not expected to appear at all.
In the other mode, enabled by '--test-unicode-suspicious', only
potentially dangerous unicode characters trigger a failure. See
*note Test unicode:: for more details on which characters are
considered suspicious.
If neither of these options is specified, the default depends upon
the profile selected. If a profile is not selected then the
default is only fail upon the detection of suspicious characters.
'--profile=el7'
'--profile=rhel-7'
'--profile=el8'
'--profile=rhel-8'
'--profile=el9'
'--profile=rhel-9'
'--profile=rawhide'
'--profile=f37'
'--profile=f36'
'--profile=f35'
'--profile=default'
'--profile=none'
'--profile=auto'
Rather than enabling and disabling specific tests a selection can
be chosen via a profile option. The '--profile=el7' and
'--profile=rhel-7' options will select the tests suitable for
_RHEL-7_ binaries. Similarly '--profile=el8' or '--profile=rhel-8'
configures the tests for _RHEL-8_ and '--profile=el9' or
'--profile=rhel-9' configures them for _RHEL-9_.
The '--profile=rawhide' option will select tests suitable for
_Fedora rawhide_ binaries, whilst '--profile=f37' selects tests
suitable for _Fedora F37_, '--profile=f36' selects tests suitable
for _Fedora F36_ and '--profile=f35' option selects tests suitable
for _Fedora F35_.
Other profiles may be added in the future.
The '--profile=auto' option will attempt to determine the profile
to use, based upon the input filename. This only works with
_rpms_, which include the OS as part of their name. This option is
the default.
Using '--profile=none' will disable the profiling.
For backwards compatibility the form '--profile-<name>' can be used
instead of '--profile=<name>'.
Currently the profiles enable and disable the following tests:
'el9'
'f35'
Disables the *note Test branch protection:: and *note Test
dynamic tags:: tests and enables their inverse, ie *note Test
not branch protection:: and *note Test not dynamic tags::.
Also enables *note Test unicode:: and sets the default to fail
for any multibyte character.
'el8'
Like 'el9' but also disables the *note Test lto:: test.
'el7'
Like 'el8' but also disables the *note Test pie::, *note Test
bind now::, *note Test fortify:: and *note Test stack clash::
tests.
'rawhide'
'f36'
Enables the *note Test branch protection:: and *note Test
dynamic tags:: tests and disables their inverse, ie *note Test
not branch protection:: and *note Test not dynamic tags::.
Also enables *note Test unicode:: and sets the default to fail
for any suspicious multibyte characters.
'--disable-hardened'
Disable the tool.
'--enable-hardened'
Enable the tool if it was previously disabled. The option is also
the default.
'--ignore-gaps'
Do not complain about gaps in the note data.
'--report-gaps'
Do complain about gaps in the note data.
'--fixed-format-messages'
Display messages in a fixed, machine parseable format. The format
is:
Hardened: <result>: test: <test-name> file: <file-name>
Where '<result>' is _PASS_ or _FAIL_ and '<test-name>' is the name
of the test, which is the same as the name used in the
'--test-<test-name>' option. The '<filename>' is the name of the
input file, but with any special characters replaced so that it
always fits on one line.
Here is an example:
Hardened: FAIL: test: pie file: a.out.
'--disable-colour'
'--enable-colour'
'--disable-color'
'--enable-color'
Do not use colour to enhance FAIL, MAYB and WARN messages. By
default annocheck will add colour to these messages so that they
stand out when displayed by a terminal emulator. This option can
be used in order to turn this feature off. The feature can be
re-enabled with '--enable-colour'. The American spelling of color
is also supported.
'--full-filenames'
'--base-filenames'
Use the full pathname for files. Useful when recursing into
directories. By default this feature is disabled in normal mode
and enabled in 'verbose' mode. This option and its inverse
'--base-filenames' can be used to set a fixed choice.
'--no-urls'
'--provide-urls'
By default when a FAIL or MAYB result is displayed by the HARDENED
checker and '--verbose' is enabled, a URL to the online version of
the relevant section in this document is also displayed. (Unless
the '--fixed-format-messages' option has been enabled). The
'--no-urls' option disables the display of the URLs and the
'--provide-urls' re-enables the display (even in non-verbose mode).
File: annobin.info, Node: Waiving Hardened Results, Next: Absence of compiled code, Prev: Hardened Command Line Options, Up: Hardened
4.2.39 How to waive the results of the hardening tests
------------------------------------------------------
[This section is Red Hat specific.]
Now that 'annocheck' is being used by the builders for Fedora and
RHEL packages it is possible that certain tests may need to be waived
for certain packages. This can be done on a per-package basis by
editing the contents of the 'rpminspect.yaml' file and adding an entry
like this:
---
annocheck:
- hardened: --skip-property-note --ignore-unknown --verbose
This example shows how the _property note_ test can be ignored.
Beware however that doing this overrides the default options that are
passed to annocheck by the rpminspect framework, which is why the
'--ignore-unknown' and '--verbose' options are also included in the
example.
Note - for RHEL the above might not work, as the hardened checker is
referred to by another name. So if that appears to be the case, please
try:
---
annocheck:
- rhel-policy: --skip-property-note --ignore-unknown --verbose
It is also possible to stop annocheck from testing specific files in
an rpm by listing them in the 'rpminspect.yaml file', like this:
---
annocheck:
ignore:
- /usr/libexec/installed-tests/glib/mem-overflow
- /usr/libexec/installed-tests/glib/resources
For more information on rpmdiff see:
<https://docs.engineering.redhat.com/display/HTD/rpmdiff-elf-binarylibrary>
For more information on the use of annobin in RHEL see:
<https://one.redhat.com/rhel-developer-guide/#_annocheck_ensuring_comprehensive_elf_distro_flags>
To get more help on deciding whether or not a test should be waived
please ask on either of the OS-DEVEL-LIST AT REDHAT.COM OS Devel or the
RHEL-DEVEL AT REDHAT.COM RHEL Devel mailing lists.
File: annobin.info, Node: Absence of compiled code, Prev: Waiving Hardened Results, Up: Hardened
4.2.40 What to do if annocheck reports that it could not find compiled code.
----------------------------------------------------------------------------
The hardening checker will automatically skip some tests if it cannot
prove that the file being checked was created by a known compiler, or if
the code was created from assembler sources, rather than a high level
language. This is because the test being skipped is checking for a
specific feature of a specific compiler.
The checker uses several different methods for determining if an
executable was compiled:
'notes'
If there are annobin notes present, these include a description of
the compiler used to create the executable.
'DWARF'
If DWARF debug information is available, the compiler can usually
be found in the DW_AT_producer tag.
'comment'
If there is a _.comment_ section in the file, then this usually
contains the name of the compiler.
'GO note'
The presence of a _.note.go.buildid_ section indicates that the
file contains GO compiler code.
'GO symbol'
The presence of a variable called 'go1.<V>' in the read-only data
section. Again this indicates the presence of GO compiled code.
'executable segments'
If the file contains one or more program segments with the
_executable_ flag set, then this indicates that it is likely to
contain compiled code.
There are several reasons why annocheck might think that the file
does not originate from compiled source code:
'fake assembler'
Sometimes when compiling code it is desireable to be able to build
it without certain security options, but also without annocheck
complaining about them. This is used by 'glibc' for example
because it does not use stack checking or function fortification.
This effect can be achieved with 'GCC' by using the
'-Wa,--generate-missing-build-notes' command line option. This
tells the assembler to generate a fake annobin note that tells
annocheck to treat all of the code as if it has been produced from
assembler sources _and_ to ignore tests specific to high level
languages.
'real assembler'
The file was created from assembler source code or some other low
level language. In this case futher manual checking is warranted.
If the source code has not been written with the particular
security feature in mind, then it may be vulnerable.
If on the other hand it does not need the security feature or it
has been written to support it, then adding an annobin note to the
assembler sources will stop annocheck from complaining.
For example the following will add a note about strong stack
protection:
.pushsection .gnu.build.attributes, "o", %note, .text
.balign 4
.dc.l 2f - 1f # Size of the name field.
.dc.l 0 # Empty description field.
.dc.l 0x100 # This is an OPEN note which applies to all the code in the covered region.
1:
.dc.b 'G', 'A', # This is a GNU attribute
.dc.b '*' # It contains a numeric value
.dc.b 0x2 # For the -fstack-protector option
.dc.b 0x3 # The value is 3, which indicated -fstack-protector-strong
.dc.b 0 # Since this field is nominally a name, it ends with a NUL byte.
2:
.dc.b 0, 0 # Padding to ensure note ends on a 4 byte boundary.
.popsection
Compiling a simple C program with the '-S -fverbose-asm
-fplugin=annobin <security option>' options should provide an
example of how to encode a note about _<security option>_.
Note - in order for annobin notes to work at least one of them
needs to specify the address range that they cover. This is
usually done by a version note, which details the version number of
the tool used to produce the code. For assembler this note would
look like this:
.pushsection .gnu.build.attributes, "o", %note, .text
.balign 4
.dc.l 2f - 1f # Size of the name field.
.dc.l 16 # Size of the description field (= 2 * sizeof (address)).
.dc.l 0x100 # This is an OPEN note which applies to all the code in the covered region.
1:
.dc.b 'G', 'A', # This is a GNU Attribute note.
.dc.b '$' # It contains a string value.
.dc.b 0x1 # The string is a VERSION string.
.dc.b '3', # Version 3 of the Watermark Protocol is being used.
.dc.b 'a', # The code has been produced by an 'a'ssembler.
.dc.b '2' # The assembler's major version number is 2.
.dc.b 0 # Since this field is nominally a name, it ends with a NUL byte.
2:
# Coincidentally, no padding is needed here.
.quad <insert-start-symbol-here>
.quad <insert-end-symbol-here>
.popsection
'unsupported source language'
The file was created by compiling high-level language source code,
but in a language with which annocheck is unfamiliar. In this case
it may still make sense to skip the test, if it is checking for a
feature that is not supported by the language's compiler.
'annobin annotation not enabled'
The file was created by compiling C and/or C++ but without any
annobin notation enabled, and without any debug information
generation. In this case there may be a problem, since the test
being skipped might actually fail if annocheck knew that the file
was compiled.
Fixing this problem involves investigating how the executable was
built and adding the necessary rules to invoke the annobin plugin
and the sought after security hardening options.
'stripped of symbols and notes'
The file was built normally, but then stripped of most of the
useful information, including its symbol table, debug information,
annobin notes and so on.
Restoring the stripped information should solve this problem.
File: annobin.info, Node: Notes, Next: Size, Prev: Hardened, Up: Annocheck
4.3 The annobin note displayer
==============================
annocheck
[-disable-hardened]
-enable-notes
FILE...
The NOTES tool displays the contents of any annobin notes inside the
specified files. It groups the notes by address range, which can help
locate missing details.
The NOTES tool is disabled by default, but it can be enabled by the
command line option '--enable-notes'. Since the hardening checker is
enabled by default it may also be useful to add the '--disable-hardened'
option to the command line.
File: annobin.info, Node: Size, Next: Timing, Prev: Notes, Up: Annocheck
4.4 The section size recorder
=============================
annocheck
[-disable-hardened]
[-size-sec=NAME]
[-size-sec-flags=!WAX]
[-size-seg-flags=!WRX]
[-size-human]
[-size-total]
[-size-missing]
[-disable-size]
FILE...
The SECTION-SIZE tool records the size of named sections within a
list of files and then reports the accumulated size at the end. Since
it is part of the 'annocheck' framework, it is able to handle
directories and rpms files as well as ordinary binary files.
The '--size-sec=NAME' option enables the tool and tells it to record
the size of section NAME. The option can be repeated multiple times to
record the sizes of multiple sections. It may also be useful to add the
'--disable-hardened' option to the command line as otherwise the
security hardening will be run at the same time.
Instead of searching for named sections, it is also possible to
search for sections with specific flags. The '--size-sec-flags=<flags>'
option will search for any section that has all of the specified <FLAGS>
set. Currently only W, A and X are recognised as flags, indicating that
the section must have the WRITE, ALLOC or EXECUTE flags set
respectively. If the ! exclamation mark character is present then it
negates the meaning of the following flags. Thus
'--section-sec-flags=W' option will search for any writable section
whereas the '--size-sec-flags=W!A' option will search only for sections
that are writable but not allocated.
Instead of searching for sections by flags it is also possible to
search for segments by flags using the '--size-seg-flags=<flags>'
option. The flags recognised for segments are W for writable, R for
readable and X for executable. Again the ! character can be used to
invert the meaning of the flags that follow it.
If the '--verbose' option is enabled, then the tool will also report
the size of the named section(s) in each file it encounters.
If the '--size-human' option is enabled then sizes will be rounded
down to the nearest byte, kibibyte, mebibyte or gibibyte, as
appropriate.
If the '--size-total' option is enabled then the total size of all
sections in all scanned files will also be reported, as well as the
ratio of the reported section sizes to the total section size.
If the '--size-missing' option is enabled then any valid ELF format
input file that does not contain any of the sought sections will be
reported.
If previously enabled the tool can be disabled via the
'--disable-size' command line option.
File: annobin.info, Node: Timing, Prev: Size, Up: Annocheck
4.5 How long did the check take ?
=================================
annocheck
-enable-timing
FILE...
[-sec]
[-usec]
[-nsec]
The TIMING tool reports on the time taken by other tools to scan the
list of files. The tool is disabled by default, but it can be enabled
by the command line option '--enable-timing'.
By default the tool will report times in microseconds, but you can
change this to reporting in seconds with the '--sec' or in nanoseconds
with the '--nsec'. The default can be restored with the '--usec'
option.
File: annobin.info, Node: Libannocheck, Next: Configure Options, Prev: Annocheck, Up: Top
5 Allowing other programs to run security checks
************************************************
The 'annocheck' program is mostly seen as a security checking tool and
in order to allow third party programs such as 'rpminspect' the ability
to access these checks a library interface is provided.
An example of how to use the libannocheck library can be found in the
annobin testsuite. In particular the 'tests/use-libannocheck.c' file
contains code to initialise, run and then close the library. In theory
however the code flow looks like this:
#include <libannocheck.h>
struct libannocheck_internals * handle;
unsigned int num_fails, num_maybs;
handle = libannocheck_init (libannocheck_version, "a.out", NULL);
libannocheck_disable_all_tests (handle);
libannocheck_enable_test (handle, "bind-now");
libannocheck_run_tests (handle, & num_fails, & num_maybs);
libannocheck_finish (handle);
The library consists of a header file ('libannocheck.h') and a shared
object file (libannocheck.so). It provides the following functions:
* Menu:
* libannocheck_init:: Initialise the library
* libannocheck_finish:: Close the library
* libannocheck_get_version:: Get the library version
* libannocheck_get_error_message:: Convert an error number into an error message
* libannocheck_get_known_tests:: Get a list of tests supported by the library
* libannocheck_enable_all_tests:: Enable all tests
* libannocheck_disable_all_tests:: Disable all tests
* libannocheck_enable_test:: Enable a specific test
* libannocheck_disable_test:: Disable a specific test
* libannocheck_enable_profile:: Enable a profile
* libannocheck_get_known_profiles:: Get a list of known profiles
* libannocheck_run_tests:: Run enabled tests
File: annobin.info, Node: libannocheck_init, Next: libannocheck_finish, Up: Libannocheck
5.1 Initialise the library
==========================
struct libannocheck_internals *
libannocheck_init (unsigned int VERSION,
const char * FILEPATH,
const char * DEBUGPATH)
Returns a token used to identify the instantiation in future calls.
VERSION is the expected version of the libannocheck library. This
should normally be 'libannocheck_version'. If the actual version of the
library cannot support VERSION then libannocheck_error_bad_version is
returned.
FILEPATH is a path the binary to be tested. It can be absolute or
relative. It may not be NULL.
DEBUGPATH is a path the debug info file associated with FILEPATH. It
can be NULL.
Returns an enum libannocheck_error cast to a struct
libannocheck_internals * if something goes wrong.
File: annobin.info, Node: libannocheck_finish, Next: libannocheck_get_version, Prev: libannocheck_init, Up: Libannocheck
5.2 Close the library
=====================
libannocheck_error
libannocheck_finish (struct libannocheck_internals * HANDLE)
Closes the connection to libannocheck. Closes any files opened by
the library and releases any memory that is may have allocated. After
this any library call using HANDLE should fail.
Returns libannocheck_error_none upon successful closure, otherwise
returns an error code.
File: annobin.info, Node: libannocheck_get_version, Next: libannocheck_get_error_message, Prev: libannocheck_finish, Up: Libannocheck
5.3 Get the library version
===========================
unsigned int
libannocheck_get_version (void)
Returns the actual version number of the libannocheck_library. This
should be >= libannocheck_version as defined in the 'libannocheck.h'
header file.
File: annobin.info, Node: libannocheck_get_error_message, Next: libannocheck_get_known_tests, Prev: libannocheck_get_version, Up: Libannocheck
5.4 Convert an error number into an error message
=================================================
const char *
libannocheck_get_error_message
(struct libannocheck_internals * HANDLE,
enum libannocheck_error ERRNUM)
Returns a (read only) string describing libannocheck error number
ERRNUM. Returns NULL if the error code is not recognised.
Handle can be NULL if one is not available. If provided a more
detailed error message may be returned.
File: annobin.info, Node: libannocheck_get_known_tests, Next: libannocheck_enable_all_tests, Prev: libannocheck_get_error_message, Up: Libannocheck
5.5 Get a list of tests supported by the library
================================================
libannocheck_error
libannocheck_get_known_tests
(struct libannocheck_internals * HANDLE,
libannocheck_test ** TESTS_RETURN,
unsigned int * NUM_TESTS_RETURN)
Returns a (read/write) array of tests known to libannocheck in
TESTS_RETURN. Returns the number of elements in the array in
NUM_TESTS_RETURN. Returns libannocheck_error_none if the retrieval
succeeded, or an error result otherwise. The returned array should not
be freed.
The array is used by libannocheck internally, so if fields are
changed this will affect the library's behaviour. In particular tests
can be enabled and disabled without needing to call
'libannocheck_enable_test' or 'libannocheck_disable_test'.
The test_result_reason and test_result_source fields will initially
be NULL. They may have their values changed as a result of a call to
'libannocheck_run_tests'.
File: annobin.info, Node: libannocheck_enable_all_tests, Next: libannocheck_disable_all_tests, Prev: libannocheck_get_known_tests, Up: Libannocheck
5.6 Enable all tests
====================
libannocheck_error
libannocheck_enable_all_tests (struct libannocheck_internals * HANDLE)
Enables all the tests supported by libannocheck.
This function may change some of the fields in the data structure
returned by the 'libannocheck_get_known_tests' function.
File: annobin.info, Node: libannocheck_disable_all_tests, Next: libannocheck_enable_test, Prev: libannocheck_enable_all_tests, Up: Libannocheck
5.7 Disable all tests
=====================
libannocheck_error
libannocheck_disable_all_tests (struct libannocheck_internals * HANDLE)
Disables all of the tests supported by libannocheck. Not normally
useful unless followed by code to enable one or more tests.
This function may change some of the fields in the data structure
returned by the 'libannocheck_get_known_tests' function.
File: annobin.info, Node: libannocheck_enable_test, Next: libannocheck_disable_test, Prev: libannocheck_disable_all_tests, Up: Libannocheck
5.8 Enable a specific test
==========================
libannocheck_error
libannocheck_enable_test
(struct libannocheck_internals * HANDLE,
const char * TEST_NAME)
Enables a specific test. Returns 'libannocheck_error_none' upon
success or an error code otherwise. If the test is not known then
'libannocheck_error_test_not_found' is returned.
This function may change some of the fields in the data structure
returned by the 'libannocheck_get_known_tests' function.
File: annobin.info, Node: libannocheck_disable_test, Next: libannocheck_enable_profile, Prev: libannocheck_enable_test, Up: Libannocheck
5.9 Disable a specific test
===========================
libannocheck_error
libannocheck_disable_test
(struct libannocheck_internals * HANDLE,
const char * TEST_NAME)
Disables a specific test. Returns 'libannocheck_error_none' upon
success or an error code otherwise. If the test is not known then
'libannocheck_error_test_not_found' is returned.
This function may change some of the fields in the data structure
returned by the 'libannocheck_get_known_tests' function.
File: annobin.info, Node: libannocheck_enable_profile, Next: libannocheck_get_known_profiles, Prev: libannocheck_disable_test, Up: Libannocheck
5.10 Enable a profile
=====================
libannocheck_error
libannocheck_enable_profile
(struct libannocheck_internals * HANDLE,
const char * PROFILE_NAME)
Enables and disables certain tests known to be relevant to a specific
profile.
Returns libannocheck_error_profile_not_known if the profile is not
recognised.
File: annobin.info, Node: libannocheck_get_known_profiles, Next: libannocheck_run_tests, Prev: libannocheck_enable_profile, Up: Libannocheck
5.11 Get a list of known profiles
=================================
libannocheck_error
libannocheck_get_known_profiles
(struct libannocheck_internals * HANDLE,
const char *** PROFILES_RETURN,
unsigned int * NUM_PROFILES_RETURN)
Retrieves a (read only) array of profile strings known to
libannocheck. The array is returned in PROFILES_RETURN. The number of
entries in the array is returned in NUM_PROFILES. Returns
libannocheck_error_none upons success, or an error code otherwise.
File: annobin.info, Node: libannocheck_run_tests, Prev: libannocheck_get_known_profiles, Up: Libannocheck
5.12 Run enabled tests
======================
libannocheck_error
libannocheck_run_tests
(struct libannocheck_internals * HANDLE,
unsigned int * NUM_FAIL_RETURN,
unsigned int * NUM_MAYB_RETURN)
Runs all enabled tests.
Returns the number of failed tests in NUM_FAIL_RETURN (if this
parameter is not NULL).
Returns the number of "maybe" results in NUM_MAYB_RETURN (if this
parameter is not NULL).
Retuns libannocheck_error_none if everything went OK.
Updates the STATE, TEST_RESULT_REASON and TEST_RESULT_SOURCES fields
in the entries in the array returned by 'libannocheck_get_known_tests'
for any enabled test.
Can be called multiple times.
File: annobin.info, Node: Configure Options, Next: Legacy Scripts, Prev: Libannocheck, Up: Top
6 Configuring annobin and annocheck
***********************************
When building annobin and annocheck from the sources there are a few
configure options available to customise the build:
'--with-debuginfod'
debuginfod is a web service that indexes ELF/DWARF debugging
resources by build-id and serves them over HTTP.
By default the 'annocheck' program will be built and linked with
the debuginfod client library 'libdebuginfod' if it is present at
build time. The '--with-debuginfod' configure option can be used
to force the linking against the library even if the run-time
'debuginfod' program cannot be found. Alternatively the '--without
debuginfod' can be used to force annobin to be built without
'libdebuginfod' support, even if it is present on the build system.
debuginfod is packaged with elfutils, starting with version 0.178.
You can get the latest version from
'https://sourceware.org/elfutils/'.
'--with-gmp=PATH'
The '--with-gmp=PATH' option can be used to specify an alternative
path to the gmp libraries, if necessary.
'--without-libelf'
The annocheck program uses 'libelf' to read ELF binaries. By
default the configure system will detect if the library is
installed and if not, then it will disable the building of
'annocheck' and the running of the tests. (Since they use
'annocheck'). This behaviour can be overridden by the
'--without-libelf' option which forces the build to assume that
libelf is absent even if it would normally be detected.
'--without-tests'
Disable running the testsuite after building the various binaries.
'--with-clang'
Enable the building of the annobin plugin for the Clang compiler.
'--with-llvm'
Enable the building of the annobin plugin for the LLVM compiler
backend. This is separate from the Clang plugin and can be used
with any language that uses LLVM as a backend compiler.
'--without-gcc-plugin'
Do not build the gcc plugin.
'--without-docs'
Do not build the documentation.
'--enable-maintainer-mode'
This enables the regeneration of the 'Makefile' and 'configure'
files when building the 'annobin' sources.
File: annobin.info, Node: Legacy Scripts, Next: GNU FDL, Prev: Configure Options, Up: Top
7 How to use the information stored in the binary.
**************************************************
The 'annobin' package includes some example scripts that demonstrate how
the binary information can be used.
_NOTE_: These scripts are now redundant, their functionality having
been subsumed into the 'annocheck' program. However they are still
useful as examples of how the annobin data can be consumed, so they are
still included in the annobin sources.
The scripts are:
* Menu:
* Who Built Me:: The built-by script
* ABI Checking:: The check-abi script
* Hardening Checks:: The hardened script
* Checking Archives:: The run-on-binaries-in script
File: annobin.info, Node: Who Built Me, Next: ABI Checking, Up: Legacy Scripts
7.1 The built-by script
=======================
built-by
[-help]
[-version]
[-verbose]
[-quiet]
[-silent]
[-ignore]
[-readelf=PATH]
[-tmpdir=DIR]
[-tool=NAME]
[-nottool=NAME]
[-before=DATE]
[-after=DATE]
[-minver=VERSION]
[-maxver=VERSION]
[-]
FILE...
The 'built-by' script reports the name and version of the tool used
to build the specified file(s). This script also demonstrates how
information can be extracted from other other locations in the file, not
just the binary annotation notes.
The script can also be used to filter files, only reporting those
built by a specific tool, or a specific version of a tool, or even by a
version of a tool that was built between a range of dates.
The options available are:
'--help'
'-h'
Displays the usage of the script and then exits.
'--version'
'-v'
Displays the version of the script.
'--verbose'
'-V'
Enables verbose mode, causing the script to detail each action it
takes.
'--quiet'
'-q'
Do not include the name of script in the out generated by the
script.
'--silent'
'-s'
Produce no output. Just return an exit status.
'--ignore'
Do not report file types that do not contain any builder
information.
'--tool=NAME'
Only report binaries built by NAME. The NAME is only an ordinary
string, not a regular expression.
'--nottool=NAME'
Skip any binary build by NAME. The NAME is only an ordinary
string, not a regular expression.
'--before=DATE'
Only report binaries built by a tool that was created before DATE.
DATE has the format YYYYMMDD.
'--after=DATE'
Only report binaries built by a tool that was created after DATE.
When combined with the '--before' option can be used to restrict
output to files which were built by tools created in a specific
date range.
'--minver=VERSION'
Only report binaries built by a tool whose version is VERSION or
higher. The VERSION string should be in the form V.V.V, for
example 6.2.1.
'--maxver=VERSION'
Only report binaries built by a tool whose version is VERSION or
lower. Can be combined with the '--minver' option to restrict
output to those binaries created by tools within a specific version
range.
'--tmpdir='dir''
'-t 'dir''
Directory to use to store temporary files.
'--readelf='path''
'-r='path''
Use the specified program to read the notes from the files.
'--'
Stop accumulating command line options. This allows the script to
be run on files whose names starts with a dash.
File: annobin.info, Node: ABI Checking, Next: Hardening Checks, Prev: Who Built Me, Up: Legacy Scripts
7.2 The check-abi script
========================
check-abi
[-help]
[-version]
[-verbose]
[-quiet]
[-silent]
[-inconsistencies]
[-ignore-unknown]
[-ignore-ABI|ENUM|FORTIFY|STACK-PROT]
[-readelf=path]
[-tmpdir=dir]
[-]
FILE...
The 'check-abi' script reports any potential ABI conflicts in the
files specified. This includes the use of the '-fshort-enums' option,
the '-fstack-protector' option and the '-D_FORTIFY_SOURCE' option. All
of these can affect passing data between functions and hence should be
used uniformly throughout the binary.
The script accepts the following command line options:
'--help'
'-h'
Displays the usage of the script and then exits.
'--version'
'-v'
Displays the version of the script.
'--verbose'
'-V'
Enables verbose mode, causing the script to detail each action it
takes.
'--quiet'
'-q'
Do not include the name of script in the out generated by the
script.
'--silent'
'-s'
Produce no output. Just return an exit status.
'--inconsistencies'
'-i'
Only report files with potential ABI problems.
'--ignore-unknown'
Do not report file types that are not supported or recognised.
'--ignore-ABI|ENUM|FORTIFY|STACK-PROT'
Disables individual ABI checks. Multiple occurrences of this
option accumulate. Possible option values are:
'ABI'
Disable checks of the general ABI information.
'enum'
Disable checks of the '-fshort-enum' option.
'FORTIFY'
Disable checks of the '-D_FORTIFY_SOURCE' option.
'stack-prot'
Disable checks of the '-fstack-protect' option.
'--tmpdir=dir'
'-t dir'
Directory to use to store temporary files.
'--readelf=path'
'-r=path'
Use the specified program to read the notes from the files.
'--'
Stop accumulating command line options. This allows the script to
be run on files whose names starts with a dash.
File: annobin.info, Node: Hardening Checks, Next: Checking Archives, Prev: ABI Checking, Up: Legacy Scripts
7.3 The hardened script
=======================
hardened
[-help]
[-version]
[-verbose]
[-quiet]
[-ignore-unknown]
[-silent]
[-vulnerable]
[-not-hardened]
[-all]
[-file-type=AUTO|LIB|EXEC|OBJ]
[-skip=OPT|STACK|FORT|NOW|RELRO|PIC|OPERATOR|CLASH|CF|CET|REALIGN]
[-readelf=path]
[-tmpdir=dir]
[-]
FILE...
The 'hardened' script reports on the hardening status of the
specified file(s). In particular it checks that the whole file was
compiled with '-O2' or higher and the '-fstack-protector-strong',
'-D_FORTIFY_SOURCE=2', '-Wl,-z,now', '-Wl,-z,relro', '-fPIE',
'-Wp,-D_GLIBCXX_ASSERTIONS', '-fstack-clash-protection'
'-fcf-protection=full' and '-mcet' options.
The script accepts the following command line options:
'--help'
'-h'
Displays the usage of the script and then exits.
'--version'
'-v'
Displays the version of the script.
'--verbose'
'-V'
Enables verbose mode, causing the script to detail each action it
takes.
'--quiet'
'-q'
Do not include the name of script in the out generated by the
script.
'--ignore-unknown'
'-i'
Do not report file types that are not supported or recognised.
'--tmpdir=dir'
'-t dir'
Directory to use to store temporary files.
'--silent'
'-s'
Produce no output. Just return an exit status.
'--vulnerable'
'-u'
Only report files that are known to be vulnerable. Ie files that
record all of the necessary information about how they were built,
but which were built with an incorrect set of options.
This option is the default behaviour of the script.
'--not-hardened'
'-n'
Report any file that cannot be proven to be hardened. This is like
the '--vulnerable' option, except that it will also report files
that do not record all of the necessary information.
'--all'
'-a'
Report the hardening status of all of the files examined.
'--file-type=AUTO|LIB|EXEC|OBJ'
'-f=AUTO|LIB|EXEC|OBJ'
Specifies the type of file being examined. Possible values are:
'auto'
Automatically determine the file type from its extension.
This is the default.
'lib'
Assume all files are shared libraries. Checks that the
'-fPIC' option was used.
'exec'
Assume all files are executables. Checks that the '-fPIE'
option was used.
'obj'
Assume all files are object files. Skips checks of the bind
now status.
'--skip=OPT|STACK|FORT|NOW|RELRO|PIC|OPERATOR|CLASH|CF|CET'
'-k=OPT|STACK|FORT|NOW|RELRO|PIC|OPERATOR|CLASH|CF|CET'
Disables checks of various different hardening features. This
option can be repeated multiple times, and the values accumulate.
Possible values are:
'opt'
Disables checks of the optimization level used.
'stack'
Disables checks of the stack protection level.
'fort'
Disables checks for '-D_FORTIFY_SOURCE'.
'now'
Disables checks for 'BIND NOW' status.
'relro'
Disables checks for 'relro' or read-only-relocs.
'pic'
Disables checks for '-fPIC'/'-fPIE'.
'operator'
Disables checks for '-D_GLIBCXX_ASSERTIONS'.
'clash'
Disables checks for stack clash protection.
'cf'
Disables checks for control flow protection. Note - these
checks are only run on x86_64 binaries.
'cet'
Disables checks for control flow enforcement. Note - these
checks are only run on x86_64 binaries.
'realign'
Disable checks for stack realignment. Note - these checks are
only run on i686 binaries.
'--readelf=path'
'-r=path'
Use the specified program to read the notes from the files.
'--'
Stop accumulating command line options. This allows the script to
be run on files whose names starts with a dash.
File: annobin.info, Node: Checking Archives, Prev: Hardening Checks, Up: Legacy Scripts
7.4 The run-on-binaries-in script
=================================
run-on-binaries-in
[-help]
[-version]
[-verbose]
[-quiet]
[-ignore]
[-prefix='text']
[-tmpdir=dir]
[-files-from=file]
[-skip-list=file]
[-]
program
[program-options]
FILE...
The 'run-on-binaries-in' script allows other scripts, or programs, to
be run on the executable files contained inside archives. This includes
'rpm' files, 'tar' and 'ar' files and compressed files.
The script does not recurse into directories, but this can be handled
by the 'find' command, like this:
find . -type f -exec run-on-binaries-in <script-to-run> {} \;
The script accepts the following command line options:
'--help'
'-h'
Displays the usage of the script and then exits.
'--version'
'-v'
Displays the version of the script.
'--verbose'
'-V'
Enables verbose mode, causing the script to detail each action it
takes.
If this option is repeated it has the special effect of canceling
out the automatic addition of the '-i' to recursive invocations of
the script.
'--quiet'
'-q'
Do not include the name of script in the out generated by the
script.
'--ignore'
'-i'
Do not report file types that are not supported or recognised.
This option is automatically enabled when the script is recursively
invoked on an archive, unless the '-V' '-V' has been enabled. This
is because it is assumed that archives are likely to contain files
that do not need to be scanned.
'--prefix='text''
'-p 'text''
Add this text to the output from the script when it runs the
program on a normal executable.
'--tmpdir=dir'
'-t dir'
Directory to use to store temporary files.
'--files-from=file'
'-f=file'
Specifies a file containing a list of other files to examine, one
per line.
'--skip-list=file'
'-s=file'
Specifies a file containing a list of files not to examine, one per
line. Blank lines and comments are ignored. Text after a file's
name is also ignored. Filenames should start at the beginning of a
line.
'--'
Stops processing of command line options. This allows the script
to be run with a program whose name starts with a dash.
File: annobin.info, Node: GNU FDL, Prev: Legacy Scripts, Up: Top
Appendix A GNU Free Documentation License
*****************************************
Version 1.3, 3 November 2008
Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
<http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
0. PREAMBLE
The purpose of this License is to make a manual, textbook, or other
functional and useful document "free" in the sense of freedom: to
assure everyone the effective freedom to copy and redistribute it,
with or without modifying it, either commercially or
noncommercially. Secondarily, this License preserves for the
author and publisher a way to get credit for their work, while not
being considered responsible for modifications made by others.
This License is a kind of "copyleft", which means that derivative
works of the document must themselves be free in the same sense.
It complements the GNU General Public License, which is a copyleft
license designed for free software.
We have designed this License in order to use it for manuals for
free software, because free software needs free documentation: a
free program should come with manuals providing the same freedoms
that the software does. But this License is not limited to
software manuals; it can be used for any textual work, regardless
of subject matter or whether it is published as a printed book. We
recommend this License principally for works whose purpose is
instruction or reference.
1. APPLICABILITY AND DEFINITIONS
This License applies to any manual or other work, in any medium,
that contains a notice placed by the copyright holder saying it can
be distributed under the terms of this License. Such a notice
grants a world-wide, royalty-free license, unlimited in duration,
to use that work under the conditions stated herein. The
"Document", below, refers to any such manual or work. Any member
of the public is a licensee, and is addressed as "you". You accept
the license if you copy, modify or distribute the work in a way
requiring permission under copyright law.
A "Modified Version" of the Document means any work containing the
Document or a portion of it, either copied verbatim, or with
modifications and/or translated into another language.
A "Secondary Section" is a named appendix or a front-matter section
of the Document that deals exclusively with the relationship of the
publishers or authors of the Document to the Document's overall
subject (or to related matters) and contains nothing that could
fall directly within that overall subject. (Thus, if the Document
is in part a textbook of mathematics, a Secondary Section may not
explain any mathematics.) The relationship could be a matter of
historical connection with the subject or with related matters, or
of legal, commercial, philosophical, ethical or political position
regarding them.
The "Invariant Sections" are certain Secondary Sections whose
titles are designated, as being those of Invariant Sections, in the
notice that says that the Document is released under this License.
If a section does not fit the above definition of Secondary then it
is not allowed to be designated as Invariant. The Document may
contain zero Invariant Sections. If the Document does not identify
any Invariant Sections then there are none.
The "Cover Texts" are certain short passages of text that are
listed, as Front-Cover Texts or Back-Cover Texts, in the notice
that says that the Document is released under this License. A
Front-Cover Text may be at most 5 words, and a Back-Cover Text may
be at most 25 words.
A "Transparent" copy of the Document means a machine-readable copy,
represented in a format whose specification is available to the
general public, that is suitable for revising the document
straightforwardly with generic text editors or (for images composed
of pixels) generic paint programs or (for drawings) some widely
available drawing editor, and that is suitable for input to text
formatters or for automatic translation to a variety of formats
suitable for input to text formatters. A copy made in an otherwise
Transparent file format whose markup, or absence of markup, has
been arranged to thwart or discourage subsequent modification by
readers is not Transparent. An image format is not Transparent if
used for any substantial amount of text. A copy that is not
"Transparent" is called "Opaque".
Examples of suitable formats for Transparent copies include plain
ASCII without markup, Texinfo input format, LaTeX input format,
SGML or XML using a publicly available DTD, and standard-conforming
simple HTML, PostScript or PDF designed for human modification.
Examples of transparent image formats include PNG, XCF and JPG.
Opaque formats include proprietary formats that can be read and
edited only by proprietary word processors, SGML or XML for which
the DTD and/or processing tools are not generally available, and
the machine-generated HTML, PostScript or PDF produced by some word
processors for output purposes only.
The "Title Page" means, for a printed book, the title page itself,
plus such following pages as are needed to hold, legibly, the
material this License requires to appear in the title page. For
works in formats which do not have any title page as such, "Title
Page" means the text near the most prominent appearance of the
work's title, preceding the beginning of the body of the text.
The "publisher" means any person or entity that distributes copies
of the Document to the public.
A section "Entitled XYZ" means a named subunit of the Document
whose title either is precisely XYZ or contains XYZ in parentheses
following text that translates XYZ in another language. (Here XYZ
stands for a specific section name mentioned below, such as
"Acknowledgements", "Dedications", "Endorsements", or "History".)
To "Preserve the Title" of such a section when you modify the
Document means that it remains a section "Entitled XYZ" according
to this definition.
The Document may include Warranty Disclaimers next to the notice
which states that this License applies to the Document. These
Warranty Disclaimers are considered to be included by reference in
this License, but only as regards disclaiming warranties: any other
implication that these Warranty Disclaimers may have is void and
has no effect on the meaning of this License.
2. VERBATIM COPYING
You may copy and distribute the Document in any medium, either
commercially or noncommercially, provided that this License, the
copyright notices, and the license notice saying this License
applies to the Document are reproduced in all copies, and that you
add no other conditions whatsoever to those of this License. You
may not use technical measures to obstruct or control the reading
or further copying of the copies you make or distribute. However,
you may accept compensation in exchange for copies. If you
distribute a large enough number of copies you must also follow the
conditions in section 3.
You may also lend copies, under the same conditions stated above,
and you may publicly display copies.
3. COPYING IN QUANTITY
If you publish printed copies (or copies in media that commonly
have printed covers) of the Document, numbering more than 100, and
the Document's license notice requires Cover Texts, you must
enclose the copies in covers that carry, clearly and legibly, all
these Cover Texts: Front-Cover Texts on the front cover, and
Back-Cover Texts on the back cover. Both covers must also clearly
and legibly identify you as the publisher of these copies. The
front cover must present the full title with all words of the title
equally prominent and visible. You may add other material on the
covers in addition. Copying with changes limited to the covers, as
long as they preserve the title of the Document and satisfy these
conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit
legibly, you should put the first ones listed (as many as fit
reasonably) on the actual cover, and continue the rest onto
adjacent pages.
If you publish or distribute Opaque copies of the Document
numbering more than 100, you must either include a machine-readable
Transparent copy along with each Opaque copy, or state in or with
each Opaque copy a computer-network location from which the general
network-using public has access to download using public-standard
network protocols a complete Transparent copy of the Document, free
of added material. If you use the latter option, you must take
reasonably prudent steps, when you begin distribution of Opaque
copies in quantity, to ensure that this Transparent copy will
remain thus accessible at the stated location until at least one
year after the last time you distribute an Opaque copy (directly or
through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of
the Document well before redistributing any large number of copies,
to give them a chance to provide you with an updated version of the
Document.
4. MODIFICATIONS
You may copy and distribute a Modified Version of the Document
under the conditions of sections 2 and 3 above, provided that you
release the Modified Version under precisely this License, with the
Modified Version filling the role of the Document, thus licensing
distribution and modification of the Modified Version to whoever
possesses a copy of it. In addition, you must do these things in
the Modified Version:
A. Use in the Title Page (and on the covers, if any) a title
distinct from that of the Document, and from those of previous
versions (which should, if there were any, be listed in the
History section of the Document). You may use the same title
as a previous version if the original publisher of that
version gives permission.
B. List on the Title Page, as authors, one or more persons or
entities responsible for authorship of the modifications in
the Modified Version, together with at least five of the
principal authors of the Document (all of its principal
authors, if it has fewer than five), unless they release you
from this requirement.
C. State on the Title page the name of the publisher of the
Modified Version, as the publisher.
D. Preserve all the copyright notices of the Document.
E. Add an appropriate copyright notice for your modifications
adjacent to the other copyright notices.
F. Include, immediately after the copyright notices, a license
notice giving the public permission to use the Modified
Version under the terms of this License, in the form shown in
the Addendum below.
G. Preserve in that license notice the full lists of Invariant
Sections and required Cover Texts given in the Document's
license notice.
H. Include an unaltered copy of this License.
I. Preserve the section Entitled "History", Preserve its Title,
and add to it an item stating at least the title, year, new
authors, and publisher of the Modified Version as given on the
Title Page. If there is no section Entitled "History" in the
Document, create one stating the title, year, authors, and
publisher of the Document as given on its Title Page, then add
an item describing the Modified Version as stated in the
previous sentence.
J. Preserve the network location, if any, given in the Document
for public access to a Transparent copy of the Document, and
likewise the network locations given in the Document for
previous versions it was based on. These may be placed in the
"History" section. You may omit a network location for a work
that was published at least four years before the Document
itself, or if the original publisher of the version it refers
to gives permission.
K. For any section Entitled "Acknowledgements" or "Dedications",
Preserve the Title of the section, and preserve in the section
all the substance and tone of each of the contributor
acknowledgements and/or dedications given therein.
L. Preserve all the Invariant Sections of the Document, unaltered
in their text and in their titles. Section numbers or the
equivalent are not considered part of the section titles.
M. Delete any section Entitled "Endorsements". Such a section
may not be included in the Modified Version.
N. Do not retitle any existing section to be Entitled
"Endorsements" or to conflict in title with any Invariant
Section.
O. Preserve any Warranty Disclaimers.
If the Modified Version includes new front-matter sections or
appendices that qualify as Secondary Sections and contain no
material copied from the Document, you may at your option designate
some or all of these sections as invariant. To do this, add their
titles to the list of Invariant Sections in the Modified Version's
license notice. These titles must be distinct from any other
section titles.
You may add a section Entitled "Endorsements", provided it contains
nothing but endorsements of your Modified Version by various
parties--for example, statements of peer review or that the text
has been approved by an organization as the authoritative
definition of a standard.
You may add a passage of up to five words as a Front-Cover Text,
and a passage of up to 25 words as a Back-Cover Text, to the end of
the list of Cover Texts in the Modified Version. Only one passage
of Front-Cover Text and one of Back-Cover Text may be added by (or
through arrangements made by) any one entity. If the Document
already includes a cover text for the same cover, previously added
by you or by arrangement made by the same entity you are acting on
behalf of, you may not add another; but you may replace the old
one, on explicit permission from the previous publisher that added
the old one.
The author(s) and publisher(s) of the Document do not by this
License give permission to use their names for publicity for or to
assert or imply endorsement of any Modified Version.
5. COMBINING DOCUMENTS
You may combine the Document with other documents released under
this License, under the terms defined in section 4 above for
modified versions, provided that you include in the combination all
of the Invariant Sections of all of the original documents,
unmodified, and list them all as Invariant Sections of your
combined work in its license notice, and that you preserve all
their Warranty Disclaimers.
The combined work need only contain one copy of this License, and
multiple identical Invariant Sections may be replaced with a single
copy. If there are multiple Invariant Sections with the same name
but different contents, make the title of each such section unique
by adding at the end of it, in parentheses, the name of the
original author or publisher of that section if known, or else a
unique number. Make the same adjustment to the section titles in
the list of Invariant Sections in the license notice of the
combined work.
In the combination, you must combine any sections Entitled
"History" in the various original documents, forming one section
Entitled "History"; likewise combine any sections Entitled
"Acknowledgements", and any sections Entitled "Dedications". You
must delete all sections Entitled "Endorsements."
6. COLLECTIONS OF DOCUMENTS
You may make a collection consisting of the Document and other
documents released under this License, and replace the individual
copies of this License in the various documents with a single copy
that is included in the collection, provided that you follow the
rules of this License for verbatim copying of each of the documents
in all other respects.
You may extract a single document from such a collection, and
distribute it individually under this License, provided you insert
a copy of this License into the extracted document, and follow this
License in all other respects regarding verbatim copying of that
document.
7. AGGREGATION WITH INDEPENDENT WORKS
A compilation of the Document or its derivatives with other
separate and independent documents or works, in or on a volume of a
storage or distribution medium, is called an "aggregate" if the
copyright resulting from the compilation is not used to limit the
legal rights of the compilation's users beyond what the individual
works permit. When the Document is included in an aggregate, this
License does not apply to the other works in the aggregate which
are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these
copies of the Document, then if the Document is less than one half
of the entire aggregate, the Document's Cover Texts may be placed
on covers that bracket the Document within the aggregate, or the
electronic equivalent of covers if the Document is in electronic
form. Otherwise they must appear on printed covers that bracket
the whole aggregate.
8. TRANSLATION
Translation is considered a kind of modification, so you may
distribute translations of the Document under the terms of section
4. Replacing Invariant Sections with translations requires special
permission from their copyright holders, but you may include
translations of some or all Invariant Sections in addition to the
original versions of these Invariant Sections. You may include a
translation of this License, and all the license notices in the
Document, and any Warranty Disclaimers, provided that you also
include the original English version of this License and the
original versions of those notices and disclaimers. In case of a
disagreement between the translation and the original version of
this License or a notice or disclaimer, the original version will
prevail.
If a section in the Document is Entitled "Acknowledgements",
"Dedications", or "History", the requirement (section 4) to
Preserve its Title (section 1) will typically require changing the
actual title.
9. TERMINATION
You may not copy, modify, sublicense, or distribute the Document
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense, or distribute it is void,
and will automatically terminate your rights under this License.
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the
copyright holder fails to notify you of the violation by some
reasonable means prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from
that copyright holder, and you cure the violation prior to 30 days
after your receipt of the notice.
Termination of your rights under this section does not terminate
the licenses of parties who have received copies or rights from you
under this License. If your rights have been terminated and not
permanently reinstated, receipt of a copy of some or all of the
same material does not give you any rights to use it.
10. FUTURE REVISIONS OF THIS LICENSE
The Free Software Foundation may publish new, revised versions of
the GNU Free Documentation License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns. See
<http://www.gnu.org/copyleft/>.
Each version of the License is given a distinguishing version
number. If the Document specifies that a particular numbered
version of this License "or any later version" applies to it, you
have the option of following the terms and conditions either of
that specified version or of any later version that has been
published (not as a draft) by the Free Software Foundation. If the
Document does not specify a version number of this License, you may
choose any version ever published (not as a draft) by the Free
Software Foundation. If the Document specifies that a proxy can
decide which future versions of this License can be used, that
proxy's public statement of acceptance of a version permanently
authorizes you to choose that version for the Document.
11. RELICENSING
"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
World Wide Web server that publishes copyrightable works and also
provides prominent facilities for anybody to edit those works. A
public wiki that anybody can edit is an example of such a server.
A "Massive Multiauthor Collaboration" (or "MMC") contained in the
site means any set of copyrightable works thus published on the MMC
site.
"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
license published by Creative Commons Corporation, a not-for-profit
corporation with a principal place of business in San Francisco,
California, as well as future copyleft versions of that license
published by that same organization.
"Incorporate" means to publish or republish a Document, in whole or
in part, as part of another Document.
An MMC is "eligible for relicensing" if it is licensed under this
License, and if all works that were first published under this
License somewhere other than this MMC, and subsequently
incorporated in whole or in part into the MMC, (1) had no cover
texts or invariant sections, and (2) were thus incorporated prior
to November 1, 2008.
The operator of an MMC Site may republish an MMC contained in the
site under CC-BY-SA on the same site at any time before August 1,
2009, provided the MMC is eligible for relicensing.
ADDENDUM: How to use this License for your documents
====================================================
To use this License in a document you have written, include a copy of
the License in the document and put the following copyright and license
notices just after the title page:
Copyright (C) YEAR YOUR NAME.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
Texts. A copy of the license is included in the section entitled ``GNU
Free Documentation License''.
If you have Invariant Sections, Front-Cover Texts and Back-Cover
Texts, replace the "with...Texts." line with this:
with the Invariant Sections being LIST THEIR TITLES, with
the Front-Cover Texts being LIST, and with the Back-Cover Texts
being LIST.
If you have Invariant Sections without Cover Texts, or some other
combination of the three, merge those two alternatives to suit the
situation.
If your document contains nontrivial examples of program code, we
recommend releasing these examples in parallel under your choice of free
software license, such as the GNU General Public License, to permit
their use in free software.