csomh / source-git / rpm

Forked from source-git/rpm 4 years ago
Clone
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"