\input texinfo @c -*-texinfo-*-
@setfilename annobin.info
@c Copyright (C) 2018-2024 Red Hat.
@settitle Annobin
@setchapternewpage odd

@c man begin INCLUDE
@set VERSION 12.0
@set VERSION_PACKAGE (Annobin) 
@set UPDATED Jan 2024
@c man end

@ifnottex
@c This is a dir.info fragment to support semi-automated addition of
@c manuals to an info tree.  zoo@cygnus.com is developing this facility.
@dircategory Software development
@direntry
* annobin: (annobin).                Annotating a compiled program
@end direntry
@end ifnottex

@copying
This file documents the annobin plugin on the Fedora system.

@c man begin COPYRIGHT
Copyright @copyright{} 2018 - 2024 Red Hat.

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, with no Front-Cover Texts, and with no
Back-Cover Texts.  A copy of the license is included in the
section entitled ``GNU Free Documentation License''.

@c man end
@end copying

@finalout
@smallbook

@titlepage
@title Annobin
@subtitle The @sc{annobin} plugin
@ifset VERSION_PACKAGE
@subtitle @value{VERSION_PACKAGE}
@end ifset
@subtitle Version @value{VERSION}
@author Nick Clifton

@page

This manual describes the @sc{annobin} plugin and the
@command{annocheck} program, and how you can use them to determine
what security features were used when a program was built. 

@vskip 0pt plus 1filll
Copyright @copyright{} 2018 - 2024 Red Hat

      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, with no Front-Cover Texts, and with no
      Back-Cover Texts.  A copy of the license is included in the
      section entitled ``GNU Free Documentation License''.

@end titlepage
@contents

@c -----------------------------------------------------------------
@ifnottex
@node Top
@top Annotating Binaries: How Was Your Program Built ?

@c man annobin title Annobin - annotating binary files.

This manual describes the @sc{annobin} plugin and the
@command{annocheck} program, and how you can use them to determine
what security features were used when a program was built. 

This manual is for @code{annobin}
@ifset VERSION_PACKAGE
@value{VERSION_PACKAGE}
@end ifset
version @value{VERSION}.

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
@end menu
@end ifnottex

@c -----------------------------------------------------------------
@node Introduction
@chapter What is Binary Annotation ?

@c man begin DESCRIPTION annobin

Binary Annotation is a method for recording information about an
application inside the application itself.  It is an implementation of
the @code{Watermark} specification defined here:
@url{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 @option{-O2} option except for
one special function which was compiled with @option{-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
@code{readelf} and @code{objdump}.  The @code{annobin} package itself
includes a program called @command{annocheck} which can can also
examine this information.  Details on this program can be found
elsewhere in this documentation.

Experience has shown however that storing the range information along
with the data does tend to significantly increase the size of
programs.  So the system also provides an alternative implementation
which uses a more compact format, at the cose of dropping the range
data.

@c man end

@c -----------------------------------------------------------------
@node Plugins
@chapter How to add Binary Annotations to your application.

@c man begin DESCRIPTION annobin

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
@samp{redhat-rpm-config} package.

Currently the binary annotations are generated by a plugin to the
compiler (@code{GCC}, @code{clang} or @code{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
@code{annobin} plugin then it can be specifically added to the compiler
command line by adding the @option{-fplugin=annobin} (for gcc) or
@option{-fplugin=annobin-for-clang} (for clang) or
@option{-fplugin=annobin-for-llvm} (for LLVM) option.  It may
also be necessary to tell the compiler where to find the plugin by
adding the @option{-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 @option{-fplugin-arg-annobin-disable} (for @code{gcc}) or
@option{-Xclang -plugin-arg-annobin-disable} (for @code{clang} or
@code{llvm}) can be used.  Note - these options must be placed
@emph{after} the @option{-fplugin=annobin} option.

On Fedora and RHEL systems the plugin can be disabled entirely for all
compilations in a package by adding
@option{%undefine _annotated_build} to the spec file.

@c man end
@c man begin OPTIONS annobin

The plugin accepts a small selection of command line arguments,
all accessed by passing
@option{-fplugin-arg-annobin-<option>} (for @code{gcc}) or
@option{-Xclang -plugin-arg-annobin-<option>} (for @code{clang} or
@code{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.

In addition it is possible to pass options via the @code{ANNOBIN}
environment variable.  Multiple arguments must be separated by commas,
and arguments that need a value must use an equals sign rather than a
space or colon.

Also - in order to support backwards compatibility - the LLVM plugin
detects the @code{ANNOBIN_VERBOSE} enviroment variable and turns on
verbose mode if it is present.

The supported options are:

@table @code
@item disable
@itemx enable
Either disable or enable the plugin.  The default is for the plugin to
be enabled.

@item 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.

@item 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.

@item 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.

@item 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.

@item stack-size-notes
@itemx 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.

@item stack-threshold=@var{N}
If stack size requirements are being recorded then this option sets
the minimum value to record.  Functions which require less than
@code{N} bytes of static stack space will not have their requirements
recorded.  If not set, then @code{N} defaults to 1024.

@item global-file-syms
@itemx no-global-file-syms
If enabled the @option{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
@option{no-global-file-syms} option.

@item attach
@itemx no-attach
When gcc compiles code with the @option{-ffunction-sections} option
active it will place each function into its own section.  When the
@code{annobin} @option{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 @option{attach}, but this can be disabled via the
@option{no-attach} option.  Note however that if both @option{attach}
and @option{link-order} are disabled then note generation for function
sections will not work properly.

@item link-order
@itemx no-link-order
As an alternative to using section groups and a special assembler
directive the plugin can use a feature of the ELF
@code{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 @option{link-order}
option.

@item rename[=@var{STR}]
Adds an extra prefix to the symbol names generated by the
@code{annobin} plugin.  This allows the plugin to be run twice on the
same executable, which can be useful for debugging and build testing.

The default prefix is ``.1'' but this can be changed by providing a
string argument to this option.

Note: if the @option{rename} option is not used then the plugin will
attempt to detect and disable multiple copies of itself.  Prior to
version 12.72 howver this detection is only reliable if the annobin
plugin is the first plugin that is specified on the gcc command line.

@item active-checks
@item no-active-checks
The @code{annobin} plugin will normally generate warning messages if it
detects that certain preprocessor command line options are missing or
misspelt.  The @option{active-checks} option changes the warnings into
errors, just as if @option{-Werror} had been specified.  The
@option{no-active-checks} option disables the messages entirely.

Currently the plugin checks for these issues:

@table @code
@item Missing FORTIFY_SOURCE
This warning is generated when neither @option{-D_FORTIFY_SOURCE=2}
nor @option{-D_FORTIFY_SOURCE=3} have been provided on the command
line and the @option{-flto} option has been enabled.

Nomrally this problem would be detected by the @command{annocheck}
tool, but LTO compilation hides preprocessor options, so information
about them cannot be passed on by the plugin.  This is why the plugin
will generate a warning message when the @code{_FORTIFY_SOURCE} option
is missing and LTO is enabled. 

@item -D_FORTIFY_SOURCE typo
The plugin will warn if the @code{-D_FORTIFY_SOURCE} option is spelt
as either @code{-DFORTIFY_SOURCE} or @code{-D__FORTIFY_SOURCE}.

@item -D_GLIBCXX_ASSERTIONS typo
The plugin will warn if the @code{-D_GLIBCXX_ASSERTIONS} option is
spelt as either @code{-DGLIBCXX_ASSERTIONS} or
@code{-D__GLIBCXX_ASSERTIONS}.

@end table

Note - in the future the @code{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
@command{autoconf} tool the warning message will not be produced if
the input source filename starts with @file{conftest.}.  In these
cases autoconf is usually checking to see if a warning will be
produced for some other reason, and so the @code{annobin} warning
would get in the way.  If the @option{active-checks} option has been
enabled however, an error message will still be generated.

@item dynamic-notes
@itemx no-dynamic-notes
@itemx static-notes
@itemx no-static-notes
These options are deprecated.

@item ppc64-nops
@itemx 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 @code{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 @option{no-ppc64-nops} is
provided in order to turn it off.

@item note-format=@code{note}|@code{string}
This option chooses the format used to store the information generated
by the plugin.  The possibilities are:

@table @code
@item note
Store the information as ELF format notes in the
@code{.gnu.build.attributes} section.

@item string
Store the information as mergeable strings in the
@code{.annobin.notes} section.

@end table

The default is @code{note}.
@end table

@c man end

The plugins record information appropriate to the compiler that is
running them.  So the @code{gcc} plugin records information about the
following options:

@table @code
@item -D_FORTIFY_SOURCE=[2|3]
@item -D_GLIBCXX_ASSERTIONS
@item -O
@item -Wall
@item -fPIC
@item -fPIE
@item -fcf-protection
@item -finstrument_functions
@item -flto
@item -fomit-frame-pointer
@item -fprofile
@item -fprofile-arcs
@item -fsanitize
@item -fshort-enums
@item -fstack-clash-protection
@item -fstack-protector
@item -g
@item -mbranch-protection (AArch64)
@item -mstack-realign (i386)
@item -mtls-size (PowerPC)
@end table

The @code{Clang} plugin records information on the following command
line options:

@table @code
@item -O
@item -Wall
@item -fPIC
@item -fPIE
@item -fcf-protection-branch
@item -fcf-protection-return
@item -fsanitize=cfi-cast-strict
@item -fsanitize=safe-stack
@item -fspeculative-load-hardening
@item -fstack-protector-strong
@end table

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 @code{LLVM} plugin records information on the following command
line options:

@table @code
@item -D_FORTIFY_SOURCE=[2|3]
@item -O
@item -Wall
@item -flto
@item -fPIC
@item -fPIE
@item -fcf-protection-branch
@item -fcf-protection-return
@item -fsanitize=safe-stack
@item -fstack-protector-strong
@item -g
@end table

@c -----------------------------------------------------------------
@node Examining
@chapter How to examine the information stored in the binary.

@c man begin DESCRIPTION annobin

The information is stored in a binary in either the ELF Note format
inside a special section called @code{.gnu.build.attributes}, or else
as ordinary strings inside a section called @code{.annobin.notes}.

The @code{readelf} program from the @code{binutils} package can
extract and display these notes.  (Adding the @option{--wide}
option is also helpful).

If the information is held in the ELF note format then readelf's
@option{--notes} option will display them.  Here is an example of the
output:

@smallexample
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)
@end smallexample

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
@samp{G} and @samp{A} followed by an encoding character (one of
@samp{*$!+}) 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.

If the information is held as strings then readelf's
@option{-p.annobin.notes} option will display them.  Here is an
example of the output:

@smallexample
String dump of section '.annobin.notes':
  [     0]  AV:4.p.1200
  [     c]  RV:running gcc 12.2.1 20221121
  [    2b]  BV:annobin gcc 12.2.1 20221121
  [    4a]  PN:annobin
  [    55]  GW:0x290540
  [    61]  SP:3
@end smallexample

@c man end

Most of the notes have a reasonably self explanatory name and value.
The exception are the @code{version} and @code{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
* String Format Notes::   String Format Notes
@end menu

@c -----------------------------------------------------------------
@node The Version Encoding
@section Encoding Protocol and Producer Versions
The @code{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 or 4 and the plugin
version will be 11 or 12.  It also encodes the tool used to generate
the notes as a single character.  The following characters are used:

@table @code
@item L
The notes have been produced by the Clang plugin.

@item V
The notes have been produced by the LLVM plugin.

@item a
The notes have been produced by the assembler.

@item c
The notes have been produced by the gcc plugin for the .text.cold section.

@item e
The notes have been produced by the gcc plugin for the .text.exit section.

@item g
The notes have been produced by the gcc plugin when running in LTO mode.

@item h
The notes have been produced by the gcc plugin for the .text.hot section.

@item l
The notes have been produced by the linker.

@item p
The notes have been produced by the gcc plugin.

@item s
The notes have been produced by the gcc plugin for the .text.startup section.

@end table

@c -----------------------------------------------------------------
@node The STACK Encoding
@section Encoding Stack Protections
The stack protection note (value 2) encodes the setting of the
@option{-fstack-protector} option.  Possible values are:

@table @code
@item 0
Not compiled with any setting of @option{-fstack-protector} (or the
setting is unknown).

@item 1
Compiled with just @option{-fstack-protector}.

@item 2
Compiled with @option{-fstack-protector-all}.

@item 3
Compiled with @option{-fstack-protector-strong}.

@item 4
Compiled with @option{-fstack-protector-explicit}.
@end table

@c -----------------------------------------------------------------
@node The PIC Encoding
@section Encoding Position Independence
The @code{Position Independence Status} note encodes the setting of
the @option{-fpic}/@option{-fpie} used when compiling the program.
The value of the note can be

@table @code
@item 0
Static code, ie neither pic nor pie.

@item 1
Compiled with @option{-fpic}.

@item 2
Compiled with @option{-fPIC}.

@item 3
Compiled with @option{-fpie}.

@item 4
Compiled with @option{-fPIE}

@end table

If both @option{pic} and @option{pie} have been specified on the
command line then @option{pie} takes the precedence in the encoding.

@c -----------------------------------------------------------------
@node The GOW Encoding
@section Encoding Optimization and Debugging Levels

The @code{GOW} note encodes the optimization level (@option{-O}) and
debugging level (@option{-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:

@table @code
@item bits 0 - 2
The debug type, ie DBX, DWARF, VMS or XCOFF.  As specified by the
@option{-gstabs}, @option{-gdwarf}, @option{-gvms} and
@option{-gxcoff} options.

@item bit  3
Set if GNU extensions to the debug type have been enabled.

@item bits 4 - 5
The debug info level ie TERSE, NORMAL or VERBOSE as set by the
@option{-g<level>} option.

@item bits 6 -  8
The DWARF version, if DWARF is being generated.  Set by the
@option{-gdwarf-<version>} option.

@item bits 9 - 10
The optimization level as set by the @option{-O<number>} option.
Levels above 3 are treated as if they were 3.

@item bit 11
Set if the optimize-for-size option (@option{-Os}) is enabled.

@item bit 12
Set if the inaccurate-but-fast optimization option (@option{-Ofast})
has been enabled.

@item bit 13
Set if the optimize-with-debugging option (@option{-Og}) has been
enabled.

@item bit 14
Set if the enable most warnings option (@option{-Wall}) has been
enabled.

@item bit 15
Set if the format security warning option (@option{-Wformat-security})
has been enabled.

@item bit 16
Set if LTO compilation has been enabled.

@item bit 17
Set if LTO compilation has not been enabled.

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.

@item bits 18 - 19
These bits are used to record the setting of gcc's
@option{-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 set but bit 19 is clear, then the compiler supports the
option, but either it was not used, or it was used but the option's
value was @option{skip}.  Otherwise if bit 19 is clear then the option
was used but its value was set to @option{pattern} (which is
inappropriate for production binaries) or if bit 19 is set then the
option was used and its value was set to @option{zero}.

@item bits 20 - 21
These bits are used to record the setting of gcc's
@option{-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 set (and bit 21 is clear) then the option is supported but it
was not used, or it was used, but its value was set to @option{skip}.
Otherwise both bits 20 and 21 should be set, indicating that the
option was used and a value other than @option{skip} was used.

@item bits 22 - 23
These bits are used to record the setting of gcc's
@option{-Wimplicit-int} warning.  Enabling this warning is important
as variables with an implicit type of int can cause problems when they
are used in situations where they are expected to be compatible with
pointers.  The meanings of the two bits are as follows:

@table @code
@item bit22 = 0, bit23 = 0
The annobin plugin did not record any information about this warning,
probably because the plugin is an old version.
@item bit22 = 1, bit23 = 0
The warning has been disabled.
@item bit22 = 0, bit23 = 1
The warning has its default value.  It has not been altered via a
command line option.
@item bit22 = 1, bit23 = 1
The warning has been enabled via a command line option.
@end table

Note - whilst this warning is normally enabled it can be manually
disabled.  Hence the need for this extra test.

Note - this test is only really relevent to C source code.  Other
languages are not affected.

@item bits 24 - 25
These bits are used to record the setting of gcc's
@option{-Wimplicit-function-declaration} warning.  Enabling this
warning is important as functions that are assumed to accept int
parameters or return int values can cause problems when pointers are
involved.  The meanings of the two bits are as follows:

@table @code
@item bit22 = 0, bit23 = 0
The annobin plugin did not record any information about this warning,
probably because the plugin is an old version.
@item bit22 = 1, bit23 = 0
The warning has been disabled.
@item bit22 = 0, bit23 = 1
The warning has its default value.  It has not been altered via a
command line option.
@item bit22 = 1, bit23 = 1
The warning has been enabled via a command line option.
@end table

Note - whilst this warning is normally enabled it can be manually
disabled.  Hence the need for this extra test.

Note - this test is only really relevent to C source code.  Other
languages are not affected.

@item bits 26 - 28
These bits record the settings of gcc's flexible array strengthening.
Bit 26 is set only if the feature is supported by the compiler.  If
bit 26 is not set then bits 27 to 28 should be ignored.  Bit 27 is set
if the @option{-Wstrict-flex-arrays} warnings is enabled.  Bit 28 is
set if the @option{-fstrict-flex-arrays} option has been set to a
value greater than zero.
@end table

The other bits are not currently used and should be set to zero so
they can be used in future extensions to the specification.

@c -----------------------------------------------------------------
@node The CF Encoding
@section Encoding Control Flow Protection
Records the setting of the @option{-cf-protection} option.  This is a
bit mask using the following bits, based upon the definition of the
@code{enum cf_protection_level} from gcc's @code{flag-types.h} header
file:

@table @code
@item bit 0
Branches are protected.  (ie @option{-fcf-protection=branch}).

@item bit 1
Returns are protected.  (ie @option{-fcf-protection=return}).

@item 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.
@end table

If both bits 0 and 1 are set then this implies the
@option{-fcf-protection=full} option, and if neither are set then this
implies the @option{-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.

@c -----------------------------------------------------------------
@node The ENUM Encoding
@section Encoding the Size of Enumerations
Record the value of the @option{-fshort-enums} option.  Possible
values are:

@table @code
@item true
The @option{-fshort-enums} option has been enabled.

@item false
The @option{-fshort-enums} option has not been enabled.
@end table

@c -----------------------------------------------------------------
@node The INSTRUMENT Encoding
@section 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 (@var{/})
character.  These values are:

@table @code
@item sanitization
Enabled via a plethora of @option{-fsanitize=@dots{}} options these
tell gcc to add extra code to help with various different types of
error checking features.

@item function instrumentation
Enabled via gcc's @option{-finstrument-functions} option, this adds
special function calls at the entry and exit point of every normal
function.

@item profiling
Enabled via gcc's @option{-p} or @option{-pg} options, this adds
instrumentation to the compiled code that generates output suitable
for analysis via the @command{prof} or @command{gprof} programs.

@item arc profiling
Enabled via gcc's @option{-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.

@end table

@c -----------------------------------------------------------------
@node String Format Notes
@section Encoding Notes in a string format
If the notes are being recorded in a string format, via the
@code{note-formt=string} command line options, then the strings take
the form of a two letter prefix, followed by a colon and then the
value associated with the note.  If the note is likely to trigger a
failure result in annocheck then the filename of the source file will
follow, separated by a space.  If the note is specific to a single
function then the function name will follow on afterwards, again
separated by a space.

The currently accepted two letter prefixes are:

@table @code
@item AV
Records the version of the plugin.

@item BV
Records the version of the compiler that built the plugin.

@item CF
Records the setting of any control flow security options.

@item FL
Records the level of the @code{-D_FORTIFY_LEVEL} option.

@item FP
Records the use of the frame pointer.

@item GA
Records the setting of the @code{-D_GLIBCCXX_ASSERTIONS} command line
option.

@item GW
Records the GOW values.

@item PF
Records any profiling options.

@item PI
Records any PIC settings.

@item PN
Records the name of the plugin.

@item RV
Records the version of the compiler that is running the plugin.

@item SC
Records the setting of any stack clash protection.

@item SE
Records the use of short enums.

@item SP
Records the use of an stack protector options.

@item aA
Records the ABI selected.  (AArch64 only).

@item aB
Records the use of Branch Target Identification.  (Aarch64 only).

@item iS
Records the use of the stack realign option.  (x86 only).

@item pA
Records the ABI selected.  (PowerPC only).

@item xA
Records the ABI selected.  (x86_64 only).

@end table

@c -----------------------------------------------------------------
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.

@c -----------------------------------------------------------------
@c -----------------------------------------------------------------
@node Annocheck
@chapter Analysing binary files.

@c man title annocheck Analysing binary files.

@smallexample
@c man begin SYNOPSIS annocheck
annocheck
  [@b{-h | --help}]
  [@b{--help-@var{tool}}]
  [@b{--version}]
  [@b{-v | --verbose}]
  [@b{-q | --quiet}]
  [@b{-i | --ignore-unknown}]
  [@b{-r | --report-unknown}]
  [@b{-f | --follow-links}]
  [@b{-I | --ignore-links}]
  [@b{--debug-rpm=}@var{file}]
  [@b{--debug-file=}@var{file}]
  [@b{--debug-dir=}@var{dir}]
  [@b{-p @var{text} | --prefix=}@var{text}]
  [@b{-t @var{dir} | --tmpdir=}@var{dir}]
  [@b{-u | --use-debuginfod}]
  [@b{-n | --no-use-debuginfod}]
  [@b{--enable-@var{tool}}]
  [@b{--disable-@var{tool}}]
  [@b{--@var{tool}}]
  [@b{--@var{tool}-@var{option}}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION annocheck

The @command{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 ?
@end menu

The @command{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 @command{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 @file{Makefile} used to build
@command{annocheck}.  The modular nature of @command{annocheck} means
that nothing else needs to be updated.

New tools must fill out a @code{struct checker} structure (defined in
@file{annocheck.h}) and they must define a constructor function that
calls @code{annocheck_add_checker} to register their presence at
program start-up.

The @command{annocheck} program supports some generic command line
options that are used regardless of which tools are enabled.

@table @code

@item --debug-rpm=@var{file}
Look inside @var{file} for separate dwarf debug information.
Multiple instances of the @option{--debug-rpm} option accumulate.

Note - if none of the @option{--debug-rpm}, @option{--debug-file} and
@option{--debug-dir} options are used and a single source file is
specified to be scanned, and this file's name ends in @emph{.rpm} then
annocheck will automatically look to see if it can find an associated
debug info rpm based upon the filename.

@item --debug-file=@var{file}
Look in @var{file} for dwarf debug information.
Multiple instances of this option accumulate.

@item --debug-dir=@var{dir}
Look in directory @var{dir} for separate dwarf debug information files.
Note: multiple instances of this option do @emph{not} accumulate.

@item --help
@itemx -h
Displays the generic annobin usage information and then exits.

@item --help-@var{tool}
Display the usage information for @var{tool} and then exits.

@item --report-unknown
@itemx --ignore-unknown
@itemx -r
@itemx -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.

@item --ignore-links
@itemx --follow-links
@itemx -I
@itemx -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.

@item --prefix=@var{text}
@itemx -p @var{text}
Include @var{text} in the output description.

@item --quiet
@itemx -q
Do not print anything, just return an exit status.

@item --tmpdir=@var{dir}
@itemx -t @var{dir}
Use @var{dir} as a directory for holding temporary files.

@item --verbose
@itemx -v
Produce informational messages whilst working.  Repeat for more
information.

@item --version
Report the version of the tool and then exit.

@item --use-debuginfod
@itemx -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.

@item --no-use-debuginfod
@itemx -n
Do not use the debuginfod service, even if it is available.

@item --enable-@var{tool}
Enable @var{tool}.  Most tools are disabled by default and so need to
be enabled via this option before they will act.

@item --disable-@var{tool}
Disable @var{tool}.  Normally used to disable the hardening checker,
which is enabled by default.

@item --@var{tool}
Enable @var{tool} and disable all other tools.

@item --@var{tool}-@var{option}
Pass @var{option} on to @var{tool}.

@end table

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.

@c man end

@c -----------------------------------------------------------------
@node Built By
@section The builder checker.

@smallexample
@c man begin SYNOPSIS annocheck: builtby

annocheck
  @b{--builtby}
  @b{--enable-builtby}
  [@b{--all}]
  [@b{--tool=}@var{name}]
  [@b{--nottool=}@var{name}]
  [@b{--no-version-info}]
  [@b{--no-lang-info}]
  [@b{--options-info}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION annocheck: builtby

The @var{builtby} tool is disabled by default, but it can be enabled
by the command line option @option{--enable-builtby} or just
@option{--builtby}.  The tool checks the specified files to see if any
information is stored about how the file was built and the source
languages involved.

Since the hardening checker is enabled by default it may also be
useful to add the @option{--disable-hardened} option to the command
line, although this is not needed if the @option{--builtby} option is
used.

The tool supports a few command line options to customise its
behaviour:

@table @code

@item --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 @option{--all} option is enabled then all successful results will
be returned.  This will probably result in the display of multiple
instances of the same information.

@item --tool=@var{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.  This option can be used multiple times in order to allow a
selection of builders to be reported.

@item --nottool=@var{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.  This option can be used multiple
times in order to allow multiple builders to be hidden.

@item --lang=@var{name}
This option can be used to restrict the output to only those files
which were written in a specific high level language.  Note - not all
binaries include information about the source code language(s), so
this option may not be completely effective.  This option can be used
multiple times in order to allow a broader selection of languages to
be reported.

@item --notlang=@var{NAME}
This option can be used to restrict the output to only those files
which were not written in a specific high level language.  Note - not
all binaries include information about the source code language(s), so
this option may not be completely effective.  This option can be used
multiple times in order to allow a broader selection of languages to
be hidden.

@item --no-version-info
@itemx --lang-info
By default @command{builtby} will report the version information for
the builders that it detects.  Enabling the @option{--no-version-info}
option will prevent this information from being displayed.

If necessary the feature can be re-enabled by the
@option{--version-info} option.

@item --no-lang-info
@itemx --lang-info
By default @command{builtby} will report the high level language(s)
of the sources used to build the program - if they have been recorded.
Enabling the @option{--no-lang-info} option will prevent this
information from being displayed.

If necessary the feature can be re-enabled by the
@option{--lang-info} option.

@item --no-tool-info
@itemx --no-builder-info
@itemx --tool-info
By default @command{builtby} will report the tool(s) used to build
the program.  Enabling the @option{--no-build-info} option will
prevent this information from being displayed, meaning that only the
high level language information will shown.  Enabling this option and
the @option{--no-lang-info} option effectively renders
@command{built-by} redundant.

Note @option{--no-builder-info} is treated as a synonym for
@option{--no-tool-info}.

If necessary the feature can be re-enabled by the
@option{--tool-info} option.

@item --options-info
@itemx --no-options-info
By default @command{builtby} will not report the command line options
provided to the tool(s) used to built the target binary.  Adding the
@option{--options-info} option will enable the display of this
information, if it is stored in the binary (or its debug info).

If necessary the feature can be disabled by the
@option{--no-options-info} option. 

@end table

@c man end

@c -----------------------------------------------------------------
@node Hardened
@section The Hardened security checker.

@smallexample
@c man begin SYNOPSIS annocheck-hardened

annocheck
  [@b{--skip-@var{name}[=@var{funcname}]}]
  [@b{--test-@var{name}}]
  [@b{--skip-all}]
  [@b{--test-all}]
  [@b{--test-future}]
  [@b{--enable-future}]
  [@b{--test-unicode-all}]
  [@b{--test-unicode-suspicious}]
  [@b{--skip-passes}]
  [@b{--profile=@var{release}}]
  [@b{--disable-hardened}]
  [@b{--ignore-gaps}]
  [@b{--fixed-format-messages}]
  [@b{--disable-colour}]
  [@b{--no-show-totals}]
  [@b{--no-allow-exceptions}]
  [@b{--full-filenames}]
  [@b{--base-filenames}]
  [@b{--suppress-version-warnings}]
  [@b{--no-urls}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION annocheck-hardened
The @var{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:
@url {https://fedoraproject.org/wiki/Security_Features}

New tests can be added to the @var{hardened} checker by adding an
entry in the @var{tests} array defined in @file{hardened.c} and then
creating the necessary code to support the test.  There is more
information on this process in this blog:
@url {https://developers.redhat.com/articles/2021/07/15/build-your-own-tool-search-code-sequences-binary-files}

Currently the @var{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
* The tests::                     The tests run by the hardening checker
* 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.
@end menu

@node The tests
@subsection The Tests Run By Annocheck

@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 fips::                     The FIPS test
* Test flex arrays::              The flex arrays 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 implicit values::          The implicit values tests
* Test instrumentation::          The instrumentation test
* Test load segments::            The loadable segments 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 OpenSSL Engine::           The openssl-engine 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 rhivos::                   The RHIVOS tests
* Test run path::                 The run-path test
* Test rwx seg::                  The rwx segment 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
@end menu


@c NOTE; the names of the nodes that follow use a fixed format that
@c allows annocheck to automatically generated references to this
@c documentation in its error messages.

@c -----------------------------------------------------------------
@node Test auto var init
@subsubsection The auto-var-init test

@smallexample
  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'
@end smallexample

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 @option{-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 @option{--test-auto-var-init} option
and disabled by the @option{--skip-auto-var-init} option.  It is also
enabled if the @option{--test-future} option is specified and disabled
if the @option{skip-future} option is specified.

@c -----------------------------------------------------------------
@node Test bind now
@subsubsection The bind-now test

@smallexample
  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
@end smallexample

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: 

@url{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
@option{-Wl,-z,now}.  The lazy binding option is @option{-Wl,-z,lazy}
although some linkers are configured to use lazy binding by default,
in which case just the absence of the @option{-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
@option{--profile=el7} option is used.

The test can be disabled via the @option{--skip-bind-now} option and
re-enabled by the @option{--test-bind-now} option.

@c -----------------------------------------------------------------
@node Test branch protection
@subsubsection The branch-protection test

@smallexample
  Problem:  Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
  Fix By:   Compile with -mbranch-protection=standard
  Waive If: Not running on AArch64
  Waive If: The application will not run on Fedora 35 or later.
  Waive If: The application will not run on newer AArch64 cores.

  Example:  FAIL: branch protection test because not enabled
  Example:  FAIL: branch protection test because only partially enabled
  Example:  FAIL: branch protection test because .note.gnu.property section not found (it is needed for branch protection support)
  Example:  FAIL: branch protection test because the -mbranch-protection option was not used
@end smallexample

AArch64 processors are vulnerable to a class of attack known as
@var{ROP} and @var{JOP} style attacks.  Preventing this kind of
exploit requires assistance from the hardware itself, in the form of
new instructions that need to be inserted by the compiler, and new
bits in the core's status that need to be set.

This test checks to see if 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
@option{-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-8
or RHEL-9.

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 @var{BTI} 
as the first instruction executed.  This instruction is safe to use
even in code that will not be executed in a BTI-enabled environment as
it translates into a no-op instruction if not needed.

In addition the assembler needs a note to indicate that it now supports
BTI.  This note can be added via including this code snippet in the
sources: 

@smallexample
	.pushsection	.note.gnu.property, "a"
	.align	3
	.word	2f - 1f
	.word	4f - 3f
	.word	5            /* NT_GNU_PROPERTY_TYPE_0 */
1:	.asciz	"GNU"

2:	.align	3
3:	.word	0xc0000000   /* type: GNU_PROPERTY_AARCH64_FEATURE_1_AND */
	.word	6f - 5f	     /* size */
5:	.word	1            /* value: GNU_PROPERTY_AARCH64_FEATURE_1_BTI */

6:	.align	3
4:	.popsection
@end smallexample

Note - this test is the inverse of the @ref{Test not branch protection}
test and directly related to the @ref{Test dynamic tags} test.

Note - this test is automatically enabled if one of the following
profile options is used:

@table @code
@item @option{--profile=rawhide}
@item @option{--profile=f43}
@item @option{--profile=f42}
@item @option{--profile=f41}
@item @option{--profile=f40}
@item @option{--profile=f39}
@item @option{--profile=f38}
@item @option{--profile=f37}
@item @option{--profile=f36}
@item @option{--profile=el10}
@end table

The test is automatically disabled if one of the other profile options
is used, ie:

@table @code
@item @option{--profile=el7}
@item @option{--profile=el8}
@item @option{--profile=el9}
@item @option{--profile=f35}
@end table

If necessary the test can be disabled via the
@option{--skip-branch-protection} option and re-enabled via the
@option{--test-branch-protection} option.

@c -----------------------------------------------------------------
@node Test cf protection
@subsubsection The cf-protection test

@smallexample
  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
@end smallexample

Intel have introduced a new security feature called @var{CET} to their
Tiger Lake and newer cores:

@url{https://www.intel.com/content/www/us/en/newsroom/opinion/intel-cet-answers-call-protect-common-malware-threats.html}

This test checks to see that this feature is enabled.  Normally this
is done by compiling the code with the @option{-fcf-protection} or
@option{-fcf-protection=full} command line option enabled.  (The first
form of the option is an alias for the second, but the second form is
preferred as it explicitly shows that all of the control flow
protection features are being 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 @var{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
@option{-fcf-protection=full} (for gcc) or the
@option{-fcf-protection-branch} and @option{-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
@var{ENDBR64} (for 64-bit assembler) or @var{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: 

@smallexample
	.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:
@end smallexample

If necessary the test can be disabled via the @option{--skip-cf-protection}
option and re-enabled via the @option{--test-cf-protection} option.

For more information on CET see: 
@url{https://www.intel.com/content/dam/develop/external/us/en/documents/catc17-introduction-intel-cet-844137.pdf}

@c -----------------------------------------------------------------
@node Test dynamic segment
@subsubsection The dynamic-segment test

@smallexample
  Problem:  Programs with more than one dynamic section will not be loaded properly
  Fix By:   Fix assembler source code and/or linker script
  Waive If: Don't.

  Example:  FAIL: dynamic segment test because multiple dynamic sections detected
@end smallexample

Dynamic executables must have a dynamic section which contains
information that is used by the loader at program startup.  The loader
however only expects there to be one dynamic section in a program, and
it does not cope it there are more than one.  Normally this is not an
issue however as the linker will ensure that there is only one dynamic
section.  It is possible however to use a custom linker script to
create more than one dynamic section, or to write some assembler code
specifically designed to create multiple dynamic sections.

If necessary the test can be disabled via the @option{--skip-dynamic-segment}
option and re-enabled via the @option{--test-dynamic-segment} option.

@c -----------------------------------------------------------------
@node Test dynamic tags
@subsubsection The dynamic-tags test

@smallexample
  Problem:  Unprotected AArch64 binaries are vulnerable to ROP/JOP style attacks
  Fix By:   Compile with -mbranch-protection=standard
  Waive If: Not running on AArch64
  Waive If: The application will not run on Fedora 35 or later.
  Waive If: The application will not run on newer AArch64 cores.

  Example:  FAIL: dynamic tags test because BTI_PLT and PAC_PLT flags missing from the dynamic tags
  Example:  FAIL: dynamic tags test because BTI_PLT flag is missing from the dynamic tags
  Example:  FAIL: dynamic tags test because PAC_PLT flag is missing from the dynamic tags
  Example:  FAIL: dynamic tags test because no dynamic tags found
@end smallexample

AArch64 processors are vulnerable to a class of attack known as
@var{ROP} and @var{JOP} style attacks.  Preventing this kind of
exploit requires assistance from the hardware itself, in the form of
new instructions that need to be inserted by the compiler, and new
bits in the core's status that need to be set.

This test checks to see if executable binaries have been marked as
supporting the necessary security features to prevent this kind of
attack.  (The BTI_PLT and PAC_PLT flags mentioned in the failure
messages).  If they are marked then the runtime loader can enable the
features in the processor core.  This marking is done by setting flags
in the tags found in the dynamic section of the executable.  If the
flags are missing then the executable is considered to be unprotected.

The security features are enabled by compiling with the
@option{-mbranch-protection=standard} gcc command line option.

Note - 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-8
or RHEL-9.

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 @var{BTI} 
as the first instruction executed.  This instruction is safe to use
even in code that will not be executed in a BTI-enabled environment as
it translates into a no-op instruction if not needed.

In addition the assembler needs a note to indicate that it now supports
BTI.  This note can be added via including this code snippet in the
sources: 

@smallexample
	.pushsection	.note.gnu.property, "a"
	.align	3
	.word	2f - 1f
	.word	4f - 3f
	.word	5            /* NT_GNU_PROPERTY_TYPE_0 */
1:	.asciz	"GNU"

2:	.align	3
3:	.word	0xc0000000   /* type: GNU_PROPERTY_AARCH64_FEATURE_1_AND */
	.word	6f - 5f	     /* size */
5:	.word	1            /* value: GNU_PROPERTY_AARCH64_FEATURE_1_BTI */

6:	.align	3
4:	.popsection
@end smallexample

Note - this test is the inverse of the @ref{Test not dynamic tags}
test and directly related to the @ref{Test branch protection} test.

Note - this test is automatically enabled if one of the following
profile options is used:

@table @code
@item @option{--profile=rawhide}
@item @option{--profile=f43}
@item @option{--profile=f42}
@item @option{--profile=f41}
@item @option{--profile=f40}
@item @option{--profile=f39}
@item @option{--profile=f38}
@item @option{--profile=f37}
@item @option{--profile=f36}
@item @option{--profile=el10}
@end table

The test is automatically disabled if one of the other profile options
is used, ie:

@table @code
@item @option{--profile=el7}
@item @option{--profile=el8}
@item @option{--profile=el9}
@item @option{--profile=f35}
@end table

If necessary the test can be disabled via the @option{--skip-dynamic-tags}
option and re-enabled via the @option{--test-dynamic-tags} option.

@c -----------------------------------------------------------------
@node Test entry
@subsubsection The entry test

@smallexample
  Problem:  Intel's CET security feature requires that the first instruction in a program be ENDBR
  Fix By:   Compile statup code with -fcf-protection
  Waive If: The application will not run on the latest Intel hardware

  Example:  FAIL: entry test because instruction at entry is not ENDBR32
  Example:  FAIL: entry test because instruction at entry is not ENDBR64
@end smallexample

This test checks to make sure that the first instruction in a program
for the x86_64 architectures is @var{ENDBR}.  This is needed as
part of Intel's @var{CET} security feature.  (See @ref{Test cf
protection} for more details on @var{CET}).

If necessary the test can be disabled via the
@option{--skip-entry} option and re-enabled via the
@option{--test-entry} option. 

@c -----------------------------------------------------------------
@node Test fast
@subsubsection The -Ofast test

@smallexample
  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.
@end smallexample

This test checks that if part of the application was compiled with
the @option{-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:
@url{https://bugzilla.redhat.com/show_bug.cgi?id=1248744}

If necessary the test can be disabled via the @option{--skip-fast}
option and re-enabled via the @option{--test-fast} option.

@c -----------------------------------------------------------------
@node Test fips
@subsubsection The FIPS test

@smallexample
  Problem:  GO binaries need to be compiled with FIPS crypto support
  Fix By:   Compiling CGO_ENABLED=1
  Waive If: The application does not use crypto

  Example:  FAIL: fips test because the binary loaded a non-FIPS compliant crypto library
@end smallexample

By default when using Fedora, applications written in GO use
cryptographic functions from the GO standard library, which is not
FIPS-validated.  RHEL however is based on upstream GO's
dev.boringcrypto branch, which is modified to use BoringSSL for crypto
primitives.  These are FIPS-validated.

For the best security GO applications should use a FIPS-validated
cryptographic library, and this test checks for this behaviour.

This is automatically disabled if a Fedora @option{profile} is used.

If necessary the test can be disabled via the @option{--skip-fips}
option or re-enabled via the @option{--test-fips} option.

@c -----------------------------------------------------------------
@node Test flex arrays
@subsubsection The flex arrays test

@smallexample
  Problem:  Flexible arrays are a C coding convention that are often
     subject to buffer overrun attacks
  Fix By:   Compiling with -fstrict-flex-arrays=[123]
  Waive If: The application does not use flexible arrays

  Example:  FAIL: flexible test because -fstrict-flex-arrays was not enabled
@end smallexample

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 that the application was compiled with the
@option{-fstrict-flex-arrays=[123]} command line option enabled.
This option enforces a stricter use of flexible arrays that is easier
for the compiler to check for ppotential buffer overrun attacks.

The test also checks that the @option{-Wstrict-flex-arrays} warning
is enabled.

If necessary the test can be disabled via the @option{--skip-flex-arrays}
option and re-enabled via the @option{--test-flex-arrays} option.

@c -----------------------------------------------------------------
@node Test fortify
@subsubsection The fortify test

@smallexample
  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)
@end smallexample

This test checks that the application was compiled with either
@option{-D_FORTIFY_SOURCE=2} or @option{-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
@option{-O2} or higher was used.  Note - for certain profiles only
@option{-D_FORTIFY_SOURCE=3} will be accepted.

The @option{_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:
@url{https://access.redhat.com/blogs/766093/posts/1976213}

Any program that uses the string or memory functions in the
@var{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
@option{--profile=el7} option is used.

Note - if either of the @option{el10} or @option{rawhide} profiles are
enabled then only @option{-D_FORTIFY_SOURCE=3} will be accepted.

If necessary the test can be disabled via the @option{--skip-fortify}
option and re-enabled via the @option{--test-fortify} option.

@c -----------------------------------------------------------------
@node Test gaps
@subsubsection The gaps test

@smallexample
  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
@end smallexample

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
@option{--skip-gaps} option and re-enabled via the
@option{--test-gaps} option.

@c -----------------------------------------------------------------
@node Test glibcxx assertions
@subsubsection The glibcxx-assertions test

@smallexample
  Problem:  Compiled C++ code might contain bugs that could have been detected and fixed
  Fix By:   Compile with -D_GLIBCXX_ASSERTIONS
  Waive If: Not compiling C++
  Waive If: Not using functions from libstdc++

  Example:  FAIL: glibcxx-assertions test because compiled without -D_GLIBCXX_ASSERTIONS
@end smallexample

This test checks to make sure that the @option{-D_GLIBCXX_ASSERTIONS}
g+= compiler command line option was used when building binaries.
This option is one of several supported by the @var{libstdc++} library
and it is used to enable various NULL pointer and bounds checking
security features.  For more information see:

@url{https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_macros.html}

If necessary the test can be disabled via the
@option{--skip-glibcxx-assertions} option and re-enabled via the
@option{--test-glibcxx-assertions} option. 

@c -----------------------------------------------------------------
@node Test gnu relro
@subsubsection The gnu-relro test

@smallexample
  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
@end smallexample

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 @var{gnu relro} test checks that
write permission can be removed once the relocations have finished.

Enabling @var{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 @var{gnu relro}
is very insignificant and highly recommended.  For programs that need
to be reloaded often, the execution penalty of @var{gnu relro} can be
eliminated by using prelinking.  For embedded systems where space is
scarce, @var{gnu relro} is not recommended due to its space overhead. 

To turn on @var{gnu relro} compile with the gcc
@option{-Wl,-z,relro,-z,now} option.

If necessary the test can be disabled via the
@option{--skip-gnu-relro} option and re-enabled via the
@option{--test-gnu-relro} option.

@c -----------------------------------------------------------------
@node Test gnu stack
@subsubsection The gnu-stack test

@smallexample
  Problem:  An attacker could place code on the stack and then run it
  Fix By:   Updating compiler, assembler sources and/or linker scripts
  Waive If: The application *really* needs to be able to dynamically create and execute code
  
  Example:  FAIL: gnu-stack test because the .stack section has incorrect permissions
  Example:  FAIL: gnu-stack test because the .note.GNU-stack section has execute permission
  Example:  FAIL: gnu-stack test because the GNU stack segment has execute permission
  Example:  FAIL: gnu-stack test because the GNU stack segment does not have both read & write permissions
  Example:  FAIL: gnu-stack test because no .note.GNU-stack section found
  Example:  MAYB: gnu-stack test because multiple stack sections detected
@end smallexample

This test checks that it is not possible to place code onto the stack
and then execute it.  Normally the stack just holds data and
addresses, but never instructions.  A favourite tactic of attackers
however is to discover a buffer overrun bug that addresses the stack
and then place instructions there before forcing the processor to
execute them.

The test actually checks several different parts of a binary file in
order to determine that its stack is safe, which is why there are
several different potential failure messages.

Most applications will have a section inserted into them by the
compiler called @var{.note.GNU-stack}.  The section has no contents,
but the read, write, and execute attributes of the section reflect the
needs of the application's stack.

Ordinary compiled code should never see this problem, but the test
failure can be triggered by programs built with an old compiler which
does not support the @var{.note-GNU-stack} section, or if the program
contains some assembler source files or linked with a custom made
linker map.

To fix the problem either the compiler needs to be upgraded or the
linker map needs to be updated or the assembler sources need to be
extended to add the @var{.note-GNU-stack} section by adding code like
this: 

@smallexample
  .section .note.GNU-stack,"",%progbits
@end smallexample

If necessary the test can be disabled via the
@option{--skip-gnu-stack} option and re-enabled via the
@option{--test-gnu-stack} option.

@c -----------------------------------------------------------------
@node Test go revision
@subsubsection The go-revision test

@smallexample
  Problem:  Using old versions of the GO compiler looses out on security enhacements
  Fix By:   Using a newer GO compiler
  Waive If: No new GO compiler is available

  Example:  FAIL: go-revision test because GO revision must be >= 14
  Example:  FAIL: go-revision test because multiple, different GO version strings found
  Example:  FAIL: go-revision test because no Go compiler revision information found
@end smallexample

This test checks to see that GO code has been compiled by at least a
revision 14 compiler.  Earlier versions of the compiler do not have
all the bug fixes and security enhancements of later versions.

Note - it is likely that the minimum revision of the GO compiler will
be increased in the future.

If necessary the test can be disabled via the
@option{--skip-go-revision} option and re-enabled via the
@option{--test-go-revision} option. 

@c -----------------------------------------------------------------
@node Test implicit values
@subsubsection The implicit values test

@smallexample
  Problem:  Binaries built with implicit types for functions and
            variables might not work in environments where pointers
            and integers are different sizes
  Fix By:   Compiling with the warnings enabled and then fixing the
            warnings
  Waive If: Enabling the warnings would generate false positives

  Example:  FAIL: -Wimplicit-int not enabled
            FAIL: -Wimplicit-function-declaration not enabled
@end smallexample

This test checks to see that gcc's @option{-Wimplicit-int} and
@option{-Wimplicit-function-declaration} options have been enabled
when the binary built.  These options are normally enabled when the
@option{-Wall} option is used (see @ref{Test warnings}), but they can
also be enabled and disabled individually.

It is important to enable these warnings and then fix any code that
triggers them.  Otherwise any code that runs in an environment where
a pointer is not the same size as an integer is likely to run into
problems where the two are used interchangeably.

If necessary the test can be disabled via the
@option{--skip-implicit-values} option and re-enabled via the
@option{--test-implicit-values} option. 

@c -----------------------------------------------------------------
@node Test instrumentation
@subsubsection The instrumentation test

@smallexample
  Problem:  Instrumented binaries are bigger and slower than regular binaries
  Fix By:   Removing instrumentation options from compiler command line
  Waive If: Instrumentation is needed

  Example:  WARN: Instrumentation enabled - this is probably a mistake for production binaries
@end smallexample

This test checks to see if any of gcc's instrumentation command line
options have been used when the binary built.  These options are:
@option{-fsanitize}, @option{-finstrument-functions}, @option{-p},
@option{-pg}, and @option{-fprofile-arcs}.

If necessary the test can be disabled via the
@option{--skip-instrumentation} option and re-enabled via the
@option{--test-instrumentation} option. 

@c -----------------------------------------------------------------
@node Test load segments
@subsubsection The loadable segments test

@smallexample
  Problem:  Loadable segments need to be properly organized.
  Fix By:   Changing the linker script and/or options used to create the binary.
  Waive If: There is a special need for unusual load segments.

  Example:  FAIL: LOAD segments not in ascending order of virtual address
  Example:  FAIL: contains an empty LOAD segment
  Example:  FAIL: LOAD segments overlap
  Example:  FAIL: gap between LOAD segments of more than one page
  Example:  FAIL: LOAD segment with Write and Execute permissions seen
@end smallexample

This test performs various checks on the loadable program segments in
the file(s) being examined.  It checks to make sure that the segments
are in order, do not overlap, and do not have unacceptable
permissions.  The test examines both normal load segments (those with
the ELF segment type PT_LOAD) and thread-local load segments (with the
ELF segment type PT_TLS).

If @option{future} tests are enabled the test also looks for large
gaps between loadable segments.  These gaps are an issue for systems
with small amounts of memory, and for containers.  In addition leaving
gaps between segments means that other shared objects could be placed
between loaded parts of a binary which seriously confuses many tools.
It also causes problems for the loader which is optimized for
contigous programs which do not contain gaps.

If necessary the test can be disabled via the
@option{--skip-load-segments} option and re-enabled via the
@option{--test-load-segments} option. 

@c -----------------------------------------------------------------
@node Test lto
@subsubsection The lto test

@smallexample
  Problem:  When LTO is supported by the compiler, it should be used
  Fix By:   Using -flto consistently
  Waive If: LTO building is not wanted

  Example:  FAIL: no indication of LTO, possibly -fno-lto was used
@end smallexample

This test checks to see if the @option{-flto} compiler command line
option was used.  Using link time optimization produces better code
and allows for more compile-time security checks to be run.  Hence if
it is supported by the compiler it should be used.

Annocheck is currently unable to distinguish between code that has
been compiled with the @option{-fno-lto} option and code that has not
been compiled with any @option{-flto} option, which is why the
failure message is so vague.

Note - this test is automatically disabled if the
@option{--profile=el7} or @option{--profile=el8} option is used.

If necessary the test can be disabled via the
@option{--skip-lto} option and re-enabled via the
@option{--test-lto} option. 

@c -----------------------------------------------------------------
@node Test not branch protection
@subsubsection The not-branch-protection test

@smallexample
  Problem:  Protecting AArch64 binaries needs newer versions of AArch64 cores
  Fix By:   Compile with -mbranch-protection=none
  Waive If: Not running on AArch64
  Waive If: The application will run on Fedora 35 or later.
  Waive If: The application will not run on newer AArch64 cores.

  Example:  FAIL: not branch protection test because protection enabled
  Example:  FAIL: not branch protection test because only partially disabled
@end smallexample

Note - this test is the inverse of the @ref{Test branch protection} test
and directly related to the @ref{Test not dynamic tags} test. 

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
@option{-mbranch-protection=none} gcc command line option.

Note - this test is automatically disabled if one of the following
profile options is used:

@table @code
@item @option{--profile=rawhide}
@item @option{--profile=f43}
@item @option{--profile=f42}
@item @option{--profile=f41}
@item @option{--profile=f40}
@item @option{--profile=f39}
@item @option{--profile=f38}
@item @option{--profile=f37}
@item @option{--profile=f36}
@item @option{--profile=el10}
@end table

The test is automatically enabled if one of the other profile options
is used, ie:

@table @code
@item @option{--profile=el7}
@item @option{--profile=el8}
@item @option{--profile=el9}
@item @option{--profile=f35}
@end table

If necessary the test can be disabled via the
@option{--skip-not-branch-protection} option and re-enabled via the
@option{--test-not-branch-protection} option. 

@c -----------------------------------------------------------------
@node Test not dynamic tags
@subsubsection The not-dynamic-tags test

@smallexample
  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
@end smallexample

Note - this test is the inverse of the @ref{Test dynamic tags} test
and directly related to the @ref{Test not branch protection} test. 

This test checks to see if executable AArch64 binaries have been
marked as supporting the @var{BTI} and @var{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
@option{-mbranch-protection=none} gcc command line option.

Note - this test is automatically disabled if one of the following
profile options is used:

@table @code
@item @option{--profile=rawhide}
@item @option{--profile=f43}
@item @option{--profile=f42}
@item @option{--profile=f41}
@item @option{--profile=f40}
@item @option{--profile=f39}
@item @option{--profile=f38}
@item @option{--profile=f37}
@item @option{--profile=f36}
@item @option{--profile=el10}
@end table

The test is automatically enabled if one of the other profile options
is used, ie:

@table @code
@item @option{--profile=el7}
@item @option{--profile=el8}
@item @option{--profile=el9}
@item @option{--profile=f35}
@end table

If necessary the test can be disabled via the @option{--skip-not-dynamic-tags}
option and re-enabled via the @option{--test-not-dynamic-tags} option.

@c -----------------------------------------------------------------
@node Test notes
@subsubsection The notes test

@smallexample
  Problem:  Lack of annobin notes in a binary means that other tests will not work properly
  Fix By:   Compiling with -fplugin=annobin
  Waive If: The annobin plugin is not available

  Example:  FAIL: notes test because gaps were detected in the annobin coverage
  Example:  MAYB: notes test because not all of the .text section is covered by notes
  Example:  FAIL: notes test because annobin notes were not found

  Example:  MAYB: lto test because no indication that LTO was used
  Example:  MAYB: stack-clash test because no notes found regarding this test
  Example:  FAIL: fortify test because no indication that the necessary option was used (and a C compiler was detected)
  Example:  FAIL: warnings test because no indication that the necessary option was used (and a C compiler was detected)
  Example:  FAIL: stack-realign test because stack realign support is mandatory
  Example:  FAIL: branch-protection test because the -mbranch-protection option was not used
@end smallexample

This test checks that there are annobin notes covering all of the
file.  Annobin notes are generated by the compiler and describe the
security features that have been enabled.  The notes contain range
information, so that it is possible to determine if all of an
application has been covered by the notes, or if there are parts that
are missing notes.

If annobin notes are missing from a file then some of the other checks
run by the @var{hardened} checker will not work, which can trigger
FAIL or MAYB results for those tests.

Annobin notes are normally produced by a compiler plugin which can be
enabled via the @option{-fplugin=annobin} option for gcc or Clang, and
the @option{-fpass-plugin=annobin} option for LLVM.  (Note for pre
version-13 of LLVM the @option{-Xclang -load -Xclang annobin} option
should be used instead).

Annobin notes can be generated for assembler sources by using the
@option{-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 @option{-S -fverbose-asm
-fplugin=annobin <security option>} options should provide an example
of how to encode an annobin  note about @emph{<security option>}.

If necessary the test can be disabled via the @option{--skip-notes}
and @option{--skip-gaps} options and re-enabled via the
@option{--test-notes} and @option{--test-gaps} options.

@c -----------------------------------------------------------------
@node Test only go
@subsubsection The only-go test

@smallexample
  Problem:  Mixing GO and C is unsafe on x86 platforms
  Fix By:   Using a new GO compiler
  Waive If: Always

  Example:  FAIL: only-go test because combining GO and non-GO object files on x86 systems is not safe - it disables CET
@end smallexample

Note - this test is currently disabled.  The GO compiler's lack of
support for @var{CET} is a known issue that cannot be addressed by
package maintainers.  Hence there is no point in issuing an error
message.

This test checks to see if GO and C are being used together in the
same program.  This is a problem for code that is going to run on x86
architectures as the GO compiler does not support Intel's @var{CET}
technology.  (See @ref{Test cf protection} for more details on
@var{CET}).  The GO language is inheritantly safer than C, but if the
two are mixed, then the C parts will be missing out on the protection
offered by @var{CET}.

If necessary the test can be disabled via the
@option{--skip-only-go} option and re-enabled via the
@option{--test-only-go} option. 

@c -----------------------------------------------------------------
@node Test OpenSSL Engine
@subsubsection The openssl-engine test

@smallexample
  Problem:  The OpenSSL ENGINE API is deprecated in RHEL-10 and later
  Fix By:   Update the OpenSSL libraries installed and then rebuild the binary
  Waive If: The application is not intended for RHEL-10
  
  Example:  FAIL: OpenSSL binary using the deprecated ENGINE API detected
@end smallexample

This test checks that the if the application uses the OpenSSL library,
it does not make use of the decpreated ENGINE API.

OpenSSL Engines are not FIPS compatible and corresponding API is
deprecated since OpenSSL 3.0.  The engine functionality we are aware
of (PKCS#11, TPM) is covered by providers maintained by Crypto Team
now. Feel free to reach crypto team (#crypto) in case of questions.

This test is normally only enabled if the profile is unknown or
RHEL-10.  If necessary the test can be disabled via the
@option{--skip-openssl-engine} option and enabled via the
@option{--test-openssl-engine} option.

@c -----------------------------------------------------------------
@node Test optimization
@subsubsection The optimization test

@smallexample
  Problem:  Insufficient optimization prevents security features from working
  Fix By:   Compiling with -O2
  Waive If: The application does not use string/memory functions
  
  Example:  FAIL: optimization test because optimization level too low
  Example:  FAIL: optimization test because level too low
  Example:  MAYB: optimization test because no valid notes found regarding this test
@end smallexample

This test checks that the application was compiled with sufficient
optimization enabled.

The C library security hardening features enabled via the
@option{-D_FORTIFY_SOURCE=2} or @option{-D_FORTIFY_SOURCE=3}
preprocessor command line options will only work properly if the
compiler is run at an optimization level of at least @option{-O2}.
Hence this test checks to make sure that this level (or higher) has
been used.

Normally the only reason for not using @option{-O2} or higher is
because the application is space sensitive and needs to be compiled
with @option{-Os} or the compilation process is so time intensive that
using @option{-O0} is the only way to obtain reasonable build times.

If necessary the test can be disabled via the @option{--skip-optimization}
option and re-enabled via the @option{--test-optimization} option.

@c -----------------------------------------------------------------
@node Test pic
@subsubsection The pic test

@smallexample
  Problem:  Static binaries are more vulnerable to attacks
  Fix By:   Compile with -fPIC or -fPIE
  Waive If: Don't.

  Example:  FAIL: pic test because -fpic/-fpie not enabled
@end smallexample

Programs can be compiled to either load at a fixed address in memory
(@var{static} programs) or at a random address assigned at startup
time (@var{dynamic} programs).  Static programs are more vulnerable to
exploits because an attacker will know exactly where every part of the
program is located.  Thus building dynamic executables is
recommended.

This test checks that the appropriate compiler option has been used to
generate dynamic code.  For shared libraries this is the
@option{-fPIE} option should be used.  For dynamic executables the
@option{-fPIC} option should be used.  Note - there are lower case
alternatives of these options (ie @option{-fpie} and @option{-fpic})
which can also be used.  The difference between the lower case and
upper case versions is architecture dependent, but usually the lower
case version will only work with smaller programs, wheres the upper
case version works for all program sizes.

Note - this check is related to the @ref{Test pie} test.  This test
checks that the correct compile time option has been used.  That test
checks that the correct link time option has been used.

If necessary the test can be disabled via the @option{--skip-pic}
option and re-enabled via the @option{--test-pic} option.

@c -----------------------------------------------------------------
@node Test pie
@subsubsection The pie test

@smallexample
  Problem:  Static binaries are more vulnerable to attacks
  Fix By:   Link with -Wl,-pie
  Waive If: Don't

  Example:  FAIL: pie test because not built with '-Wl,-pie' (gcc/clang) or '-buildmode pie' (go)
@end smallexample

Programs can be compiled to either load at a fixed address in memory
(@var{static} programs) or at a random address assigned at startup
time (@var{dynamic} programs).  Static programs are more vulnerable to
exploits because an attacker will know exactly where every part of the
program is located.  Thus building dynamic executables is
recommended.

This test checks that the appropriate linker option (@option{-pie})
has been used to generate dynamic executables.  The option is only
needed for linking executables, not shared libraries.

Note - this check is related to the @ref{Test pic} test.  This test
checks that the correct linker option has been used.  That test
checks that the correct compile time option has been used.

Note - this test is automatically disabled if the
@option{--profile=el7} option is used.

If necessary the test can be disabled via the @option{--skip-pie}
option and re-enabled via the @option{--test-pie} option.

@c -----------------------------------------------------------------
@node Test production
@subsubsection The production test

@smallexample
  Problem:  Shipping code generated by an experimental compiler is bad
  Fix By:   Compile with a production ready compiler
  Waive If: The code is never going to be shipped

  Example:  FAIL: production test because a production-ready compiler was not used to build the binary
@end smallexample

This test checks to make sure that the binary was not produced by an
experimental compiler.  Experimental compilers can be detected by
examining their version information, which will include the string
@var{NOT_FOR_PRODUCTION} or @var{cross from}.

If necessary the test can be disabled via the
@option{--skip-production} option and re-enabled via the
@option{--test-production} option. 

@c -----------------------------------------------------------------
@node Test property note
@subsubsection The property-note test

@smallexample
  Problem:  Badly formed or missing GNU property notes can compromise an application at runtime
  Fix By:   Investigate and fix the creation of the notes
  Waive If: Using old tools that do not generate the notes

  Example:  FAIL: property-note test because there is more than one GNU Property note
  Example:  FAIL: property-note test because the property note does not have expected name
  Example:  FAIL: property-note test because the property note data has the wrong size
  Example:  FAIL: property-note test because the note section is present but empty
  Example:  FAIL: property-note test because the property note data has an invalid size
  Example:  FAIL: property-note test because the IBT property is not enabled
  Example:  FAIL: property-note test because the SHSTK property is not enabled
  Example:  FAIL: property-note test because unexpected property note type
  Example:  FAIL: property-note test because the BTI property is not enabled
  Example:  FAIL: property-note test because the GNU Property note segment not 8 byte aligned
  Example:  FAIL: property-note test because there is more than one GNU Property note in the note segment
  Example:  FAIL: property-note test because .note.gnu.property section not found (it is needed for branch protection support
  Example:  FAIL: property-note test because no .note.gnu.property section = no control flow information
  Example:  FAIL: property-note test because control flow protection is not enabled
@end smallexample

GNU property notes are special markers in binary files that provide
information about the program to the runtime loader.  This information
is architecture specific and it often includes details about any
security features that were enabled when the program was compiled.

This test checks that the property note is present - if needed for the
particular architcture - and that it is properly formatted.

Problems with property notes are usually related to other security
options being missing, or the use of assembler source files which do
not contain their own instructions for creating property notes.

If necessary the test can be disabled via the
@option{--skip-property-note} option and re-enabled via the
@option{--test-property-note} option. 

@c -----------------------------------------------------------------
@node Test rhivos
@subsubsection The RHIVOS tests

@smallexample
  Problem:  Development for the RHIVOS environment requires that some
    extra hardening features be enabled.
  Fix By:   Follow the requirements for RHIVOS delveopment.
  Waive If: The application is not going to be used in the RHIVOS environment.
  
  Example:  FAIL: INITFIRST dynamic flag seen
  Example:  FAIL: SONAME includes a directory separator character
  Example:  FAIL: SONAME not the same as the filename
  Example:  FAIL: the DT_AUDIT dynamic tag is present
  Example:  FAIL: the DT_AUXILIARY dynamic tag is present
  Example:  FAIL: the DT_DEPAUDIT dynamic tag is present
  Example:  FAIL: the DT_FILTER dynamic tag is present
  Example:  FAIL: the DT_PREINIT_ARRAY dynamic tag is present
  Example:  FAIL: RHIVOS does not support the use of the .hash section.  Please use --hash-style=gnu
  Example:  FAIL: not linked with -Wl,-z,now
  Example:  FAIL: dlopen/dlclose found in symbol table
  Example:  FAIL: GNU TLS version 1 functions found in symbol table
  Example:  FAIL: LOAD segment with Write and Execute permissions seen
  Example:  FAIL: Building with Clang/LLVM is not supported for RHIVOS
@end smallexample

Deleopment for the RHIVOS environment requires that some extra
hardening measures are applied.  This test attempts to check for most
of these requirements.

Enabling this test automatically enables the @option{--test-bind-now},
@option{--test-gnu-relro}, @option{--test-gnu-stack}.
@option{--test-load-segments} and @option{--test-run-path} tests.  In
addition the following extra checks are run:

@table @code
@item Clang/LLVM is not used.
@item The linker option @option{--initfirst} has not been used.
@item The linker option @option{--audit} has not been used.
@item The linker option @option{--depaudit} has not been used.
@item The linker option @option{--auxiliary} has not been used.
@item The linker option @option{--filter} has not been used.
@item Shared libraries names match their filenames and do not include
  the directory separator character.
@item The binary does not have a pre-init array.
@item The linker option @option{--hash-style=hash} or
  @option{--hash-style=both} has been used.
@item Dynamically loaded code is used.
@item Loadable segments with both the Write and Execute permissions
  are found in the binary.
@end table

This test is normally only enabled if the @option{--profile=rhivos}
option is used to select the RHIVOS profile.  But it can be enabled
independently by the @option{--test-rhivos} option.

@c -----------------------------------------------------------------
@node Test run path
@subsubsection The run-path test

@smallexample
  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
@end smallexample

An application that uses shared libraries contains information on how
to locate those libraries.  This information is a list of directories
which should be searched for the libraries.  The test checks that the
list is secure.

The test actually covers several different aspects, such as all
directory paths must be absolute, start with @var{/usr} and must not
contain @var{..}.  If any of these rules are broken then an attacker
might be able to exploit the search paths to force the application to
load their own, corrupted version of a shared library.

In addition if the @option{--profile=rawhide} option has been enabled
then the presence of the @var{DT_RPATH} dynamic tag will generate a
MAYB result, since in Fedora the @var{DT_RUNPATH} tag is preferred.
(The two tags only differ in when they are evaluated by the program
loader).  The @var{DT_RUNPATH} dynamic tag should be generated by
default, if it is needed, but in some cases it may be necessary to add
the @option{--enable-new-dtags} option to the linker command line, or
the @option{-Wl,--enable-new-dtags} option if you use gcc to drive the
linker.

If necessary the test can be disabled via the @option{--skip-run-path}
option and re-enabled via the @option{--test-run-path} option.

@c -----------------------------------------------------------------
@node Test rwx seg
@subsubsection The rwx-seg test

This test has been renamed to @option{load-segments} as it now checks
for more than just segments with read, write and execute permission.
See @ref{Test load segments} for more details.

@c -----------------------------------------------------------------
@node Test short enums
@subsubsection The short-enums test

@smallexample
  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
@end smallexample

The @option{-fshort-enums} gcc compiler option can be used to reduce
code size by storing enums in a @var{short} instead of an @var{int}.
But if the code passes enums between functions compiled in different
files then the @option{-fshort-enums} option must be used consistently
or there could be problems.

This test checks that either all files in an application were compiled
with the @option{-fshort-enums} option, or that the option was never
used.

If necessary the test can be disabled via the
@option{--skip-short-enums} option and re-enabled via the
@option{--test-short-enums} option. 

@c -----------------------------------------------------------------
@node Test stack clash
@subsubsection The stack-clash test

@smallexample
  Problem:  Attackers exploiting stack overrun bugs can gain control of an application
  Fix By:   Compiling with -fstack-clash-protection
  Waive If: Don't
  
  Example:  FAIL: stack-clash test because -fstack-clash-protection not enabled
@end smallexample

This test checks that the application has been compiled with stack
clash protection enabled (either gcc's
@option{-fstack-clash-protection} or LLVM's @option{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:

@url{https://developers.redhat.com/blog/2017/09/25/stack-clash-mitigation-gcc-background}

@url{https://developers.redhat.com/blog/2019/04/30/stack-clash-mitigation-in-gcc-why-fstack-check-is-not-the-answer}

@url{https://developers.redhat.com/blog/2020/05/22/stack-clash-mitigation-in-gcc-part-3}

Note - this test is automatically disabled if the
@option{--profile=el7} option is used.

If necessary the test can be disabled via the @option{--skip-stack-clash}
option and re-enabled via the @option{--test-stack-clash} option.

@c -----------------------------------------------------------------
@node Test stack prot
@subsubsection The stack-prot test

@smallexample
  Problem:  Attackers exploiting stack overrun bugs can gain control of an application
  Fix By:   Compiling with -fstack-protector-strong
  Waive If: Don't
  
  Example:  FAIL: stack-prot test because insufficient protection enabled
  Example:  FAIL: stack-prot test because stack protection deliberately disabled
  Example:  FAIL: stack-prot test because only some functions protected
  Example:  FAIL: stack-prot test because insufficient Stack Safe sanitization
@end smallexample

This test checks that the application has been compiled with stack
protection enabled.  For gcc this means using the
@option{-fstack-protector-strong} option and for Clang the
@option{-fsanitize=safe-stack} option.  The gcc option does have some
levels of protection other than @var{strong}, but @var{strong} is the
only one that provides full protection.

The stack protection feature adds checks to compiled code that attempt
to detect buffer overflows for local buffers.  These are often a
source of vulnerability that can be exploited by an attacker.

If necessary the test can be disabled via the @option{--skip-stack-prot}
option and re-enabled via the @option{--test-stack-prot} option.

@c -----------------------------------------------------------------
@node Test stack realign
@subsubsection The stack-realign test

@smallexample
  Problem:  Legacy i686 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
@end smallexample

On the Intel 32-bit i686 architecture most instructions work with
4-byte aligned addresses.  The @var{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 @option{-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 i686 binaries.

If necessary the test can be disabled via the
@option{--skip-stack-realign} option and re-enabled via the
@option{--test-stack-realign} option. 

@c -----------------------------------------------------------------
@node Test textrel
@subsubsection The textrel test

@smallexample
  Problem:  An attacker could change the code in an executable
  Fix By:   Compiling with -fPIC enabled
  Waive If: The code @emph{must} be static
  
  Example:  FAIL: textrel test because the DT_TEXTREL tag was detected
@end smallexample

This test checks to make sure that a binary file does not contain any
relocations that alter the contents of a code section.  Relocations
are special instructions that the program loader uses to alter pieces
of a application when it starts up.  Normally these relocations are
restricted to altering the application's data, but if any of them
alter its code then an attacker might be able to exploit this to
change the program.

This problem usually only arises when a binary - or part of it - 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 all parts of the binary to be
position independent by using the @option{-fPIC} or @option{-fPIE}
compiler command line options.

If necessary the test can be disabled via the @option{--skip-textrel}
option and re-enabled via the @option{--test-textrel} option.

@c -----------------------------------------------------------------
@node Test threads
@subsubsection The threads test

@smallexample
  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
@end smallexample

This test checks to make sure that the @option{-fexceptions} g++
command line option was used when building the binary.  The test is
only triggered if the binary uses the @var{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
@option{--skip-threads} option and re-enabled via the
@option{--test-threads} option. 

@c -----------------------------------------------------------------
@node Test unicode
@subsubsection The unicode test

@smallexample
  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
@end smallexample

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.

@c Add URL to description of attack, once it is no longer embargoed.

The test looks for the following characters in symbol names:

@table @code
@item Any control character
@item The space and DEL characters
@item Any non-unicode multibyte character
@end table

In addition if the @option{--test-unicode-all} option has been enabled
(either via the command line, or via selecting a RHEL profile with the
@option{--profile} option) then the test will fail is any multibyte
character is found.

On the other hand, if the opposite @option{--test-unicode-suspicious}
option has been enabled then the test looks for:

@table @code
@item Any character with zero width
@item Any character that changes the direction of the text
@end table

Other suspicious multibyte characters may be added in the future.

If necessary the test can be disabled via the
@option{--skip-unicode} option and re-enabled via the
@option{--test-unicode} option. 

@c -----------------------------------------------------------------
@node Test warnings
@subsubsection The warnings test

@smallexample
  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
@end smallexample

This test checks to see that a file has been compiled with either or
both of the @option{-Wall} and @option{-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
@option{--skip-warnings} option and re-enabled via the
@option{--test-warnings} option. 

@c -----------------------------------------------------------------
@node Test writable got
@subsubsection The writable-got test

@smallexample
  Problem:  An attacker could intercept and redirect shared library function calls
  Fix By:   Link with -Wl,--secure-plt
  Waive If: No shared libraries are used
  
  Example:  FAIL: writable-got test because the GOT/PLT relocs are writable
@end smallexample

This test checks that the instructions to set up the @var{GOT} and
@var{PLT} tables in a dynamic executable cannot be altered by an
outside source.

Dynamic executables use two tables to help them connect to shared
libraries.  These tables - the @var{GOT} and the @var{PLT} - are set
up when the program runs, based upon instructions held in special
sections in the file.  If these sections are writable then an
attacker could change their contents and thus cause the program to
call the wrong functions in the shared libraries.

Under normal circumstances this test should never fail.  If it does
then something unusual is going on.  One possible cure is to add the
@option{-Wl,--secure-plt} option to the final link command line.

If necessary the test can be disabled via the
@option{--skip-writable-got} option and re-enabled via the
@option{--test-writable-got} option.

@c -----------------------------------------------------------------
@node Test zero call used regs
@subsubsection The zero-call-used-regs test

@smallexample
  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'
@end smallexample

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 @option{-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 @option{--test-zero-call-used-regs} option
and disabled by the @option{--skip-zero-call-used-regs} option.  It is also
enabled if the @option{--test-future} option is specified and disabled
if the @option{skip-future} option is specified.

@c -----------------------------------------------------------------
@node Hardened Command Line Options
@subsection Command line options specific to the hardened tool

@table @code

@item --skip-@var{test}[=@var{funcname}]
Disable the test called @var{test}.  If the optional @var{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.

@item --skip-all
Disable all tests.  Not really useful unless followed by one or more
options to enable specific tests.

Note - using this option also sets the @option{profile} to
@emph{none}.  If the enabling of profile specific tests is desired the
@option{--profile} option must appear after the @option{--skip-all} on
the command line.

@item --test-@var{name}
Enable test @var{name}.

@item --test-all
Enable all the tests.

@item --test-future
@itemx --skip-future
@itemx --enable-future
@itemx --disable-future
Enable all the @emph{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 @option{--skip-future} option can be
used to restore the default behaviour of skipping all of these tests.

Individual future fail tests can be enabled by name by using
@option{--test-@var{name}}.  In addition it is possible to allow
future fails without specifically enabling any of them by using the
@option{--enable-future} option, and to disable them by using the
@option{--disable-future} option.  This may be useful as some tests
have parts which are future fail and parts which are not.

@item --test-unicode-all
@itemx --test-unicode-suspicious
The @option{--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 @option{--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 @option{--test-unicode-suspicious}, only
potentially dangerous unicode characters trigger a failure.  See
@ref{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.

@item --skip-passes
@itemx --no-skip-passes
Tells annocheck to display (or not display) a ``PASS <filename>''
result for each binary that passes all of the tests.  In addition, if
running in @option{--verbose} mode, individual tests that succeed will
be displayed as ``<filename> PASS <testname>'' if this option is
enabled.  The default is to have the option enabled.

@item --profile=el7
@itemx --profile=rhel-7
@itemx --profile=el8
@itemx --profile=rhel-8
@itemx --profile=el9
@itemx --profile=rhel-9
@itemx --profile=el10
@itemx --profile=rhel-10
@itemx --profile=rawhide
@itemx --profile=f43
@itemx --profile=f42
@itemx --profile=f41
@itemx --profile=f40
@itemx --profile=f39
@itemx --profile=f38
@itemx --profile=f37
@itemx --profile=f36
@itemx --profile=f35
@itemx --profile=rhivos
@itemx --profile=default
@itemx --profile=none
@itemx --profile=auto
Rather than enabling and disabling specific tests a selection can be
chosen via a profile option.  The @option{--profile=el7} and
@option{--profile=rhel-7} options will select the tests suitable for
@emph{RHEL-7} binaries.  Similarly @option{--profile=el8} or
@option{--profile=rhel-8} configures the tests for @emph{RHEL-8} and 
so on.

The  @option{--profile=rawhide} option will select tests suitable for
@emph{Fedora rawhide} binaries, whilst @option{--profile=f38} selects
tests suitable for @emph{Fedora F38}, and so on for the other Fedora
releases.

Other profiles may be added in the future.

The @option{--profile=rhivos} option enables tests mandated for
RHIVOS development.

The @option{--profile=auto} option will attempt to determine the
profile to use, based upon the input filename.  This only works with
@file{rpms}, which include the OS as part of their name.  This option
is the default.  The @option{--profile=default} option is a synonym
for the @option{--profile=auto} option.

Using @option{--profile=none} will disable the profiling.

For backwards compatibility the form @option{--profile-<name>} can be
used instead of @option{--profile=<name>}.

Currently the profiles enable and disable the following tests:

@table @code
@item el9
@itemx f35
Disables the @ref{Test branch protection} and @ref{Test dynamic tags}
tests and enables their inverse, ie @ref{Test not branch protection}
and @ref{Test not dynamic tags}.

Also enables @ref{Test unicode} and sets the default to fail for any
multibyte character.

@item el8
Like @code{el9} but also disables the @ref{Test lto} test.

@item el7
Like @code{el8} but also disables the @ref{Test pie}, @ref{Test bind
now}, @ref{Test fortify} and @ref{Test stack clash} tests.

@item el10
Enables the @ref{Test branch protection} and @ref{Test dynamic tags}
tests and disables their inverse, ie @ref{Test not branch protection}
and @ref{Test not dynamic tags}.

@item rawhide
@itemx f36
Like @code{el10} but also disables the @xref{Test fips} test.

@end table

In addition the @ref{Test unicode} test is enabled for all of the RHEL
profiles, but disabled for the Fedora profiles.

@item --disable-hardened
@itemx --enable-hardened
Disables or enables the tool.

@item --ignore-gaps
@itemx --report-gaps
The @option{--ignore-gaps} option is an alias for the
@option{--skip-gaps} option which disables the gaps test.
The @option{--report-gaps} option is an alias for the
@option{--test-gaps} option which enables the gaps test if
it has been disabled.  (The test is enabled by default).

@item --fixed-format-messages
Display messages in a fixed, machine parseable format.  The format is:

@smallexample
Hardened: <result>: test: <test-name> file: <file-name>
@end smallexample

Where @code{<result>} is @emph{PASS} or @emph{FAIL} and
@code{<test-name>} is the name of the test, which is the same as the
name used in the @option{--test-<test-name>} option.  The
@code{<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:

@smallexample
  Hardened: FAIL: test: pie file: a.out.
@end smallexample

@item --disable-colour
@itemx --enable-colour
@itemx --disable-color
@itemx --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
@option{--enable-colour}.  The American spelling of color is also
supported.

@item --show-totals
@itemx --no-show-totals
Do, or do not, show cumulative results when testing multiple files.
The default is to show the cumulative results.

@item --allow-exceptions
@itemx --no-allow-exceptions
By default annocheck will skip some tests for known special case
binaries - eg glibc components or gcc support files.  This behaviour
can be disabled by the @option{--no-allow-exceptions} option and
restored by the @option{--allow-exceptions}.

@item --full-filenames
@itemx --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 @option{verbose} mode.  This option and its inverse
@option{--base-filenames} can be used to set a fixed choice.

@item --suppress-version-warnings
Do not issue warning messages about version mismatches between the
version of the compiler used to build the annobin plugin and the
version of the compiler used to run the annobin plugin.

@item --no-urls
@itemx --provide-urls
By default when a FAIL or MAYB result is displayed by the
@var{hardened} checker and @option{--verbose} is enabled, a URL to the
online version of the relevant section in this document is also
displayed.  (Unless the @option{--fixed-format-messages} option has
been enabled).  The @option{--no-urls} option disables the display of
the URLs and the @option{--provide-urls} re-enables the display (even
in non-verbose mode).

@end table

@c man end

@c -----------------------------------------------------------------
@node Waiving Hardened Results
@subsection How to waive the results of the hardening tests

[This section is Red Hat specific.]

Now that @command{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 @file{rpminspect.yaml} file and
adding an entry like this:

@smallexample
 ---
 annocheck:
    extra_opts:
        - hardened: --skip-property-note --ignore-unknown --verbose
@end smallexample

This example shows how the @emph{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
@option{--ignore-unknown} and @option{--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:

@smallexample
 ---
 annocheck:
    - rhel-policy: --skip-property-note --ignore-unknown --verbose
@end smallexample

It is also possible to stop annocheck from testing specific files
in an rpm by listing them in the @file{rpminspect.yaml file}, like
this:

@smallexample
---
annocheck:
    ignore:
        - /usr/libexec/installed-tests/glib/mem-overflow
        - /usr/libexec/installed-tests/glib/resources
@end smallexample

For more information on rpmdiff see:

@url{https://docs.engineering.redhat.com/display/HTD/rpmdiff-elf-binarylibrary}

For more information on the use of annobin in RHEL see:

@url{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
@var{os-devel-list@@redhat.com} OS Devel
or the 
@var{rhel-devel@@redhat.com} RHEL Devel mailing lists.

@c -----------------------------------------------------------------
@node Absence of compiled code
@subsection What to do if annocheck reports that it could not find compiled code.

The hardening checker will skip or fail 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 is checking
for a specific feature of a specific compiler.

The checker uses several different methods for determining if an
executable was compiled:

@table @code
@item notes
If there are annobin notes present, these include a description of the
compiler used to create the executable.

@item DWARF
If DWARF debug information is available, the compiler can usually be
found in the DW_AT_producer attribute and the source language in the
DW_AT_language attribute.

@item comment
If there is a @emph{.comment} section in the file, then this usually
contains the name of the compiler.

@item GO note
The presence of a @emph{.note.go.buildid} section indicates that the
file contains GO compiler code.

@item GO symbol
The presence of a variable called @samp{go1.<V>} in the read-only data
section.  Again this indicates the presence of GO compiled code.

@item executable segments
If the file contains one or more program segments with the
@emph{executable} flag set, then this indicates that it is likely to
contain compiled code.

@end table

There are several reasons why annocheck might think that the file does
not originate from compiled source code:

@table @code
@item 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 @command{glibc} for example
because it does not use stack checking or function fortification.

This effect can be achieved with @command{GCC} by using the
@option{-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 @emph{and} to ignore tests specific to high level
languages. 

@item 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:

@smallexample
	.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
@end smallexample

Compiling a simple C program with the @option{-S -fverbose-asm
-fplugin=annobin <security option>} options should provide an example
of how to encode a note about @emph{<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:

@smallexample
	.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
@end smallexample

@item 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.

@item 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.

@item 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.

@item missing debug information file
Commonly binaries that are compiled with debug information enabled
have that information moved into a separate debug info file as part of
the build process.  If annocheck is unable to locate the debug info
file that is associated with a binary then it looses out on a lot of
information.

In addition it is quite common for the build process to also move any
annobin notes into the separate debug info file.  So again if that
file cannot be found then annocheck is hampered in its activities.

@end table

@c -----------------------------------------------------------------
@node Notes
@section The annobin note displayer

@smallexample
@c man begin SYNOPSIS annocheck-notes

annocheck
  [@b{--disable-hardened}]
  @b{--enable-notes}
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION annocheck-notes

The @var{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 @var{notes} tool is disabled by default, but it can be enabled
by the command line option @option{--enable-notes}.  Since the
hardening checker is enabled by default it may also be useful to add
the @option{--disable-hardened} option to the command line.

@c man end

@c -----------------------------------------------------------------
@node Size
@section The section size recorder

@smallexample
@c man begin SYNOPSIS annocheck-size

annocheck
  [@b{--disable-hardened}]
  [@b{--size-sec=@var{name}}]
  [@b{--size-sec-flags=@var{!WAX}}]
  [@b{--size-seg-flags=@var{!WRX}}]
  [@b{--size-human}]
  [@b{--size-total}]
  [@b{--size-missing}]
  [@b{--disable-size}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION annocheck-size
The @var{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 @command{annocheck} framework, it is able to
handle directories and rpms files as well as ordinary binary files.

The @option{--size-sec=@var{name}} option enables the tool and
tells it to record the size of section @var{name}.  The option can be
repeated multiple times to record the sizes of multiple sections.  It
may also be useful to add the @option{--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 @option{--size-sec-flags=<flags>}
option will search for any section that has all of the specified
@var{<flags>} set.  Currently only @var{W}, @var{A} and @var{X} are
recognised as flags, indicating that the section must have the
@var{Write}, @var{Alloc} or @var{Execute} flags set respectively.  If
the @var{!} exclamation mark character is present then it negates the
meaning of the following flags.  Thus @option{--section-sec-flags=W}
option will search for any writable section whereas the
@option{--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
@option{--size-seg-flags=<flags>} option.  The flags recognised for
segments are @var{W} for writable, @var{R} for readable and @var{X}
for executable.  Again the @var{!} character can be used to invert the
meaning of the flags that follow it.

If the @option{--verbose} option is enabled, then the tool will also
report the size of the named section(s) in each file it encounters.

If the @option{--size-human} option is enabled then sizes will be
rounded down to the nearest byte, kibibyte, mebibyte or gibibyte, as
appropriate.

If the @option{--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 @option{--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
@option{--disable-size} command line option.

@c man end

@c -----------------------------------------------------------------
@node Timing
@section How long did the check take ?

@smallexample
@c man begin SYNOPSIS annocheck-timing

annocheck
  @b{--enable-timing}
  @var{file}@dots{}
  [@b{--sec}]
  [@b{--usec}]
  [@b{--nsec}]
@c man end
@end smallexample

@c man begin DESCRIPTION annocheck-timing
The @var{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 @option{--enable-timing}.

By default the tool will report times in microseconds, but you can
change this to reporting in seconds with the @option{--sec} or in
nanoseconds with the @option{--nsec}.  The default can be restored
with the @option{--usec} option.

@c man end

@c -----------------------------------------------------------------
@node Libannocheck
@chapter Allowing other programs to run security checks
The @code{annocheck} program is mostly seen as a security checking
tool and in order to allow third party programs such as
@code{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 @code{tests/use-libannocheck.c}
file contains code to initialise, run and then close the library.  In
theory however the code flow looks like this:

@smallexample
  #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);
@end smallexample

The library consists of a header file (@code{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
@end menu

@c -----------------------------------------------------------------
@node libannocheck_init
@section Initialise the library
@smallexample
struct libannocheck_internals *
libannocheck_init (unsigned int  VERSION,
                   const char *  FILEPATH,
                   const char *  DEBUGPATH)
@end smallexample

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.

@c -----------------------------------------------------------------
@node libannocheck_finish
@section Close the library
@smallexample
libannocheck_error
libannocheck_finish (struct libannocheck_internals * HANDLE)
@end smallexample

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.

@c -----------------------------------------------------------------
@node libannocheck_get_version
@section Get the library version
@smallexample
unsigned int
libannocheck_get_version (void)
@end smallexample

Returns the actual version number of the libannocheck_library.
This should be >= libannocheck_version as defined in the
@code{libannocheck.h} header file.

@c -----------------------------------------------------------------
@node libannocheck_get_error_message
@section Convert an error number into an error message
@smallexample
const char *
libannocheck_get_error_message
  (struct libannocheck_internals *  HANDLE,
   enum libannocheck_error          ERRNUM)
@end smallexample

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.

@c -----------------------------------------------------------------
@node libannocheck_get_known_tests
@section Get a list of tests supported by the library
@smallexample
libannocheck_error
libannocheck_get_known_tests
  (struct libannocheck_internals * HANDLE,
   libannocheck_test **            TESTS_RETURN,
   unsigned int *                  NUM_TESTS_RETURN)
@end smallexample

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
@code{libannocheck_enable_test} or @code{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
@code{libannocheck_run_tests}.

@c -----------------------------------------------------------------
@node libannocheck_enable_all_tests
@section Enable all tests
@smallexample
libannocheck_error
libannocheck_enable_all_tests (struct libannocheck_internals * HANDLE)
@end smallexample

Enables all the tests supported by libannocheck.

This function may change some of the fields in the data structure
returned by the @code{libannocheck_get_known_tests} function.

@c -----------------------------------------------------------------
@node libannocheck_disable_all_tests
@section Disable all tests
@smallexample
libannocheck_error
libannocheck_disable_all_tests (struct libannocheck_internals * HANDLE)
@end smallexample

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 @code{libannocheck_get_known_tests} function.

@c -----------------------------------------------------------------
@node libannocheck_enable_test
@section Enable a specific test
@smallexample
libannocheck_error
libannocheck_enable_test
  (struct libannocheck_internals * HANDLE,
   const char *                    TEST_NAME)
@end smallexample

Enables a specific test.  Returns @code{libannocheck_error_none} upon
success or an error code otherwise.  If the test is not known then
@code{libannocheck_error_test_not_found} is returned.

This function may change some of the fields in the data structure
returned by the @code{libannocheck_get_known_tests} function.

@c -----------------------------------------------------------------
@node libannocheck_disable_test
@section Disable a specific test
@smallexample
libannocheck_error
libannocheck_disable_test
  (struct libannocheck_internals * HANDLE,
  const char *                     TEST_NAME)
@end smallexample
  
Disables a specific test.  Returns @code{libannocheck_error_none} upon
success or an error code otherwise.  If the test is not known then
@code{libannocheck_error_test_not_found} is returned.

This function may change some of the fields in the data structure
returned by the @code{libannocheck_get_known_tests} function.

@c -----------------------------------------------------------------
@node libannocheck_enable_profile
@section Enable a profile
@smallexample
libannocheck_error
libannocheck_enable_profile
  (struct libannocheck_internals * HANDLE,
   const char *                    PROFILE_NAME)
@end smallexample

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.

@c -----------------------------------------------------------------
@node libannocheck_get_known_profiles
@section Get a list of known profiles
@smallexample
libannocheck_error
libannocheck_get_known_profiles
  (struct libannocheck_internals * HANDLE,
   const char ***                  PROFILES_RETURN,
   unsigned int *                  NUM_PROFILES_RETURN)
@end smallexample

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.

@c -----------------------------------------------------------------
@node libannocheck_run_tests
@section Run enabled tests
@smallexample
libannocheck_error
libannocheck_run_tests
  (struct libannocheck_internals * HANDLE,
   unsigned int *                  NUM_FAIL_RETURN,
   unsigned int *                  NUM_MAYB_RETURN)
@end smallexample

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
@code{libannocheck_get_known_tests} for any enabled test. 

Can be called multiple times.

@c -----------------------------------------------------------------
@node Configure Options
@chapter Configuring annobin and annocheck 

@c man begin
When building annobin and annocheck from the sources there are a
few configure options available to customise the build:

@table @code
@item --with-debuginfod
debuginfod is a web service that indexes ELF/DWARF debugging resources
by build-id and serves them over HTTP.

By default the @command{annocheck} program will be built and linked
with the debuginfod client library @file{libdebuginfod} if it is
present at build time.  The @option{--with-debuginfod} configure
option can be used to force the linking against the library even if
the run-time @command{debuginfod} program cannot be found.
Alternatively the @option{--without debuginfod} can be used to force
annobin to be built without @file{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/'.

@item --with-gmp=PATH
The @option{--with-gmp=PATH} option can be used to specify an
alternative path to the gmp libraries, if necessary.

@item --without-libelf
The annocheck program uses @file{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 @command{annocheck}
and the running of the tests.  (Since they use @command{annocheck}).
This behaviour can be overridden by the @option{--without-libelf}
option which forces the build to assume that libelf is absent even if
it would normally be detected.

@item --without-tests
Disable running the testsuite after building the various binaries.

@item --without-clang-plugin
Disable the building of the annobin plugin for the Clang compiler.

@item --without-llvm-plugin
Disable the building of the annobin plugin for the LLVM compiler
backend.  The LLVM plugin is separate from the Clang plugin and can be
used with any language that uses LLVM as a backend compiler.

@item --without-gcc-plugin
Do not build the gcc plugin.

@item --without-docs
Do not build the documentation.

@item --without-annocheck
Do not build the annocheck tool.

@item --enable-maintainer-mode
This enables the regeneration of the @file{Makefile} and
@file{configure} files when building the @code{annobin} sources.

@end table
@c man end

Also note that there is a script in the top level source directory
called @file{regenerate-configure-and-makefiles.sh} which can be used
to rebuild the configure and Makefile.in files, should something
change.

@c -----------------------------------------------------------------
@node Legacy Scripts
@chapter How to use the information stored in the binary.

The @code{annobin} package includes some example scripts that
demonstrate how the binary information can be used.

@emph{NOTE}: These scripts are now redundant, their functionality
having been subsumed into the @command{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
@end menu

@c -----------------------------------------------------------------
@node Who Built Me
@section The built-by script

@c man title built-by Who Built Me

@smallexample
@c man begin SYNOPSIS built-by
built-by
  [@b{--help}]
  [@b{--version}]
  [@b{--verbose}]
  [@b{--quiet}]
  [@b{--silent}]
  [@b{--ignore}]
  [@b{--readelf=}@var{path}]
  [@b{--tmpdir=}@var{dir}]
  [@b{--tool=}@var{name}]
  [@b{--nottool=}@var{name}]
  [@b{--before=}@var{date}]
  [@b{--after=}@var{date}]
  [@b{--minver=}@var{version}]
  [@b{--maxver=}@var{version}]
  [@b{--}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION built-by

The @file{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:

@table @samp

@item --help
@itemx -h
Displays the usage of the script and then exits.

@item --version
@itemx -v
Displays the version of the script.

@item --verbose
@itemx -V
Enables verbose mode, causing the script to detail each action it
takes.

@item --quiet
@itemx -q
Do not include the name of script in the out generated by the script.

@item --silent
@itemx -s
Produce no output.  Just return an exit status.

@item --ignore
Do not report file types that do not contain any builder information.

@item --tool=@var{name}
Only report binaries built by @var{name}.  The @var{name} is only an
ordinary string, not a regular expression.

@item --nottool=@var{name}
Skip any binary build by @var{name}.  The @var{name} is only an
ordinary string, not a regular expression.

@item --before=@var{date}
Only report binaries built by a tool that was created before
@var{date}.  @var{date} has the format @var{YYYYMMDD}.

@item --after=@var{date}
Only report binaries built by a tool that was created after
@var{date}.  When combined with the @option{--before} option can be
used to restrict output to files which were built by tools created in
a specific date range.

@item --minver=@var{version}
Only report binaries built by a tool whose version is @var{version} or
higher.  The @var{version} string should be in the form @var{V.V.V},
for example @var{6.2.1}.

@item --maxver=@var{version}
Only report binaries built by a tool whose version is @var{version} or
lower.  Can be combined with the @option{--minver} option to restrict
output to those binaries created by tools within a specific version
range.

@item --tmpdir=@file{dir}
@itemx -t @file{dir}
Directory to use to store temporary files.

@item --readelf=@file{path}
@itemx -r=@file{path}
Use the specified program to read the notes from the files.

@item --
Stop accumulating command line options.  This allows the script to be
run on files whose names starts with a dash.

@end table

@c man end

@c -----------------------------------------------------------------
@node ABI Checking
@section The check-abi script

@c man title check-abi ABI Checking

@smallexample
@c man begin SYNOPSIS check-abi
check-abi
  [@b{--help}]
  [@b{--version}]
  [@b{--verbose}]
  [@b{--quiet}]
  [@b{--silent}]
  [@b{--inconsistencies}]
  [@b{--ignore-unknown}]
  [@b{--ignore-}@var{ABI|enum|FORTIFY|stack-prot}]
  [@b{--readelf=}@file{path}]
  [@b{--tmpdir=}@file{dir}]
  [@b{--}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION check-abi

The @file{check-abi} script reports any potential ABI conflicts in
the files specified.  This includes the use of the
@option{-fshort-enums} option, the @option{-fstack-protector} option
and the @option{-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:
@table @env

@item --help
@itemx -h
Displays the usage of the script and then exits.

@item --version
@itemx -v
Displays the version of the script.

@item --verbose
@itemx -V
Enables verbose mode, causing the script to detail each action it
takes.

@item --quiet
@itemx -q
Do not include the name of script in the out generated by the script.

@item --silent
@itemx -s
Produce no output.  Just return an exit status.

@item --inconsistencies
@itemx -i
Only report files with potential ABI problems.

@item --ignore-unknown
Do not report file types that are not supported or recognised.

@item --ignore-@var{ABI|enum|FORTIFY|stack-prot}
Disables individual ABI checks.  Multiple occurrences of this option
accumulate.  Possible option values are:

@table @samp
@item ABI
Disable checks of the general ABI information.

@item enum
Disable checks of the @option{-fshort-enum} option.

@item FORTIFY
Disable checks of the @samp{-D_FORTIFY_SOURCE} option.

@item stack-prot
Disable checks of the @option{-fstack-protect} option.
@end table

@item --tmpdir=@file{dir}
@itemx -t @file{dir}
Directory to use to store temporary files.

@item --readelf=@file{path}
@itemx -r=@file{path}
Use the specified program to read the notes from the files.

@item --
Stop accumulating command line options.  This allows the script to be
run on files whose names starts with a dash.

@end table

@c man end

@c -----------------------------------------------------------------
@node Hardening Checks
@section The hardened script

@c man title hardened  Hardening Checks

@smallexample
@c man begin SYNOPSIS hardened
hardened
  [@b{--help}]
  [@b{--version}]
  [@b{--verbose}]
  [@b{--quiet}]
  [@b{--ignore-unknown}]
  [@b{--silent}]
  [@b{--vulnerable}]
  [@b{--not-hardened}]
  [@b{--all}]
  [@b{--file-type=}@var{auto|lib|exec|obj}]
  [@b{--skip=}@var{opt|stack|fort|now|relro|pic|operator|clash|cf|cet|realign}]
  [@b{--readelf=}@file{path}]
  [@b{--tmpdir=}@file{dir}]
  [@b{--}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION hardened

The @file{hardened} script reports on the hardening status of the
specified file(s).  In particular it checks that the whole file was
compiled with @option{-O2} or higher and the
@option{-fstack-protector-strong}, @option{-D_FORTIFY_SOURCE=2},
@option{-Wl,-z,now}, @option{-Wl,-z,relro}, @option{-fPIE}, 
@option{-Wp,-D_GLIBCXX_ASSERTIONS}, @option{-fstack-clash-protection}
@option{-fcf-protection=full} and @option{-mcet}
options.

The script accepts the following command line options:
@table @env

@item --help
@itemx -h
Displays the usage of the script and then exits.

@item --version
@itemx -v
Displays the version of the script.

@item --verbose
@itemx -V
Enables verbose mode, causing the script to detail each action it
takes.

@item --quiet
@itemx -q
Do not include the name of script in the out generated by the script.

@item --ignore-unknown
@itemx -i
Do not report file types that are not supported or recognised.

@item --tmpdir=@file{dir}
@itemx -t @file{dir}
Directory to use to store temporary files.

@item --silent
@itemx -s
Produce no output.  Just return an exit status.

@item --vulnerable
@itemx -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.

@item --not-hardened
@itemx -n
Report any file that cannot be proven to be hardened.  This is like
the @option{--vulnerable} option, except that it will also report
files that do not record all of the necessary information.

@item --all
@itemx -a
Report the hardening status of all of the files examined.

@item --file-type=@var{auto|lib|exec|obj}
@itemx -f=@var{auto|lib|exec|obj}
Specifies the type of file being examined.  Possible values are:

@table @samp
@item auto
Automatically determine the file type from its extension.
This is the default.
@item lib
Assume all files are shared libraries.  Checks that the @option{-fPIC}
option was used.
@item exec
Assume all files are executables.  Checks that the @option{-fPIE}
option was used.
@item obj
Assume all files are object files.  Skips checks of the bind now status.
@end table

@item --skip=@var{opt|stack|fort|now|relro|pic|operator|clash|cf|cet}
@itemx -k=@var{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:

@table @samp
@item opt
Disables checks of the optimization level used.

@item stack
Disables checks of the stack protection level.

@item fort
Disables checks for @env{-D_FORTIFY_SOURCE}.

@item now
Disables checks for @samp{BIND NOW} status.

@item relro
Disables checks for @samp{relro} or read-only-relocs.

@item pic
Disables checks for @option{-fPIC}/@option{-fPIE}.

@item operator
Disables checks for @samp{-D_GLIBCXX_ASSERTIONS}.

@item clash
Disables checks for stack clash protection.

@item cf
Disables checks for control flow protection.
Note - these checks are only run on x86_64 binaries.

@item cet
Disables checks for control flow enforcement.
Note - these checks are only run on x86_64 binaries.

@item realign
Disable checks for stack realignment.
Note - these checks are only run on i686 binaries.
@end table

@item --readelf=@file{path}
@itemx -r=@file{path}
Use the specified program to read the notes from the files.

@item --
Stop accumulating command line options.  This allows the script to be
run on files whose names starts with a dash.

@end table

@c man end

@c -----------------------------------------------------------------
@node Checking Archives
@section The run-on-binaries-in script

@c man title run-on-binaries  Checking Archives

@smallexample
@c man begin SYNOPSIS run-on-binaries-in
run-on-binaries-in
  [@b{--help}]
  [@b{--version}]
  [@b{--verbose}]
  [@b{--quiet}]
  [@b{--ignore}]
  [@b{--prefix=}@samp{text}]
  [@b{--tmpdir=}@file{dir}]
  [@b{--files-from=}@file{file}]
  [@b{--skip-list=}@file{file}]
  [@b{--}]
  @file{program}
  [@b{program-options}]
  @var{file}@dots{}
@c man end
@end smallexample

@c man begin DESCRIPTION run-on-binaries-in

The @file{run-on-binaries-in} script allows other scripts, or
programs, to be run on the executable files contained inside archives.
This includes @samp{rpm} files, @samp{tar} and @samp{ar} files and
compressed files.

The script does not recurse into directories, but this can be handled
by the @code{find} command, like this:

@smallexample
  find . -type f -exec run-on-binaries-in <script-to-run> @{@} \;
@end smallexample

The script accepts the following command line options:
@table @env

@item --help
@itemx -h
Displays the usage of the script and then exits.

@item --version
@itemx -v
Displays the version of the script.

@item --verbose
@itemx -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  @option{-i} to recursive invocations of
the script.

@item --quiet
@itemx -q
Do not include the name of script in the out generated by the script.

@item --ignore
@itemx -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 @option{-V} @option{-V} has been
enabled.  This is because it is assumed that archives are likely to
contain files that do not need to be scanned.

@item --prefix=@samp{text}
@itemx -p @samp{text}
Add this text to the output from the script when it runs the program
on a normal executable.

@item --tmpdir=@file{dir}
@itemx -t @file{dir}
Directory to use to store temporary files.

@item --files-from=@file{file}
@itemx -f=@file{file}
Specifies a file containing a list of other files to examine,
one per line.

@item --skip-list=@file{file}
@itemx -s=@file{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.

@item --
Stops processing of command line options.  This allows the script to
be run with a program whose name starts with a dash.

@end table

@c man end

@c -----------------------------------------------------------------
@node GNU FDL
@appendix GNU Free Documentation License
@include fdl.texi

@bye
