Gentoo Archives: gentoo-portage-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-portage-dev@l.g.o
Cc: "Michał Górny" <mgorny@g.o>
Subject: [gentoo-portage-dev] [PATCH] Split install_qa_check() into install-qa-check.d scripts
Date: Wed, 10 Sep 2014 19:58:34
Message-Id: 1410379094-28471-1-git-send-email-mgorny@gentoo.org
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

Replies