1 |
Convert the horrendous install_qa_check() function into a plug-in system |
2 |
that calls separate QA checking scripts from install-qa-check.d. |
3 |
--- |
4 |
bin/install-qa-check.d/05double-D | 17 + |
5 |
bin/install-qa-check.d/05prefix | 117 +++ |
6 |
bin/install-qa-check.d/10executable-issues | 140 ++++ |
7 |
bin/install-qa-check.d/10ignored-flags | 99 +++ |
8 |
bin/install-qa-check.d/20deprecated-directories | 18 + |
9 |
bin/install-qa-check.d/20runtime-directories | 26 + |
10 |
bin/install-qa-check.d/60bash-completion | 130 ++++ |
11 |
bin/install-qa-check.d/60openrc | 41 ++ |
12 |
bin/install-qa-check.d/60pkgconfig | 15 + |
13 |
bin/install-qa-check.d/60pngfix | 35 + |
14 |
bin/install-qa-check.d/60systemd | 25 + |
15 |
bin/install-qa-check.d/60udev | 21 + |
16 |
bin/install-qa-check.d/80libraries | 158 ++++ |
17 |
bin/install-qa-check.d/80multilib-strict | 50 ++ |
18 |
bin/install-qa-check.d/90gcc-warnings | 145 ++++ |
19 |
bin/install-qa-check.d/90world-writable | 25 + |
20 |
bin/misc-functions.sh | 939 +----------------------- |
21 |
17 files changed, 1073 insertions(+), 928 deletions(-) |
22 |
create mode 100644 bin/install-qa-check.d/05double-D |
23 |
create mode 100644 bin/install-qa-check.d/05prefix |
24 |
create mode 100644 bin/install-qa-check.d/10executable-issues |
25 |
create mode 100644 bin/install-qa-check.d/10ignored-flags |
26 |
create mode 100644 bin/install-qa-check.d/20deprecated-directories |
27 |
create mode 100644 bin/install-qa-check.d/20runtime-directories |
28 |
create mode 100644 bin/install-qa-check.d/60bash-completion |
29 |
create mode 100644 bin/install-qa-check.d/60openrc |
30 |
create mode 100644 bin/install-qa-check.d/60pkgconfig |
31 |
create mode 100644 bin/install-qa-check.d/60pngfix |
32 |
create mode 100644 bin/install-qa-check.d/60systemd |
33 |
create mode 100644 bin/install-qa-check.d/60udev |
34 |
create mode 100644 bin/install-qa-check.d/80libraries |
35 |
create mode 100644 bin/install-qa-check.d/80multilib-strict |
36 |
create mode 100644 bin/install-qa-check.d/90gcc-warnings |
37 |
create mode 100644 bin/install-qa-check.d/90world-writable |
38 |
|
39 |
diff --git a/bin/install-qa-check.d/05double-D b/bin/install-qa-check.d/05double-D |
40 |
new file mode 100644 |
41 |
index 0000000..1634afd |
42 |
--- /dev/null |
43 |
+++ b/bin/install-qa-check.d/05double-D |
44 |
@@ -0,0 +1,17 @@ |
45 |
+# Check for accidential install into ${D}/${D} |
46 |
+ |
47 |
+DD_check() { |
48 |
+ if [[ -d ${D%/}${D} ]] ; then |
49 |
+ local -i INSTALLTOD=0 |
50 |
+ while read -r -d $'\0' i ; do |
51 |
+ eqawarn "QA Notice: /${i##${D%/}${D}} installed in \${D}/\${D}" |
52 |
+ ((INSTALLTOD++)) |
53 |
+ done < <(find "${D%/}${D}" -print0) |
54 |
+ die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D%/}${D}" |
55 |
+ fi |
56 |
+} |
57 |
+ |
58 |
+DD_check |
59 |
+: # guarantee successful exit |
60 |
+ |
61 |
+# vim:ft=sh |
62 |
diff --git a/bin/install-qa-check.d/05prefix b/bin/install-qa-check.d/05prefix |
63 |
new file mode 100644 |
64 |
index 0000000..e1fc2bd |
65 |
--- /dev/null |
66 |
+++ b/bin/install-qa-check.d/05prefix |
67 |
@@ -0,0 +1,117 @@ |
68 |
+# Prefix specific QA checks |
69 |
+ |
70 |
+install_qa_check_prefix() { |
71 |
+ [[ ${ED} == ${D} ]] && return |
72 |
+ |
73 |
+ if [[ -d ${ED}/${D} ]] ; then |
74 |
+ find "${ED}/${D}" | \ |
75 |
+ while read i ; do |
76 |
+ eqawarn "QA Notice: /${i##${ED}/${D}} installed in \${ED}/\${D}" |
77 |
+ done |
78 |
+ die "Aborting due to QA concerns: files installed in ${ED}/${D}" |
79 |
+ fi |
80 |
+ |
81 |
+ if [[ -d ${ED}/${EPREFIX} ]] ; then |
82 |
+ find "${ED}/${EPREFIX}/" | \ |
83 |
+ while read i ; do |
84 |
+ eqawarn "QA Notice: ${i#${D}} double prefix" |
85 |
+ done |
86 |
+ die "Aborting due to QA concerns: double prefix files installed" |
87 |
+ fi |
88 |
+ |
89 |
+ if [[ -d ${D} ]] ; then |
90 |
+ INSTALLTOD=$(find ${D%/} | egrep -v "^${ED}" | sed -e "s|^${D%/}||" | awk '{if (length($0) <= length("'"${EPREFIX}"'")) { if (substr("'"${EPREFIX}"'", 1, length($0)) != $0) {print $0;} } else if (substr($0, 1, length("'"${EPREFIX}"'")) != "'"${EPREFIX}"'") {print $0;} }') |
91 |
+ if [[ -n ${INSTALLTOD} ]] ; then |
92 |
+ eqawarn "QA Notice: the following files are outside of the prefix:" |
93 |
+ eqawarn "${INSTALLTOD}" |
94 |
+ die "Aborting due to QA concerns: there are files installed outside the prefix" |
95 |
+ fi |
96 |
+ fi |
97 |
+ |
98 |
+ # all further checks rely on ${ED} existing |
99 |
+ [[ -d ${ED} ]] || return |
100 |
+ |
101 |
+ # check shebangs, bug #282539 |
102 |
+ rm -f "${T}"/non-prefix-shebangs-errs |
103 |
+ local WHITELIST=" /usr/bin/env " |
104 |
+ # this is hell expensive, but how else? |
105 |
+ find "${ED}" -executable \! -type d -print0 \ |
106 |
+ | xargs -0 grep -H -n -m1 "^#!" \ |
107 |
+ | while read f ; |
108 |
+ do |
109 |
+ local fn=${f%%:*} |
110 |
+ local pos=${f#*:} ; pos=${pos%:*} |
111 |
+ local line=${f##*:} |
112 |
+ # shebang always appears on the first line ;) |
113 |
+ [[ ${pos} != 1 ]] && continue |
114 |
+ local oldIFS=${IFS} |
115 |
+ IFS=$'\r'$'\n'$'\t'" " |
116 |
+ line=( ${line#"#!"} ) |
117 |
+ IFS=${oldIFS} |
118 |
+ [[ ${WHITELIST} == *" ${line[0]} "* ]] && continue |
119 |
+ local fp=${fn#${D}} ; fp=/${fp%/*} |
120 |
+ # line[0] can be an absolutised path, bug #342929 |
121 |
+ local eprefix=$(canonicalize ${EPREFIX}) |
122 |
+ local rf=${fn} |
123 |
+ # in case we deal with a symlink, make sure we don't replace it |
124 |
+ # with a real file (sed -i does that) |
125 |
+ if [[ -L ${fn} ]] ; then |
126 |
+ rf=$(readlink ${fn}) |
127 |
+ [[ ${rf} != /* ]] && rf=${fn%/*}/${rf} |
128 |
+ # ignore symlinks pointing to outside prefix |
129 |
+ # as seen in sys-devel/native-cctools |
130 |
+ [[ $(canonicalize "/${rf#${D}}") != ${eprefix}/* ]] && continue |
131 |
+ fi |
132 |
+ # does the shebang start with ${EPREFIX}, and does it exist? |
133 |
+ if [[ ${line[0]} == ${EPREFIX}/* || ${line[0]} == ${eprefix}/* ]] ; then |
134 |
+ if [[ ! -e ${ROOT%/}${line[0]} && ! -e ${D%/}${line[0]} ]] ; then |
135 |
+ # hmm, refers explicitly to $EPREFIX, but doesn't exist, |
136 |
+ # if it's in PATH that's wrong in any case |
137 |
+ if [[ ":${PATH}:" == *":${fp}:"* ]] ; then |
138 |
+ echo "${fn#${D}}:${line[0]} (explicit EPREFIX but target not found)" \ |
139 |
+ >> "${T}"/non-prefix-shebangs-errs |
140 |
+ else |
141 |
+ eqawarn "${fn#${D}} has explicit EPREFIX in shebang but target not found (${line[0]})" |
142 |
+ fi |
143 |
+ fi |
144 |
+ continue |
145 |
+ fi |
146 |
+ # unprefixed shebang, is the script directly in $PATH? |
147 |
+ if [[ ":${PATH}:" == *":${fp}:"* ]] ; then |
148 |
+ if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; then |
149 |
+ # is it unprefixed, but we can just fix it because a |
150 |
+ # prefixed variant exists |
151 |
+ eqawarn "prefixing shebang of ${fn#${D}}" |
152 |
+ # statement is made idempotent on purpose, because |
153 |
+ # symlinks may point to the same target, and hence the |
154 |
+ # same real file may be sedded multiple times since we |
155 |
+ # read the shebangs in one go upfront for performance |
156 |
+ # reasons |
157 |
+ sed -i -e '1s:^#! \?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}" |
158 |
+ continue |
159 |
+ else |
160 |
+ # this is definitely wrong: script in $PATH and invalid shebang |
161 |
+ echo "${fn#${D}}:${line[0]} (script ${fn##*/} installed in PATH but interpreter ${line[0]} not found)" \ |
162 |
+ >> "${T}"/non-prefix-shebangs-errs |
163 |
+ fi |
164 |
+ else |
165 |
+ # unprefixed/invalid shebang, but outside $PATH, this may be |
166 |
+ # intended (e.g. config.guess) so remain silent by default |
167 |
+ has stricter ${FEATURES} && \ |
168 |
+ eqawarn "invalid shebang in ${fn#${D}}: ${line[0]}" |
169 |
+ fi |
170 |
+ done |
171 |
+ if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then |
172 |
+ eqawarn "QA Notice: the following files use invalid (possible non-prefixed) shebangs:" |
173 |
+ while read line ; do |
174 |
+ eqawarn " ${line}" |
175 |
+ done < "${T}"/non-prefix-shebangs-errs |
176 |
+ rm -f "${T}"/non-prefix-shebangs-errs |
177 |
+ die "Aborting due to QA concerns: invalid shebangs found" |
178 |
+ fi |
179 |
+} |
180 |
+ |
181 |
+install_qa_check_prefix |
182 |
+: # guarantee successful exit |
183 |
+ |
184 |
+# vim:ft=sh |
185 |
diff --git a/bin/install-qa-check.d/10executable-issues b/bin/install-qa-check.d/10executable-issues |
186 |
new file mode 100644 |
187 |
index 0000000..f765749 |
188 |
--- /dev/null |
189 |
+++ b/bin/install-qa-check.d/10executable-issues |
190 |
@@ -0,0 +1,140 @@ |
191 |
+# Check for major issues with built executables: insecure RPATHs, |
192 |
+# text relocations, executable stacks |
193 |
+ |
194 |
+elf_check() { |
195 |
+ if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then |
196 |
+ local insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET} |
197 |
+ local f x |
198 |
+ |
199 |
+ # display warnings when using stricter because we die afterwards |
200 |
+ if has stricter ${FEATURES} ; then |
201 |
+ local PORTAGE_QUIET |
202 |
+ fi |
203 |
+ |
204 |
+ # Make sure we disallow insecure RUNPATH/RPATHs. |
205 |
+ # 1) References to PORTAGE_BUILDDIR are banned because it's a |
206 |
+ # security risk. We don't want to load files from a |
207 |
+ # temporary directory. |
208 |
+ # 2) If ROOT != "/", references to ROOT are banned because |
209 |
+ # that directory won't exist on the target system. |
210 |
+ # 3) Null paths are banned because the loader will search $PWD when |
211 |
+ # it finds null paths. |
212 |
+ local forbidden_dirs="${PORTAGE_BUILDDIR}" |
213 |
+ if [[ -n "${ROOT}" && "${ROOT}" != "/" ]]; then |
214 |
+ forbidden_dirs+=" ${ROOT}" |
215 |
+ fi |
216 |
+ local dir l rpath_files=$(scanelf -F '%F:%r' -qBR "${ED}") |
217 |
+ f="" |
218 |
+ for dir in ${forbidden_dirs}; do |
219 |
+ for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do |
220 |
+ f+=" ${l%%:*}\n" |
221 |
+ if ! has stricter ${FEATURES}; then |
222 |
+ __vecho "Auto fixing rpaths for ${l%%:*}" |
223 |
+ TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null |
224 |
+ fi |
225 |
+ done |
226 |
+ done |
227 |
+ |
228 |
+ # Reject set*id binaries with $ORIGIN in RPATH #260331 |
229 |
+ x=$( |
230 |
+ find "${ED}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \ |
231 |
+ xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN' |
232 |
+ ) |
233 |
+ |
234 |
+ # Print QA notice. |
235 |
+ if [[ -n ${f}${x} ]] ; then |
236 |
+ __vecho -ne '\n' |
237 |
+ eqawarn "QA Notice: The following files contain insecure RUNPATHs" |
238 |
+ eqawarn " Please file a bug about this at http://bugs.gentoo.org/" |
239 |
+ eqawarn " with the maintaining herd of the package." |
240 |
+ eqawarn "${f}${f:+${x:+\n}}${x}" |
241 |
+ __vecho -ne '\n' |
242 |
+ if [[ -n ${x} ]] || has stricter ${FEATURES} ; then |
243 |
+ insecure_rpath=1 |
244 |
+ fi |
245 |
+ fi |
246 |
+ |
247 |
+ # TEXTRELs are baaaaaaaad |
248 |
+ # Allow devs to mark things as ignorable ... e.g. things that are |
249 |
+ # binary-only and upstream isn't cooperating (nvidia-glx) ... we |
250 |
+ # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ... |
251 |
+ # the former overrides the latter ... regexes allowed ! :) |
252 |
+ local qa_var="QA_TEXTRELS_${ARCH/-/_}" |
253 |
+ [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var} |
254 |
+ [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS="" |
255 |
+ export QA_TEXTRELS="${QA_TEXTRELS} lib*/modules/*.ko" |
256 |
+ f=$(scanelf -qyRF '%t %p' "${ED}" | grep -v 'usr/lib/debug/') |
257 |
+ if [[ -n ${f} ]] ; then |
258 |
+ scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log |
259 |
+ __vecho -ne '\n' |
260 |
+ eqawarn "QA Notice: The following files contain runtime text relocations" |
261 |
+ eqawarn " Text relocations force the dynamic linker to perform extra" |
262 |
+ eqawarn " work at startup, waste system resources, and may pose a security" |
263 |
+ eqawarn " risk. On some architectures, the code may not even function" |
264 |
+ eqawarn " properly, if at all." |
265 |
+ eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml" |
266 |
+ eqawarn " Please include the following list of files in your report:" |
267 |
+ eqawarn "${f}" |
268 |
+ __vecho -ne '\n' |
269 |
+ die_msg="${die_msg} textrels," |
270 |
+ sleep 1 |
271 |
+ fi |
272 |
+ |
273 |
+ # Also, executable stacks only matter on linux (and just glibc atm ...) |
274 |
+ f="" |
275 |
+ case ${CTARGET:-${CHOST}} in |
276 |
+ *-linux-gnu*) |
277 |
+ # Check for files with executable stacks, but only on arches which |
278 |
+ # are supported at the moment. Keep this list in sync with |
279 |
+ # http://www.gentoo.org/proj/en/hardened/gnu-stack.xml (Arch Status) |
280 |
+ case ${CTARGET:-${CHOST}} in |
281 |
+ arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*) |
282 |
+ # Allow devs to mark things as ignorable ... e.g. things |
283 |
+ # that are binary-only and upstream isn't cooperating ... |
284 |
+ # we allow ebuild authors to set QA_EXECSTACK_arch and |
285 |
+ # QA_EXECSTACK ... the former overrides the latter ... |
286 |
+ # regexes allowed ! :) |
287 |
+ |
288 |
+ qa_var="QA_EXECSTACK_${ARCH/-/_}" |
289 |
+ [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var} |
290 |
+ [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK="" |
291 |
+ qa_var="QA_WX_LOAD_${ARCH/-/_}" |
292 |
+ [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var} |
293 |
+ [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD="" |
294 |
+ export QA_EXECSTACK="${QA_EXECSTACK} lib*/modules/*.ko" |
295 |
+ export QA_WX_LOAD="${QA_WX_LOAD} lib*/modules/*.ko" |
296 |
+ f=$(scanelf -qyRAF '%e %p' "${ED}" | grep -v 'usr/lib/debug/') |
297 |
+ ;; |
298 |
+ esac |
299 |
+ ;; |
300 |
+ esac |
301 |
+ if [[ -n ${f} ]] ; then |
302 |
+ # One more pass to help devs track down the source |
303 |
+ scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log |
304 |
+ __vecho -ne '\n' |
305 |
+ eqawarn "QA Notice: The following files contain writable and executable sections" |
306 |
+ eqawarn " Files with such sections will not work properly (or at all!) on some" |
307 |
+ eqawarn " architectures/operating systems. A bug should be filed at" |
308 |
+ eqawarn " http://bugs.gentoo.org/ to make sure the issue is fixed." |
309 |
+ eqawarn " For more information, see http://hardened.gentoo.org/gnu-stack.xml" |
310 |
+ eqawarn " Please include the following list of files in your report:" |
311 |
+ eqawarn " Note: Bugs should be filed for the respective maintainers" |
312 |
+ eqawarn " of the package in question and not hardened@g.o." |
313 |
+ eqawarn "${f}" |
314 |
+ __vecho -ne '\n' |
315 |
+ die_msg="${die_msg} execstacks" |
316 |
+ sleep 1 |
317 |
+ fi |
318 |
+ |
319 |
+ if [[ ${insecure_rpath} -eq 1 ]] ; then |
320 |
+ die "Aborting due to serious QA concerns with RUNPATH/RPATH" |
321 |
+ elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then |
322 |
+ die "Aborting due to QA concerns: ${die_msg}" |
323 |
+ fi |
324 |
+ fi |
325 |
+} |
326 |
+ |
327 |
+elf_check |
328 |
+: # guarantee successful exit |
329 |
+ |
330 |
+# vim:ft=sh |
331 |
diff --git a/bin/install-qa-check.d/10ignored-flags b/bin/install-qa-check.d/10ignored-flags |
332 |
new file mode 100644 |
333 |
index 0000000..7aa9eb6 |
334 |
--- /dev/null |
335 |
+++ b/bin/install-qa-check.d/10ignored-flags |
336 |
@@ -0,0 +1,99 @@ |
337 |
+# QA checks for ignored *FLAGS. |
338 |
+ |
339 |
+ignored_flag_check() { |
340 |
+ type -P scanelf > /dev/null || return |
341 |
+ has binchecks ${RESTRICT} && return |
342 |
+ |
343 |
+ local qa_var="QA_FLAGS_IGNORED_${ARCH/-/_}" |
344 |
+ eval "[[ -n \${!qa_var} ]] && QA_FLAGS_IGNORED=(\"\${${qa_var}[@]}\")" |
345 |
+ if [[ ${#QA_FLAGS_IGNORED[@]} -eq 1 ]] ; then |
346 |
+ local shopts=$- |
347 |
+ set -o noglob |
348 |
+ QA_FLAGS_IGNORED=(${QA_FLAGS_IGNORED}) |
349 |
+ set +o noglob |
350 |
+ set -${shopts} |
351 |
+ fi |
352 |
+ |
353 |
+ local f x |
354 |
+ |
355 |
+ # Check for files built without respecting *FLAGS. Note that |
356 |
+ # -frecord-gcc-switches must be in all *FLAGS variables, in |
357 |
+ # order to avoid false positive results here. |
358 |
+ # NOTE: This check must execute before prepall/prepstrip, since |
359 |
+ # prepstrip strips the .GCC.command.line sections. |
360 |
+ if [[ "${CFLAGS}" == *-frecord-gcc-switches* ]] && \ |
361 |
+ [[ "${CXXFLAGS}" == *-frecord-gcc-switches* ]] && \ |
362 |
+ [[ "${FFLAGS}" == *-frecord-gcc-switches* ]] && \ |
363 |
+ [[ "${FCFLAGS}" == *-frecord-gcc-switches* ]] ; then |
364 |
+ rm -f "${T}"/scanelf-ignored-CFLAGS.log |
365 |
+ for x in $(scanelf -qyRF '#k%p' -k '!.GCC.command.line' "${ED}") ; do |
366 |
+ # Separate out file types that are known to support |
367 |
+ # .GCC.command.line sections, using the `file` command |
368 |
+ # similar to how prepstrip uses it. |
369 |
+ f=$(file "${x}") || continue |
370 |
+ [[ -z ${f} ]] && continue |
371 |
+ if [[ ${f} == *"SB executable"* || |
372 |
+ ${f} == *"SB shared object"* ]] ; then |
373 |
+ echo "${x}" >> "${T}"/scanelf-ignored-CFLAGS.log |
374 |
+ fi |
375 |
+ done |
376 |
+ |
377 |
+ if [[ -f "${T}"/scanelf-ignored-CFLAGS.log ]] ; then |
378 |
+ |
379 |
+ if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then |
380 |
+ for x in "${QA_FLAGS_IGNORED[@]}" ; do |
381 |
+ sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-CFLAGS.log |
382 |
+ done |
383 |
+ fi |
384 |
+ # Filter anything under /usr/lib/debug/ in order to avoid |
385 |
+ # duplicate warnings for splitdebug files. |
386 |
+ sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \ |
387 |
+ -i "${T}"/scanelf-ignored-CFLAGS.log |
388 |
+ f=$(<"${T}"/scanelf-ignored-CFLAGS.log) |
389 |
+ if [[ -n ${f} ]] ; then |
390 |
+ __vecho -ne '\n' |
391 |
+ eqawarn "${BAD}QA Notice: Files built without respecting CFLAGS have been detected${NORMAL}" |
392 |
+ eqawarn " Please include the following list of files in your report:" |
393 |
+ eqawarn "${f}" |
394 |
+ __vecho -ne '\n' |
395 |
+ sleep 1 |
396 |
+ else |
397 |
+ rm -f "${T}"/scanelf-ignored-CFLAGS.log |
398 |
+ fi |
399 |
+ fi |
400 |
+ fi |
401 |
+ |
402 |
+ # Check for files built without respecting LDFLAGS |
403 |
+ if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && \ |
404 |
+ ! has binchecks ${RESTRICT} ; then |
405 |
+ f=$(scanelf -qyRF '#k%p' -k .hash "${ED}") |
406 |
+ if [[ -n ${f} ]] ; then |
407 |
+ echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log |
408 |
+ if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then |
409 |
+ for x in "${QA_FLAGS_IGNORED[@]}" ; do |
410 |
+ sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log |
411 |
+ done |
412 |
+ fi |
413 |
+ # Filter anything under /usr/lib/debug/ in order to avoid |
414 |
+ # duplicate warnings for splitdebug files. |
415 |
+ sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \ |
416 |
+ -i "${T}"/scanelf-ignored-LDFLAGS.log |
417 |
+ f=$(<"${T}"/scanelf-ignored-LDFLAGS.log) |
418 |
+ if [[ -n ${f} ]] ; then |
419 |
+ __vecho -ne '\n' |
420 |
+ eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}" |
421 |
+ eqawarn " Please include the following list of files in your report:" |
422 |
+ eqawarn "${f}" |
423 |
+ __vecho -ne '\n' |
424 |
+ sleep 1 |
425 |
+ else |
426 |
+ rm -f "${T}"/scanelf-ignored-LDFLAGS.log |
427 |
+ fi |
428 |
+ fi |
429 |
+ fi |
430 |
+} |
431 |
+ |
432 |
+ignored_flag_check |
433 |
+: # guarantee successful exit |
434 |
+ |
435 |
+# vim:ft=sh |
436 |
diff --git a/bin/install-qa-check.d/20deprecated-directories b/bin/install-qa-check.d/20deprecated-directories |
437 |
new file mode 100644 |
438 |
index 0000000..fb82bfe |
439 |
--- /dev/null |
440 |
+++ b/bin/install-qa-check.d/20deprecated-directories |
441 |
@@ -0,0 +1,18 @@ |
442 |
+# Check for deprecated directories |
443 |
+ |
444 |
+deprecated_dir_check() { |
445 |
+ local x f= |
446 |
+ for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do |
447 |
+ [[ -d ${ED}/$x ]] && f+=" $x\n" |
448 |
+ done |
449 |
+ if [[ -n $f ]] ; then |
450 |
+ eqawarn "QA Notice: This ebuild installs into the following deprecated directories:" |
451 |
+ eqawarn |
452 |
+ eqawarn "$f" |
453 |
+ fi |
454 |
+} |
455 |
+ |
456 |
+deprecated_dir_check |
457 |
+: # guarantee successful exit |
458 |
+ |
459 |
+# vim:ft=sh |
460 |
diff --git a/bin/install-qa-check.d/20runtime-directories b/bin/install-qa-check.d/20runtime-directories |
461 |
new file mode 100644 |
462 |
index 0000000..2e21d6d |
463 |
--- /dev/null |
464 |
+++ b/bin/install-qa-check.d/20runtime-directories |
465 |
@@ -0,0 +1,26 @@ |
466 |
+# Check for directories that need to be created at runtime |
467 |
+ |
468 |
+runtime_dir_check() { |
469 |
+ # It's ok create these directories, but not to install into them. #493154 |
470 |
+ # TODO: We should add var/lib to this list. |
471 |
+ local x f= |
472 |
+ for x in var/cache var/lock var/run run ; do |
473 |
+ if [[ ! -L ${ED}/${x} && -d ${ED}/${x} ]] ; then |
474 |
+ if [[ -z $(find "${ED}/${x}" -prune -empty) ]] ; then |
475 |
+ f+=$(cd "${ED}"; find "${x}" -printf ' %p\n') |
476 |
+ fi |
477 |
+ fi |
478 |
+ done |
479 |
+ if [[ -n ${f} ]] ; then |
480 |
+ eqawarn "QA Notice: This ebuild installs into paths that should be created at runtime." |
481 |
+ eqawarn " To fix, simply do not install into these directories. Instead, your package" |
482 |
+ eqawarn " should create dirs on the fly at runtime as needed via init scripts/etc..." |
483 |
+ eqawarn |
484 |
+ eqawarn "${f}" |
485 |
+ fi |
486 |
+} |
487 |
+ |
488 |
+runtime_dir_check |
489 |
+: # guarantee successful exit |
490 |
+ |
491 |
+# vim:ft=sh |
492 |
diff --git a/bin/install-qa-check.d/60bash-completion b/bin/install-qa-check.d/60bash-completion |
493 |
new file mode 100644 |
494 |
index 0000000..c154761 |
495 |
--- /dev/null |
496 |
+++ b/bin/install-qa-check.d/60bash-completion |
497 |
@@ -0,0 +1,130 @@ |
498 |
+# QA checks for bash-completion files |
499 |
+ |
500 |
+bashcomp_check() { |
501 |
+ # Check for correct bash-completion install path. |
502 |
+ local syscompdir=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null) |
503 |
+ : ${syscompdir:=${EPREFIX}/usr/share/bash-completion/completions} |
504 |
+ |
505 |
+ local instcompdir |
506 |
+ if [[ -d ${ED}/usr/share/bash-completion/completions ]]; then |
507 |
+ instcompdir=${ED}/usr/share/bash-completion/completions |
508 |
+ elif [[ -d ${ED}/usr/share/bash-completion ]]; then |
509 |
+ if [[ ${syscompdir} != ${EPREFIX}/usr/share/bash-completion ]]; then |
510 |
+ eqawarn "Bash completions were installed in legacy location. Please update" |
511 |
+ eqawarn "the ebuild to get the install paths using bash-completion-r1.eclass." |
512 |
+ eqawarn |
513 |
+ fi |
514 |
+ |
515 |
+ instcompdir=${ED}/usr/share/bash-completion |
516 |
+ fi |
517 |
+ |
518 |
+ # Do a few QA tests on bash completions. |
519 |
+ if [[ -n ${instcompdir} && -f ${EROOT}/usr/share/bash-completion/bash_completion ]]; then |
520 |
+ _get_completions() { |
521 |
+ # source the file |
522 |
+ source "${1}" &>/dev/null |
523 |
+ |
524 |
+ [[ ${USED_HAVE} == yes ]] && echo '__HAVE_USED__' |
525 |
+ |
526 |
+ # print the completed commands |
527 |
+ while read -a args; do |
528 |
+ [[ ${args[0]} == complete ]] || continue |
529 |
+ # command always comes last, one per line |
530 |
+ echo "${args[$(( ${#args[@]} - 1))]}" |
531 |
+ done < <(complete -p) |
532 |
+ } |
533 |
+ |
534 |
+ # load the global helpers |
535 |
+ source "${EROOT}"/usr/share/bash-completion/bash_completion |
536 |
+ |
537 |
+ # clean up predefined completions |
538 |
+ complete -r |
539 |
+ |
540 |
+ # force all completions on |
541 |
+ _have() { |
542 |
+ return 0 |
543 |
+ } |
544 |
+ |
545 |
+ local USED_HAVE=no |
546 |
+ # add a replacement for have() |
547 |
+ have() { |
548 |
+ USED_HAVE=yes |
549 |
+ |
550 |
+ unset -v have |
551 |
+ _have ${1} && have=yes |
552 |
+ } |
553 |
+ |
554 |
+ local f c completions |
555 |
+ local all_compls=() |
556 |
+ local all_files=() |
557 |
+ local qa_warnings=() |
558 |
+ |
559 |
+ for f in "${instcompdir}"/*; do |
560 |
+ # ignore directories and other non-files |
561 |
+ [[ ! -f ${f} ]] && continue |
562 |
+ |
563 |
+ # skip the common code file |
564 |
+ # (in case we're run in /usr/share/bash-completion) |
565 |
+ [[ ${f##*/} == bash_completion ]] && continue |
566 |
+ |
567 |
+ completions=( $(_get_completions "${f}") ) |
568 |
+ |
569 |
+ if [[ ${completions[0]} == __HAVE_USED__ ]]; then |
570 |
+ qa_warnings+=( |
571 |
+ "${f##*/}: 'have' command is deprecated and must not be used." |
572 |
+ ) |
573 |
+ unset 'completions[0]' |
574 |
+ fi |
575 |
+ |
576 |
+ if [[ -z ${completions[@]} ]]; then |
577 |
+ qa_warnings+=( |
578 |
+ "${f##*/}: does not define any completions (failed to source?)." |
579 |
+ ) |
580 |
+ continue |
581 |
+ fi |
582 |
+ |
583 |
+ for c in "${completions[@]}"; do |
584 |
+ if [[ ${c} == /* ]]; then |
585 |
+ qa_warnings+=( |
586 |
+ "${f##*/}: absolute paths can not be used for completions (on '${c}')." |
587 |
+ ) |
588 |
+ else |
589 |
+ all_compls+=( "${c}" ) |
590 |
+ fi |
591 |
+ done |
592 |
+ |
593 |
+ if ! has "${f##*/}" "${all_compls[@]}"; then |
594 |
+ qa_warnings+=( |
595 |
+ "${f##*/}: incorrect name, no completions for '${f##*/}' command defined." |
596 |
+ ) |
597 |
+ fi |
598 |
+ |
599 |
+ all_files+=( "${f##*/}" ) |
600 |
+ done |
601 |
+ |
602 |
+ for c in "${all_compls[@]}"; do |
603 |
+ if ! has "${c}" "${all_files[@]}"; then |
604 |
+ qa_warnings+=( |
605 |
+ "${c}: missing alias (symlink) for completed command." |
606 |
+ ) |
607 |
+ fi |
608 |
+ done |
609 |
+ |
610 |
+ if [[ -n ${qa_warnings[@]} ]]; then |
611 |
+ eqawarn "Problems with installed bash completions were found:" |
612 |
+ eqawarn |
613 |
+ for c in "${qa_warnings[@]}"; do |
614 |
+ eqawarn " ${c}" |
615 |
+ done |
616 |
+ eqawarn |
617 |
+ eqawarn "For more details on installing bash-completions, please see:" |
618 |
+ eqawarn "https://wiki.gentoo.org/wiki/Bash/Installing_completion_files" |
619 |
+ eqawarn |
620 |
+ fi |
621 |
+ fi |
622 |
+} |
623 |
+ |
624 |
+bashcomp_check |
625 |
+: # guarantee successful exit |
626 |
+ |
627 |
+# vim:ft=sh |
628 |
diff --git a/bin/install-qa-check.d/60openrc b/bin/install-qa-check.d/60openrc |
629 |
new file mode 100644 |
630 |
index 0000000..9b7fc6d |
631 |
--- /dev/null |
632 |
+++ b/bin/install-qa-check.d/60openrc |
633 |
@@ -0,0 +1,41 @@ |
634 |
+# QA checks for OpenRC init.d files. |
635 |
+ |
636 |
+openrc_check() { |
637 |
+ # Sanity check syntax errors in init.d scripts |
638 |
+ local d i |
639 |
+ for d in /etc/conf.d /etc/init.d ; do |
640 |
+ [[ -d ${ED}/${d} ]] || continue |
641 |
+ for i in "${ED}"/${d}/* ; do |
642 |
+ [[ -L ${i} ]] && continue |
643 |
+ # if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist |
644 |
+ [[ ! -e ${i} ]] && continue |
645 |
+ if [[ ${d} == /etc/init.d && ${i} != *.sh ]] ; then |
646 |
+ # skip non-shell-script for bug #451386 |
647 |
+ [[ $(head -n1 "${i}") =~ ^#!.*[[:space:]/](runscript|sh)$ ]] || continue |
648 |
+ fi |
649 |
+ bash -n "${i}" || die "The init.d file has syntax errors: ${i}" |
650 |
+ done |
651 |
+ done |
652 |
+ |
653 |
+ local checkbashisms=$(type -P checkbashisms) |
654 |
+ if [[ -n ${checkbashisms} ]] ; then |
655 |
+ for d in /etc/init.d ; do |
656 |
+ [[ -d ${ED}${d} ]] || continue |
657 |
+ for i in "${ED}${d}"/* ; do |
658 |
+ [[ -e ${i} ]] || continue |
659 |
+ [[ -L ${i} ]] && continue |
660 |
+ f=$("${checkbashisms}" -f "${i}" 2>&1) |
661 |
+ [[ $? != 0 && -n ${f} ]] || continue |
662 |
+ eqawarn "QA Notice: shell script appears to use non-POSIX feature(s):" |
663 |
+ while read -r ; |
664 |
+ do eqawarn " ${REPLY}" |
665 |
+ done <<< "${f//${ED}}" |
666 |
+ done |
667 |
+ done |
668 |
+ fi |
669 |
+} |
670 |
+ |
671 |
+openrc_check |
672 |
+: # guarantee successful exit |
673 |
+ |
674 |
+# vim:ft=sh |
675 |
diff --git a/bin/install-qa-check.d/60pkgconfig b/bin/install-qa-check.d/60pkgconfig |
676 |
new file mode 100644 |
677 |
index 0000000..1b34c04 |
678 |
--- /dev/null |
679 |
+++ b/bin/install-qa-check.d/60pkgconfig |
680 |
@@ -0,0 +1,15 @@ |
681 |
+# Check for pkg-config file issues |
682 |
+ |
683 |
+pkgconfig_check() { |
684 |
+ # Look for leaking LDFLAGS into pkg-config files |
685 |
+ local f=$(egrep -sH '^Libs.*-Wl,(-O[012]|--hash-style)' "${ED}"/usr/*/pkgconfig/*.pc) |
686 |
+ if [[ -n ${f} ]] ; then |
687 |
+ eqawarn "QA Notice: pkg-config files with wrong LDFLAGS detected:" |
688 |
+ eqawarn "${f//${D}}" |
689 |
+ fi |
690 |
+} |
691 |
+ |
692 |
+pkgconfig_check |
693 |
+: # guarantee successful exit |
694 |
+ |
695 |
+# vim:ft=sh |
696 |
diff --git a/bin/install-qa-check.d/60pngfix b/bin/install-qa-check.d/60pngfix |
697 |
new file mode 100644 |
698 |
index 0000000..8d53040 |
699 |
--- /dev/null |
700 |
+++ b/bin/install-qa-check.d/60pngfix |
701 |
@@ -0,0 +1,35 @@ |
702 |
+# Check for issues with PNG files |
703 |
+ |
704 |
+pngfix_check() { |
705 |
+ local pngfix=$(type -P pngfix) |
706 |
+ if [[ -n ${pngfix} ]] ; then |
707 |
+ local pngout=() |
708 |
+ local next |
709 |
+ |
710 |
+ while read -r -a pngout ; do |
711 |
+ local error="" |
712 |
+ |
713 |
+ case "${pngout[1]}" in |
714 |
+ CHK) |
715 |
+ error='invalid checksum' |
716 |
+ ;; |
717 |
+ TFB) |
718 |
+ error='broken IDAT window length' |
719 |
+ ;; |
720 |
+ esac |
721 |
+ |
722 |
+ if [[ -n ${error} ]] ; then |
723 |
+ if [[ -z ${next} ]] ; then |
724 |
+ eqawarn "QA Notice: broken .png files found:" |
725 |
+ next=1 |
726 |
+ fi |
727 |
+ eqawarn " ${pngout[@]:7}: ${error}" |
728 |
+ fi |
729 |
+ done < <(find "${ED}" -type f -name '*.png' -exec "${pngfix}" {} +) |
730 |
+ fi |
731 |
+} |
732 |
+ |
733 |
+pngfix_check |
734 |
+: # guarantee successful exit |
735 |
+ |
736 |
+# vim:ft=sh |
737 |
diff --git a/bin/install-qa-check.d/60systemd b/bin/install-qa-check.d/60systemd |
738 |
new file mode 100644 |
739 |
index 0000000..f134a30 |
740 |
--- /dev/null |
741 |
+++ b/bin/install-qa-check.d/60systemd |
742 |
@@ -0,0 +1,25 @@ |
743 |
+# QA checks for systemd units. |
744 |
+ |
745 |
+systemd_check() { |
746 |
+ local systemddir f |
747 |
+ |
748 |
+ # Common mistakes in systemd service files. |
749 |
+ if type -P pkg-config >/dev/null && pkg-config --exists systemd; then |
750 |
+ systemddir=$(pkg-config --variable=systemdsystemunitdir systemd) |
751 |
+ else |
752 |
+ systemddir=/usr/lib/systemd/system |
753 |
+ fi |
754 |
+ if [[ -d ${ED%/}${systemddir} ]]; then |
755 |
+ f=$(grep -sH '^EnvironmentFile.*=.*/etc/conf\.d' "${ED%/}${systemddir}"/*.service) |
756 |
+ if [[ -n ${f} ]] ; then |
757 |
+ eqawarn "QA Notice: systemd units using /etc/conf.d detected:" |
758 |
+ eqawarn "${f//${D}}" |
759 |
+ eqawarn "See: https://wiki.gentoo.org/wiki/Project:Systemd/conf.d_files" |
760 |
+ fi |
761 |
+ fi |
762 |
+} |
763 |
+ |
764 |
+systemd_check |
765 |
+: # guarantee successful exit |
766 |
+ |
767 |
+# vim:ft=sh |
768 |
diff --git a/bin/install-qa-check.d/60udev b/bin/install-qa-check.d/60udev |
769 |
new file mode 100644 |
770 |
index 0000000..4327d06 |
771 |
--- /dev/null |
772 |
+++ b/bin/install-qa-check.d/60udev |
773 |
@@ -0,0 +1,21 @@ |
774 |
+# Check udev rule installs |
775 |
+ |
776 |
+udev_check() { |
777 |
+ set +f |
778 |
+ local x f= |
779 |
+ for x in "${ED}etc/udev/rules.d/"* "${ED}lib"*"/udev/rules.d/"* ; do |
780 |
+ [[ -e ${x} ]] || continue |
781 |
+ [[ ${x} == ${ED}lib/udev/rules.d/* ]] && continue |
782 |
+ f+=" ${x#${ED}}\n" |
783 |
+ done |
784 |
+ if [[ -n $f ]] ; then |
785 |
+ eqawarn "QA Notice: udev rules should be installed in /lib/udev/rules.d:" |
786 |
+ eqawarn |
787 |
+ eqawarn "$f" |
788 |
+ fi |
789 |
+} |
790 |
+ |
791 |
+udev_check |
792 |
+: # guarantee successful exit |
793 |
+ |
794 |
+# vim:ft=sh |
795 |
diff --git a/bin/install-qa-check.d/80libraries b/bin/install-qa-check.d/80libraries |
796 |
new file mode 100644 |
797 |
index 0000000..3977bae |
798 |
--- /dev/null |
799 |
+++ b/bin/install-qa-check.d/80libraries |
800 |
@@ -0,0 +1,158 @@ |
801 |
+# Check for issues with installed libraries |
802 |
+ |
803 |
+lib_check() { |
804 |
+ local f x i j |
805 |
+ |
806 |
+ if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then |
807 |
+ # Check for shared libraries lacking SONAMEs |
808 |
+ local qa_var="QA_SONAME_${ARCH/-/_}" |
809 |
+ eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")" |
810 |
+ f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:") |
811 |
+ if [[ -n ${f} ]] ; then |
812 |
+ echo "${f}" > "${T}"/scanelf-missing-SONAME.log |
813 |
+ if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then |
814 |
+ if [[ ${#QA_SONAME[@]} -gt 1 ]] ; then |
815 |
+ for x in "${QA_SONAME[@]}" ; do |
816 |
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log |
817 |
+ done |
818 |
+ else |
819 |
+ local shopts=$- |
820 |
+ set -o noglob |
821 |
+ for x in ${QA_SONAME} ; do |
822 |
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log |
823 |
+ done |
824 |
+ set +o noglob |
825 |
+ set -${shopts} |
826 |
+ fi |
827 |
+ fi |
828 |
+ sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log |
829 |
+ f=$(<"${T}"/scanelf-missing-SONAME.log) |
830 |
+ if [[ -n ${f} ]] ; then |
831 |
+ __vecho -ne '\n' |
832 |
+ eqawarn "QA Notice: The following shared libraries lack a SONAME" |
833 |
+ eqawarn "${f}" |
834 |
+ __vecho -ne '\n' |
835 |
+ sleep 1 |
836 |
+ else |
837 |
+ rm -f "${T}"/scanelf-missing-SONAME.log |
838 |
+ fi |
839 |
+ fi |
840 |
+ |
841 |
+ # Check for shared libraries lacking NEEDED entries |
842 |
+ qa_var="QA_DT_NEEDED_${ARCH/-/_}" |
843 |
+ eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")" |
844 |
+ f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:") |
845 |
+ if [[ -n ${f} ]] ; then |
846 |
+ echo "${f}" > "${T}"/scanelf-missing-NEEDED.log |
847 |
+ if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then |
848 |
+ if [[ ${#QA_DT_NEEDED[@]} -gt 1 ]] ; then |
849 |
+ for x in "${QA_DT_NEEDED[@]}" ; do |
850 |
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log |
851 |
+ done |
852 |
+ else |
853 |
+ local shopts=$- |
854 |
+ set -o noglob |
855 |
+ for x in ${QA_DT_NEEDED} ; do |
856 |
+ sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log |
857 |
+ done |
858 |
+ set +o noglob |
859 |
+ set -${shopts} |
860 |
+ fi |
861 |
+ fi |
862 |
+ sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log |
863 |
+ f=$(<"${T}"/scanelf-missing-NEEDED.log) |
864 |
+ if [[ -n ${f} ]] ; then |
865 |
+ __vecho -ne '\n' |
866 |
+ eqawarn "QA Notice: The following shared libraries lack NEEDED entries" |
867 |
+ eqawarn "${f}" |
868 |
+ __vecho -ne '\n' |
869 |
+ sleep 1 |
870 |
+ else |
871 |
+ rm -f "${T}"/scanelf-missing-NEEDED.log |
872 |
+ fi |
873 |
+ fi |
874 |
+ fi |
875 |
+ |
876 |
+ # this should help to ensure that all (most?) shared libraries are executable |
877 |
+ # and that all libtool scripts / static libraries are not executable |
878 |
+ for i in "${ED}"opt/*/lib* \ |
879 |
+ "${ED}"lib* \ |
880 |
+ "${ED}"usr/lib* ; do |
881 |
+ [[ ! -d ${i} ]] && continue |
882 |
+ |
883 |
+ for j in "${i}"/*.so.* "${i}"/*.so ; do |
884 |
+ [[ ! -e ${j} ]] && continue |
885 |
+ [[ -L ${j} ]] && continue |
886 |
+ [[ -x ${j} ]] && continue |
887 |
+ __vecho "making executable: ${j#${ED}}" |
888 |
+ chmod +x "${j}" |
889 |
+ done |
890 |
+ |
891 |
+ for j in "${i}"/*.a "${i}"/*.la ; do |
892 |
+ [[ ! -e ${j} ]] && continue |
893 |
+ [[ -L ${j} ]] && continue |
894 |
+ [[ ! -x ${j} ]] && continue |
895 |
+ __vecho "removing executable bit: ${j#${ED}}" |
896 |
+ chmod -x "${j}" |
897 |
+ done |
898 |
+ |
899 |
+ for j in "${i}"/*.{a,dll,dylib,sl,so}.* "${i}"/*.{a,dll,dylib,sl,so} ; do |
900 |
+ [[ ! -e ${j} ]] && continue |
901 |
+ [[ ! -L ${j} ]] && continue |
902 |
+ linkdest=$(readlink "${j}") |
903 |
+ if [[ ${linkdest} == /* ]] ; then |
904 |
+ __vecho -ne '\n' |
905 |
+ eqawarn "QA Notice: Found an absolute symlink in a library directory:" |
906 |
+ eqawarn " ${j#${D}} -> ${linkdest}" |
907 |
+ eqawarn " It should be a relative symlink if in the same directory" |
908 |
+ eqawarn " or a linker script if it crosses the /usr boundary." |
909 |
+ fi |
910 |
+ done |
911 |
+ done |
912 |
+ |
913 |
+ # When installing static libraries into /usr/lib and shared libraries into |
914 |
+ # /lib, we have to make sure we have a linker script in /usr/lib along side |
915 |
+ # the static library, or gcc will utilize the static lib when linking :(. |
916 |
+ # http://bugs.gentoo.org/4411 |
917 |
+ local abort="no" |
918 |
+ local a s |
919 |
+ for a in "${ED}"usr/lib*/*.a ; do |
920 |
+ s=${a%.a}.so |
921 |
+ if [[ ! -e ${s} ]] ; then |
922 |
+ s=${s%usr/*}${s##*/usr/} |
923 |
+ if [[ -e ${s} ]] ; then |
924 |
+ __vecho -ne '\n' |
925 |
+ eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}" |
926 |
+ abort="yes" |
927 |
+ fi |
928 |
+ fi |
929 |
+ done |
930 |
+ [[ ${abort} == "yes" ]] && die "add those ldscripts" |
931 |
+ |
932 |
+ # Make sure people don't store libtool files or static libs in /lib |
933 |
+ f=$(ls "${ED}"lib*/*.{a,la} 2>/dev/null) |
934 |
+ if [[ -n ${f} ]] ; then |
935 |
+ __vecho -ne '\n' |
936 |
+ eqawarn "QA Notice: Excessive files found in the / partition" |
937 |
+ eqawarn "${f}" |
938 |
+ __vecho -ne '\n' |
939 |
+ die "static archives (*.a) and libtool library files (*.la) belong in /usr/lib*, not /lib*" |
940 |
+ fi |
941 |
+ |
942 |
+ # Verify that the libtool files don't contain bogus $D entries. |
943 |
+ local abort=no gentoo_bug=no always_overflow=no |
944 |
+ for a in "${ED}"usr/lib*/*.la ; do |
945 |
+ s=${a##*/} |
946 |
+ if grep -qs "${ED}" "${a}" ; then |
947 |
+ __vecho -ne '\n' |
948 |
+ eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths" |
949 |
+ abort="yes" |
950 |
+ fi |
951 |
+ done |
952 |
+ [[ ${abort} == "yes" ]] && die "soiled libtool library files found" |
953 |
+} |
954 |
+ |
955 |
+lib_check |
956 |
+: # guarantee successful exit |
957 |
+ |
958 |
+# vim:ft=sh |
959 |
diff --git a/bin/install-qa-check.d/80multilib-strict b/bin/install-qa-check.d/80multilib-strict |
960 |
new file mode 100644 |
961 |
index 0000000..f944be9 |
962 |
--- /dev/null |
963 |
+++ b/bin/install-qa-check.d/80multilib-strict |
964 |
@@ -0,0 +1,50 @@ |
965 |
+# Strict multilib directory checks |
966 |
+multilib_strict_check() { |
967 |
+ if has multilib-strict ${FEATURES} && \ |
968 |
+ [[ -x /usr/bin/file && -x /usr/bin/find ]] && \ |
969 |
+ [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]] |
970 |
+ then |
971 |
+ rm -f "${T}/multilib-strict.log" |
972 |
+ local abort=no dir file |
973 |
+ MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g') |
974 |
+ for dir in ${MULTILIB_STRICT_DIRS} ; do |
975 |
+ [[ -d ${ED}/${dir} ]] || continue |
976 |
+ for file in $(find ${ED}/${dir} -type f | grep -v "^${ED}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do |
977 |
+ if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then |
978 |
+ echo "${file#${ED}//}" >> "${T}/multilib-strict.log" |
979 |
+ fi |
980 |
+ done |
981 |
+ done |
982 |
+ |
983 |
+ if [[ -s ${T}/multilib-strict.log ]] ; then |
984 |
+ if [[ ${#QA_MULTILIB_PATHS[@]} -eq 1 ]] ; then |
985 |
+ local shopts=$- |
986 |
+ set -o noglob |
987 |
+ QA_MULTILIB_PATHS=(${QA_MULTILIB_PATHS}) |
988 |
+ set +o noglob |
989 |
+ set -${shopts} |
990 |
+ fi |
991 |
+ if [ "${QA_STRICT_MULTILIB_PATHS-unset}" = unset ] ; then |
992 |
+ local x |
993 |
+ for x in "${QA_MULTILIB_PATHS[@]}" ; do |
994 |
+ sed -e "s#^${x#/}\$##" -i "${T}/multilib-strict.log" |
995 |
+ done |
996 |
+ sed -e "/^\$/d" -i "${T}/multilib-strict.log" |
997 |
+ fi |
998 |
+ if [[ -s ${T}/multilib-strict.log ]] ; then |
999 |
+ abort=yes |
1000 |
+ echo "Files matching a file type that is not allowed:" |
1001 |
+ while read -r ; do |
1002 |
+ echo " ${REPLY}" |
1003 |
+ done < "${T}/multilib-strict.log" |
1004 |
+ fi |
1005 |
+ fi |
1006 |
+ |
1007 |
+ [[ ${abort} == yes ]] && die "multilib-strict check failed!" |
1008 |
+ fi |
1009 |
+} |
1010 |
+ |
1011 |
+multilib_strict_check |
1012 |
+: # guarantee successful exit |
1013 |
+ |
1014 |
+# vim:ft=sh |
1015 |
diff --git a/bin/install-qa-check.d/90gcc-warnings b/bin/install-qa-check.d/90gcc-warnings |
1016 |
new file mode 100644 |
1017 |
index 0000000..ae39485 |
1018 |
--- /dev/null |
1019 |
+++ b/bin/install-qa-check.d/90gcc-warnings |
1020 |
@@ -0,0 +1,145 @@ |
1021 |
+# Check for important gcc warning |
1022 |
+ |
1023 |
+gcc_warn_check() { |
1024 |
+ local f |
1025 |
+ |
1026 |
+ # Evaluate misc gcc warnings |
1027 |
+ if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then |
1028 |
+ # In debug mode, this variable definition and corresponding grep calls |
1029 |
+ # will produce false positives if they're shown in the trace. |
1030 |
+ local reset_debug=0 |
1031 |
+ if [[ ${-/x/} != $- ]] ; then |
1032 |
+ set +x |
1033 |
+ reset_debug=1 |
1034 |
+ fi |
1035 |
+ local m msgs=( |
1036 |
+ ": warning: dereferencing type-punned pointer will break strict-aliasing rules" |
1037 |
+ ": warning: dereferencing pointer .* does break strict-aliasing rules" |
1038 |
+ ": warning: implicit declaration of function" |
1039 |
+ ": warning: incompatible implicit declaration of built-in function" |
1040 |
+ ": warning: is used uninitialized in this function" # we'll ignore "may" and "might" |
1041 |
+ ": warning: comparisons like X<=Y<=Z do not have their mathematical meaning" |
1042 |
+ ": warning: null argument where non-null required" |
1043 |
+ ": warning: array subscript is below array bounds" |
1044 |
+ ": warning: array subscript is above array bounds" |
1045 |
+ ": warning: attempt to free a non-heap object" |
1046 |
+ ": warning: .* called with .*bigger.* than .* destination buffer" |
1047 |
+ ": warning: call to .* will always overflow destination buffer" |
1048 |
+ ": warning: assuming pointer wraparound does not occur when comparing" |
1049 |
+ ": warning: hex escape sequence out of range" |
1050 |
+ ": warning: [^ ]*-hand operand of comma .*has no effect" |
1051 |
+ ": warning: converting to non-pointer type .* from NULL" |
1052 |
+ ": warning: NULL used in arithmetic" |
1053 |
+ ": warning: passing NULL to non-pointer argument" |
1054 |
+ ": warning: the address of [^ ]* will always evaluate as" |
1055 |
+ ": warning: the address of [^ ]* will never be NULL" |
1056 |
+ ": warning: too few arguments for format" |
1057 |
+ ": warning: reference to local variable .* returned" |
1058 |
+ ": warning: returning reference to temporary" |
1059 |
+ ": warning: function returns address of local variable" |
1060 |
+ ": warning: .*\\[-Wsizeof-pointer-memaccess\\]" |
1061 |
+ ": warning: .*\\[-Waggressive-loop-optimizations\\]" |
1062 |
+ # this may be valid code :/ |
1063 |
+ #": warning: multi-character character constant" |
1064 |
+ # need to check these two ... |
1065 |
+ #": warning: assuming signed overflow does not occur when" |
1066 |
+ #": warning: comparison with string literal results in unspecified behav" |
1067 |
+ # yacc/lex likes to trigger this one |
1068 |
+ #": warning: extra tokens at end of .* directive" |
1069 |
+ # only gcc itself triggers this ? |
1070 |
+ #": warning: .*noreturn.* function does return" |
1071 |
+ # these throw false positives when 0 is used instead of NULL |
1072 |
+ #": warning: missing sentinel in function call" |
1073 |
+ #": warning: not enough variable arguments to fit a sentinel" |
1074 |
+ ) |
1075 |
+ local abort="no" |
1076 |
+ local i=0 |
1077 |
+ local grep_cmd=grep |
1078 |
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep |
1079 |
+ while [[ -n ${msgs[${i}]} ]] ; do |
1080 |
+ m=${msgs[$((i++))]} |
1081 |
+ # force C locale to work around slow unicode locales #160234 |
1082 |
+ f=$(LC_ALL=C $grep_cmd "${m}" "${PORTAGE_LOG_FILE}") |
1083 |
+ if [[ -n ${f} ]] ; then |
1084 |
+ abort="yes" |
1085 |
+ # for now, don't make this fatal (see bug #337031) |
1086 |
+ #case "$m" in |
1087 |
+ # ": warning: call to .* will always overflow destination buffer") always_overflow=yes ;; |
1088 |
+ #esac |
1089 |
+ if [[ $always_overflow = yes ]] ; then |
1090 |
+ eerror |
1091 |
+ eerror "QA Notice: Package triggers severe warnings which indicate that it" |
1092 |
+ eerror " may exhibit random runtime failures." |
1093 |
+ eerror |
1094 |
+ eerror "${f}" |
1095 |
+ eerror |
1096 |
+ eerror " Please file a bug about this at http://bugs.gentoo.org/" |
1097 |
+ eerror " with the maintaining herd of the package." |
1098 |
+ eerror |
1099 |
+ else |
1100 |
+ __vecho -ne '\n' |
1101 |
+ eqawarn "QA Notice: Package triggers severe warnings which indicate that it" |
1102 |
+ eqawarn " may exhibit random runtime failures." |
1103 |
+ eqawarn "${f}" |
1104 |
+ __vecho -ne '\n' |
1105 |
+ fi |
1106 |
+ fi |
1107 |
+ done |
1108 |
+ local cat_cmd=cat |
1109 |
+ [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat |
1110 |
+ [[ $reset_debug = 1 ]] && set -x |
1111 |
+ # Use safe cwd, avoiding unsafe import for bug #469338. |
1112 |
+ f=$(cd "${PORTAGE_PYM_PATH}" ; $cat_cmd "${PORTAGE_LOG_FILE}" | \ |
1113 |
+ "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed") |
1114 |
+ if [[ -n ${f} ]] ; then |
1115 |
+ |
1116 |
+ # In the future this will be a forced "die". In preparation, |
1117 |
+ # increase the log level from "qa" to "eerror" so that people |
1118 |
+ # are aware this is a problem that must be fixed asap. |
1119 |
+ |
1120 |
+ # just warn on 32bit hosts but bail on 64bit hosts |
1121 |
+ case ${CHOST} in |
1122 |
+ alpha*|hppa64*|ia64*|powerpc64*|mips64*|sparc64*|sparcv9*|x86_64*) gentoo_bug=yes ;; |
1123 |
+ esac |
1124 |
+ |
1125 |
+ abort=yes |
1126 |
+ |
1127 |
+ if [[ $gentoo_bug = yes ]] ; then |
1128 |
+ eerror |
1129 |
+ eerror "QA Notice: Package triggers severe warnings which indicate that it" |
1130 |
+ eerror " will almost certainly crash on 64bit architectures." |
1131 |
+ eerror |
1132 |
+ eerror "${f}" |
1133 |
+ eerror |
1134 |
+ eerror " Please file a bug about this at http://bugs.gentoo.org/" |
1135 |
+ eerror " with the maintaining herd of the package." |
1136 |
+ eerror |
1137 |
+ else |
1138 |
+ __vecho -ne '\n' |
1139 |
+ eqawarn "QA Notice: Package triggers severe warnings which indicate that it" |
1140 |
+ eqawarn " will almost certainly crash on 64bit architectures." |
1141 |
+ eqawarn "${f}" |
1142 |
+ __vecho -ne '\n' |
1143 |
+ fi |
1144 |
+ |
1145 |
+ fi |
1146 |
+ if [[ ${abort} == "yes" ]] ; then |
1147 |
+ if [[ $gentoo_bug = yes || $always_overflow = yes ]] ; then |
1148 |
+ die "install aborted due to severe warnings shown above" |
1149 |
+ else |
1150 |
+ echo "Please do not file a Gentoo bug and instead" \ |
1151 |
+ "report the above QA issues directly to the upstream" \ |
1152 |
+ "developers of this software." | fmt -w 70 | \ |
1153 |
+ while read -r line ; do eqawarn "${line}" ; done |
1154 |
+ eqawarn "Homepage: ${HOMEPAGE}" |
1155 |
+ has stricter ${FEATURES} && \ |
1156 |
+ die "install aborted due to severe warnings shown above" |
1157 |
+ fi |
1158 |
+ fi |
1159 |
+ fi |
1160 |
+} |
1161 |
+ |
1162 |
+gcc_warn_check |
1163 |
+: # guarantee successful exit |
1164 |
+ |
1165 |
+# vim:ft=sh |
1166 |
diff --git a/bin/install-qa-check.d/90world-writable b/bin/install-qa-check.d/90world-writable |
1167 |
new file mode 100644 |
1168 |
index 0000000..771027e |
1169 |
--- /dev/null |
1170 |
+++ b/bin/install-qa-check.d/90world-writable |
1171 |
@@ -0,0 +1,25 @@ |
1172 |
+# Check for world-writable files |
1173 |
+ |
1174 |
+world_writable_check() { |
1175 |
+ # Now we look for all world writable files. |
1176 |
+ local unsafe_files=$(find "${ED}" -type f -perm -2 | sed -e "s:^${ED}:- :") |
1177 |
+ if [[ -n ${unsafe_files} ]] ; then |
1178 |
+ __vecho "QA Security Notice: world writable file(s):" |
1179 |
+ __vecho "${unsafe_files}" |
1180 |
+ __vecho "- This may or may not be a security problem, most of the time it is one." |
1181 |
+ __vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly." |
1182 |
+ sleep 1 |
1183 |
+ fi |
1184 |
+ |
1185 |
+ local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')' | sed -e "s:^${ED}:/:") |
1186 |
+ if [[ -n ${unsafe_files} ]] ; then |
1187 |
+ eqawarn "QA Notice: Unsafe files detected (set*id and world writable)" |
1188 |
+ eqawarn "${unsafe_files}" |
1189 |
+ die "Unsafe files found in \${D}. Portage will not install them." |
1190 |
+ fi |
1191 |
+} |
1192 |
+ |
1193 |
+world_writable_check |
1194 |
+: # guarantee successful exit |
1195 |
+ |
1196 |
+# vim:ft=sh |
1197 |
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh |
1198 |
index f6c3c1c..d701ba6 100755 |
1199 |
--- a/bin/misc-functions.sh |
1200 |
+++ b/bin/misc-functions.sh |
1201 |
@@ -170,63 +170,17 @@ install_qa_check() { |
1202 |
|
1203 |
cd "${ED}" || die "cd failed" |
1204 |
|
1205 |
- qa_var="QA_FLAGS_IGNORED_${ARCH/-/_}" |
1206 |
- eval "[[ -n \${!qa_var} ]] && QA_FLAGS_IGNORED=(\"\${${qa_var}[@]}\")" |
1207 |
- if [[ ${#QA_FLAGS_IGNORED[@]} -eq 1 ]] ; then |
1208 |
- local shopts=$- |
1209 |
- set -o noglob |
1210 |
- QA_FLAGS_IGNORED=(${QA_FLAGS_IGNORED}) |
1211 |
- set +o noglob |
1212 |
- set -${shopts} |
1213 |
- fi |
1214 |
- |
1215 |
- # Check for files built without respecting *FLAGS. Note that |
1216 |
- # -frecord-gcc-switches must be in all *FLAGS variables, in |
1217 |
- # order to avoid false positive results here. |
1218 |
- # NOTE: This check must execute before prepall/prepstrip, since |
1219 |
- # prepstrip strips the .GCC.command.line sections. |
1220 |
- if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT} && \ |
1221 |
- [[ "${CFLAGS}" == *-frecord-gcc-switches* ]] && \ |
1222 |
- [[ "${CXXFLAGS}" == *-frecord-gcc-switches* ]] && \ |
1223 |
- [[ "${FFLAGS}" == *-frecord-gcc-switches* ]] && \ |
1224 |
- [[ "${FCFLAGS}" == *-frecord-gcc-switches* ]] ; then |
1225 |
- rm -f "${T}"/scanelf-ignored-CFLAGS.log |
1226 |
- for x in $(scanelf -qyRF '#k%p' -k '!.GCC.command.line' "${ED}") ; do |
1227 |
- # Separate out file types that are known to support |
1228 |
- # .GCC.command.line sections, using the `file` command |
1229 |
- # similar to how prepstrip uses it. |
1230 |
- f=$(file "${x}") || continue |
1231 |
- [[ -z ${f} ]] && continue |
1232 |
- if [[ ${f} == *"SB executable"* || |
1233 |
- ${f} == *"SB shared object"* ]] ; then |
1234 |
- echo "${x}" >> "${T}"/scanelf-ignored-CFLAGS.log |
1235 |
- fi |
1236 |
- done |
1237 |
- |
1238 |
- if [[ -f "${T}"/scanelf-ignored-CFLAGS.log ]] ; then |
1239 |
- |
1240 |
- if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then |
1241 |
- for x in "${QA_FLAGS_IGNORED[@]}" ; do |
1242 |
- sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-CFLAGS.log |
1243 |
- done |
1244 |
- fi |
1245 |
- # Filter anything under /usr/lib/debug/ in order to avoid |
1246 |
- # duplicate warnings for splitdebug files. |
1247 |
- sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \ |
1248 |
- -i "${T}"/scanelf-ignored-CFLAGS.log |
1249 |
- f=$(<"${T}"/scanelf-ignored-CFLAGS.log) |
1250 |
- if [[ -n ${f} ]] ; then |
1251 |
- __vecho -ne '\n' |
1252 |
- eqawarn "${BAD}QA Notice: Files built without respecting CFLAGS have been detected${NORMAL}" |
1253 |
- eqawarn " Please include the following list of files in your report:" |
1254 |
- eqawarn "${f}" |
1255 |
- __vecho -ne '\n' |
1256 |
- sleep 1 |
1257 |
- else |
1258 |
- rm -f "${T}"/scanelf-ignored-CFLAGS.log |
1259 |
- fi |
1260 |
- fi |
1261 |
- fi |
1262 |
+ # Run QA checks from install-qa-check.d. |
1263 |
+ # Note: checks need to be run *before* stripping. |
1264 |
+ local f |
1265 |
+ # TODO: handle nullglob-like |
1266 |
+ for f in "${PORTAGE_BIN_PATH}"/install-qa-check.d/*; do |
1267 |
+ # Run in a subshell to treat it like external script, |
1268 |
+ # but use 'source' to pass all variables through. |
1269 |
+ ( |
1270 |
+ source "${f}" || eerror "Post-install QA check ${f##*/} failed to run" |
1271 |
+ ) |
1272 |
+ done |
1273 |
|
1274 |
export STRIP_MASK |
1275 |
prepall |
1276 |
@@ -234,290 +188,6 @@ install_qa_check() { |
1277 |
ecompressdir --dequeue |
1278 |
ecompress --dequeue |
1279 |
|
1280 |
- # Prefix specific checks |
1281 |
- [[ ${ED} != ${D} ]] && install_qa_check_prefix |
1282 |
- |
1283 |
- f= |
1284 |
- for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do |
1285 |
- [[ -d ${ED}/$x ]] && f+=" $x\n" |
1286 |
- done |
1287 |
- if [[ -n $f ]] ; then |
1288 |
- eqawarn "QA Notice: This ebuild installs into the following deprecated directories:" |
1289 |
- eqawarn |
1290 |
- eqawarn "$f" |
1291 |
- fi |
1292 |
- |
1293 |
- # It's ok create these directories, but not to install into them. #493154 |
1294 |
- # TODO: We should add var/lib to this list. |
1295 |
- f= |
1296 |
- for x in var/cache var/lock var/run run ; do |
1297 |
- if [[ ! -L ${ED}/${x} && -d ${ED}/${x} ]] ; then |
1298 |
- if [[ -z $(find "${ED}/${x}" -prune -empty) ]] ; then |
1299 |
- f+=$(cd "${ED}"; find "${x}" -printf ' %p\n') |
1300 |
- fi |
1301 |
- fi |
1302 |
- done |
1303 |
- if [[ -n ${f} ]] ; then |
1304 |
- eqawarn "QA Notice: This ebuild installs into paths that should be created at runtime." |
1305 |
- eqawarn " To fix, simply do not install into these directories. Instead, your package" |
1306 |
- eqawarn " should create dirs on the fly at runtime as needed via init scripts/etc..." |
1307 |
- eqawarn |
1308 |
- eqawarn "${f}" |
1309 |
- fi |
1310 |
- |
1311 |
- set +f |
1312 |
- f= |
1313 |
- for x in "${ED}etc/udev/rules.d/"* "${ED}lib"*"/udev/rules.d/"* ; do |
1314 |
- [[ -e ${x} ]] || continue |
1315 |
- [[ ${x} == ${ED}lib/udev/rules.d/* ]] && continue |
1316 |
- f+=" ${x#${ED}}\n" |
1317 |
- done |
1318 |
- if [[ -n $f ]] ; then |
1319 |
- eqawarn "QA Notice: udev rules should be installed in /lib/udev/rules.d:" |
1320 |
- eqawarn |
1321 |
- eqawarn "$f" |
1322 |
- fi |
1323 |
- |
1324 |
- # Now we look for all world writable files. |
1325 |
- local unsafe_files=$(find "${ED}" -type f -perm -2 | sed -e "s:^${ED}:- :") |
1326 |
- if [[ -n ${unsafe_files} ]] ; then |
1327 |
- __vecho "QA Security Notice: world writable file(s):" |
1328 |
- __vecho "${unsafe_files}" |
1329 |
- __vecho "- This may or may not be a security problem, most of the time it is one." |
1330 |
- __vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly." |
1331 |
- sleep 1 |
1332 |
- fi |
1333 |
- |
1334 |
- if type -P scanelf > /dev/null && ! has binchecks ${RESTRICT}; then |
1335 |
- local insecure_rpath=0 tmp_quiet=${PORTAGE_QUIET} |
1336 |
- local x |
1337 |
- |
1338 |
- # display warnings when using stricter because we die afterwards |
1339 |
- if has stricter ${FEATURES} ; then |
1340 |
- unset PORTAGE_QUIET |
1341 |
- fi |
1342 |
- |
1343 |
- # Make sure we disallow insecure RUNPATH/RPATHs. |
1344 |
- # 1) References to PORTAGE_BUILDDIR are banned because it's a |
1345 |
- # security risk. We don't want to load files from a |
1346 |
- # temporary directory. |
1347 |
- # 2) If ROOT != "/", references to ROOT are banned because |
1348 |
- # that directory won't exist on the target system. |
1349 |
- # 3) Null paths are banned because the loader will search $PWD when |
1350 |
- # it finds null paths. |
1351 |
- local forbidden_dirs="${PORTAGE_BUILDDIR}" |
1352 |
- if [[ -n "${ROOT}" && "${ROOT}" != "/" ]]; then |
1353 |
- forbidden_dirs+=" ${ROOT}" |
1354 |
- fi |
1355 |
- local dir l rpath_files=$(scanelf -F '%F:%r' -qBR "${ED}") |
1356 |
- f="" |
1357 |
- for dir in ${forbidden_dirs}; do |
1358 |
- for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do |
1359 |
- f+=" ${l%%:*}\n" |
1360 |
- if ! has stricter ${FEATURES}; then |
1361 |
- __vecho "Auto fixing rpaths for ${l%%:*}" |
1362 |
- TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null |
1363 |
- fi |
1364 |
- done |
1365 |
- done |
1366 |
- |
1367 |
- # Reject set*id binaries with $ORIGIN in RPATH #260331 |
1368 |
- x=$( |
1369 |
- find "${ED}" -type f \( -perm -u+s -o -perm -g+s \) -print0 | \ |
1370 |
- xargs -0 scanelf -qyRF '%r %p' | grep '$ORIGIN' |
1371 |
- ) |
1372 |
- |
1373 |
- # Print QA notice. |
1374 |
- if [[ -n ${f}${x} ]] ; then |
1375 |
- __vecho -ne '\n' |
1376 |
- eqawarn "QA Notice: The following files contain insecure RUNPATHs" |
1377 |
- eqawarn " Please file a bug about this at http://bugs.gentoo.org/" |
1378 |
- eqawarn " with the maintaining herd of the package." |
1379 |
- eqawarn "${f}${f:+${x:+\n}}${x}" |
1380 |
- __vecho -ne '\n' |
1381 |
- if [[ -n ${x} ]] || has stricter ${FEATURES} ; then |
1382 |
- insecure_rpath=1 |
1383 |
- fi |
1384 |
- fi |
1385 |
- |
1386 |
- # TEXTRELs are baaaaaaaad |
1387 |
- # Allow devs to mark things as ignorable ... e.g. things that are |
1388 |
- # binary-only and upstream isn't cooperating (nvidia-glx) ... we |
1389 |
- # allow ebuild authors to set QA_TEXTRELS_arch and QA_TEXTRELS ... |
1390 |
- # the former overrides the latter ... regexes allowed ! :) |
1391 |
- qa_var="QA_TEXTRELS_${ARCH/-/_}" |
1392 |
- [[ -n ${!qa_var} ]] && QA_TEXTRELS=${!qa_var} |
1393 |
- [[ -n ${QA_STRICT_TEXTRELS} ]] && QA_TEXTRELS="" |
1394 |
- export QA_TEXTRELS="${QA_TEXTRELS} lib*/modules/*.ko" |
1395 |
- f=$(scanelf -qyRF '%t %p' "${ED}" | grep -v 'usr/lib/debug/') |
1396 |
- if [[ -n ${f} ]] ; then |
1397 |
- scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log |
1398 |
- __vecho -ne '\n' |
1399 |
- eqawarn "QA Notice: The following files contain runtime text relocations" |
1400 |
- eqawarn " Text relocations force the dynamic linker to perform extra" |
1401 |
- eqawarn " work at startup, waste system resources, and may pose a security" |
1402 |
- eqawarn " risk. On some architectures, the code may not even function" |
1403 |
- eqawarn " properly, if at all." |
1404 |
- eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml" |
1405 |
- eqawarn " Please include the following list of files in your report:" |
1406 |
- eqawarn "${f}" |
1407 |
- __vecho -ne '\n' |
1408 |
- die_msg="${die_msg} textrels," |
1409 |
- sleep 1 |
1410 |
- fi |
1411 |
- |
1412 |
- # Also, executable stacks only matter on linux (and just glibc atm ...) |
1413 |
- f="" |
1414 |
- case ${CTARGET:-${CHOST}} in |
1415 |
- *-linux-gnu*) |
1416 |
- # Check for files with executable stacks, but only on arches which |
1417 |
- # are supported at the moment. Keep this list in sync with |
1418 |
- # http://www.gentoo.org/proj/en/hardened/gnu-stack.xml (Arch Status) |
1419 |
- case ${CTARGET:-${CHOST}} in |
1420 |
- arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*) |
1421 |
- # Allow devs to mark things as ignorable ... e.g. things |
1422 |
- # that are binary-only and upstream isn't cooperating ... |
1423 |
- # we allow ebuild authors to set QA_EXECSTACK_arch and |
1424 |
- # QA_EXECSTACK ... the former overrides the latter ... |
1425 |
- # regexes allowed ! :) |
1426 |
- |
1427 |
- qa_var="QA_EXECSTACK_${ARCH/-/_}" |
1428 |
- [[ -n ${!qa_var} ]] && QA_EXECSTACK=${!qa_var} |
1429 |
- [[ -n ${QA_STRICT_EXECSTACK} ]] && QA_EXECSTACK="" |
1430 |
- qa_var="QA_WX_LOAD_${ARCH/-/_}" |
1431 |
- [[ -n ${!qa_var} ]] && QA_WX_LOAD=${!qa_var} |
1432 |
- [[ -n ${QA_STRICT_WX_LOAD} ]] && QA_WX_LOAD="" |
1433 |
- export QA_EXECSTACK="${QA_EXECSTACK} lib*/modules/*.ko" |
1434 |
- export QA_WX_LOAD="${QA_WX_LOAD} lib*/modules/*.ko" |
1435 |
- f=$(scanelf -qyRAF '%e %p' "${ED}" | grep -v 'usr/lib/debug/') |
1436 |
- ;; |
1437 |
- esac |
1438 |
- ;; |
1439 |
- esac |
1440 |
- if [[ -n ${f} ]] ; then |
1441 |
- # One more pass to help devs track down the source |
1442 |
- scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log |
1443 |
- __vecho -ne '\n' |
1444 |
- eqawarn "QA Notice: The following files contain writable and executable sections" |
1445 |
- eqawarn " Files with such sections will not work properly (or at all!) on some" |
1446 |
- eqawarn " architectures/operating systems. A bug should be filed at" |
1447 |
- eqawarn " http://bugs.gentoo.org/ to make sure the issue is fixed." |
1448 |
- eqawarn " For more information, see http://hardened.gentoo.org/gnu-stack.xml" |
1449 |
- eqawarn " Please include the following list of files in your report:" |
1450 |
- eqawarn " Note: Bugs should be filed for the respective maintainers" |
1451 |
- eqawarn " of the package in question and not hardened@g.o." |
1452 |
- eqawarn "${f}" |
1453 |
- __vecho -ne '\n' |
1454 |
- die_msg="${die_msg} execstacks" |
1455 |
- sleep 1 |
1456 |
- fi |
1457 |
- |
1458 |
- # Check for files built without respecting LDFLAGS |
1459 |
- if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && \ |
1460 |
- ! has binchecks ${RESTRICT} ; then |
1461 |
- f=$(scanelf -qyRF '#k%p' -k .hash "${ED}") |
1462 |
- if [[ -n ${f} ]] ; then |
1463 |
- echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log |
1464 |
- if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then |
1465 |
- for x in "${QA_FLAGS_IGNORED[@]}" ; do |
1466 |
- sed -e "s#^${x#/}\$##" -i "${T}"/scanelf-ignored-LDFLAGS.log |
1467 |
- done |
1468 |
- fi |
1469 |
- # Filter anything under /usr/lib/debug/ in order to avoid |
1470 |
- # duplicate warnings for splitdebug files. |
1471 |
- sed -e "s#^usr/lib/debug/.*##" -e "/^\$/d" -e "s#^#/#" \ |
1472 |
- -i "${T}"/scanelf-ignored-LDFLAGS.log |
1473 |
- f=$(<"${T}"/scanelf-ignored-LDFLAGS.log) |
1474 |
- if [[ -n ${f} ]] ; then |
1475 |
- __vecho -ne '\n' |
1476 |
- eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}" |
1477 |
- eqawarn " Please include the following list of files in your report:" |
1478 |
- eqawarn "${f}" |
1479 |
- __vecho -ne '\n' |
1480 |
- sleep 1 |
1481 |
- else |
1482 |
- rm -f "${T}"/scanelf-ignored-LDFLAGS.log |
1483 |
- fi |
1484 |
- fi |
1485 |
- fi |
1486 |
- |
1487 |
- if [[ ${insecure_rpath} -eq 1 ]] ; then |
1488 |
- die "Aborting due to serious QA concerns with RUNPATH/RPATH" |
1489 |
- elif [[ -n ${die_msg} ]] && has stricter ${FEATURES} ; then |
1490 |
- die "Aborting due to QA concerns: ${die_msg}" |
1491 |
- fi |
1492 |
- |
1493 |
- # Check for shared libraries lacking SONAMEs |
1494 |
- qa_var="QA_SONAME_${ARCH/-/_}" |
1495 |
- eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")" |
1496 |
- f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:") |
1497 |
- if [[ -n ${f} ]] ; then |
1498 |
- echo "${f}" > "${T}"/scanelf-missing-SONAME.log |
1499 |
- if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then |
1500 |
- if [[ ${#QA_SONAME[@]} -gt 1 ]] ; then |
1501 |
- for x in "${QA_SONAME[@]}" ; do |
1502 |
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log |
1503 |
- done |
1504 |
- else |
1505 |
- local shopts=$- |
1506 |
- set -o noglob |
1507 |
- for x in ${QA_SONAME} ; do |
1508 |
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-SONAME.log |
1509 |
- done |
1510 |
- set +o noglob |
1511 |
- set -${shopts} |
1512 |
- fi |
1513 |
- fi |
1514 |
- sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log |
1515 |
- f=$(<"${T}"/scanelf-missing-SONAME.log) |
1516 |
- if [[ -n ${f} ]] ; then |
1517 |
- __vecho -ne '\n' |
1518 |
- eqawarn "QA Notice: The following shared libraries lack a SONAME" |
1519 |
- eqawarn "${f}" |
1520 |
- __vecho -ne '\n' |
1521 |
- sleep 1 |
1522 |
- else |
1523 |
- rm -f "${T}"/scanelf-missing-SONAME.log |
1524 |
- fi |
1525 |
- fi |
1526 |
- |
1527 |
- # Check for shared libraries lacking NEEDED entries |
1528 |
- qa_var="QA_DT_NEEDED_${ARCH/-/_}" |
1529 |
- eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")" |
1530 |
- f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:") |
1531 |
- if [[ -n ${f} ]] ; then |
1532 |
- echo "${f}" > "${T}"/scanelf-missing-NEEDED.log |
1533 |
- if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then |
1534 |
- if [[ ${#QA_DT_NEEDED[@]} -gt 1 ]] ; then |
1535 |
- for x in "${QA_DT_NEEDED[@]}" ; do |
1536 |
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log |
1537 |
- done |
1538 |
- else |
1539 |
- local shopts=$- |
1540 |
- set -o noglob |
1541 |
- for x in ${QA_DT_NEEDED} ; do |
1542 |
- sed -e "s#^/${x#/}\$##" -i "${T}"/scanelf-missing-NEEDED.log |
1543 |
- done |
1544 |
- set +o noglob |
1545 |
- set -${shopts} |
1546 |
- fi |
1547 |
- fi |
1548 |
- sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log |
1549 |
- f=$(<"${T}"/scanelf-missing-NEEDED.log) |
1550 |
- if [[ -n ${f} ]] ; then |
1551 |
- __vecho -ne '\n' |
1552 |
- eqawarn "QA Notice: The following shared libraries lack NEEDED entries" |
1553 |
- eqawarn "${f}" |
1554 |
- __vecho -ne '\n' |
1555 |
- sleep 1 |
1556 |
- else |
1557 |
- rm -f "${T}"/scanelf-missing-NEEDED.log |
1558 |
- fi |
1559 |
- fi |
1560 |
- |
1561 |
- PORTAGE_QUIET=${tmp_quiet} |
1562 |
- fi |
1563 |
- |
1564 |
# Create NEEDED.ELF.2 regardless of RESTRICT=binchecks, since this info is |
1565 |
# too useful not to have (it's required for things like preserve-libs), and |
1566 |
# it's tempting for ebuild authors to set RESTRICT=binchecks for packages |
1567 |
@@ -546,595 +216,8 @@ install_qa_check() { |
1568 |
fi |
1569 |
fi |
1570 |
|
1571 |
- local unsafe_files=$(find "${ED}" -type f '(' -perm -2002 -o -perm -4002 ')' | sed -e "s:^${ED}:/:") |
1572 |
- if [[ -n ${unsafe_files} ]] ; then |
1573 |
- eqawarn "QA Notice: Unsafe files detected (set*id and world writable)" |
1574 |
- eqawarn "${unsafe_files}" |
1575 |
- die "Unsafe files found in \${D}. Portage will not install them." |
1576 |
- fi |
1577 |
- |
1578 |
- if [[ -d ${D%/}${D} ]] ; then |
1579 |
- local -i INSTALLTOD=0 |
1580 |
- while read -r -d $'\0' i ; do |
1581 |
- eqawarn "QA Notice: /${i##${D%/}${D}} installed in \${D}/\${D}" |
1582 |
- ((INSTALLTOD++)) |
1583 |
- done < <(find "${D%/}${D}" -print0) |
1584 |
- die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D%/}${D}" |
1585 |
- fi |
1586 |
- |
1587 |
- # Sanity check syntax errors in init.d scripts |
1588 |
- local d |
1589 |
- for d in /etc/conf.d /etc/init.d ; do |
1590 |
- [[ -d ${ED}/${d} ]] || continue |
1591 |
- for i in "${ED}"/${d}/* ; do |
1592 |
- [[ -L ${i} ]] && continue |
1593 |
- # if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist |
1594 |
- [[ ! -e ${i} ]] && continue |
1595 |
- if [[ ${d} == /etc/init.d && ${i} != *.sh ]] ; then |
1596 |
- # skip non-shell-script for bug #451386 |
1597 |
- [[ $(head -n1 "${i}") =~ ^#!.*[[:space:]/](runscript|sh)$ ]] || continue |
1598 |
- fi |
1599 |
- bash -n "${i}" || die "The init.d file has syntax errors: ${i}" |
1600 |
- done |
1601 |
- done |
1602 |
- |
1603 |
- local checkbashisms=$(type -P checkbashisms) |
1604 |
- if [[ -n ${checkbashisms} ]] ; then |
1605 |
- for d in /etc/init.d ; do |
1606 |
- [[ -d ${ED}${d} ]] || continue |
1607 |
- for i in "${ED}${d}"/* ; do |
1608 |
- [[ -e ${i} ]] || continue |
1609 |
- [[ -L ${i} ]] && continue |
1610 |
- f=$("${checkbashisms}" -f "${i}" 2>&1) |
1611 |
- [[ $? != 0 && -n ${f} ]] || continue |
1612 |
- eqawarn "QA Notice: shell script appears to use non-POSIX feature(s):" |
1613 |
- while read -r ; |
1614 |
- do eqawarn " ${REPLY}" |
1615 |
- done <<< "${f//${ED}}" |
1616 |
- done |
1617 |
- done |
1618 |
- fi |
1619 |
- |
1620 |
- # Common mistakes in systemd service files. |
1621 |
- if type -P pkg-config >/dev/null && pkg-config --exists systemd; then |
1622 |
- systemddir=$(pkg-config --variable=systemdsystemunitdir systemd) |
1623 |
- else |
1624 |
- systemddir=/usr/lib/systemd/system |
1625 |
- fi |
1626 |
- if [[ -d ${ED%/}${systemddir} ]]; then |
1627 |
- f=$(grep -sH '^EnvironmentFile.*=.*/etc/conf\.d' "${ED%/}${systemddir}"/*.service) |
1628 |
- if [[ -n ${f} ]] ; then |
1629 |
- eqawarn "QA Notice: systemd units using /etc/conf.d detected:" |
1630 |
- eqawarn "${f//${D}}" |
1631 |
- eqawarn "See: https://wiki.gentoo.org/wiki/Project:Systemd/conf.d_files" |
1632 |
- fi |
1633 |
- fi |
1634 |
- |
1635 |
- # Check for correct bash-completion install path. |
1636 |
- local syscompdir=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null) |
1637 |
- : ${syscompdir:=${EPREFIX}/usr/share/bash-completion/completions} |
1638 |
- |
1639 |
- local instcompdir |
1640 |
- if [[ -d ${ED}/usr/share/bash-completion/completions ]]; then |
1641 |
- instcompdir=${ED}/usr/share/bash-completion/completions |
1642 |
- elif [[ -d ${ED}/usr/share/bash-completion ]]; then |
1643 |
- if [[ ${syscompdir} != ${EPREFIX}/usr/share/bash-completion ]]; then |
1644 |
- eqawarn "Bash completions were installed in legacy location. Please update" |
1645 |
- eqawarn "the ebuild to get the install paths using bash-completion-r1.eclass." |
1646 |
- eqawarn |
1647 |
- fi |
1648 |
- |
1649 |
- instcompdir=${ED}/usr/share/bash-completion |
1650 |
- fi |
1651 |
- |
1652 |
- # Do a few QA tests on bash completions. |
1653 |
- if [[ -n ${instcompdir} && -f ${EROOT}/usr/share/bash-completion/bash_completion ]]; then |
1654 |
- ( |
1655 |
- _get_completions() { |
1656 |
- # source the file |
1657 |
- source "${1}" &>/dev/null |
1658 |
- |
1659 |
- [[ ${USED_HAVE} == yes ]] && echo '__HAVE_USED__' |
1660 |
- |
1661 |
- # print the completed commands |
1662 |
- while read -a args; do |
1663 |
- [[ ${args[0]} == complete ]] || continue |
1664 |
- # command always comes last, one per line |
1665 |
- echo "${args[$(( ${#args[@]} - 1))]}" |
1666 |
- done < <(complete -p) |
1667 |
- } |
1668 |
- |
1669 |
- # load the global helpers |
1670 |
- source "${EROOT}"/usr/share/bash-completion/bash_completion |
1671 |
- |
1672 |
- # clean up predefined completions |
1673 |
- complete -r |
1674 |
- |
1675 |
- # force all completions on |
1676 |
- _have() { |
1677 |
- return 0 |
1678 |
- } |
1679 |
- |
1680 |
- local USED_HAVE=no |
1681 |
- # add a replacement for have() |
1682 |
- have() { |
1683 |
- USED_HAVE=yes |
1684 |
- |
1685 |
- unset -v have |
1686 |
- _have ${1} && have=yes |
1687 |
- } |
1688 |
- |
1689 |
- local f c completions |
1690 |
- local all_compls=() |
1691 |
- local all_files=() |
1692 |
- local qa_warnings=() |
1693 |
- |
1694 |
- for f in "${instcompdir}"/*; do |
1695 |
- # ignore directories and other non-files |
1696 |
- [[ ! -f ${f} ]] && continue |
1697 |
- |
1698 |
- # skip the common code file |
1699 |
- # (in case we're run in /usr/share/bash-completion) |
1700 |
- [[ ${f##*/} == bash_completion ]] && continue |
1701 |
- |
1702 |
- completions=( $(_get_completions "${f}") ) |
1703 |
- |
1704 |
- if [[ ${completions[0]} == __HAVE_USED__ ]]; then |
1705 |
- qa_warnings+=( |
1706 |
- "${f##*/}: 'have' command is deprecated and must not be used." |
1707 |
- ) |
1708 |
- unset 'completions[0]' |
1709 |
- fi |
1710 |
- |
1711 |
- if [[ -z ${completions[@]} ]]; then |
1712 |
- qa_warnings+=( |
1713 |
- "${f##*/}: does not define any completions (failed to source?)." |
1714 |
- ) |
1715 |
- continue |
1716 |
- fi |
1717 |
- |
1718 |
- for c in "${completions[@]}"; do |
1719 |
- if [[ ${c} == /* ]]; then |
1720 |
- qa_warnings+=( |
1721 |
- "${f##*/}: absolute paths can not be used for completions (on '${c}')." |
1722 |
- ) |
1723 |
- else |
1724 |
- all_compls+=( "${c}" ) |
1725 |
- fi |
1726 |
- done |
1727 |
- |
1728 |
- if ! has "${f##*/}" "${all_compls[@]}"; then |
1729 |
- qa_warnings+=( |
1730 |
- "${f##*/}: incorrect name, no completions for '${f##*/}' command defined." |
1731 |
- ) |
1732 |
- fi |
1733 |
- |
1734 |
- all_files+=( "${f##*/}" ) |
1735 |
- done |
1736 |
- |
1737 |
- for c in "${all_compls[@]}"; do |
1738 |
- if ! has "${c}" "${all_files[@]}"; then |
1739 |
- qa_warnings+=( |
1740 |
- "${c}: missing alias (symlink) for completed command." |
1741 |
- ) |
1742 |
- fi |
1743 |
- done |
1744 |
- |
1745 |
- if [[ -n ${qa_warnings[@]} ]]; then |
1746 |
- eqawarn "Problems with installed bash completions were found:" |
1747 |
- eqawarn |
1748 |
- for c in "${qa_warnings[@]}"; do |
1749 |
- eqawarn " ${c}" |
1750 |
- done |
1751 |
- eqawarn |
1752 |
- eqawarn "For more details on installing bash-completions, please see:" |
1753 |
- eqawarn "https://wiki.gentoo.org/wiki/Bash/Installing_completion_files" |
1754 |
- eqawarn |
1755 |
- fi |
1756 |
- ) |
1757 |
- fi |
1758 |
- |
1759 |
- # Look for leaking LDFLAGS into pkg-config files |
1760 |
- f=$(egrep -sH '^Libs.*-Wl,(-O[012]|--hash-style)' "${ED}"/usr/*/pkgconfig/*.pc) |
1761 |
- if [[ -n ${f} ]] ; then |
1762 |
- eqawarn "QA Notice: pkg-config files with wrong LDFLAGS detected:" |
1763 |
- eqawarn "${f//${D}}" |
1764 |
- fi |
1765 |
- |
1766 |
- # this should help to ensure that all (most?) shared libraries are executable |
1767 |
- # and that all libtool scripts / static libraries are not executable |
1768 |
- local j |
1769 |
- for i in "${ED}"opt/*/lib* \ |
1770 |
- "${ED}"lib* \ |
1771 |
- "${ED}"usr/lib* ; do |
1772 |
- [[ ! -d ${i} ]] && continue |
1773 |
- |
1774 |
- for j in "${i}"/*.so.* "${i}"/*.so ; do |
1775 |
- [[ ! -e ${j} ]] && continue |
1776 |
- [[ -L ${j} ]] && continue |
1777 |
- [[ -x ${j} ]] && continue |
1778 |
- __vecho "making executable: ${j#${ED}}" |
1779 |
- chmod +x "${j}" |
1780 |
- done |
1781 |
- |
1782 |
- for j in "${i}"/*.a "${i}"/*.la ; do |
1783 |
- [[ ! -e ${j} ]] && continue |
1784 |
- [[ -L ${j} ]] && continue |
1785 |
- [[ ! -x ${j} ]] && continue |
1786 |
- __vecho "removing executable bit: ${j#${ED}}" |
1787 |
- chmod -x "${j}" |
1788 |
- done |
1789 |
- |
1790 |
- for j in "${i}"/*.{a,dll,dylib,sl,so}.* "${i}"/*.{a,dll,dylib,sl,so} ; do |
1791 |
- [[ ! -e ${j} ]] && continue |
1792 |
- [[ ! -L ${j} ]] && continue |
1793 |
- linkdest=$(readlink "${j}") |
1794 |
- if [[ ${linkdest} == /* ]] ; then |
1795 |
- __vecho -ne '\n' |
1796 |
- eqawarn "QA Notice: Found an absolute symlink in a library directory:" |
1797 |
- eqawarn " ${j#${D}} -> ${linkdest}" |
1798 |
- eqawarn " It should be a relative symlink if in the same directory" |
1799 |
- eqawarn " or a linker script if it crosses the /usr boundary." |
1800 |
- fi |
1801 |
- done |
1802 |
- done |
1803 |
- |
1804 |
- # When installing static libraries into /usr/lib and shared libraries into |
1805 |
- # /lib, we have to make sure we have a linker script in /usr/lib along side |
1806 |
- # the static library, or gcc will utilize the static lib when linking :(. |
1807 |
- # http://bugs.gentoo.org/4411 |
1808 |
- abort="no" |
1809 |
- local a s |
1810 |
- for a in "${ED}"usr/lib*/*.a ; do |
1811 |
- s=${a%.a}.so |
1812 |
- if [[ ! -e ${s} ]] ; then |
1813 |
- s=${s%usr/*}${s##*/usr/} |
1814 |
- if [[ -e ${s} ]] ; then |
1815 |
- __vecho -ne '\n' |
1816 |
- eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}" |
1817 |
- abort="yes" |
1818 |
- fi |
1819 |
- fi |
1820 |
- done |
1821 |
- [[ ${abort} == "yes" ]] && die "add those ldscripts" |
1822 |
- |
1823 |
- # Make sure people don't store libtool files or static libs in /lib |
1824 |
- f=$(ls "${ED}"lib*/*.{a,la} 2>/dev/null) |
1825 |
- if [[ -n ${f} ]] ; then |
1826 |
- __vecho -ne '\n' |
1827 |
- eqawarn "QA Notice: Excessive files found in the / partition" |
1828 |
- eqawarn "${f}" |
1829 |
- __vecho -ne '\n' |
1830 |
- die "static archives (*.a) and libtool library files (*.la) belong in /usr/lib*, not /lib*" |
1831 |
- fi |
1832 |
- |
1833 |
- # Verify that the libtool files don't contain bogus $D entries. |
1834 |
- local abort=no gentoo_bug=no always_overflow=no |
1835 |
- for a in "${ED}"usr/lib*/*.la ; do |
1836 |
- s=${a##*/} |
1837 |
- if grep -qs "${ED}" "${a}" ; then |
1838 |
- __vecho -ne '\n' |
1839 |
- eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths" |
1840 |
- abort="yes" |
1841 |
- fi |
1842 |
- done |
1843 |
- [[ ${abort} == "yes" ]] && die "soiled libtool library files found" |
1844 |
- |
1845 |
- # Evaluate misc gcc warnings |
1846 |
- if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then |
1847 |
- # In debug mode, this variable definition and corresponding grep calls |
1848 |
- # will produce false positives if they're shown in the trace. |
1849 |
- local reset_debug=0 |
1850 |
- if [[ ${-/x/} != $- ]] ; then |
1851 |
- set +x |
1852 |
- reset_debug=1 |
1853 |
- fi |
1854 |
- local m msgs=( |
1855 |
- ": warning: dereferencing type-punned pointer will break strict-aliasing rules" |
1856 |
- ": warning: dereferencing pointer .* does break strict-aliasing rules" |
1857 |
- ": warning: implicit declaration of function" |
1858 |
- ": warning: incompatible implicit declaration of built-in function" |
1859 |
- ": warning: is used uninitialized in this function" # we'll ignore "may" and "might" |
1860 |
- ": warning: comparisons like X<=Y<=Z do not have their mathematical meaning" |
1861 |
- ": warning: null argument where non-null required" |
1862 |
- ": warning: array subscript is below array bounds" |
1863 |
- ": warning: array subscript is above array bounds" |
1864 |
- ": warning: attempt to free a non-heap object" |
1865 |
- ": warning: .* called with .*bigger.* than .* destination buffer" |
1866 |
- ": warning: call to .* will always overflow destination buffer" |
1867 |
- ": warning: assuming pointer wraparound does not occur when comparing" |
1868 |
- ": warning: hex escape sequence out of range" |
1869 |
- ": warning: [^ ]*-hand operand of comma .*has no effect" |
1870 |
- ": warning: converting to non-pointer type .* from NULL" |
1871 |
- ": warning: NULL used in arithmetic" |
1872 |
- ": warning: passing NULL to non-pointer argument" |
1873 |
- ": warning: the address of [^ ]* will always evaluate as" |
1874 |
- ": warning: the address of [^ ]* will never be NULL" |
1875 |
- ": warning: too few arguments for format" |
1876 |
- ": warning: reference to local variable .* returned" |
1877 |
- ": warning: returning reference to temporary" |
1878 |
- ": warning: function returns address of local variable" |
1879 |
- ": warning: .*\\[-Wsizeof-pointer-memaccess\\]" |
1880 |
- ": warning: .*\\[-Waggressive-loop-optimizations\\]" |
1881 |
- # this may be valid code :/ |
1882 |
- #": warning: multi-character character constant" |
1883 |
- # need to check these two ... |
1884 |
- #": warning: assuming signed overflow does not occur when" |
1885 |
- #": warning: comparison with string literal results in unspecified behav" |
1886 |
- # yacc/lex likes to trigger this one |
1887 |
- #": warning: extra tokens at end of .* directive" |
1888 |
- # only gcc itself triggers this ? |
1889 |
- #": warning: .*noreturn.* function does return" |
1890 |
- # these throw false positives when 0 is used instead of NULL |
1891 |
- #": warning: missing sentinel in function call" |
1892 |
- #": warning: not enough variable arguments to fit a sentinel" |
1893 |
- ) |
1894 |
- abort="no" |
1895 |
- i=0 |
1896 |
- local grep_cmd=grep |
1897 |
- [[ $PORTAGE_LOG_FILE = *.gz ]] && grep_cmd=zgrep |
1898 |
- while [[ -n ${msgs[${i}]} ]] ; do |
1899 |
- m=${msgs[$((i++))]} |
1900 |
- # force C locale to work around slow unicode locales #160234 |
1901 |
- f=$(LC_ALL=C $grep_cmd "${m}" "${PORTAGE_LOG_FILE}") |
1902 |
- if [[ -n ${f} ]] ; then |
1903 |
- abort="yes" |
1904 |
- # for now, don't make this fatal (see bug #337031) |
1905 |
- #case "$m" in |
1906 |
- # ": warning: call to .* will always overflow destination buffer") always_overflow=yes ;; |
1907 |
- #esac |
1908 |
- if [[ $always_overflow = yes ]] ; then |
1909 |
- eerror |
1910 |
- eerror "QA Notice: Package triggers severe warnings which indicate that it" |
1911 |
- eerror " may exhibit random runtime failures." |
1912 |
- eerror |
1913 |
- eerror "${f}" |
1914 |
- eerror |
1915 |
- eerror " Please file a bug about this at http://bugs.gentoo.org/" |
1916 |
- eerror " with the maintaining herd of the package." |
1917 |
- eerror |
1918 |
- else |
1919 |
- __vecho -ne '\n' |
1920 |
- eqawarn "QA Notice: Package triggers severe warnings which indicate that it" |
1921 |
- eqawarn " may exhibit random runtime failures." |
1922 |
- eqawarn "${f}" |
1923 |
- __vecho -ne '\n' |
1924 |
- fi |
1925 |
- fi |
1926 |
- done |
1927 |
- local cat_cmd=cat |
1928 |
- [[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat |
1929 |
- [[ $reset_debug = 1 ]] && set -x |
1930 |
- # Use safe cwd, avoiding unsafe import for bug #469338. |
1931 |
- f=$(cd "${PORTAGE_PYM_PATH}" ; $cat_cmd "${PORTAGE_LOG_FILE}" | \ |
1932 |
- "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed") |
1933 |
- if [[ -n ${f} ]] ; then |
1934 |
- |
1935 |
- # In the future this will be a forced "die". In preparation, |
1936 |
- # increase the log level from "qa" to "eerror" so that people |
1937 |
- # are aware this is a problem that must be fixed asap. |
1938 |
- |
1939 |
- # just warn on 32bit hosts but bail on 64bit hosts |
1940 |
- case ${CHOST} in |
1941 |
- alpha*|hppa64*|ia64*|powerpc64*|mips64*|sparc64*|sparcv9*|x86_64*) gentoo_bug=yes ;; |
1942 |
- esac |
1943 |
- |
1944 |
- abort=yes |
1945 |
- |
1946 |
- if [[ $gentoo_bug = yes ]] ; then |
1947 |
- eerror |
1948 |
- eerror "QA Notice: Package triggers severe warnings which indicate that it" |
1949 |
- eerror " will almost certainly crash on 64bit architectures." |
1950 |
- eerror |
1951 |
- eerror "${f}" |
1952 |
- eerror |
1953 |
- eerror " Please file a bug about this at http://bugs.gentoo.org/" |
1954 |
- eerror " with the maintaining herd of the package." |
1955 |
- eerror |
1956 |
- else |
1957 |
- __vecho -ne '\n' |
1958 |
- eqawarn "QA Notice: Package triggers severe warnings which indicate that it" |
1959 |
- eqawarn " will almost certainly crash on 64bit architectures." |
1960 |
- eqawarn "${f}" |
1961 |
- __vecho -ne '\n' |
1962 |
- fi |
1963 |
- |
1964 |
- fi |
1965 |
- if [[ ${abort} == "yes" ]] ; then |
1966 |
- if [[ $gentoo_bug = yes || $always_overflow = yes ]] ; then |
1967 |
- die "install aborted due to severe warnings shown above" |
1968 |
- else |
1969 |
- echo "Please do not file a Gentoo bug and instead" \ |
1970 |
- "report the above QA issues directly to the upstream" \ |
1971 |
- "developers of this software." | fmt -w 70 | \ |
1972 |
- while read -r line ; do eqawarn "${line}" ; done |
1973 |
- eqawarn "Homepage: ${HOMEPAGE}" |
1974 |
- has stricter ${FEATURES} && \ |
1975 |
- die "install aborted due to severe warnings shown above" |
1976 |
- fi |
1977 |
- fi |
1978 |
- fi |
1979 |
- |
1980 |
# Portage regenerates this on the installed system. |
1981 |
rm -f "${ED}"/usr/share/info/dir{,.gz,.bz2} || die "rm failed!" |
1982 |
- |
1983 |
- if has multilib-strict ${FEATURES} && \ |
1984 |
- [[ -x /usr/bin/file && -x /usr/bin/find ]] && \ |
1985 |
- [[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]] |
1986 |
- then |
1987 |
- rm -f "${T}/multilib-strict.log" |
1988 |
- local abort=no dir file |
1989 |
- MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g') |
1990 |
- for dir in ${MULTILIB_STRICT_DIRS} ; do |
1991 |
- [[ -d ${ED}/${dir} ]] || continue |
1992 |
- for file in $(find ${ED}/${dir} -type f | grep -v "^${ED}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do |
1993 |
- if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then |
1994 |
- echo "${file#${ED}//}" >> "${T}/multilib-strict.log" |
1995 |
- fi |
1996 |
- done |
1997 |
- done |
1998 |
- |
1999 |
- if [[ -s ${T}/multilib-strict.log ]] ; then |
2000 |
- if [[ ${#QA_MULTILIB_PATHS[@]} -eq 1 ]] ; then |
2001 |
- local shopts=$- |
2002 |
- set -o noglob |
2003 |
- QA_MULTILIB_PATHS=(${QA_MULTILIB_PATHS}) |
2004 |
- set +o noglob |
2005 |
- set -${shopts} |
2006 |
- fi |
2007 |
- if [ "${QA_STRICT_MULTILIB_PATHS-unset}" = unset ] ; then |
2008 |
- for x in "${QA_MULTILIB_PATHS[@]}" ; do |
2009 |
- sed -e "s#^${x#/}\$##" -i "${T}/multilib-strict.log" |
2010 |
- done |
2011 |
- sed -e "/^\$/d" -i "${T}/multilib-strict.log" |
2012 |
- fi |
2013 |
- if [[ -s ${T}/multilib-strict.log ]] ; then |
2014 |
- abort=yes |
2015 |
- echo "Files matching a file type that is not allowed:" |
2016 |
- while read -r ; do |
2017 |
- echo " ${REPLY}" |
2018 |
- done < "${T}/multilib-strict.log" |
2019 |
- fi |
2020 |
- fi |
2021 |
- |
2022 |
- [[ ${abort} == yes ]] && die "multilib-strict check failed!" |
2023 |
- fi |
2024 |
- |
2025 |
- local pngfix=$(type -P pngfix) |
2026 |
- if [[ -n ${pngfix} ]] ; then |
2027 |
- local pngout=() |
2028 |
- local next |
2029 |
- |
2030 |
- while read -r -a pngout ; do |
2031 |
- local error="" |
2032 |
- |
2033 |
- case "${pngout[1]}" in |
2034 |
- CHK) |
2035 |
- error='invalid checksum' |
2036 |
- ;; |
2037 |
- TFB) |
2038 |
- error='broken IDAT window length' |
2039 |
- ;; |
2040 |
- esac |
2041 |
- |
2042 |
- if [[ -n ${error} ]] ; then |
2043 |
- if [[ -z ${next} ]] ; then |
2044 |
- eqawarn "QA Notice: broken .png files found:" |
2045 |
- next=1 |
2046 |
- fi |
2047 |
- eqawarn " ${pngout[@]:7}: ${error}" |
2048 |
- fi |
2049 |
- done < <(find "${ED}" -type f -name '*.png' -exec "${pngfix}" {} +) |
2050 |
- fi |
2051 |
-} |
2052 |
- |
2053 |
-install_qa_check_prefix() { |
2054 |
- if [[ -d ${ED}/${D} ]] ; then |
2055 |
- find "${ED}/${D}" | \ |
2056 |
- while read i ; do |
2057 |
- eqawarn "QA Notice: /${i##${ED}/${D}} installed in \${ED}/\${D}" |
2058 |
- done |
2059 |
- die "Aborting due to QA concerns: files installed in ${ED}/${D}" |
2060 |
- fi |
2061 |
- |
2062 |
- if [[ -d ${ED}/${EPREFIX} ]] ; then |
2063 |
- find "${ED}/${EPREFIX}/" | \ |
2064 |
- while read i ; do |
2065 |
- eqawarn "QA Notice: ${i#${D}} double prefix" |
2066 |
- done |
2067 |
- die "Aborting due to QA concerns: double prefix files installed" |
2068 |
- fi |
2069 |
- |
2070 |
- if [[ -d ${D} ]] ; then |
2071 |
- INSTALLTOD=$(find ${D%/} | egrep -v "^${ED}" | sed -e "s|^${D%/}||" | awk '{if (length($0) <= length("'"${EPREFIX}"'")) { if (substr("'"${EPREFIX}"'", 1, length($0)) != $0) {print $0;} } else if (substr($0, 1, length("'"${EPREFIX}"'")) != "'"${EPREFIX}"'") {print $0;} }') |
2072 |
- if [[ -n ${INSTALLTOD} ]] ; then |
2073 |
- eqawarn "QA Notice: the following files are outside of the prefix:" |
2074 |
- eqawarn "${INSTALLTOD}" |
2075 |
- die "Aborting due to QA concerns: there are files installed outside the prefix" |
2076 |
- fi |
2077 |
- fi |
2078 |
- |
2079 |
- # all further checks rely on ${ED} existing |
2080 |
- [[ -d ${ED} ]] || return |
2081 |
- |
2082 |
- # check shebangs, bug #282539 |
2083 |
- rm -f "${T}"/non-prefix-shebangs-errs |
2084 |
- local WHITELIST=" /usr/bin/env " |
2085 |
- # this is hell expensive, but how else? |
2086 |
- find "${ED}" -executable \! -type d -print0 \ |
2087 |
- | xargs -0 grep -H -n -m1 "^#!" \ |
2088 |
- | while read f ; |
2089 |
- do |
2090 |
- local fn=${f%%:*} |
2091 |
- local pos=${f#*:} ; pos=${pos%:*} |
2092 |
- local line=${f##*:} |
2093 |
- # shebang always appears on the first line ;) |
2094 |
- [[ ${pos} != 1 ]] && continue |
2095 |
- local oldIFS=${IFS} |
2096 |
- IFS=$'\r'$'\n'$'\t'" " |
2097 |
- line=( ${line#"#!"} ) |
2098 |
- IFS=${oldIFS} |
2099 |
- [[ ${WHITELIST} == *" ${line[0]} "* ]] && continue |
2100 |
- local fp=${fn#${D}} ; fp=/${fp%/*} |
2101 |
- # line[0] can be an absolutised path, bug #342929 |
2102 |
- local eprefix=$(canonicalize ${EPREFIX}) |
2103 |
- local rf=${fn} |
2104 |
- # in case we deal with a symlink, make sure we don't replace it |
2105 |
- # with a real file (sed -i does that) |
2106 |
- if [[ -L ${fn} ]] ; then |
2107 |
- rf=$(readlink ${fn}) |
2108 |
- [[ ${rf} != /* ]] && rf=${fn%/*}/${rf} |
2109 |
- # ignore symlinks pointing to outside prefix |
2110 |
- # as seen in sys-devel/native-cctools |
2111 |
- [[ $(canonicalize "/${rf#${D}}") != ${eprefix}/* ]] && continue |
2112 |
- fi |
2113 |
- # does the shebang start with ${EPREFIX}, and does it exist? |
2114 |
- if [[ ${line[0]} == ${EPREFIX}/* || ${line[0]} == ${eprefix}/* ]] ; then |
2115 |
- if [[ ! -e ${ROOT%/}${line[0]} && ! -e ${D%/}${line[0]} ]] ; then |
2116 |
- # hmm, refers explicitly to $EPREFIX, but doesn't exist, |
2117 |
- # if it's in PATH that's wrong in any case |
2118 |
- if [[ ":${PATH}:" == *":${fp}:"* ]] ; then |
2119 |
- echo "${fn#${D}}:${line[0]} (explicit EPREFIX but target not found)" \ |
2120 |
- >> "${T}"/non-prefix-shebangs-errs |
2121 |
- else |
2122 |
- eqawarn "${fn#${D}} has explicit EPREFIX in shebang but target not found (${line[0]})" |
2123 |
- fi |
2124 |
- fi |
2125 |
- continue |
2126 |
- fi |
2127 |
- # unprefixed shebang, is the script directly in $PATH? |
2128 |
- if [[ ":${PATH}:" == *":${fp}:"* ]] ; then |
2129 |
- if [[ -e ${EROOT}${line[0]} || -e ${ED}${line[0]} ]] ; then |
2130 |
- # is it unprefixed, but we can just fix it because a |
2131 |
- # prefixed variant exists |
2132 |
- eqawarn "prefixing shebang of ${fn#${D}}" |
2133 |
- # statement is made idempotent on purpose, because |
2134 |
- # symlinks may point to the same target, and hence the |
2135 |
- # same real file may be sedded multiple times since we |
2136 |
- # read the shebangs in one go upfront for performance |
2137 |
- # reasons |
2138 |
- sed -i -e '1s:^#! \?'"${line[0]}"':#!'"${EPREFIX}"${line[0]}':' "${rf}" |
2139 |
- continue |
2140 |
- else |
2141 |
- # this is definitely wrong: script in $PATH and invalid shebang |
2142 |
- echo "${fn#${D}}:${line[0]} (script ${fn##*/} installed in PATH but interpreter ${line[0]} not found)" \ |
2143 |
- >> "${T}"/non-prefix-shebangs-errs |
2144 |
- fi |
2145 |
- else |
2146 |
- # unprefixed/invalid shebang, but outside $PATH, this may be |
2147 |
- # intended (e.g. config.guess) so remain silent by default |
2148 |
- has stricter ${FEATURES} && \ |
2149 |
- eqawarn "invalid shebang in ${fn#${D}}: ${line[0]}" |
2150 |
- fi |
2151 |
- done |
2152 |
- if [[ -e "${T}"/non-prefix-shebangs-errs ]] ; then |
2153 |
- eqawarn "QA Notice: the following files use invalid (possible non-prefixed) shebangs:" |
2154 |
- while read line ; do |
2155 |
- eqawarn " ${line}" |
2156 |
- done < "${T}"/non-prefix-shebangs-errs |
2157 |
- rm -f "${T}"/non-prefix-shebangs-errs |
2158 |
- die "Aborting due to QA concerns: invalid shebangs found" |
2159 |
- fi |
2160 |
} |
2161 |
|
2162 |
install_mask() { |
2163 |
-- |
2164 |
2.1.0 |