]> sourceware.org Git - annobin.git/commitdiff
Improve run-on script and add documentation of scripts
authorNick Clifton <nickc@redhat.com>
Fri, 2 Feb 2018 13:41:29 +0000 (13:41 +0000)
committerNick Clifton <nickc@redhat.com>
Fri, 2 Feb 2018 13:41:29 +0000 (13:41 +0000)
doc/annobin.info
doc/annobin.texi
scripts/built-by.sh
scripts/check-abi.sh
scripts/hardened.sh
scripts/run-on-binaries-in.sh
tests/Makefile.am
tests/Makefile.in

index b3e9d24be920b7ee75658c82883316cef8cd0b52..2da14708ca34e05001a498e1630c4e14c203575c 100644 (file)
@@ -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
 
 \1f
@@ -154,10 +155,10 @@ after the plugin itself is mentioned.  The options are:
      recorded.  If not set, then 'N' defaults to 1024.
 
 \1f
-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.
-
 \1f
 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).
 
 \1f
-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
+
+\1f
+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.
+
+\1f
+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.
+
+\1f
+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.
+
+\1f
+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 <script-to-run> {} \;
+
+   The script accepts the following command line options:
+
+'--help'
+'-h'
+     Displays the usage of the script and then exits.
+
+'--version'
+'-v'
+     Displays the version of the script.
+
+'--verbose'
+'-V'
+     Enables verbose mode, causing the script to detail each action it
+     takes.
+
+     If this option is repeated it has the special effect of 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.
+
+\1f
+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.
 \1f
 Tag Table:
 Node: Top\7f706
-Node: Introduction\7f1543
-Node: Invocation\7f3645
-Node: Checking\7f6476
-Node: The Version Encoding\7f10243
-Node: The GOW Encoding\7f10588
-Node: The CF Encoding\7f12039
-Node: The CET Encoding\7f13109
-Node: GNU Free Documentation License\7f13877
+Node: Introduction\7f1616
+Node: Invocation\7f3718
+Node: Checking\7f6549
+Node: The Version Encoding\7f8836
+Node: The GOW Encoding\7f9181
+Node: The CF Encoding\7f10632
+Node: The CET Encoding\7f11702
+Node: Using\7f12470
+Node: Who Built Me\7f13008
+Node: ABI Checking\7f15786
+Node: Hardening Checks\7f17914
+Node: Checking Archives\7f21756
+Node: GNU Free Documentation License\7f24194
 \1f
 End Tag Table
index 17b5b3e113471a5bc7d8f91b648402951e12f200..c43b3d0a1beb8032016c6c3a4f178b3c28045016 100644 (file)
@@ -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 <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 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
index f295587c23ba1df7a73ae3905c639849b03f557c..b554697d13b7b9d1670f645862ffaf48fe238bae 100755 (executable)
@@ -2,7 +2,7 @@
 
 # Script to check which tools built the specified binaries.
 #
-# Created by Nick Clifton.
+# Created by Nick Clifton.  <nickc@redhat.com>
 # 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
 #
 #   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=<PATH> --readelf=<PATH>  Path to version of readelf to use to read notes.
   -t=<PATH> --tmpfile=<PATH>  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
index 3210df6ed19c22f8ed36590800bfa4429bc89719..f6b1cc5d00b6bac0073dba68153030f777284689 100755 (executable)
@@ -2,7 +2,7 @@
 
 # Script to check for ABI conflicts in annotated binaries.
 #
-# Created by Nick Clifton.
+# Created by Nick Clifton.  <nickc@redhat.com>
 # Copyright (c) 2017-2018 Red Hat.
 #
 # This is free software; you can redistribute it and/or modify it
 #
 #   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=<PATH> --readelf=<PATH>   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;
                ;;
            --*)
index c052fa33f8d225ec3feb3c4cde0ec414c2d3f3f9..26d91cc529738fc2ef60c726db9f20db0305469c 100755 (executable)
@@ -2,7 +2,7 @@
 
 # Script to check for hardening options in annotated binaries
 #
-# Created by Nick Clifton.
+# Created by Nick Clifton.  <nickc@redhat.com>
 # 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;
                ;;
            --*)
index 86802e5ae8ec849e85f3a32db487219046499ce7..b023e15d5255e0a52e491a4953c1b9b05b641b96 100755 (executable)
@@ -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.  <nickc@redhat.com>
 # 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=<NAME> --prefix=<NAME>   Prefix normal output with this string.
-  -t=<PATH> --tmpdir=<PATH>   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=<TEXT>  --prefix=<TEXT>      Prefix normal output with this string.
+  -t=<DIR>   --tmpdir=<DIR>       Temporary directory to use when opening archives.
+  -f=<FILE>  --files-from=<FILE>  Process files listed in <FILE>.
+  -s=<FILE>  --skip-list=<FILE>   Skip any file listed in <FILE>.
+  --                              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
index f0430241390a037cae40c0ab0cc47d6658b7cc5e..75086b0a0e9411a6a2104ec48cd7c64104a67327 100644 (file)
@@ -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...
index 11e79dc225a4aedacc964307fc7168f832f988ad..f82468283004932195598af0bd4ee2791ca3e5ec 100644 (file)
@@ -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:
This page took 0.079917 seconds and 5 git commands to generate.