OpenWrt – Diff between revs 2 and 3

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 2 Rev 3
1 #!/usr/bin/env bash 1 #!/usr/bin/env bash
2 # 2 #
3 # Script to install host system binaries along with required libraries. 3 # Script to install host system binaries along with required libraries.
4 # 4 #
5 # Copyright (C) 2012-2017 Jo-Philipp Wich <jo@mein.io> 5 # Copyright (C) 2012-2017 Jo-Philipp Wich <jo@mein.io>
6 # 6 #
7 # This program is free software; you can redistribute it and/or modify 7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by 8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or 9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version. 10 # (at your option) any later version.
11 # 11 #
12 # This program is distributed in the hope that it will be useful, 12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details. 15 # GNU General Public License for more details.
16 # 16 #
17 # You should have received a copy of the GNU General Public License 17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software 18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20   20  
21 DIR="$1"; shift 21 DIR="$1"; shift
22   22  
23 _cp() { 23 _cp() {
24 cp ${VERBOSE:+-v} -L "$1" "$2" || { 24 cp ${VERBOSE:+-v} -L "$1" "$2" || {
25 echo "cp($1 $2) failed" >&2 25 echo "cp($1 $2) failed" >&2
26 exit 1 26 exit 1
27 } 27 }
28 } 28 }
29   29  
30 _mv() { 30 _mv() {
31 mv ${VERBOSE:+-v} "$1" "$2" || { 31 mv ${VERBOSE:+-v} "$1" "$2" || {
32 echo "mv($1 $2) failed" >&2 32 echo "mv($1 $2) failed" >&2
33 exit 1 33 exit 1
34 } 34 }
35 } 35 }
36   36  
37 _md() { 37 _md() {
38 mkdir ${VERBOSE:+-v} -p "$1" || { 38 mkdir ${VERBOSE:+-v} -p "$1" || {
39 echo "mkdir($1) failed" >&2 39 echo "mkdir($1) failed" >&2
40 exit 2 40 exit 2
41 } 41 }
42 } 42 }
43   43  
44 _ln() { 44 _ln() {
45 ln ${VERBOSE:+-v} -sf "$1" "$2" || { 45 ln ${VERBOSE:+-v} -sf "$1" "$2" || {
46 echo "ln($1 $2) failed" >&2 46 echo "ln($1 $2) failed" >&2
47 exit 3 47 exit 3
48 } 48 }
49 } 49 }
50   50  
51 _relpath() { 51 _relpath() {
52 local base="$(readlink -f "$1")" 52 local base="$(readlink -f "$1")"
53 local dest="$(readlink -f "$2")" 53 local dest="$(readlink -f "$2")"
54 local up 54 local up
55   55  
56 [ -d "$base" ] || base="${base%/*}" 56 [ -d "$base" ] || base="${base%/*}"
57 [ -d "$dest" ] || dest="${dest%/*}" 57 [ -d "$dest" ] || dest="${dest%/*}"
58   58  
59 while true; do 59 while true; do
60 case "$base" 60 case "$base"
61 in "$dest"/*) 61 in "$dest"/*)
62 echo "$up/${base#$dest/}" 62 echo "$up/${base#$dest/}"
63 break 63 break
64 ;; 64 ;;
65 *) 65 *)
66 dest="${dest%/*}" 66 dest="${dest%/*}"
67 up="${up:+$up/}.." 67 up="${up:+$up/}.."
68 ;; 68 ;;
69 esac 69 esac
70 done 70 done
71 } 71 }
72   72  
73 _runas_so() { 73 _runas_so() {
74 cat <<-EOT | ${CC:-gcc} -x c -fPIC -shared -o "$1" - 74 cat <<-EOT | ${CC:-gcc} -x c -fPIC -shared -o "$1" -
75 #include <unistd.h> 75 #include <unistd.h>
76 #include <stdio.h> 76 #include <stdio.h>
77 #include <stdlib.h> 77 #include <stdlib.h>
78   78  
79 int mangle_arg0(int argc, char **argv, char **env) { 79 int mangle_arg0(int argc, char **argv, char **env) {
80 char *arg0 = getenv("RUNAS_ARG0"); 80 char *arg0 = getenv("RUNAS_ARG0");
81   81  
82 if (arg0) { 82 if (arg0) {
83 argv[0] = arg0; 83 argv[0] = arg0;
84 unsetenv("RUNAS_ARG0"); 84 unsetenv("RUNAS_ARG0");
85 } 85 }
86   86  
87 return 0; 87 return 0;
88 } 88 }
89   89  
90 #ifdef __APPLE__ 90 #ifdef __APPLE__
91 __attribute__((section("__DATA,__mod_init_func"))) 91 __attribute__((section("__DATA,__mod_init_func")))
92 #else 92 #else
93 __attribute__((section(".init_array"))) 93 __attribute__((section(".init_array")))
94 #endif 94 #endif
95 static void *mangle_arg0_constructor = &mangle_arg0; 95 static void *mangle_arg0_constructor = &mangle_arg0;
96 EOT 96 EOT
97   97  
98 [ -x "$1" ] || { 98 [ -x "$1" ] || {
99 echo "compiling preload library failed" >&2 99 echo "compiling preload library failed" >&2
100 exit 5 100 exit 5
101 } 101 }
102 } 102 }
103   103  
104 _patch_ldso() { 104 _patch_ldso() {
105 _cp "$1" "$1.patched" 105 _cp "$1" "$1.patched"
106 sed -i -e 's,/\(usr\|lib\|etc\)/,/###/,g' "$1.patched" 106 sed -i -e 's,/\(usr\|lib\|etc\)/,/###/,g' "$1.patched"
107   107  
108 if "$1.patched" 2>&1 | grep -q -- --library-path; then 108 if "$1.patched" 2>&1 | grep -q -- --library-path; then
109 _mv "$1.patched" "$1" 109 _mv "$1.patched" "$1"
110 else 110 else
111 echo "binary patched ${1##*/} not executable, using original" >&2 111 echo "binary patched ${1##*/} not executable, using original" >&2
112 rm -f "$1.patched" 112 rm -f "$1.patched"
113 fi 113 fi
114 } 114 }
115   -  
116 _patch_glibc() { -  
117 _cp "$1" "$1.patched" -  
118 sed -i -e 's,/usr/\(\(lib\|share\)/locale\),/###/\1,g' "$1.patched" -  
119   -  
120 if "$1.patched" 2>&1 | grep -q -- GNU; then -  
121 _mv "$1.patched" "$1" -  
122 else -  
123 echo "binary patched ${1##*/} not executable, using original" >&2 -  
124 rm -f "$1.patched" -  
125 fi -  
126 } -  
127   115  
128 for LDD in ${PATH//://ldd }/ldd; do 116 for LDD in ${PATH//://ldd }/ldd; do
129 "$LDD" --version >/dev/null 2>/dev/null && break 117 "$LDD" --version >/dev/null 2>/dev/null && break
130 LDD="" 118 LDD=""
131 done 119 done
132   120  
133 [ -n "$LDD" -a -x "$LDD" ] || LDD= 121 [ -n "$LDD" -a -x "$LDD" ] || LDD=
134   122  
135 for BIN in "$@"; do 123 for BIN in "$@"; do
136 [ -n "$BIN" -a -n "$DIR" ] || { 124 [ -n "$BIN" -a -n "$DIR" ] || {
137 echo "Usage: $0 <destdir> <executable> ..." >&2 125 echo "Usage: $0 <destdir> <executable> ..." >&2
138 exit 1 126 exit 1
139 } 127 }
140   128  
141 [ ! -d "$DIR/lib" ] && { 129 [ ! -d "$DIR/lib" ] && {
142 _md "$DIR/lib" 130 _md "$DIR/lib"
143 _md "$DIR/usr" 131 _md "$DIR/usr"
144 _ln "../lib" "$DIR/usr/lib" 132 _ln "../lib" "$DIR/usr/lib"
145 } 133 }
146   134  
147 [ ! -x "$DIR/lib/runas.so" ] && { 135 [ ! -x "$DIR/lib/runas.so" ] && {
148 _runas_so "$DIR/lib/runas.so" 136 _runas_so "$DIR/lib/runas.so"
149 } 137 }
150   138  
151 LDSO="" 139 LDSO=""
152   140  
153 [ -n "$LDD" ] && [ -x "$BIN" ] && file "$BIN" | grep -sqE "ELF.*(executable|interpreter)" && { 141 [ -n "$LDD" ] && [ -x "$BIN" ] && file "$BIN" | grep -sqE "ELF.*(executable|interpreter)" && {
154 for token in $("$LDD" "$BIN" 2>/dev/null); do 142 for token in $("$LDD" "$BIN" 2>/dev/null); do
155 case "$token" in */*.so*) 143 case "$token" in */*.so*)
156 dest="$DIR/lib/${token##*/}" -  
157 ddir="${dest%/*}" -  
158   -  
159 case "$token" in 144 case "$token" in
160 */ld-*.so*) LDSO="${token##*/}" ;; 145 *ld-*.so*) LDSO="${token##*/}" ;;
161 esac 146 esac
-   147  
-   148 dest="$DIR/lib/${token##*/}"
-   149 ddir="${dest%/*}"
162   150  
163 [ -f "$token" -a ! -f "$dest" ] && { 151 [ -f "$token" -a ! -f "$dest" ] && {
164 _md "$ddir" 152 _md "$ddir"
165 _cp "$token" "$dest" 153 _cp "$token" "$dest"
166 case "$token" in -  
167 */ld-*.so*) _patch_ldso "$dest" ;; 154 [ -n "$LDSO" ] && _patch_ldso "$dest"
168 */libc.so.6) _patch_glibc "$dest" ;; -  
169 esac -  
170 } 155 }
171 ;; esac 156 ;; esac
172 done 157 done
173 } 158 }
174   159  
175 # is a dynamically linked executable 160 # is a dynamically linked executable
176 if [ -n "$LDSO" ]; then 161 if [ -n "$LDSO" ]; then
177 echo "Bundling ${BIN##*/}" 162 echo "Bundling ${BIN##*/}"
178   163  
179 RUNDIR="$(readlink -f "$BIN")"; RUNDIR="${RUNDIR%/*}" 164 RUNDIR="$(readlink -f "$BIN")"; RUNDIR="${RUNDIR%/*}"
180 RUN="${LDSO#ld-}"; RUN="run-${RUN%%.so*}.sh" 165 RUN="${LDSO#ld-}"; RUN="run-${RUN%%.so*}.sh"
181 REL="$(_relpath "$DIR/lib" "$BIN")" 166 REL="$(_relpath "$DIR/lib" "$BIN")"
182   167  
183 _mv "$BIN" "$RUNDIR/.${BIN##*/}.bin" 168 _mv "$BIN" "$RUNDIR/.${BIN##*/}.bin"
184   169  
185 cat <<-EOF > "$BIN" 170 cat <<-EOF > "$BIN"
186 #!/usr/bin/env bash 171 #!/usr/bin/env bash
187 dir="\$(dirname "\$0")" 172 dir="\$(dirname "\$0")"
188 export RUNAS_ARG0="\$0" 173 export RUNAS_ARG0="\$0"
189 export LD_PRELOAD="\$dir/${REL:+$REL/}runas.so" 174 export LD_PRELOAD="\$dir/${REL:+$REL/}runas.so"
190 exec "\$dir/${REL:+$REL/}$LDSO" --library-path "\$dir/${REL:+$REL/}" "\$dir/.${BIN##*/}.bin" "\$@" 175 exec "\$dir/${REL:+$REL/}$LDSO" --library-path "\$dir/${REL:+$REL/}" "\$dir/.${BIN##*/}.bin" "\$@"
191 EOF 176 EOF
192   177  
193 chmod ${VERBOSE:+-v} 0755 "$BIN" 178 chmod ${VERBOSE:+-v} 0755 "$BIN"
194 fi 179 fi
195 done 180 done
196   181