kiss: ignore libraries with RPATH in dependency detector (#69)

This commit is contained in:
Wolf Gupta 2022-09-16 13:17:47 +00:00 committed by GitHub
parent af2335c55e
commit 36df1ae0e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

43
kiss
View File

@ -647,21 +647,23 @@ pkg_strip() {
esac done < "$pkg_dir/$1/$pkg_db/$1/manifest" || : esac done < "$pkg_dir/$1/$pkg_db/$1/manifest" || :
} }
prepend() { should_ignore_rpath() {
pre=$3
sep=$2
cat=''
# Intentional, globbing disabled. # Intentional, globbing disabled.
# shellcheck disable=2086 # shellcheck disable=2086
{ IFS="$sep"; set -- $1; unset IFS; } { IFS=:; set -- $1; unset IFS; }
for str do for path do
ok "$str" || continue # TODO maybe check if the RPATH is set to a redundant value
cat="$cat$sep$pre$str" # like /lib or /usr/lib ?
# ORIGIN is relative - no need to ignore it.
# Library rpath: [$ORIGIN/../lib]
# shellcheck disable=2016
case $path in '$ORIGIN'*|'${ORIGIN}'*) continue; esac
# Non-relative path, should be ignored.
return 0
done done
printf '%s' "$cat" return 1
} }
pkg_fix_deps() { pkg_fix_deps() {
@ -688,7 +690,6 @@ pkg_fix_deps() {
*/lib??/?*[!/]|*/lib???/?*[!/]|*/lib????/?*[!/]) */lib??/?*[!/]|*/lib???/?*[!/]|*/lib????/?*[!/])
unset elf unset elf
unset lib_rpath
# Attempt to get information from readelf. If this fails (or we # Attempt to get information from readelf. If this fails (or we
# are in ldd mode), do full ldd mode (which has the downside of # are in ldd mode), do full ldd mode (which has the downside of
@ -700,11 +701,22 @@ pkg_fix_deps() {
# RPATH/RUNPATH allows the binary to set a relative path for the # RPATH/RUNPATH allows the binary to set a relative path for the
# dynamic loader that might not be present on the rootfs at the time # dynamic loader that might not be present on the rootfs at the time
# of installation. So, ignoring it can cause the dependency detector to # of installation. So, ignoring it can cause the dependency detector to
# wrongly add packages. # wrongly add packages. The problem also exists in reverse when the
# package links to a library bundled inside it and present in system paths
# aswell, and a package update unbundles it - the package gets a dependency
# on itself due to RPATH causing ldd to find the bundled lib.
# Example: libnss3.so exists in /usr/lib at the time of installation # Example: libnss3.so exists in /usr/lib at the time of installation
# But the package links to libnss3 in /usr/lib/PKG/libnss3.so, which is # But the package links to libnss3 in /usr/lib/PKG/libnss3.so, which is
# present only in the build dir. So, KISS wrongly adds the installed nss # present only in the build dir. So, KISS wrongly adds the installed nss
# as a dependency. # as a dependency.
# To avoid dealing with this, we just ignore any libraries with RPATH set.
# A solution to this could be to just get the NEEDED libs and RPATH with
# readelf and resolve the paths ourselves - with adhoc logic for RPATH and
# the build dir.
# Another solution could be to resolve the dependencies after installation,
# but that can cause issues with reinstalling that tarball later on.
# https://github.com/kiss-community/kiss/issues/64
# https://github.com/kiss-community/repo/issues/97
while read -r _ entry_type value; do while read -r _ entry_type value; do
# Technically RUNPATH is supposed to have a higher priority # Technically RUNPATH is supposed to have a higher priority
# than RPATH but a binary that has both RPATH and RUNPATH set, # than RPATH but a binary that has both RPATH and RUNPATH set,
@ -713,7 +725,8 @@ pkg_fix_deps() {
value=${value##*\[} value=${value##*\[}
value=${value%%\]*} value=${value%%\]*}
lib_rpath="$value" should_ignore_rpath "$value" && continue 2
# Found RPATH which shouldn't be ignored
break break
esac esac
done <<EOF done <<EOF
@ -722,9 +735,7 @@ EOF
# The readelf mode requires ldd's output to resolve the library # The readelf mode requires ldd's output to resolve the library
# path for a given file. If ldd fails, silently skip the file. # path for a given file. If ldd fails, silently skip the file.
# We set LD_LIBRARY_PATH to the RPATH we found above to allow ldd ldd=$(ldd -- "$pkg_dir/$repo_name$_file" 2>/dev/null) || continue
# to resolve accurate paths.
ldd=$(LD_LIBRARY_PATH=$(prepend "$lib_rpath" : "$pkg_dir/$repo_name") ldd -- "$pkg_dir/$repo_name$_file" 2>/dev/null) || continue
ok "$elf" || elf=$ldd ok "$elf" || elf=$ldd
# Iterate over the output of readelf or ldd, extract file names, # Iterate over the output of readelf or ldd, extract file names,