Gentoo Archives: gentoo-commits

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