Add macro %isu_package to generate ISU Package
[platform/upstream/rpm.git] / scripts / check-rpaths-worker
1 #! /bin/bash
2
3 # Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 #  
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License.
8 #  
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #  
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18
19 fail=
20 already_shown=0
21
22 # effect of this expression is obviously:
23 # * match paths beginning with:
24 #   - $SOMETHING/<something>/..
25 #   - /<something>/..
26 # * but not paths beginning with
27 #   - $SOMETHING/..
28 #   - $SOMETHING/../../../.....
29 BADNESS_EXPR_32='\(\(\$[^/]\+\)\?\(/.*\)\?/\(\([^.][^/]*\)\|\(\.[^./][^/]*\)\|\(\.\.[^/]\+\)\)\)/\.\.\(/.*\)\?$'
30
31 function showHint()
32 {
33     test "$already_shown" -eq 0 || return
34     already_shown=1
35     
36     cat <<EOF >&2
37 *******************************************************************************
38 *
39 * WARNING: 'check-rpaths' detected a broken RPATH and will cause 'rpmbuild'
40 *          to fail. To ignore these errors, you can set the '\$QA_RPATHS'
41 *          environment variable which is a bitmask allowing the values
42 *          below. The current value of QA_RPATHS is $(printf '0x%04x' $QA_RPATHS).
43 *
44 *    0x0001 ... standard RPATHs (e.g. /usr/lib); such RPATHs are a minor
45 *               issue but are introducing redundant searchpaths without
46 *               providing a benefit. They can also cause errors in multilib
47 *               environments.
48 *    0x0002 ... invalid RPATHs; these are RPATHs which are neither absolute
49 *               nor relative filenames and can therefore be a SECURITY risk
50 *    0x0004 ... insecure RPATHs; these are relative RPATHs which are a
51 *               SECURITY risk
52 *    0x0008 ... the special '\$ORIGIN' RPATHs are appearing after other
53 *               RPATHs; this is just a minor issue but usually unwanted
54 *    0x0010 ... the RPATH is empty; there is no reason for such RPATHs
55 *               and they cause unneeded work while loading libraries
56 *    0x0020 ... an RPATH references '..' of an absolute path; this will break
57 *               the functionality when the path before '..' is a symlink
58 *          
59 *
60 * Examples:
61 * - to ignore standard and empty RPATHs, execute 'rpmbuild' like
62 *   \$ QA_RPATHS=\$(( 0x0001|0x0010 )) rpmbuild my-package.src.rpm
63 * - to check existing files, set \$RPM_BUILD_ROOT and execute check-rpaths like
64 *   \$ RPM_BUILD_ROOT=<top-dir> /usr/lib/rpm/check-rpaths
65 *  
66 *******************************************************************************
67 EOF
68 }
69
70 function msg()
71 {
72     local val=$1
73     local cmp=$2
74     local msg=
75     local fail=
76     local code
77
78     test $[ $val & $cmp ] -ne 0 || return 0
79
80     code=$(printf '%04x' $cmp)
81     if test $[ $val & ~$QA_RPATHS ] -eq 0; then
82         msg="WARNING"
83     else
84         showHint
85         msg="ERROR  "
86         fail=1
87     fi
88
89     shift 2
90     echo "$msg $code: $@" >&2
91
92     test -z "$fail"
93 }
94
95 : ${QA_RPATHS:=0}
96 old_IFS=$IFS
97
98 for i; do
99     pos=0
100     rpath=$(readelf -d "$i" 2>/dev/null | LANG=C grep '(RPATH).*:') || continue
101     rpath=$(echo "$rpath" | LANG=C sed -e 's!.*(RPATH).*: \[\(.*\)\]!\1!p;d')
102     tmp=aux:$rpath:/lib/aux || :
103     IFS=:
104     set -- $tmp
105     IFS=$old_IFS
106     shift
107
108     allow_ORIGIN=1
109     for j; do
110         new_allow_ORIGIN=0
111
112         if test -z "$j"; then
113             badness=16
114         elif expr match "$j" "$BADNESS_EXPR_32" >/dev/null; then
115             badness=32
116         else
117             case "$j" in
118                 (/lib/*|/usr/lib/*|/usr/X11R6/lib/*|/usr/local/lib/*)
119                     badness=0;;
120                 (/lib64/*|/usr/lib64/*|/usr/X11R6/lib64/*|/usr/local/lib64/*)
121                     badness=0;;
122
123                 (\$ORIGIN|\${ORIGINX}|\$ORIGIN/*|\${ORIGINX}/*)
124                     test $allow_ORIGIN -eq 0 && badness=8 || {
125                         badness=0
126                         new_allow_ORIGIN=1
127                     }
128                     ;;
129                 (/*\$PLATFORM*|/*\${PLATFORM}*|/*\$LIB*|/*\${LIB}*)
130                     badness=0;;
131                 
132                 (/lib|/usr/lib|/usr/X11R6/lib)
133                     badness=1;;
134                 (/lib64|/usr/lib64|/usr/X11R6/lib64)
135                     badness=1;;
136                 
137                 (.*)
138                     badness=4;;
139                 (*) badness=2;;
140             esac
141         fi
142
143         allow_ORIGIN=$new_allow_ORIGIN
144
145         base=${i##$RPM_BUILD_ROOT}
146         msg "$badness"  1 "file '$base' contains a standard rpath '$j' in [$rpath]"  || fail=1
147         msg "$badness"  2 "file '$base' contains an invalid rpath '$j' in [$rpath]"  || fail=1
148         msg "$badness"  4 "file '$base' contains an insecure rpath '$j' in [$rpath]" || fail=1
149         msg "$badness"  8 "file '$base' contains the \$ORIGIN rpath specifier at the wrong position in [$rpath]" || fail=1
150         msg "$badness" 16 "file '$base' contains an empty rpath in [$rpath]"         || fail=1
151         msg "$badness" 32 "file '$base' contains an rpath referencing '..' of an absolute path [$rpath]" || fail=2
152         let ++pos
153     done
154 done
155
156 test -z "$fail"