diff options
Diffstat (limited to 'sbopkglint.d/20-arch.t.sh')
| -rw-r--r-- | sbopkglint.d/20-arch.t.sh | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/sbopkglint.d/20-arch.t.sh b/sbopkglint.d/20-arch.t.sh index bf6124e..c904fb2 100644 --- a/sbopkglint.d/20-arch.t.sh +++ b/sbopkglint.d/20-arch.t.sh @@ -9,6 +9,8 @@ # for noarch packages, do nothing. # for everything else, make sure any ELF binaries/libraries match the # ARCH, and that libs are in the correct directory (lib vs. lib64). +# also, check the required glibc version of each bin/lib, and complain +# if it's newer than the glibc on the system. # warnings: # if an i?86 package has any 64-bit ELF objects (libs or bins) @@ -21,12 +23,48 @@ # false "wrong directory" warnings, so we exclude that dir from the # search. +set_glibc_ver() { + GLIBC_VER="$( /$1/libc.so.6 --version | \ + grep version | \ + head -n1 | \ + sed 's,.* \([0-9]\.[0-9]\+\)\.*$,\1,' )" + [ "$GLIBC_VER" = "" ] && note "can't get glibc version, disabling glibc check" +} + +# compare the highest required version of glibc from a binary against +# the version we have installed. ugly code, sorry. +# one approach would be to run ldd and look for "version `.*' not found", +# but it's better not to run ldd on arbitrary binaries as root... +glibc_check() { + local ver + local highver + + [ "$GLIBC_VER" = "" ] && return + + # get the highest required glibc verson from the binary. there *must* + # be a cleaner way to do this, but I haven't found it yet. + ver="$( objdump -p "$1" 2>/dev/null | \ + sed -n '/Version Ref/,$s/GLIBC_/&/p' | \ + rev | cut -d_ -f1 | rev | sort -V | tail -n 1 )" + [ "$ver" = "" ] && return # probably a static binary + + # highver is whichever of (our glibc, binary's highest required glibc) + # is higher (or, same as our glibc, if they're the same) + highver="$( ( echo $GLIBC_VER ; echo $ver ) | sort -V | tail -n 1 )" + + #echo "===> ver: $ver highver: $highver" + + if [ "$highver" != "$GLIBC_VER" ]; then + echo "$1" >> .badglibc.$$ + fi +} + case "$ARCH" in noarch) ;; # ok, do nothing. - i?86) WRONGDIR="lib64"; CPU="80386" ;; - x86_64) WRONGDIR="lib"; CPU="x86-64" ;; - aarch64) WRONGDIR="lib"; CPU="aarch64" ;; - arm) WRONGDIR="lib64"; CPU="ARM" ;; + i?86) WRONGDIR="lib64"; CPU="80386" ; set_glibc_ver "lib" ;; + x86_64) WRONGDIR="lib"; CPU="x86-64" ; set_glibc_ver "lib64" ;; + aarch64) WRONGDIR="lib"; CPU="aarch64" ; set_glibc_ver "lib64" ;; + arm) WRONGDIR="lib64"; CPU="ARM" ; set_glibc_ver "lib" ;; *) warn "ARCH isn't noarch, i?86, x86_64, arm, or aarch64. don't know how to check binaries." ;; esac @@ -85,10 +123,12 @@ if [ -n "$WRONGDIR" ]; then # don't check "no machine" ELF objects for being stripped. # our strip command doesn't know how to strip them! + # also, check for binaries that need too new of a glibc. if [ ! "$nomachine" ]; then if echo "$filetype" | grep -q "not stripped"; then ls -lb "$file" >> .notstripped.$$ fi + glibc_check "$file" fi done < .tmp.$$ rm -f .tmp.$$ @@ -98,6 +138,7 @@ fi [ -s .wrongarch.$$ ] && warn "ELF object(s) with wrong arch (should be $CPU):" && cat .wrongarch.$$ [ -s .notstripped.$$ ] && warn "ELF object(s) not stripped:" && cat .notstripped.$$ [ -s .nonexec.$$ ] && warn "ELF binaries/libraries should be executable:" && cat .nonexec.$$ +[ -s .badglibc.$$ ] && warn "ELF binaries/libraries with bad glibc version:" && cat .badglibc.$$ if [ "$WRONGDIR" = "lib64" ]; then [ -e usr/lib64 ] && warn "32-bit $ARCH package may not contain /usr/lib64" @@ -106,4 +147,4 @@ elif [ "$WRONGDIR" = "lib" -a -e usr/lib ]; then note "64-bit $ARCH package contains /usr/lib; this may or may not be a problem." fi -rm -f .inwrongdir.$$ .wrongarch.$$ .notstripped.$$ .nonexec.$$ +rm -f .inwrongdir.$$ .wrongarch.$$ .notstripped.$$ .nonexec.$$ .badglibc.$$ |
