c1cfee290e
We sanity-check the host executables that they have a correct RPATH pointing to the host libraries. This is currently done by looking for all files in $(HOST_DIR) that match the 'ELF executable' pattern (a bit more complex, but that's idea). However, when an executable is built with -fPIE of -fpie, it no longer appears to be an 'ELF executable', but it rather looks like an 'ELF sheard object' (like if it were an library. So, we miss those files. It turns out that the problem is a real one, because quite a few mainline distros, expecially those based on Debian for example, have already switched to generating PIE code by default, and thus we miss on a whole class of systems.. We fix that by simply looking if we can find an ELF interpreter in each file. If we there is one, this is an ELF executable; if not, it may be anything else: we don't care (not even about ELF libraries). Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr> Cc: Arnout Vandecappelle <arnout@mind.be> Signed-off-by: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
77 lines
2.2 KiB
Bash
Executable File
77 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# This script scans $(HOST_DIR)/{bin,sbin} for all ELF files, and checks
|
|
# they have an RPATH to $(HOST_DIR)/lib if they need libraries from
|
|
# there.
|
|
|
|
# Override the user's locale so we are sure we can parse the output of
|
|
# readelf(1) and file(1)
|
|
export LC_ALL=C
|
|
|
|
main() {
|
|
local pkg="${1}"
|
|
local hostdir="${2}"
|
|
local file ret
|
|
|
|
# Remove duplicate and trailing '/' for proper match
|
|
hostdir="$( sed -r -e 's:/+:/:g; s:/$::;' <<<"${hostdir}" )"
|
|
|
|
ret=0
|
|
while read file; do
|
|
is_elf "${file}" || continue
|
|
elf_needs_rpath "${file}" "${hostdir}" || continue
|
|
check_elf_has_rpath "${file}" "${hostdir}" && continue
|
|
if [ ${ret} -eq 0 ]; then
|
|
ret=1
|
|
printf "***\n"
|
|
printf "*** ERROR: package %s installs executables without proper RPATH:\n" "${pkg}"
|
|
fi
|
|
printf "*** %s\n" "${file}"
|
|
done < <( find "${hostdir}"/{bin,sbin} -type f 2>/dev/null )
|
|
|
|
return ${ret}
|
|
}
|
|
|
|
is_elf() {
|
|
local f="${1}"
|
|
|
|
readelf -l "${f}" 2>/dev/null \
|
|
|grep -E 'Requesting program interpreter:' >/dev/null 2>&1
|
|
}
|
|
|
|
elf_needs_rpath() {
|
|
local file="${1}"
|
|
local hostdir="${2}"
|
|
local lib
|
|
|
|
while read lib; do
|
|
[ -e "${hostdir}/lib/${lib}" ] && return 0
|
|
done < <( readelf -d "${file}" \
|
|
|sed -r -e '/^.* \(NEEDED\) .*Shared library: \[(.+)\]$/!d;' \
|
|
-e 's//\1/;' \
|
|
)
|
|
|
|
return 1
|
|
}
|
|
|
|
check_elf_has_rpath() {
|
|
local file="${1}"
|
|
local hostdir="${2}"
|
|
local rpath dir
|
|
|
|
while read rpath; do
|
|
for dir in ${rpath//:/ }; do
|
|
# Remove duplicate and trailing '/' for proper match
|
|
dir="$( sed -r -e 's:/+:/:g; s:/$::;' <<<"${dir}" )"
|
|
[ "${dir}" = "${hostdir}/lib" -o "${dir}" = "\$ORIGIN/../lib" ] && return 0
|
|
done
|
|
done < <( readelf -d "${file}" \
|
|
|sed -r -e '/.* \(R(UN)?PATH\) +Library r(un)?path: \[(.+)\]$/!d' \
|
|
-e 's//\3/;' \
|
|
)
|
|
|
|
return 1
|
|
}
|
|
|
|
main "${@}"
|