|
|
2ff057 |
#! /bin/bash
|
|
|
2ff057 |
|
|
|
2ff057 |
# Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
|
|
|
2ff057 |
#
|
|
|
2ff057 |
# This program is free software; you can redistribute it and/or modify
|
|
|
2ff057 |
# it under the terms of the GNU General Public License as published by
|
|
|
2ff057 |
# the Free Software Foundation; version 2 of the License.
|
|
|
2ff057 |
#
|
|
|
2ff057 |
# This program is distributed in the hope that it will be useful,
|
|
|
2ff057 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
2ff057 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
2ff057 |
# GNU General Public License for more details.
|
|
|
2ff057 |
#
|
|
|
2ff057 |
# You should have received a copy of the GNU General Public License
|
|
|
2ff057 |
# along with this program; if not, write to the Free Software
|
|
|
2ff057 |
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
2ff057 |
|
|
|
2ff057 |
|
|
|
2ff057 |
fail=
|
|
|
2ff057 |
already_shown=0
|
|
|
2ff057 |
|
|
|
2ff057 |
# effect of this expression is obviously:
|
|
|
2ff057 |
# * match paths beginning with:
|
|
|
2ff057 |
# - $SOMETHING/<something>/..
|
|
|
2ff057 |
# - /<something>/..
|
|
|
2ff057 |
# * but not paths beginning with
|
|
|
2ff057 |
# - $SOMETHING/..
|
|
|
2ff057 |
# - $SOMETHING/../../../.....
|
|
|
2ff057 |
BADNESS_EXPR_32='\(\(\$[^/]\+\)\?\(/.*\)\?/\(\([^.][^/]*\)\|\(\.[^./][^/]*\)\|\(\.\.[^/]\+\)\)\)/\.\.\(/.*\)\?$'
|
|
|
2ff057 |
|
|
|
2ff057 |
function showHint()
|
|
|
2ff057 |
{
|
|
|
2ff057 |
test "$already_shown" -eq 0 || return
|
|
|
2ff057 |
already_shown=1
|
|
|
2ff057 |
|
|
|
2ff057 |
cat <<EOF >&2
|
|
|
2ff057 |
*******************************************************************************
|
|
|
2ff057 |
*
|
|
|
2ff057 |
* WARNING: 'check-rpaths' detected a broken RPATH and will cause 'rpmbuild'
|
|
|
2ff057 |
* to fail. To ignore these errors, you can set the '\$QA_RPATHS'
|
|
|
2ff057 |
* environment variable which is a bitmask allowing the values
|
|
|
2ff057 |
* below. The current value of QA_RPATHS is $(printf '0x%04x' $QA_RPATHS).
|
|
|
2ff057 |
*
|
|
|
2ff057 |
* 0x0001 ... standard RPATHs (e.g. /usr/lib); such RPATHs are a minor
|
|
|
2ff057 |
* issue but are introducing redundant searchpaths without
|
|
|
2ff057 |
* providing a benefit. They can also cause errors in multilib
|
|
|
2ff057 |
* environments.
|
|
|
2ff057 |
* 0x0002 ... invalid RPATHs; these are RPATHs which are neither absolute
|
|
|
2ff057 |
* nor relative filenames and can therefore be a SECURITY risk
|
|
|
2ff057 |
* 0x0004 ... insecure RPATHs; these are relative RPATHs which are a
|
|
|
2ff057 |
* SECURITY risk
|
|
|
2ff057 |
* 0x0008 ... the special '\$ORIGIN' RPATHs are appearing after other
|
|
|
2ff057 |
* RPATHs; this is just a minor issue but usually unwanted
|
|
|
2ff057 |
* 0x0010 ... the RPATH is empty; there is no reason for such RPATHs
|
|
|
2ff057 |
* and they cause unneeded work while loading libraries
|
|
|
2ff057 |
* 0x0020 ... an RPATH references '..' of an absolute path; this will break
|
|
|
2ff057 |
* the functionality when the path before '..' is a symlink
|
|
|
2ff057 |
*
|
|
|
2ff057 |
*
|
|
|
2ff057 |
* Examples:
|
|
|
2ff057 |
* - to ignore standard and empty RPATHs, execute 'rpmbuild' like
|
|
|
2ff057 |
* \$ QA_RPATHS=\$(( 0x0001|0x0010 )) rpmbuild my-package.src.rpm
|
|
|
2ff057 |
* - to check existing files, set \$RPM_BUILD_ROOT and execute check-rpaths like
|
|
|
2ff057 |
* \$ RPM_BUILD_ROOT=<top-dir> /usr/lib/rpm/check-rpaths
|
|
|
2ff057 |
*
|
|
|
2ff057 |
*******************************************************************************
|
|
|
2ff057 |
EOF
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
function msg()
|
|
|
2ff057 |
{
|
|
|
2ff057 |
local val=$1
|
|
|
2ff057 |
local cmp=$2
|
|
|
2ff057 |
local msg=
|
|
|
2ff057 |
local fail=
|
|
|
2ff057 |
local code
|
|
|
2ff057 |
|
|
|
2ff057 |
test $[ $val & $cmp ] -ne 0 || return 0
|
|
|
2ff057 |
|
|
|
2ff057 |
code=$(printf '%04x' $cmp)
|
|
|
2ff057 |
if test $[ $val & ~$QA_RPATHS ] -eq 0; then
|
|
|
2ff057 |
msg="WARNING"
|
|
|
2ff057 |
else
|
|
|
2ff057 |
showHint
|
|
|
2ff057 |
msg="ERROR "
|
|
|
2ff057 |
fail=1
|
|
|
2ff057 |
fi
|
|
|
2ff057 |
|
|
|
2ff057 |
shift 2
|
|
|
2ff057 |
echo "$msg $code: $@" >&2
|
|
|
2ff057 |
|
|
|
2ff057 |
test -z "$fail"
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
: ${QA_RPATHS:=0}
|
|
|
2ff057 |
old_IFS=$IFS
|
|
|
2ff057 |
|
|
|
2ff057 |
for i; do
|
|
|
2ff057 |
pos=0
|
|
|
2ff057 |
rpath=$(readelf -d "$i" 2>/dev/null | LANG=C grep '(RPATH).*:') || continue
|
|
|
2ff057 |
rpath=$(echo "$rpath" | LANG=C sed -e 's!.*(RPATH).*: \[\(.*\)\]!\1!p;d')
|
|
|
2ff057 |
tmp=aux:$rpath:/lib/aux || :
|
|
|
2ff057 |
IFS=:
|
|
|
2ff057 |
set -- $tmp
|
|
|
2ff057 |
IFS=$old_IFS
|
|
|
2ff057 |
shift
|
|
|
2ff057 |
|
|
|
2ff057 |
allow_ORIGIN=1
|
|
|
2ff057 |
for j; do
|
|
|
2ff057 |
new_allow_ORIGIN=0
|
|
|
2ff057 |
|
|
|
2ff057 |
if test -z "$j"; then
|
|
|
2ff057 |
badness=16
|
|
|
2ff057 |
elif expr match "$j" "$BADNESS_EXPR_32" >/dev/null; then
|
|
|
2ff057 |
badness=32
|
|
|
2ff057 |
else
|
|
|
2ff057 |
case "$j" in
|
|
|
2ff057 |
(/lib/*|/usr/lib/*|/usr/X11R6/lib/*|/usr/local/lib/*)
|
|
|
2ff057 |
badness=0;;
|
|
|
2ff057 |
(/lib64/*|/usr/lib64/*|/usr/X11R6/lib64/*|/usr/local/lib64/*)
|
|
|
2ff057 |
badness=0;;
|
|
|
2ff057 |
|
|
|
2ff057 |
(\$ORIGIN|\${ORIGINX}|\$ORIGIN/*|\${ORIGINX}/*)
|
|
|
2ff057 |
test $allow_ORIGIN -eq 0 && badness=8 || {
|
|
|
2ff057 |
badness=0
|
|
|
2ff057 |
new_allow_ORIGIN=1
|
|
|
2ff057 |
}
|
|
|
2ff057 |
;;
|
|
|
2ff057 |
(/*\$PLATFORM*|/*\${PLATFORM}*|/*\$LIB*|/*\${LIB}*)
|
|
|
2ff057 |
badness=0;;
|
|
|
2ff057 |
|
|
|
2ff057 |
(/lib|/usr/lib|/usr/X11R6/lib)
|
|
|
2ff057 |
badness=1;;
|
|
|
2ff057 |
(/lib64|/usr/lib64|/usr/X11R6/lib64)
|
|
|
2ff057 |
badness=1;;
|
|
|
2ff057 |
|
|
|
2ff057 |
(.*)
|
|
|
2ff057 |
badness=4;;
|
|
|
2ff057 |
(*) badness=2;;
|
|
|
2ff057 |
esac
|
|
|
2ff057 |
fi
|
|
|
2ff057 |
|
|
|
2ff057 |
allow_ORIGIN=$new_allow_ORIGIN
|
|
|
2ff057 |
|
|
|
2ff057 |
base=${i##$RPM_BUILD_ROOT}
|
|
|
2ff057 |
msg "$badness" 1 "file '$base' contains a standard rpath '$j' in [$rpath]" || fail=1
|
|
|
2ff057 |
msg "$badness" 2 "file '$base' contains an invalid rpath '$j' in [$rpath]" || fail=1
|
|
|
2ff057 |
msg "$badness" 4 "file '$base' contains an insecure rpath '$j' in [$rpath]" || fail=1
|
|
|
2ff057 |
msg "$badness" 8 "file '$base' contains the \$ORIGIN rpath specifier at the wrong position in [$rpath]" || fail=1
|
|
|
2ff057 |
msg "$badness" 16 "file '$base' contains an empty rpath in [$rpath]" || fail=1
|
|
|
2ff057 |
msg "$badness" 32 "file '$base' contains an rpath referencing '..' of an absolute path [$rpath]" || fail=2
|
|
|
2ff057 |
let ++pos
|
|
|
2ff057 |
done
|
|
|
2ff057 |
done
|
|
|
2ff057 |
|
|
|
2ff057 |
test -z "$fail"
|