#!/bin/sh # sbopkglint test, must be sourced by sbopkglint (not run standalone). # PKG, PRGNAM, VERSION, ARCH are set by sbopkglint. also the current # directory is the root of the installed package tree. ######################################################################## # checks permissions and ownership of static libraries lib dirs. # checks that static libraries actually *are* static libraries. # if the package includes both a static and shared library, a note is # triggered, suggesting removal of the static lib. this is not an error. # TODO: this will give us file's idea of what's inside a .a archive: # $ ar p blah.a | file -Sb - # ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped # For 32-bit: # ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped # Note that file needs the -S, seccomp causes file to occasionally fail # with 'Bad system call' when working on stdin. No idea why, -S fixes it. # 'not stripped' is *correct*, don't complain about it! actually maybe # it should complain if it *is* stripped...? # Armed with this knowledge, we can do the same kind of arch checks for # static libs as we do for shared (32-bit belongs in lib, 64 in lib64, # arch of the static lib should match package's ARCH, etc). # Have a look at /usr/lib64/libm.a: it's a linker script. File says it's # ASCII text. # r0ni says aarch64 does this: # ELF 64-bit LSB relocatable, ARM aarch64, version 1 (SYSV), not stripped check_static_arch() { local lib="$1" local libarch="$2" local libdir="$( dirname "$lib" )" local dir="$( basename "$libdir" )" # lib or lib64 case "$libarch" in x86) wantdir="lib" ;; x86_64|aarch64) wantdir="lib64" ;; esac } check_static_lib() { case "$( ar p "$1" | file -Sb - )" in empty) # empty static libs are allowed, but get a 'note'. note "$1 is an empty static library, remove it if not needed by a dependee." ;; LLVM*) ;; # e.g. "LLVM IR bitcode", assume OK. ELF*x86-64*) check_static_arch "$1" x86_64 ;; ELF*80386*) check_static_arch "$1" x86 ;; ELF*aarch64*) check_static_arch "$1" aarch64 ;; *) ;; # dunno, assume OK esac } for libdir in lib lib64 usr/lib usr/lib64; do if [ -d $libdir ]; then find_warnfiles "bad static library ownership (should be root:root):" \ -L $libdir -mindepth 1 -maxdepth 1 -name '*.a' \! \( -user root -a -group root \) find_warnfiles "bad static library permissions (should be 0644 or 0444):" \ -L $libdir -mindepth 1 -maxdepth 1 -name '*.a' \! \( -perm 444 -o -perm 644 \) find $libdir -mindepth 1 -maxdepth 1 -name '*.a' | while read static; do ftype="$( file -L -b --mime-type "$static" )" case "$ftype" in "application/x-archive") check_static_lib "$static" ;; "application/x-executable") warn "$static is an executable, not a static library." ;; "application/x-object") warn "$static is a shared library (.so), not a static library." ;; "text/plain") # TODO: check that this is a valid linker script (when I learn how). for now, ignore. ;; *) warn "$static is not a valid static library. MIME type is '$ftype'." ;; esac shared=$libdir/"$( basename "$static" .a)".so if [ -e "$shared" ]; then shname="$( basename "$shared" )" stname="$( basename "$static" )" note "$libdir has both $shname and $stname; unless it's needed by a dependee, consider removing $stname" fi done fi done