The annocheck program can analyse programs 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:
The annocheck program is able to scan inside rpm files and libraries. It will automatically recurse into any directories that are specified on the command line. In addition annocheck knows how to find debug information held in separate debug files, and it will search for these whenever it needs the resources that they contain.
New tools can be added to the annocheck framework by creating a new source file and including it in the Makefile used to build annocheck. The modular nature of annocheck means that nothing else needs to be updated.
New tools must fill out a
struct checker structure (defined in annocheck.h) and they must define a constructor function that calls
annocheck_add_checker to register their presence at program start-up.
The annocheck program supports some generic command line options that are used regardless of which tools are enabled.
Look in file for separate dwarf debug information.
Look in dir for separate dwarf debug information files.
Display this message & exit.
Report file types not recognised by annocheck. The default behaviour can be restored by the --ignore-unknown option.
Include text in the output description.
Do not print anything, just return an exit status.
Produce informational messages whilst working. Repeat for more information.
Report the version of the tool and then exit.
The built-by tool is disabled by default, but it can be enabled by the command line option --enable-builtby. The tool checks the specified files to see if any information is stored about how the file was built.
Since the hardening checker is enabled by default it may also be useful to add the --disable-hardened option to the command line.
The tool supports a few command line options to customise its behaviour:
Report all builder identification strings. The tool has several different heuristics for determining the builder. By default it will report the information return by the first successful heuristic. If the --all option is enabled then all successful results will be returned.
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 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.
The hardened tool checks that the specified files were compiled with the required security hardening options, as outlined in the elf-policy document. It runs a series of tests checking compilation options and link time options. These tests are outlined below, along with the command line option that can be used to disable each test.
New tests can be added to the hardened checker by adding an entry in the tests array defined in hardened.c and then creating the necessary code to support the test.
Lazy binding must not have been enabled via the linker option -z lazy. Instead the -z now option must have been used. Disabled by --skip-bind-now.
- Non executable stack
The program must not have a stack in an executable region of memory. Disabled by --skip-gnu-stack.
- Safe GOT relocations
The relocations for the GOT table must be read only. Disabled by --skip-writeable-got.
- No RWX segments.
No program segment should have all three of the read, write and execute permission bits set. Disabled by --skip-rwx-seg.
- No text relocations
There should be no relocations against executable code. Disabled by --skip-textrel.
- Correct runpaths
The runpath information used to locate shared libraries at runtime must only include directories rooted at /usr. Disabled by --skip-run-path.
- Missing annobin data
The program must have been compiled with annobin notes enabled. Disabled by --ignore-gaps.
- Strong stack protection
The program must have been compiled with the -fstack-protector-strong option enabled, and with -D_FORTIFY_SOURCE=2 specified. It must also have been compiled at at least optimization level 2. Disabled by --skip-stack-prot.
- Dynamic data present
Dynamic executables must have a dynamic segment. Disabled by --skip-dynamic-segment.
- Position Independent compilation
Shared libraries must have been compiled with -fPIC or
-fPIEbut not -static. This check can be disabled by --skip-pic.
Dynamic executables must have been compiled with -fPIE and linked with -pie. This check can be disabled by --skip-pie.
- Safe exceptions
Program which use exception handling must have been compiled with -fexceptions enabled and with -D_GLIBCXX_ASSERTIONS specified. Disabled by --skip-threads and/or --skip-glibcxx-assertions.
- Stack Clash protection
If available the -fstack-clash-protection must have been used. Disabled by --skip-stack-clash.
- Control Flow protection
If available the -fcf-protection=full option must have been used. Disabled by --skip-cf-protection. If this option is disabled then the check for GNU Property notes will also be disabled.
- Branch protection
For AArch64 binaries. the -mbranch-protection option, if available, must have been used. Disabled by --skip-branch-protection.
- Stack realignment
For i686 binaries, the -mstackrealign option must have been specified. Disabled by --skip-stack-realign.
- Source fortification
The program must have been compiled with the -D_FORTIFY_SOURCE=2 command line option specified. Disabled by --skip-fortify.
The program must have been compiled with at least -O2 optimization enabled. Disabled by --skip-optimization.
- Read only relocations
The program must not have any relocations that are held in a writeable section. Disabled by --skip-gnu-relro.
- GNU Property Note
For x86_64 binaries, check that a correctly formatted GNU Property note is present. These notes are only generated with a program is compiled with the -fcf-protection gcc option is enabled, so if annocheck's --skip-cf-protection option is enabled then this test will be skipped as well.
- Enum Size
Check that the program makes consistent use of the -fshort-enum option.
The tool does support a couple of other command line options as well:
Enable the tool if it was previously disabled. The option is the default.
Disable the tool.
The notes tool displays the contents of any annobin notes inside the specified files. It groups the notes by address range, which can help locate missing details.
The notes tool is disabled by default, but it can be enabled by the command line option --enable-notes. Since the hardening checker is enabled by default it may also be useful to add the --disable-hardened option to the command line.
The section-size tool records the size of named sections within a list of files and then reports the accumulated size at the end. Since it is part of the annocheck framework, it is able to handle directories and rpms files as well as ordinary binary files.
The --size-sec=name option enables the tool and tells it to record the size of section name. The option can be repeated multiple times to record the sizes of multiple sections. It may also be useful to add the --disable-hardened option to the command line as otherwise the security hardening will be run at the same time.
Instead of searching for named sections, it is also possible to search for sections with specific flags. The --size-sec-flags=<flags> option will search for any section that has all of the specified <flags> set. Currently only W, A and X are recognised as flags, indicating that the section must have the Write, Alloc or Execute flags set respectively. If the ! exclamation mark character is present then it negates the meaning of the following flags. Thus --section-sec-flags=W option will search for any writeable section whereas the --size-sec-flags=W!A option will search only for sections that are writeable but not allocated.
Instead of searching for sections by flags it is also possible to search for segments by flags using the --size-seg-flags=<flags> option. The flags recognised for segments are W for writeable, R for readable and X for executable. Again the ! character can be used to invert the meaning of the flags that follow it.
If the --verbose option is enabled, then the tool will also report the size of the named section(s) in each file it encounters. If the --size-human option is enabled then sizes will be rounded down to the nearest byte, kibibyte, mebibyte or gibibyte, as appropriate.
The timing tool reports on the time taken by other tools to scan the list of files. The tool is disabled by default, but it can be enabled by the command line option --enable-timing.
By default the tool will report times in microseconds, but you can change this to reporting in seconds with the --sec or in nanoseconds with the --nsec. The default can be restored with the --usec option.
Copyright (c) 2018 - 2020 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”.