From 20a18da64487189b55b5530031dd352dc5bb7560 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Fri, 2 Feb 2018 13:41:29 +0000 Subject: [PATCH] Improve run-on script and add documentation of scripts --- doc/annobin.info | 491 ++++++++++++++++++++++++++++++--- doc/annobin.texi | 499 +++++++++++++++++++++++++++++++--- scripts/built-by.sh | 141 ++++++++-- scripts/check-abi.sh | 53 +++- scripts/hardened.sh | 88 +++++- scripts/run-on-binaries-in.sh | 295 ++++++++++++++------ tests/Makefile.am | 2 +- tests/Makefile.in | 2 + 8 files changed, 1368 insertions(+), 203 deletions(-) diff --git a/doc/annobin.info b/doc/annobin.info index b3e9d24..2da1470 100644 --- a/doc/annobin.info +++ b/doc/annobin.info @@ -37,6 +37,7 @@ the section entitled "GNU Free Documentation License". * Introduction:: What is Binary Annotation ? * Invocation:: How to add Binary Annotations to your application. * Checking:: How to examine the information stored in the binary. +* Using:: How to use the information stored in the binary. * GNU Free Documentation License:: GNU Free Documentation License  @@ -154,10 +155,10 @@ after the plugin itself is mentioned. The options are: recorded. If not set, then 'N' defaults to 1024.  -File: annobin.info, Node: Checking, Next: GNU Free Documentation License, Prev: Invocation, Up: Top +File: annobin.info, Node: Checking, Next: Using, Prev: Invocation, Up: Top -3 How to examine the Binary Annotations stored in an application. -***************************************************************** +3 How to examine the information stored in the binary. +****************************************************** The information is stored in the ELF Note format in a special section called '.gnu.build.attributes'. The 'readelf' program from the @@ -198,35 +199,6 @@ below. * The CF Encoding:: Encoding Control Flow Protection * The CET Encoding:: Encoding Control Flow Enforcement Technology - The 'annobin' package includes some example scripts that demonstrate -how the binary information can be used. The scripts are: - -'built-by.sh' - 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. - -'check-abi.sh' - Reports any potential ABI conflicts in the files specified. This - includes the use of the '-fshort-enums' option, the - '-fstack-protector' option and the '-D_FORTIFY_SOURCE' option. All - of these can affect passing data between functions and hence should - be used uniformly throughout the binary. - -'hardened.sh' - Reports on the hardening status of the specified file(s). In - particular it checks that the whole file was compiled with '-O2' or - higher and the '-fstack-protector-strong', '-D_FORTIFY_SOURCE=2', - '-Wl,-z,now', '-Wl,-z,relro', '-fPIE', '-Wp,-D_GLIBCXX_ASSERTIONS', - '-fstack-clash-protection' '-fcf-protection=full' and '-mcet' - options. Tests of each of these options can be individually - toggled on and off using command line options to the script. -  File: annobin.info, Node: The Version Encoding, Next: The GOW Encoding, Up: Checking @@ -338,7 +310,439 @@ of bytes that indicate various different flags: 2 (set).  -File: annobin.info, Node: GNU Free Documentation License, Prev: Checking, Up: Top +File: annobin.info, Node: Using, Next: GNU Free Documentation License, Prev: Checking, Up: Top + +4 How to use the information stored in the binary. +************************************************** + +The 'annobin' package includes some example scripts that demonstrate how +the binary information can be used. The scripts are: + +* Menu: + +* Who Built Me:: The built-by.sh script +* ABI Checking:: The check-abi.sh script +* Hardening Checks:: The hardened.sh script +* Checking Archives:: The run-on-binaries-in.sh script + + +File: annobin.info, Node: Who Built Me, Next: ABI Checking, Up: Using + +4.1 The built-by.sh script +========================== + + built-by.sh + [--help] + [--version] + [--verbose] + [--quiet] + [--silent] + [--ignore] + [--readelf=path] + [--tmpdir=dir] + [--tool=NAME] + [--nottool=NAME] + [--before=DATE] + [--after=DATE] + [--minver=VERSION] + [--maxver=VERSION] + [--] + FILE... + + The 'built-by.sh' script reports the name and version of the tool +used to build the specified file(s). This script also demonstrates how +information can be extracted from other other locations in the file, not +just the binary annotation notes. + + The script can also be used to filter files, only reporting those +built by a specific tool, or a specific version of a tool, or even by a +version of a tool that was built between a range of dates. + + The options available are: + +'--help' +'-h' + Displays the usage of the script and then exits. + +'--version' +'-v' + Displays the version of the script. + +'--verbose' +'-V' + Enables verbose mode, causing the script to detail each action it + takes. + +'--quiet' +'-q' + Do not include the name of script in the out generated by the + script. + +'--silent' +'-s' + Produce no output. Just return an exit status. + +'--ignore' + Do not report file types that do not contain any builder + information. + +'--tool=NAME' + Only report binaries built by NAME. The NAME is only an ordinary + string, not a regular expression. + +'--nottool=NAME' + Skip any binary build by NAME. The NAME is only an ordinary + string, not a regular expression. + +'--before=DATE' + Only report binaries built by a tool that was created before DATE. + DATE has the format YYYYMMDD. + +'--after=DATE' + Only report binaries built by a tool that was created after DATE. + When combined with the '--before' option can be used to restrict + output to files which were built by tools created in a specific + date range. + +'--minver=VERSION' + Only report binaries built by a tool whose version is VERSION or + higher. The VERSION string should be in the form V.V.V, for + example 6.2.1. + +'--maxver=VERSION' + Only report binaries built by a tool whoes version is VERSION or + lower. Can be combined with the '--minver' option to restrict + output to those binaries created by tools within a specific version + range. + +'--tmpdir='dir'' +'-t='dir'' + Directory to use to store temporary files. + +'--readelf='path'' +'-r='path'' + Use the specified program to read the notes from the files. + +'--' + Stop accumulating command line options. This allows the script to + be run on files whose names starts with a dash. + + +File: annobin.info, Node: ABI Checking, Next: Hardening Checks, Prev: Who Built Me, Up: Using + +4.2 The check-abi.sh script +=========================== + + check-abi.sh + [--help] + [--version] + [--verbose] + [--quiet] + [--silent] + [--inconsistencies] + [--ignore-unknown] + [--ignore-ABI|ENUM|FORTIFY|STACK-PROT] + [--readelf=path] + [--tmpdir=dir] + [--] + FILE... + + The 'check-abi.sh' script reports any potential ABI conflicts in the +files specified. This includes the use of the '-fshort-enums' option, +the '-fstack-protector' option and the '-D_FORTIFY_SOURCE' option. All +of these can affect passing data between functions and hence should be +used uniformly throughout the binary. + + The script accepts the following command line options: + +'--help' +'-h' + Displays the usage of the script and then exits. + +'--version' +'-v' + Displays the version of the script. + +'--verbose' +'-V' + Enables verbose mode, causing the script to detail each action it + takes. + +'--quiet' +'-q' + Do not include the name of script in the out generated by the + script. + +'--silent' +'-s' + Produce no output. Just return an exit status. + +'--inconsitencies' +'-i' + Only report files with potential ABI problems. + +'--ignore-unknown' + Do not report file types that are not supported or recognised. + +'--ignore-ABI|ENUM|FORTIFY|STACK-PROT' + Disables individual ABI checks. Multiple occurences of this option + accumulate. Possible option values are: + + 'ABI' + Disable checks of the general ABI information. + + 'enum' + Disable checks of the '-fshort-enum' option. + + 'FORTIFY' + Disable checks of the '-D_FORTIFY_SOURCE' option. + + 'stack-prot' + Disable checks of the '-fstack-protect' option. + +'--tmpdir=dir' +'-t=dir' + Directory to use to store temporary files. + +'--readelf=path' +'-r=path' + Use the specified program to read the notes from the files. + +'--' + Stop accumulating command line options. This allows the script to + be run on files whose names starts with a dash. + + +File: annobin.info, Node: Hardening Checks, Next: Checking Archives, Prev: ABI Checking, Up: Using + +4.3 The hardened.sh script +========================== + + hardened.sh + [--help] + [--version] + [--verbose] + [--quiet] + [--ignore-unknown] + [--silent] + [--vulnerable] + [--not-hardened] + [--all] + [--file-type=AUTO|LIB|EXEC|OBJ] + [--skip=OPT|STACK|FORT|NOW|RELRO|PIC|OPERATOR|CLASH|CF|CET] + [--readelf=path] + [--tmpdir=dir] + [--] + FILE... + + The 'hardened.sh' script reports on the hardening status of the +specified file(s). In particular it checks that the whole file was +compiled with '-O2' or higher and the '-fstack-protector-strong', +'-D_FORTIFY_SOURCE=2', '-Wl,-z,now', '-Wl,-z,relro', '-fPIE', +'-Wp,-D_GLIBCXX_ASSERTIONS', '-fstack-clash-protection' +'-fcf-protection=full' and '-mcet' options. + + The script accepts the following command line options: + +'--help' +'-h' + Displays the usage of the script and then exits. + +'--version' +'-v' + Displays the version of the script. + +'--verbose' +'-V' + Enables verbose mode, causing the script to detail each action it + takes. + +'--quiet' +'-q' + Do not include the name of script in the out generated by the + script. + +'--ignore-unknown' +'-i' + Do not report file types that are not supported or recognised. + +'--tmpdir=dir' +'-t=dir' + Directory to use to store temporary files. + +'--silent' +'-s' + Produce no output. Just return an exit status. + +'--vulnerable' +'-u' + Only report files that are known to be vulnerable. Ie files that + record all of the necessary information about how they were built, + but which were built with an incorrect set of options. + + This option is the default behaviour of the script. + +'--not-hardened' +'-n' + Report any file that cannot be proven to be hardened. This is like + the '--vulnerable' option, except that it will also report files + that do not record all of the necessary information. + +'--all' +'-a' + Report the hardening status of all of the files examined. + +'--file-type=AUTO|LIB|EXEC|OBJ' +'-f=AUTO|LIB|EXEC|OBJ' + Specifies the type of file being examined. Possible values are: + + 'auto' + Automatically determine the file type from its extension. + This is the default. + 'lib' + Assume all files are shared libraries. Checks that the + '-fPIC' option was used. + 'exec' + Assume all files are executables. Checks that the '-fPIE' + option was used. + 'obj' + Assume all files are object files. Skips checks of the bind + now status. + +'--skip=OPT|STACK|FORT|NOW|RELRO|PIC|OPERATOR|CLASH|CF|CET' +'-k=OPT|STACK|FORT|NOW|RELRO|PIC|OPERATOR|CLASH|CF|CET' + Disables checks of various different hardening features. This + option can be repeated multiple times, and the values accumulate. + Possible values are: + + 'opt' + Disables checks of the optimization level used. + + 'stack' + Disables checks of the stack protection level. + + 'fort' + Disables checks for '-D_FORTIFY_SOURCE'. + + 'now' + Disables checks for 'BIND NOW' status. + + 'relro' + Disables checks for 'relro' or read-only-relocs. + + 'pic' + Disables checks for '-fPIC'/'-fPIE'. + + 'operator' + Disables checks for '-D_GLIBCXX_ASSERTIONS'. + + 'clash' + Disables checks for stack clash protection. + + 'cf' + Disables checks for control flow protections. + + 'cet' + Disables checks for control flow enforcement. + +'--readelf=path' +'-r=path' + Use the specified program to read the notes from the files. + +'--' + Stop accumulating command line options. This allows the script to + be run on files whose names starts with a dash. + + +File: annobin.info, Node: Checking Archives, Prev: Hardening Checks, Up: Using + +4.4 The run-on-binaries-in.sh script +==================================== + + run-on-binaries-in.sh + [--help] + [--version] + [--verbose] + [--quiet] + [--ignore] + [--prefix='text'] + [--tmpdir=dir] + [--files-from=file] + [--skip-list=file] + [--] + program + [program-options] + FILE... + + The 'run-on-binaries-in.sh' script allows other scripts, or programs, +to be run on the executable files contained inside archives. This +includes 'rpm' files, 'tar' and 'ar' files and compressed files. + + The script does not recurse into directories, but this can be handled +by the 'find' command, like this: + + find . -type f -exec run-on-binaries-in.sh {} \; + + The script accepts the following command line options: + +'--help' +'-h' + Displays the usage of the script and then exits. + +'--version' +'-v' + Displays the version of the script. + +'--verbose' +'-V' + Enables verbose mode, causing the script to detail each action it + takes. + + If this option is repeated it has the special effect of cancelling + out the automatic addition of the '-i' to recursive invocations of + the script. + +'--quiet' +'-q' + Do not include the name of script in the out generated by the + script. + +'--ignore' +'-i' + Do not report file types that are not supported or recognised. + + This option is automatically enabled when the script is recursively + invoked on an archive, unless the '-V' '-V' has been enabled. This + is because it is assumed that archives are likely to contain files + that do not need to be scanned. + +'--prefix='text'' +'-p='text'' + Add this text to the output from the script when it runs the + program on a normal executable. + +'--tmpdir=dir' +'-t=dir' + Directory to use to store temporary files. + +'--files-from=file' +'-f=file' + Specifies a file containing a list of other files to examine, one + per line. + +'--skip-list=file' +'-s=file' + Specifies a file containing a list of files not to examine, one per + line. Blank lines and comments are ignored. Text after a file's + name is also ignored. Filenames should start at the beginning of a + line. + +'--' + Stops processing of command line options. This allows the script + to be run with a program whoes name starts with a dash. + + +File: annobin.info, Node: GNU Free Documentation License, Prev: Using, Up: Top Appendix A GNU Free Documentation License ***************************************** @@ -823,13 +1227,18 @@ their use in free software.  Tag Table: Node: Top706 -Node: Introduction1543 -Node: Invocation3645 -Node: Checking6476 -Node: The Version Encoding10243 -Node: The GOW Encoding10588 -Node: The CF Encoding12039 -Node: The CET Encoding13109 -Node: GNU Free Documentation License13877 +Node: Introduction1616 +Node: Invocation3718 +Node: Checking6549 +Node: The Version Encoding8836 +Node: The GOW Encoding9181 +Node: The CF Encoding10632 +Node: The CET Encoding11702 +Node: Using12470 +Node: Who Built Me13008 +Node: ABI Checking15786 +Node: Hardening Checks17914 +Node: Checking Archives21756 +Node: GNU Free Documentation License24194  End Tag Table diff --git a/doc/annobin.texi b/doc/annobin.texi index 17b5b3e..c43b3d0 100644 --- a/doc/annobin.texi +++ b/doc/annobin.texi @@ -65,6 +65,7 @@ Copyright @copyright{} 2018 Red Hat @end titlepage @contents +@c ----------------------------------------------------------------- @ifnottex @node Top @top Annotating Binaries: How Was Your Program Built ? @@ -86,10 +87,12 @@ in the section entitled ``GNU Free Documentation License''. * Introduction:: What is Binary Annotation ? * Invocation:: How to add Binary Annotations to your application. * Checking:: How to examine the information stored in the binary. +* Using:: How to use the information stored in the binary. * GNU Free Documentation License:: GNU Free Documentation License @end menu @end ifnottex +@c ----------------------------------------------------------------- @node Introduction @chapter What is Binary Annotation ? @@ -131,6 +134,7 @@ of an application, such as its conformation to the hardening requirements, or possible ABI violations. +@c ----------------------------------------------------------------- @node Invocation @chapter How to add Binary Annotations to your application. @@ -202,9 +206,9 @@ recorded. If not set, then @code{N} defaults to 1024. @end table - +@c ----------------------------------------------------------------- @node Checking -@chapter How to examine the Binary Annotations stored in an application. +@chapter How to examine the information stored in the binary. The information is stored in the ELF Note format in a special section called @code{.gnu.build.attributes}. The @code{readelf} program from @@ -247,48 +251,14 @@ explained below. * The CET Encoding:: Encoding Control Flow Enforcement Technology @end menu -The @command{annobin} package includes some example scripts that -demonstrate how the binary information can be used. The scripts are: - -@table @code -@item built-by.sh -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. - -@item check-abi.sh -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. - -@item hardened.sh -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. -Tests of each of these options can be individually toggled on and off -using command line options to the script. -@end table - - +@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 these will both be 3. - +@c ----------------------------------------------------------------- @node The GOW Encoding @section Encoding Optimization and Debugging Levels @@ -337,7 +307,7 @@ enabled. 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 @@ -366,7 +336,7 @@ 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 CET Encoding @section Encoding Control Flow Enforcement Technology Records the setting of the Control Flow Enforcement Technology @@ -391,7 +361,456 @@ The setting of the @option{-mshstk} option. This is either 1 (not set) or 2 (set). @end table +@c ----------------------------------------------------------------- +@node Using +@chapter How to use the information stored in the binary. + +The @command{annobin} package includes some example scripts that +demonstrate how the binary information can be used. The scripts are: + +@menu +* Who Built Me:: The built-by.sh script +* ABI Checking:: The check-abi.sh script +* Hardening Checks:: The hardened.sh script +* Checking Archives:: The run-on-binaries-in.sh script +@end menu + +@c ----------------------------------------------------------------- +@node Who Built Me +@section The built-by.sh script + +@smallexample +built-by.sh + [@option{--help}] + [@option{--version}] + [@option{--verbose}] + [@option{--quiet}] + [@option{--silent}] + [@option{--ignore}] + [@option{--readelf=}@file{path}] + [@option{--tmpdir=}@file{dir}] + [@option{--tool=}@var{name}] + [@option{--nottool=}@var{name}] + [@option{--before=}@var{date}] + [@option{--after=}@var{date}] + [@option{--minver=}@var{version}] + [@option{--maxver=}@var{version}] + [@option{--}] + @var{file}@dots{} +@end smallexample + +The @file{built-by.sh} 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 whoes 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 ----------------------------------------------------------------- +@node ABI Checking +@section The check-abi.sh script + +@smallexample +check-abi.sh + [@option{--help}] + [@option{--version}] + [@option{--verbose}] + [@option{--quiet}] + [@option{--silent}] + [@option{--inconsistencies}] + [@option{--ignore-unknown}] + [@option{--ignore-}@var{ABI|enum|FORTIFY|stack-prot}] + [@option{--readelf=}@file{path}] + [@option{--tmpdir=}@file{dir}] + [@option{--}] + @var{file}@dots{} +@end smallexample + +The @file{check-abi.sh} 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 --inconsitencies +@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 occurences 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 ----------------------------------------------------------------- +@node Hardening Checks +@section The hardened.sh script + +@smallexample +hardened.sh + [@option{--help}] + [@option{--version}] + [@option{--verbose}] + [@option{--quiet}] + [@option{--ignore-unknown}] + [@option{--silent}] + [@option{--vulnerable}] + [@option{--not-hardened}] + [@option{--all}] + [@option{--file-type=}@var{auto|lib|exec|obj}] + [@option{--skip=}@var{opt|stack|fort|now|relro|pic|operator|clash|cf|cet}] + [@option{--readelf=}@file{path}] + [@option{--tmpdir=}@file{dir}] + [@option{--}] + @var{file}@dots{} +@end smallexample + +The @file{hardened.sh} 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 protections. + +@item cet +Disables checks for control flow enforcement. +@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 ----------------------------------------------------------------- +@node Checking Archives +@section The run-on-binaries-in.sh script + +@smallexample +run-on-binaries-in.sh + [@option{--help}] + [@option{--version}] + [@option{--verbose}] + [@option{--quiet}] + [@option{--ignore}] + [@option{--prefix=}@samp{text}] + [@option{--tmpdir=}@file{dir}] + [@option{--files-from=}@file{file}] + [@option{--skip-list=}@file{file}] + [@option{--}] + @file{program} + [@option{program-options}] + @var{file}@dots{} +@end smallexample + +The @file{run-on-binaries-in.sh} 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.sh @{@} \; +@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 cancelling 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 whoes name starts with a dash. + +@end table +@c ----------------------------------------------------------------- @node GNU Free Documentation License @appendix GNU Free Documentation License @include fdl.texi diff --git a/scripts/built-by.sh b/scripts/built-by.sh index f295587..b554697 100755 --- a/scripts/built-by.sh +++ b/scripts/built-by.sh @@ -2,7 +2,7 @@ # Script to check which tools built the specified binaries. # -# Created by Nick Clifton. +# Created by Nick Clifton. # Copyright (c) 2016-2018 Red Hat. # # This is free software; you can redistribute it and/or modify it @@ -16,7 +16,7 @@ # GNU General Public License for more details. # # Usage: -# built-by [switches] file(s) +# built-by [options] file(s) # # This script does not handle directories. This is deliberate. # It is intended that if recursion is needed then it will be @@ -24,12 +24,7 @@ # # find . -type f -exec built-by.sh {} \; -# To Do: -# -# * Allow arguments to command line options to be separated from the -# the option name by a space. Eg: --before 20161212 - -version=3.0 +version=3.1 help () { @@ -50,6 +45,7 @@ Usage: $prog {files|options} -v --version Report the version number of this script. -V --verbose Report on progress. -s --silent Produce no output, just an exit status. + -q --quiet Do not include the script name in the output. -i --ignore Silently ignore files where the builder cannot be found. -r= --readelf= Path to version of readelf to use to read notes. -t= --tmpfile= Temporary file to use. @@ -94,10 +90,17 @@ main () report () { - if [ $silent -eq 0 ] + if [ $silent -ne 0 ]; then - echo $prog":" ${1+"$@"} + return fi + + if [ $quiet -eq 0 ]; + then + echo -n $prog": " + fi + + echo ${1+"$@"} } fail () @@ -110,7 +113,7 @@ verbose () { if [ $verb -ne 0 ] then - echo $prog":" ${1+"$@"} + report ${1+"$@"} fi } @@ -124,6 +127,7 @@ init () failed=0 silent=0 + quiet=0 verb=0 ignore_unknown=0 scanner=readelf @@ -161,6 +165,9 @@ parse_args () silent=1; verb=0; ;; + -q | --quiet) + quiet=1; + ;; -V | --verbose) silent=0; verb=1; @@ -169,32 +176,121 @@ parse_args () ignore_unknown=1; ;; -r | --readelf) - scanner="$optarg" + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs a program name" + else + scanner=$1 + fi + else + scanner="$optarg" + fi ;; -t | --tmpfile) - tmpfile="$optarg" + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs a filename argument" + else + tmpfile=$1 + fi + else + tmpfile="$optarg" + fi ;; --tool) nottool="" - tool=$optarg + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + tool=$1 + fi + else + tool=$optarg + fi ;; --nottool) tool="" - nottool=$optarg + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + nottool=$1 + fi + else + nottool=$optarg + fi ;; --before) - before=$optarg + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + before=$1 + fi + else + before=$optarg + fi ;; --after) - after=$optarg + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + after=$1 + fi + else + after=$optarg + fi ;; --minver) - minver=$optarg + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + minver=$1 + fi + else + minver=$optarg + fi ;; --maxver) - maxver=$optarg + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + maxver=$1 + fi + else + maxver=$optarg + fi ;; --) + shift break; ;; --*) @@ -356,6 +452,10 @@ scan_file () verbose "scan for build notes failed, trying debug information" # Try examining the debug information in case -grecord-gcc-switches has been used. + + # FIXME: If we have a new enough version of readelf we could add the + # --debug-dump=follow-links option to cope with separate debug info files.. + $scanner --wide --debug-dump=info $file | grep -e DW_AT_producer > $tmpfile eval 'builder=($(grep -e GNU $tmpfile))' @@ -387,7 +487,8 @@ scan_file () if [ ${#builder[*]} -lt 5 ]; then if [ $ignore_unknown -eq 0 ]; then - report "$file: could not parse .comment section" + verbose "$file: could not parse .comment section" + report "$file: creator unknown" failed=1 fi tell=0 diff --git a/scripts/check-abi.sh b/scripts/check-abi.sh index 3210df6..f6b1cc5 100755 --- a/scripts/check-abi.sh +++ b/scripts/check-abi.sh @@ -2,7 +2,7 @@ # Script to check for ABI conflicts in annotated binaries. # -# Created by Nick Clifton. +# Created by Nick Clifton. # Copyright (c) 2017-2018 Red Hat. # # This is free software; you can redistribute it and/or modify it @@ -24,11 +24,7 @@ # # find . -type f -exec check-abi.sh {} \; -# To Do: -# * Allow arguments to command line options to be separated from the -# the option name by a space. Eg: --readelf foobar - -version=3.0 +version=3.1 help () { @@ -48,6 +44,7 @@ Usage: $prog {files|options} -h --help Display this information. -v --version Report the version number of this script. -s --silent Produce no output, just an exit status. + -q --quiet Do not include the script name in the output. -V --verbose Report on progress. -i --inconsistencies Only report potential ABI problems. -r= --readelf= Path to version of readelf to use to read notes. @@ -87,10 +84,17 @@ main () report () { - if [ $silent -eq 0 ] + if [ $silent -ne 0 ]; + then + return + fi + + if [ $quiet -eq 0 ]; then - echo $prog":" ${1+"$@"} + echo -n $prog": " fi + + echo ${1+"$@"} } fail () @@ -103,7 +107,7 @@ verbose () { if [ $verb -ne 0 ] then - echo $prog":" ${1+"$@"} + report ${1+"$@"} fi } @@ -118,6 +122,7 @@ init () failed=0 silent=0 verb=0 + quiet=0 inconsistencies=0 ignore_abi=0 ignore_enum=0 @@ -153,6 +158,9 @@ parse_args () silent=1; verb=0; ;; + -q | --quiet) + quiet=1; + ;; -V | --verbose) silent=0; verb=1; @@ -162,10 +170,32 @@ parse_args () inconsistencies=1; ;; -r | --readelf) - scanner="$optarg" + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "-$optname option needs a program name" + else + scanner=$1 + fi + else + scanner="$optarg" + fi ;; -t | --tmpfile) - tmpfile="$optarg" + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "-t option needs a file name" + else + tmpfile=$1 + fi + else + tmpfile="$optarg" + fi ;; --ignore-unknown) @@ -197,6 +227,7 @@ parse_args () ;; --) + shift break; ;; --*) diff --git a/scripts/hardened.sh b/scripts/hardened.sh index c052fa3..26d91cc 100755 --- a/scripts/hardened.sh +++ b/scripts/hardened.sh @@ -2,7 +2,7 @@ # Script to check for hardening options in annotated binaries # -# Created by Nick Clifton. +# Created by Nick Clifton. # Copyright (c) 2017-2018 Red Hat. # # This is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ # * Allow arguments to command line options to be separated from the # the option name by a space. Eg: --readelf foobar -version=3.0 +version=3.1 help () { @@ -70,6 +70,7 @@ Usage: $prog {files|options} -h --help Display this information and exit. -v --version Report the version number of this script and exit. + -q --quiet Do not include the script name in the output. -s --silent Produce no output, just an exit status. -V --verbose Report on progress. -u --vulnerable Only report files known to be vulnerable. [default] @@ -125,10 +126,17 @@ main () report () { - if [ $report -ne 0 ] + if [ $report -eq 0 ]; then - echo $prog":" ${1+"$@"} + return + fi + + if [ $quiet -eq 0 ]; + then + echo -n $prog": " fi + + echo ${1+"$@"} } ICE () @@ -141,7 +149,7 @@ verbose () { if [ $verb -ne 0 ] then - echo $prog":" ${1+"$@"} + report ${1+"$@"} fi } @@ -149,7 +157,7 @@ maybe () { if [ $report -gt 1 ] then - echo $prog": $file: MAYBE:" ${1+"$@"} + report "$file: MAYBE:" ${1+"$@"} fi vulnerable=1 @@ -159,7 +167,7 @@ fail () { if [ $report -gt 0 ] then - echo $prog": $file: FAIL:" ${1+"$@"} + report "$file: FAIL:" ${1+"$@"} fi vulnerable=1 @@ -169,7 +177,7 @@ pass () { if [ $report -gt 2 ] then - echo $prog": $file: PASS:" ${1+"$@"} + report "$file: PASS:" ${1+"$@"} fi } @@ -184,6 +192,7 @@ init () failed=0 report=1 # Quad-state, 0=> report nothing, 1=> report known vulnerable, 2=> report not proven hardened, 3=> report all verb=0 + quiet=0 filetype=auto skip_opt=0 @@ -226,6 +235,9 @@ parse_args () report=0; verb=0; ;; + -q | --quiet) + quiet=1; + ;; -V | --verbose) verb=1; ;; @@ -240,7 +252,19 @@ parse_args () ;; -f | --file-type) - case "$optarg" in + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + ft=$1 + fi + else + ft=$optarg + fi + case "$ft" in auto) filetype=auto ;; @@ -254,13 +278,25 @@ parse_args () filetype=object ;; *) - report "unknown file type: $optarg" + report "unknown argument to $optname: $ft" ;; esac ;; -k | --skip) - case "$optarg" in + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + sk=$1 + fi + else + sk=$optarg + fi + case "$sk" in opt) skip_opt=1 ;; @@ -292,16 +328,39 @@ parse_args () skip_cet=1; ;; *) - report "unknown option skip: $optarg" + report "unknown argument to $optname: $sk" ;; esac ;; -r | --readelf) - scanner="$optarg" + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + scanner=$1 + fi + else + scanner="$optarg" + fi ;; + -t | --tmpfile) - tmpfile="$optarg" + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs an argument" + else + tmpfile=$1 + fi + else + tmpfile="$optarg" + fi ;; -i | --ignore-unknown) @@ -309,6 +368,7 @@ parse_args () ;; --) + shift break; ;; --*) diff --git a/scripts/run-on-binaries-in.sh b/scripts/run-on-binaries-in.sh index 86802e5..b023e15 100755 --- a/scripts/run-on-binaries-in.sh +++ b/scripts/run-on-binaries-in.sh @@ -2,7 +2,7 @@ # Script to run another script/program on the executables inside a given file. # -# Created by Nick Clifton. +# Created by Nick Clifton. # Copyright (c) 2018 Red Hat. # # This is free software; you can redistribute it and/or modify it @@ -40,17 +40,19 @@ This is a shell script to run another script/program on one or more binary files. If the file(s) specified are archives of some kind (including rpms) then the script/program is run on the binary excecutables inside the archive. -Usage: $prog {options} {program} {options-for-the-program} files(s) +Usage: $prog {options} program {options-for-the-program} files(s) {options} are: - -h --help Display this information and then exits. - -v --version Report the version number of this script. - -V --verbose Report on progress. Repeat for more verbosity. - -q --quiet Do not include the script name in the output. - -i --ignore Silently ignore files that are not exectuables or archives. - -p= --prefix= Prefix normal output with this string. - -t= --tmpdir= Temporary directory to use when opening archives. - -- Stop accumulating options. + -h --help Display this information and then exit. + -v --version Report the version number of this script. + -V --verbose Report on progress. + -q --quiet Do not include the script name in the output. + -i --ignore Silently ignore files that are not exectuables or archives. + -p= --prefix= Prefix normal output with this string. + -t= --tmpdir= Temporary directory to use when opening archives. + -f= --files-from= Process files listed in . + -s= --skip-list= Skip any file listed in . + -- Stop accumulating options. Examples: @@ -58,14 +60,14 @@ Examples: Runs the hardened.sh script on the executable files inside foo.rpm. - $prog check-abi.sh -v fred.tar - Runs the check-abi.sh script on the file - fred.tar, passing the -v option to check-abi.sh - as it does so. + $prog check-abi.sh -v fred.tar.xz + Runs the check-abi.sh script on the decompressed + contents of the fred.tar.xz archive, passing the + -v option to check-abi.sh as it does so. - $prog -V readelf -a * + $prog -V -f=list.txt readelf -a Runs the readelf program, with the -a option on - every file in the current directory. Describes + every file listed in the list.txt. Describes what is being done as it works. $prog -v -- -fred -a jim -b bert -- -c harry @@ -86,19 +88,7 @@ main () if [ $failed -eq 0 ]; then - # Use quotes when accessing files in order to preserve - # any spaces that might be in the directory name. - script="${files[0]}"; - - if ! [ -a "$script" ] - then - fail "$script: script not found" - elif ! [ -x "$script" ] - then - fail "$script: script not executable" - else - run_script_on_files - fi + run_script_on_files fi if [ $failed -ne 0 ]; @@ -162,9 +152,10 @@ init () prog_opts="-i" - prefix="" - tmpdir=/dev/shm + prefix="" + files_from="" + skip_list="" failed=0 verbose=0 @@ -204,9 +195,9 @@ parse_args () # script will complain about unrecognised file types. if [ $quiet -eq 0 ]; then - prog_opts="-V" + prog_opts="-V -V" else - prog_opts="-V -q" + prog_opts="-V -V -q" fi else verbose=1; @@ -217,21 +208,63 @@ parse_args () ignore=1 ;; -t | --tmpdir) - if test "x$optarg" = "x" ; + if test "x$optarg" = "x$optname" ; then - fail "-t option must have a directory name attached to it with an equals sign" + shift + if [ $# -eq 0 ] + then + fail "$optname needs a directory name" + else + tmpdir=$1 + fi else tmpdir="$optarg" fi ;; -p | --prefix) - if test "x$optarg" = "x" ; + if test "x$optarg" = "x$optname" ; then - fail "-p option must have a directory name attached to it with an equals sign" + shift + if [ $# -eq 0 ] + then + fail "$optname needs a string argument" + else + prefix=$1 + fi else prefix="$optarg" fi ;; + -f | --files_from) + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs a file name" + else + files_from=$1 + fi + else + files_from="$optarg" + fi + ;; + + -s | --skip-list) + if test "x$optarg" = "x$optname" ; + then + shift + if [ $# -eq 0 ] + then + fail "$optname needs a file name" + else + skip_list=$1 + fi + else + skip_list="$optarg" + fi + ;; + --) shift break; @@ -241,8 +274,14 @@ parse_args () help ;; *) - files[$num_files]="$1"; - let "num_files++" + script="$1"; + if ! [ -a "$script" ] + then + fail "$script: program/script not found" + elif ! [ -x "$script" ] + then + fail "$script: program/script not executable" + fi # After we have seen the first non-option we stop # accumulating options for this script and instead # start accumulating options for the script to be @@ -254,6 +293,34 @@ parse_args () shift done + # Read in the contents of the --file-from list, if specified. + if test "x$files_from" != "x" ; + then + if ! [ -a "$files_from" ] + then + fail "$files_from: file not found" + elif ! [ -r "$files_from" ] + then + fail "$files_from: file not readable" + else + eval 'files=($(cat $files_from))' + num_files=${#files[*]} + fi + fi + skip_files[foo]=bar + + # Check that the skip list exists, if specified. + if test "x$skip_list" != "x" ; + then + if ! [ -a "$skip_list" ] + then + fail "$skip_list: file not found" + elif ! [ -r "$skip_list" ] + then + fail "$files_from: file not readable" + fi + fi + # Accumulate any remaining arguments separating out the arguments # for the script from the names of the files to scan. while [ $# -gt 0 ] @@ -284,12 +351,12 @@ parse_args () shift done - if [ $num_files -gt 1 ]; + if [ $num_files -gt 0 ]; then # Remember that we are counting from zero not one. let "num_files--" else - fail "Must specify a script and at least one file to scan." + fail "Must specify a program/script and at least one file to scan." fi } @@ -297,7 +364,7 @@ run_script_on_files () { local i - i=1; + i=0; while [ $i -le $num_files ] do run_on_file i @@ -322,6 +389,37 @@ run () ${1+$@} } +decompress () +{ + local abs_file decompressor decomp_args orig_file base_file + + # Paranoia checks - the user should never encounter these. + if test "x$4" = "x" ; + then + ice "decompress called with too few arguments" + fi + if test "x$5" != "x" ; + then + ice "decompress called with too many arguments" + fi + + abs_file=$1 + decompressor=$2 + decomp_args=$3 + orig_file=$4 + + base_file=`basename $abs_file` + + run cp $abs_file $base_file + run $decompressor $decomp_args $base_file + if [ $? != 0 ]; + then + fail "$orig_file: Unable to decompress" + fi + + rm $base_file +} + run_on_file () { local file @@ -346,22 +444,38 @@ run_on_file () file="./$file" fi + # See if we should skip this file. + if test "x$skip_list" != "x" ; + then + # This regexp looks for $file being the first text on a line, either + # on its own, or with additional text separated from it by at least + # one space character. So searching for "fred" in the following gives: + # fr <- no match + # fred <- match + # fredjim <- no match + # fred bert <- match + regexp="^$file[^[:graph:]]*" + grep --silent --regexp="$regexp" $skip_list + if [ $? = 0 ]; + then + verbose "$file: skipping" + return + fi + fi + + # Check the file. if ! [ -a "$file" ] then fail "$file: file not found" return - fi - - if ! [ -r "$file" ] + elif ! [ -r "$file" ] then if [ $ignore -eq 0 ]; then fail "$file: not readable" fi return - fi - - if [ -d "$file" ] + elif [ -d "$file" ] then if [ $ignore -eq 0 ]; then @@ -373,9 +487,7 @@ run_on_file () fi fi return - fi - - if ! [ -f "$file" ] + elif ! [ -f "$file" ] then if [ $ignore -eq 0 ]; then @@ -387,7 +499,7 @@ run_on_file () file_type=`file -b $file` case "$file_type" in *"ELF "*) - verbose "$file: RPM format." + verbose "$file: ELF format - running script/program" if test "x$prefix" != "x" ; then report_n "$prefix: " @@ -404,12 +516,24 @@ run_on_file () *"tar "*) verbose "$file: TAR archive." ;; - *"XZ compressed data"*) - verbose "$file: contains xz compressed data" + *"Zip archive"*) + verbose "$file: ZIP archive." + ;; + *"ar archive"*) + verbose "$file: AR archive." + ;; + *"bzip2 compressed data"*) + verbose "$file: contains bzip2 compressed data" ;; *"gzip compressed data"*) verbose "$file: contains gzip compressed data" ;; + *"lzip compressed data"*) + verbose "$file: contains lzip compressed data" + ;; + *"XZ compressed data"*) + verbose "$file: contains xz compressed data" + ;; *"shell script"* | *"ASCII text"*) if [ $ignore -eq 0 ]; then @@ -417,6 +541,14 @@ run_on_file () fi return ;; + *"symbolic link"*) + if [ $ignore -eq 0 ]; + then + # FIXME: We ought to be able to follow symbolic links + fail "$file: symbolic links are not followed." + fi + return + ;; *) if [ $ignore -eq 0 ]; then @@ -458,13 +590,15 @@ run_on_file () return fi - # Run the file type switch again, although this time we do not need to check - # for unrecognised types. Note since are transforming the file we reinvoke - # the run-on-binaries script on the decoded contents. This allows for archives - # that contain other archives, and so on. We pass the -i option to the invoked - # script so that it will not complain about unrecognised files in the decoded - # archive. We also pass the -t option to ensure that any sub-archives are - # extracted into a unique directory tree. + # Run the file type switch again, although this time we do not need to + # check for unrecognised types. (But we do, just in case...) + # Note since are transforming the file we reinvoke the run-on-binaries + # script on the decoded contents. This allows for archives that contain + # other archives, and so on. We normally pass the -i option to the + # invoked script so that it will not complain about unrecognised files in + # the decoded archive, although we do not do this when running in very + # verbose mode. We also pass an extended -t option to ensure that any + # sub-archives are extracted into a unique directory tree. case "$file_type" in "RPM "*) @@ -479,7 +613,7 @@ run_on_file () run cpio --quiet --extract --make-directories --file delme.cpio if [ $? != 0 ]; then - fail "$file: Unable to extract from cpio archive" + fail "$file: Unable to extract files from cpio archive" fi run rm -f delme.cpio fi @@ -489,7 +623,7 @@ run_on_file () run cpio --quiet --extract --make-directories --file=$abs_file if [ $? != 0 ]; then - fail "$file: Unable to extract from cpio archive" + fail "$file: Unable to extract files from cpio archive" fi ;; @@ -497,26 +631,35 @@ run_on_file () run tar --extract --file=$abs_file if [ $? != 0 ]; then - fail "$file: Unable to extract from tar file" + fail "$file: Unable to extract files from tarball" fi ;; - *"XZ compressed data"*) - run cp $abs_file `basename $file` - run xz --quiet --decompress `basename $file` + *"ar archive"*) + run ar x $abs_file if [ $? != 0 ]; then - fail "$file: Unable to decompress" + fail "$file: Unable to extract files from ar archive" fi ;; + *"Zip archive"*) + decompress $abs_file unzip "-q" $file + ;; + *"bzip compressed data"*) + decompress $abs_file bzip2 "--quiet --decompress" $file + ;; *"gzip compressed data"*) - run cp $abs_file `basename $file` - run gzip --quiet --decompress `basename $file` - if [ $? != 0 ]; - then - fail "$file: Unable to decompress" - fi + decompress $abs_file gzip "--quiet --decompress" $file + ;; + *"lzip compressed data"*) + decompress $abs_file lzip "--quiet --decompress" $file + ;; + *"XZ compressed data"*) + decompress $abs_file xz "--quiet --decompress" $file + ;; + *) + ice "unahndled file type: $file_type" ;; esac @@ -526,8 +669,8 @@ run_on_file () run find . -type f -execdir $abs_prog $prog_opts -t=$tmp_root/$file -p=$file $abs_script $script_opts {} + fi - verbose " Deleting temporary directory: $tmp_root/$file" - rm -fr $tmp_root/$file + verbose " Deleting temporary directory: $tmp_root" + rm -fr $tmp_root verbose " Return to previous directory" popd > /dev/null diff --git a/tests/Makefile.am b/tests/Makefile.am index f043024..75086b0 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -10,4 +10,4 @@ TESTS=compile-test hardening-test hardening-fail-test abi-test missing-notes-tes XFAIL_TESTS=hardening-fail-test # FIXME: Add a test for merging notes... - +# FIXME: Add a test for examining archives... diff --git a/tests/Makefile.in b/tests/Makefile.in index 11e79dc..f824682 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -466,6 +466,8 @@ uninstall-am: mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am +# FIXME: Add a test for merging notes... + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: -- 2.43.5