section using this proposal.
-* The information is stored in a new section called .gnu.static.attributes.
+* The information is stored in a new section called .gnu.build.attributes.
(The name can be changed - it is basically irrelevant anyway, it is
the new section flag (defined below) that matters).
* The type field of a note is used to distinguish the range of memory
over which an attribute applies. The name field identifies the
attribute and gives it a value. The description field specifies the
- starting address for where the attribute is applied.
+ starting and ending addresses for where the attribute is applied.
Two new note types are defined: NT_GNU_BUILD_ATTRIBUTE_OPEN (0x100)
and NT_GNU_BUILD_ATTRIBUTE_FUNC (0x101). These are used by the
Character Allowed Meaning
--------------- Types -------
- - <none> Reserved for future use.
+ 0 <none> Reserved for future use.
1 $ Version of the specification supported and producer(s) of the notes (see below).
2 * Stack protector
3 !+ Relro
6 $* ABI
7 * Position Independence Status: 0 => static, 1 => pic, 2 => PIC, 3 => pie
8 !+ Short enums
- 9..30 <none> Reserved for future use.
- 31..126 $* An annotation type not explicitly defined by this specification.
+ 9..31 <none> Reserved for future use.
+ 32..126 $* An annotation type not explicitly defined by this specification.
127+ <none> Reserved for future use.
For * and $ type attributes the value is then appended.
This note serves as the base address for other open notes that
follow, allowing them to use an empty description field.
- The last note should be an end-note (ascii value 0) which specifies
- the end address of the range covered by the previous open notes. If
- no end note is present then the address range is presumed to be open
- at the higher end.
-
- End-notes can also be used to indicate the end of a function
- specific note's address range. These notes must have the
- NT_GNU_BUILD_ATTRIBUTE_FUNC type.
-
* When the linker merges two or more files containing these notes it
should ensure that the above rules are maintained. Simply
concatenating the incoming note sections should ensure this.
# Script to check which tools built the specified binaries.
#
# Created by Nick Clifton.
-# Copyright (c) 2016-2017 Red Hat.
+# Copyright (c) 2016-2018 Red Hat.
#
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published
# * Allow arguments to command line options to be separated from the
# the option name by a space. Eg: --before 20161212
-version=2.0
+version=3.0
help ()
{
{options} are:
-h --help Display this information.
-v --version Report the version number of this script.
+ -V --verbose Report on progress.
-s --silent Produce no output, just an exit status.
-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.
scan_files
- if [ $failed -ne 0 ] ; then
+ if [ $failed -ne 0 ];
+ then
exit 1
else
exit 0
report ()
{
- if [ $silent -ne 0 ]
+ if [ $silent -eq 0 ]
then
- return
+ echo $prog":" ${1+"$@"}
fi
- echo $prog":" ${1+"$@"}
}
fail ()
exit 1
}
+verbose ()
+{
+ if [ $verb -ne 0 ]
+ then
+ echo $prog":" ${1+"$@"}
+ fi
+}
+
# Initialise global variables.
init ()
{
failed=0
silent=0
+ verb=0
ignore_unknown=0
scanner=readelf
tmpfile=/dev/shm/built.by.delme
;;
-s | --silent)
silent=1;
+ verb=0;
+ ;;
+ -V | --verbose)
+ silent=0;
+ verb=1;
;;
-i | --ignore)
ignore_unknown=1;
shift
done
- if [ $num_files -gt 0 ] ;
+ if [ $num_files -gt 0 ];
then
# Remember that we are counting from zero not one.
let "num_files--"
fi
file $file | grep --silent -e ELF
- if [ $? != 0 ] ; then
- if [ $ignore_unknown -eq 0 ]; then
+ if [ $? != 0 ];
+ then
+ if [ $ignore_unknown -eq 0 ];
+ then
report "$file: not an ELF format file"
failed=1
fi
fi
$scanner --wide --notes $file > $tmpfile 2>&1
- if [ $? != 0 ] ; then
+ if [ $? != 0 ];
+ then
if [ $ignore_unknown -eq 0 ]; then
report "$file: scanner '$scanner' failed - see $tmpfile"
failed=1
grep --silent -e "\$<tool>" $tmpfile
- if [ $? == 0 ] ; then
+ if [ $? == 0 ];
+ then
# Convert:
# $<tool>gcc 7.0.0 20161212 0x00000000 NT_GNU...
# or
ver_index=1
date_index=2
- eval 'builder=($(grep -e tool $tmpfile | cut -d " " -f 3-5))'
-
- if [ ${#builder[*]} -gt 3 ] ; then
- report "$file: contains multiple different creator notes"
+ eval 'builder=($(grep -e tool $tmpfile | cut -d " " -f 3-5 | sort -u))'
+
+ verbose "build notes contain: ${builder[*]}"
+
+ if [ ${#builder[*]} -gt 3 ];
+ then
+ report "$file: contains multiple, different creator notes"
fi
- if [ ${#builder[*]} -lt 3 ] ; then
- if [ $ignore_unknown -eq 0 ]; then
+
+ if [ ${#builder[*]} -lt 3 ];
+ then
+ if [ $ignore_unknown -eq 0 ];
+ then
report "$file: contains truncated creator notes"
failed=1
fi
fi
builder[0]=`echo ${builder[0]} | cut -d \> -f 2`
else
+ verbose "scan for build notes failed, trying debug information"
+
# Try examining the debug information in case -grecord-gcc-switches has been used.
$scanner --wide --debug-dump=info $file | grep -e DW_AT_producer > $tmpfile
eval 'builder=($(grep -e GNU $tmpfile))'
- if [ ${#builder[*]} -ge 11 ] ; then
+ if [ ${#builder[*]} -ge 11 ];
+ then
# FIXME: We should grep for the right strings, rather than using
# builtin knowledge of the format of the DW_AT_producer contents
+
+ verbose "DW_AT_producer contains: ${builder[*]}"
+
tool_index=7
ver_index=9
date_index=10
builder[7]="${builder[7]} ${builder[8]}"
else
+ verbose "scan for debug information failed, trying .comment section"
+
# Alright - last chance. Check the .comment section
$scanner -p.comment $file > $tmpfile 2>&1
grep --silent -e "does not exist" $tmpfile
- if [ $? != 0 ] ; then
+ if [ $? != 0 ];
+ then
eval 'builder=($(grep -e GNU $tmpfile))'
+ verbose ".comment contains: ${builder[*]}"
+
# FIXME: We are using assumed knowledge of the layout of the builder comment.
- if [ ${#builder[*]} -lt 5 ] ; then
+ if [ ${#builder[*]} -lt 5 ];
+ then
if [ $ignore_unknown -eq 0 ]; then
report "$file: could not parse .comment section"
failed=1
fi
fi
- if [ $tell -eq 1 ] ; then
- if [ x$tool != x ] ; then
- if [ ${builder[$tool_index]} != $tool ] ; then
+ if [ $tell -eq 1 ];
+ then
+ if [ x$tool != x ];
+ then
+ if [ "${builder[$tool_index]}" == $tool ];
+ then
tell=0
fi
fi
- if [ x$nottool != x ] ; then
- if [ ${builder[$tool_index]} == $nottool ] ; then
+ if [ x$nottool != x ];
+ then
+ if [ "${builder[$tool_index]}" == $nottool ];
+ then
tell=0
fi
fi
- if [ x$minver != x ] ; then
- if [[ ${builder[$ver_index]} < $minver ]] ; then
+ if [ x$minver != x ];
+ then
+ if [[ ${builder[$ver_index]} < $minver ]];
+ then
tell=0
fi
fi
- if [ x$maxver != x ] ; then
- if [[ ${builder[$ver_index]} > $maxver ]] ; then
+ if [ x$maxver != x ];
+ then
+ if [[ ${builder[$ver_index]} > $maxver ]];
+ then
tell=0
fi
fi
- if [ x$before != x ] ; then
- if [ ${builder[$date_index]} -ge $before ] ; then
+ if [ x$before != x ];
+ then
+ if [ ${builder[$date_index]} -ge $before ];
+ then
tell=0
fi
fi
- if [ x$after != x ] ; then
- if [ ${builder[$date_index]} -le $after ] ; then
+ if [ x$after != x ];
+ then
+ if [ ${builder[$date_index]} -le $after ];
+ then
tell=0
fi
fi
fi
- if [ $tell -eq 1 ]; then
+ if [ $tell -eq 1 ];
+ then
report "$file: created by: ${builder[$tool_index]} v${builder[$ver_index]} ${builder[$date_index]}"
fi
#!/bin/bash
-# Script to check for ABI conflicts in annotated binaries
+# Script to check for ABI conflicts in annotated binaries.
#
# Created by Nick Clifton.
-# Copyright (c) 2017 Red Hat.
+# Copyright (c) 2017-2018 Red Hat.
#
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published
# * Allow arguments to command line options to be separated from the
# the option name by a space. Eg: --readelf foobar
-version=2.0
+version=3.0
help ()
{
-h --help Display this information.
-v --version Report the version number of this script.
-s --silent Produce no output, just an exit status.
+ -V --verbose Report on progress.
-i --inconsistencies Only report potential ABI problems.
- -V --verbose Report files without conflicts
-r=<PATH> --readelf=<PATH> Path to version of readelf to use to read notes.
-t=<PATH> --tmpfile=<PATH> Temporary file to use.
scan_files
- if [ $failed -ne 0 ] ; then
+ if [ $failed -ne 0 ];
+ then
exit 1
else
exit 0
report ()
{
- if [ $silent -ne 0 ]
+ if [ $silent -eq 0 ]
then
- return
+ echo $prog":" ${1+"$@"}
fi
- echo $prog":" ${1+"$@"}
}
fail ()
exit 1
}
+verbose ()
+{
+ if [ $verb -ne 0 ]
+ then
+ echo $prog":" ${1+"$@"}
+ fi
+}
+
# Initialise global variables.
init ()
{
failed=0
silent=0
- verbose=0
+ verb=0
inconsistencies=0
ignore_abi=0
ignore_enum=0
report "version: $version"
exit 0
;;
-
-h | --help)
help
exit 0
;;
-s | --silent)
silent=1;
- verbose=0;
+ verb=0;
;;
-V | --verbose)
silent=0;
- verbose=1;
+ verb=1;
;;
-i | --inconsistencies)
silent=0;
shift
done
- if [ $num_files -gt 0 ] ;
+ if [ $num_files -gt 0 ];
then
# Remember that we are counting from zero not one.
let "num_files--"
fi
file $file | grep --silent -e ELF
- if [ $? != 0 ] ;
+ if [ $? != 0 ];
then
if [ $ignore_unknown -eq 0 ];
then
fi
$scanner --wide --notes $file > $tmpfile 2>&1
- if [ $? != 0 ] ;
+ if [ $? != 0 ];
then
report "$file: scanner '$scanner' failed - see $tmpfile"
failed=1
return
fi
+ grep -q -e "Unknown note" $tmpfile
+ if [ $? == 0 ];
+ then
+ report "$file: scanner '$scanner' failed - see $tmpfile"
+ failed=1
+ # Leave the tmpfile intact so that it can be examined by the user.
+ return
+ fi
+
+ grep -q -e "Gap in build notes" $tmpfile
+ if [ $? == 0 ];
+ then
+ report "$file: there are gaps in the build notes"
+ failed=1
+ fi
+
local -a abis
if [ $ignore_abi -ne 1 ];
# into:
# abis[n]=145e82c442000192
- eval 'abis=($(grep -e \<ABI\> $tmpfile | cut -d " " -f 3 | cut -d x -f 2))'
+ eval 'abis=($(grep -e \<ABI\> $tmpfile | cut -d " " -f 3 | cut -d x -f 2 | sort -u))'
+
+ verbose "ABI Info: ${abis[*]}"
if [ ${#abis[*]} -lt 1 ];
then
if [[ $ignore_abi -eq 0 && $inconsistencies -eq 0 ]];
then
report "$file: does not have an ABI note"
- # grep -e ABI $tmpfile
fi
else
- if [ ${#abis[*]} -eq 1 ];
+ if [ ${#abis[*]} -gt 1 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: ABI: ${abis[0]}"
- fi
- else
local i mismatch=0
if [ $inconsistencies -eq 0 ];
then
report "$file: contains ${#abis[*]} ABI notes"
fi
+
i=1;
while [ $i -lt ${#abis[*]} ]
do
then
# FIXME: Add code to differentiate between functions which have changed ABI and files ?
report "$file: differing ABI values detected: ${abis[i]} vs ${abis[i-1]}"
- failed=1;
- mismatch=1;
+ failed=1
+ mismatch=1
fi
let "i++"
done
if [ $mismatch -eq 0 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: ABI: ${abis[0]}"
- fi
+ verbose "$file: ABI: ${abis[0]}"
fi
fi
fi
# into:
# abis[n]=false
- eval 'abis=($(grep -e "short enum" $tmpfile | cut -f 2 -d ">" | cut -f 1 -d " "))'
+ eval 'abis=($(grep -e "short enum" $tmpfile | cut -f 2 -d ">" | cut -f 1 -d " " | sort -u))'
+
+ verbose "Enum Info: ${abis[*]}"
if [ ${#abis[*]} -lt 1 ];
then
report "$file: does not record enum size"
fi
else
- if [ ${#abis[*]} -eq 1 ];
+ if [ ${#abis[*]} -gt 1 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: -fshort-enums: ${abis[0]}"
- fi
- else
local i mismatch=0
if [ $inconsistencies -eq 0 ];
if test "${abis[i]}" != "${abis[i-1]}" ;
then
report "$file: differing -fshort-enums detected: ${abis[i]} vs ${abis[i-1]}"
- failed=1;
- mismatch=1;
+ failed=1
+ mismatch=1
fi
let "i++"
done
- if [ $mismatch -eq 0 ] ;
+ if [ $mismatch -eq 0 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: -fshort-enums: ${abis[0]}"
- fi
+ verbose "$file: -fshort-enums: ${abis[0]}"
fi
fi
fi
# into:
# abis[n]=1
- eval 'abis=($(grep -e FORTIFY $tmpfile | cut -f 2 -d ":" | cut -b 3-5 | sed -e "s/ff/unknown/"))'
+ eval 'abis=($(grep -e FORTIFY $tmpfile | cut -f 2 -d ":" | cut -b 3-5 | sed -e "s/ff/unknown/" | sort -u))'
+
+ verbose "Fortify Info: ${abis[*]}"
if [ ${#abis[*]} -lt 1 ];
then
report "$file: does not record _FORTIFY_SOURCE level"
fi
else
- if [ ${#abis[*]} -eq 1 ];
+ if [ ${#abis[*]} -gt 1 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: -D_FORTIFY_SOURCE=${abis[0]}"
- fi
- else
local i mismatch=0
if [ $inconsistencies -eq 0 ];
if [ $mismatch -eq 0 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: -D_FORTIFY_SOURCE=${abis[0]}"
- fi
+ verbose "$file: -D_FORTIFY_SOURCE=${abis[0]}"
fi
fi
fi
# into:
# abis[n]=<type>
- eval 'abis=($(grep -e "stack prot" $tmpfile | cut -f 4 -d " " | cut -b 6-))'
+ eval 'abis=($(grep -e "stack prot" $tmpfile | cut -f 4 -d " " | cut -b 6- | sort -u))'
+
+ verbose "Stack Protection Info: ${abis[*]}"
if [ ${#abis[*]} -lt 1 ];
then
else
if [ ${#abis[*]} -eq 1 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: -fstack-protect=${abis[0]}"
- fi
+ verbose "$file: -fstack-protect=${abis[0]}"
else
local i mismatch=0
if [ $mismatch -eq 0 ];
then
- if [ $verbose -eq 1 ];
- then
- report "$file: -fstack-protect=${abis[0]}"
- fi
+ verbose "$file: -fstack-protect=${abis[0]}"
fi
fi
fi
# Script to check for hardening options in annotated binaries
#
# Created by Nick Clifton.
-# Copyright (c) 2017 Red Hat.
+# Copyright (c) 2017-2018 Red Hat.
#
# This is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published
# * Allow arguments to command line options to be separated from the
# the option name by a space. Eg: --readelf foobar
-version=2.0
+version=3.0
help ()
{
-v --version Report the version number of this script and exit.
-s --silent Produce no output, just an exit status.
+ -V --verbose Report on progress.
-u --vulnerable Only report files known to be vulnerable. [default]
-n --not-hardened Report any file that is not proven to be hardened.
-a --all Report the hardening status of all files.
scan_files
- if [ $failed -ne 0 ] ; then
+ if [ $failed -ne 0 ];
+ then
exit 1
else
exit 0
report ()
{
- if [ $report -eq 0 ]
+ if [ $report -ne 0 ]
then
- return
+ echo $prog":" ${1+"$@"}
fi
- echo $prog":" ${1+"$@"}
}
-fail ()
+ICE ()
{
report "Internal error: " ${1+"$@"}
exit 1
}
+verbose ()
+{
+ if [ $verb -ne 0 ]
+ then
+ echo $prog":" ${1+"$@"}
+ fi
+}
+
+maybe ()
+{
+ if [ $report -gt 1 ]
+ then
+ echo $prog": $file: MAYBE:" ${1+"$@"}
+ fi
+
+ vulnerable=1
+}
+
+fail ()
+{
+ if [ $report -gt 0 ]
+ then
+ echo $prog": $file: FAIL:" ${1+"$@"}
+ fi
+
+ vulnerable=1
+}
+
+pass ()
+{
+ if [ $report -gt 2 ]
+ then
+ echo $prog": $file: PASS:" ${1+"$@"}
+ fi
+}
+
# Initialise global variables.
init ()
{
failed=0
report=1 # Quad-state, 0=> report nothing, 1=> report known vulnerable, 2=> report not proven hardened, 3=> report all
+ verb=0
filetype=auto
skip_opt=0
skip_stack=0
help
exit 0
;;
-
-s | --silent)
report=0;
+ verb=0;
+ ;;
+ -V | --verbose)
+ verb=1;
;;
-u | --vulnerable)
report=1;
shift
done
- if [ $num_files -gt 0 ] ;
+ if [ $num_files -gt 0 ];
then
# Remember that we are counting from zero not one.
let "num_files--"
# Paranoia checks - the user should never encounter these.
if test "x$1" = "x" ;
then
- fail "scan_file called without an argument"
+ ICE "scan_file called without an argument"
fi
if test "x$2" != "x" ;
then
- fail "scan_file called with too many arguments"
+ ICE "scan_file called with too many arguments"
fi
# Use quotes when accessing files in order to preserve
fi
file $file | grep --silent -e ELF
- if [ $? != 0 ] ;
+ if [ $? != 0 ];
then
if [ $ignore_unknown -eq 0 ];
then
fi
$scanner --wide --notes --debug-dump=info --dynamic --segments $file > $tmpfile 2>&1
- if [ $? != 0 ] ;
+ if [ $? != 0 ];
then
- report "$file: scanner '$scanner' failed - see $tmpfile"
+ report "scanner '$scanner' failed - see $tmpfile"
failed=1
# Leave the tmpfile intact so that it can be examined by the user.
return
fi
+ grep -q -e "Unknown note" $tmpfile
+ if [ $? == 0 ];
+ then
+ report "scanner '$scanner' did not recognise the build attribute notes - see $tmpfile"
+ failed=1
+ # Leave the tmpfile intact so that it can be examined by the user.
+ return
+ fi
+
+ grep -q -e "Gap in build notes" $tmpfile
+ if [ $? == 0 ];
+ then
+ maybe "there are gaps in the build notes"
+ fi
+
local -a hard
local vulnerable=0
- if [ $skip_opt -eq 0 ] ;
+ if [ $skip_opt -eq 0 ];
then
check_optimization_level
fi
- if [ $skip_stack -eq 0 ] ;
+ if [ $skip_stack -eq 0 ];
then
check_for_stack_protector
fi
- if [ $skip_fortify -eq 0 ] ;
+ if [ $skip_fortify -eq 0 ];
then
check_for_fortify
fi
# Do not check the bind_now or relro status of unlinked files.
if [[ $filetype == exec || $filetype == lib || ( $filetype == auto && $file != *.o && $file != x*.a ) ]] ;
then
- if [ $skip_bind_now -eq 0 ] ;
+ if [ $skip_bind_now -eq 0 ];
then
check_for_bind_now
fi
- if [ $skip_relro -eq 0 ] ;
+ if [ $skip_relro -eq 0 ];
then
check_for_relro
fi
fi
- if [ $skip_pic -eq 0 ] ;
+ if [ $skip_pic -eq 0 ];
then
check_for_pie_or_pic
fi
# into:
# 2
- eval 'hard=($(grep -e FORTIFY $tmpfile | grep NT_GNU_BUILD_ATTRIBUTE_OPEN | cut -f 2 -d ":" | cut -b 3-5 | sed -e "s/ff/-1/" | sort | uniq))'
+ eval 'hard=($(grep -e FORTIFY $tmpfile | grep OPEN | cut -f 2 -d ":" | cut -b 3-5 | sed -e "s/ff/-1/" | sort -u))'
+ verbose "FORTIFY Info: ${hard[*]}"
+
if [ ${#hard[*]} -lt 1 ];
then
- if [ $report -gt 1 ];
- then
- # Or an old version of readelf is being used which does not recognise the fortify note...
- report "$file: MAYBE: does not record _FORTIFY_SOURCE level"
- fi
- vulnerable=1
+ # Or an old version of readelf is being used which does not recognise the fortify note...
+ maybe "does not record _FORTIFY_SOURCE level"
else
- if [ ${#hard[*]} -gt 1 ];
- then
- # FIXME: Check for multiple values above 1 ?
- if [ $report -gt 1 ];
- then
- report "$file: MAYBE: multiple values for _FORTIFY_SOURCE level recorded"
- fi
- vulnerable=1
- else
- if [ ${hard[0]} -lt 0 ];
+ # Check the value(s) to make sure that they are all >= 2.
+ local i
+
+ i=0;
+ while [ $i -lt ${#hard[*]} ]
+ do
+ if [ ${hard[i]} -lt 0 ];
then
- if [ $report -gt 1 ];
- then
- report "$file: MAYBE: sources compiled with --save-temps do not record _FORTIFY_SOURCE level"
- fi
- vulnerable=1
+ maybe "sources compiled with --save-temps do not record _FORTIFY_SOURCE level"
else
- if [[ ${hard[0]} -lt 2 ]];
+ if [[ ${hard[i]} -lt 2 ]];
then
- report "$file: FAIL: insufficient value for -D_FORTIFY_SOURCE=${hard[0]}"
- vulnerable=1
+ fail "insufficient value for -D_FORTIFY_SOURCE=${hard[i]}"
else
- if [ $report -gt 2 ];
- then
- report "$file: PASS: -D_FORTIFY_SOURCE=${hard[0]}"
- fi
+ pass "-D_FORTIFY_SOURCE=${hard[i]}"
fi
fi
- fi
+ let "i++"
+ done
fi
}
# GA*<stack prot>strong 0x00000000 NT_GNU_BUILD_ATTRIBUTE_OPEN
# into:
# strong
- eval 'hard=($(grep -e "stack prot" $tmpfile | grep NT_GNU_BUILD_ATTRIBUTE_OPEN | cut -f 2 -d ">" | cut -f 1 -d " " | sort | uniq))'
+ eval 'hard=($(grep -e "stack prot" $tmpfile | grep OPEN | cut -f 2 -d ">" | cut -f 1 -d " " | sort -u))'
+ verbose "Stack Protection Info: ${hard[*]}"
+
if [ ${#hard[*]} -lt 1 ];
then
# Stack protector note not recorded. Try examining the debug
# into:
# strong
eval hard=($(gawk -e 'BEGIN { FPAT = "-f[no-]*stack-protector[^ ]*" } /f/ { print substr ($1,19) ; }' $tmpfile | sort | uniq))
+
+ verbose "DW_AT_producer stack records: ${hard[*]}"
fi
if [ ${#hard[*]} -lt 1 ];
then
- if [ $report -gt 1 ];
- then
- report "$file: MAYBE: does not record -fstack_protector setting"
- fi
- vulnerable=1
+ maybe "does not record -fstack_protector setting"
else
if [ ${#hard[*]} -gt 1 ];
then
- report "$file: FAIL: multiple, different, settings of -fstack-protector used"
- vulnerable=1
+ fail "multiple, different, settings of -fstack-protector used"
else
if test "x${hard[0]}" = "xstrong" ;
then
- if [ $report -gt 2 ];
- then
- report "$file: PASS: compiled with -fstack-protector-strong"
- fi
+ pass "compiled with -fstack-protector-strong"
else
- vulnerable=1
- report "$file: FAIL: compiled with -fstack-protector-${hard[0]}"
+ fail "compiled with -fstack-protector-${hard[0]}"
fi
fi
fi
# GA*<stack prot>strong 0x00000000 NT_GNU_BUILD_ATTRIBUTE_FUNC
# into:
# strong
- eval 'hard=($(grep -e "stack prot" $tmpfile | grep NT_GNU_BUILD_ATTRIBUTE_FUNC | cut -f 2 -d ">" | cut -f 1 -d " " | sort | uniq))'
+ eval 'hard=($(grep -e "stack prot" $tmpfile | grep -e NT_GNU_BUILD_ATTRIBUTE_FUNC -e func | cut -f 2 -d ">" | cut -f 1 -d " " | sort -u))'
+
+ verbose "Stack Prot Info: ${hard[*]}"
if [ ${#hard[*]} -gt 0 ];
then
if [ ${#hard[*]} -gt 1 ];
then
- report "$file: FAIL: contains functions compiled without -fstack-protector=strong"
- vulnerable=1
+ fail "contains functions compiled without -fstack-protector=strong"
else
if test "x${hard[0]}" != "xstrong" ;
then
- report "$file: FAIL: contains functions compiled with -fstack-protector-${hard[0]}"
- vulnerable=1
+ fail "contains functions compiled with -fstack-protector-${hard[0]}"
fi
fi
fi
# GA*<PIC>PIE 0x00000000 NT_GNU_BUILD_ATTRIBUTE_OPEN
# into:
# PIE
- eval 'hard=($(grep -e "<PIC>" $tmpfile | grep NT_GNU_BUILD_ATTRIBUTE_OPEN | cut -f 2 -d ">" | cut -f 1 -d " " | sort | uniq))'
+ eval 'hard=($(grep -e "<PIC>" $tmpfile | grep OPEN | cut -f 2 -d ">" | cut -f 1 -d " " | sort -u))'
+
+ verbose "PIC Info: ${hard[*]}"
if [ ${#hard[*]} -lt 1 ];
then
# <c> DW_AT_producer : (indirect string, offset: 0x0): GNU C11 6.3.1 20161221 (Red Hat 6.3.1-1) -g -O2 -fPIC
# into:
# PIC
- eval hard=($(gawk -e 'BEGIN { FPAT = "-f[pP][iI][cCeE]" } /f/ { print substr ($1,3) ; }' $tmpfile | sort | uniq))
+ eval hard=($(gawk -e 'BEGIN { FPAT = "-f[pP][iI][cCeE]" } /f/ { print substr ($1,3) ; }' $tmpfile | sort -u))
+
+ verbose "DW_AT_producer records: ${hard[*]}"
fi
if [ ${#hard[*]} -lt 1 ];
then
- if [ $report -gt 1 ];
- then
- report "$file: MAYBE: does not record -fpic/-fpie setting"
- fi
- vulnerable=1
+ maybe "does not record -fpic/-fpie setting"
else
if [ ${#hard[*]} -gt 1 ];
then
- report "$file: FAIL: multiple, different, settings of -fpic/-fpie used"
- vulnerable=1
+ fail "multiple, different, settings of -fpic/-fpie used"
else
if [[ $filetype = lib || ( $filetype = auto && $file == *.so ) ]] ;
then
if [[ "x${hard[0]}" -eq "xPIC" || "x${hard[0]}" -eq "xpic" ]] ;
then
- if [ $report -gt 2 ];
- then
- report "$file: PASS: compiled with -f${hard[0]}"
- fi
+ pass "compiled with -f${hard[0]}"
else
- vulnerable=1
- report "$file: FAIL: compiled with -f${hard[0]}"
+ fail "compiled with -f${hard[0]}"
fi
else
if [[ "x${hard[0]}" -eq "xPIE" || "x${hard[0]}" -eq "xpie" ]] ;
then
- if [ $report -gt 2 ];
- then
- report "$file: PASS: compiled with -f${hard[0]}"
- fi
+ pass "compiled with -f${hard[0]}"
else
- vulnerable=1
- report "$file: FAIL: compiled with -f${hard[0]}"
+ fail "compiled with -f${hard[0]}"
fi
fi
fi
# GA*GOW:0x052b 0x00000000 NT_GNU_BUILD_ATTRIBUTE_OPEN
# into:
# 0x052b
- eval 'hard=($(grep -e "GOW:" $tmpfile | grep NT_GNU_BUILD_ATTRIBUTE_OPEN | cut -f 2 -d ":" | cut -f 1 -d " " | sort | uniq))'
+ eval 'hard=($(grep -e "GOW:" $tmpfile | grep OPEN | cut -f 2 -d ":" | cut -f 1 -d " " | sort -u))'
+
+ verbose "Optimization Info: ${hard[*]}"
if [ ${#hard[*]} -lt 1 ];
then
# <c> DW_AT_producer : (indirect string, offset: 0x0): GNU C11 6.3.1 20161221 (Red Hat 6.3.1-1) -g -O2 -fPIC
# into:
# 2
- eval hard=($(gawk -e 'BEGIN { FPAT = "-O[0123]" } /O[0123]/ { print substr ($1,3,1) ; }' $tmpfile | sort | uniq))
+ eval hard=($(gawk -e 'BEGIN { FPAT = "-O[0123]" } /O[0123]/ { print substr ($1,3,1) ; }' $tmpfile | sort -u))
+
+ verbose "DW_AT_producer records: ${hard[*]}"
if [ ${#hard[*]} -lt 1 ];
then
- if [ $report -gt 1 ];
- then
- report "$file: MAYBE: does not record -O setting"
- fi
-
- vulnerable=1
+ maybe "does not record -O setting"
else
local i
do
if [ ${hard[i]} -lt 2 ];
then
- report "$file: FAIL: optimization level of -O${hard[i]} used"
- vulnerable=1
+ fail "optimization level of -O${hard[i]} used"
break
else
- if [ $report -gt 2 ];
- then
- report "$file: PASS: optimization level of -O${hard[i]} used"
- fi
+ pass "optimization level of -O${hard[i]} used"
fi
let "i++"
done
declare -i opt=$(((${hard[i]} & 0x600) >> 9))
if [ $opt -lt 2 ];
then
- report "$file: FAIL: optimization level of -O$opt used"
- vulnerable=1
+ fail "optimization level of -O$opt used"
break
else
- if [ $report -gt 2 ];
- then
- report "$file: PASS: optimization level of -O$opt used"
- fi
+ pass "optimization level of -O$opt used"
fi
let "i++"
done
{
# Look for the DT_BIND_NOW dynamic tag
eval hard='($(grep -e BIND_NOW $tmpfile))'
+
+ verbose "BIND_NOW tags: ${hard[*]}"
+
if [ ${#hard[*]} -lt 1 ];
then
- report "$file: FAIL: -Wl,-z,now not used"
- vulnerable=1
+ fail "-Wl,-z,now not used"
else
- if [ $report -gt 2 ];
- then
- report "$file: PASS: -Wl,-z,now used"
- fi
+ pass "-Wl,-z,now used"
fi
}
{
# Look for the DT_BIND_NOW dynamic tag
eval hard='($(grep -e GNU_RELRO $tmpfile))'
+
+ verbose "GNU_RELRO tags: ${hard[*]}"
+
if [ ${#hard[*]} -lt 1 ];
then
- report "$file: FAIL: -Wl,-z,relro not used"
- vulnerable=1
+ fail "-Wl,-z,relro not used"
else
- if [ $report -gt 2 ];
- then
- report "$file: PASS: -Wl,-z,relro used"
- fi
+ pass "-Wl,-z,relro used"
fi
}