diff --git a/scripts/static-audit.sh b/scripts/static-audit.sh index b6d9db02..ebea5b63 100755 --- a/scripts/static-audit.sh +++ b/scripts/static-audit.sh @@ -72,18 +72,34 @@ for f in $recetas; do [ -z "${art:-}" ] && { sin=$((sin + 1)); continue; } fi - # El primer ELF *ejecutable* del artefacto. Una `.so` tiene NEEDED por definición y no prueba - # nada; sólo el ejecutable dice si el enlace final fue estático. - bin="" - for b in $(find "$art" -type f -perm -u+x 2>/dev/null | head -40); do - if file -b "$b" 2>/dev/null | grep -q 'ELF.*executable'; then bin="$b"; break; fi - done - [ -z "$bin" ] && { sin=$((sin + 1)); continue; } - - needed=$(readelf -d "$bin" 2>/dev/null | grep -oE 'Shared library: \[[^]]+\]' \ + # TODOS los ELF *ejecutables* del artefacto, no el primero. Una `.so` tiene NEEDED por + # definición y no prueba nada; sólo los ejecutables dicen si el enlace final fue estático. + # + # ⚠ Antes esto miraba UNO y cortaba (`break`). Con dwarves se vio lo que eso deja pasar: sus + # DIEZ ejecutables eran dinámicos y el audit reportaba uno — acertó de casualidad, porque el + # primero también lo era. El caso que se escapaba en silencio es el inverso: primer binario + # estático y el resto no, que se leía como receta honesta. Es «no comprobar no es aprobar» + # aplicado al propio guardián (2026-08-31). + vistos=0; needed=""; primer_malo=""; malos=0 + for b in $(find "$art" -type f -perm -u+x 2>/dev/null); do + file -b "$b" 2>/dev/null | grep -q 'ELF.*executable' || continue + vistos=$((vistos + 1)) + nb=$(readelf -d "$b" 2>/dev/null | grep -oE 'Shared library: \[[^]]+\]' \ | sed 's/.*\[//;s/\]//' | tr '\n' ' ') || true + if [ -n "$nb" ]; then + malos=$((malos + 1)) + [ -z "$primer_malo" ] && { primer_malo="${b#$art/}"; needed="$nb"; } + fi + done + [ "$vistos" -eq 0 ] && { sin=$((sin + 1)); continue; } + if [ -n "$needed" ]; then - printf ' ✗ %-18s dice static, es DINÁMICO → %s\n' "$n" "$needed" + if [ "$malos" -gt 1 ]; then + printf ' ✗ %-18s dice static, %d de %d ejecutables DINÁMICOS (p.ej. %s) → %s\n' \ + "$n" "$malos" "$vistos" "$primer_malo" "$needed" + else + printf ' ✗ %-18s dice static, es DINÁMICO (%s) → %s\n' "$n" "$primer_malo" "$needed" + fi case "$needed" in *libgcc_s*) printf ' %-18s ↑ arrastra libgcc_s de Alpine: deuda de matar-gcc no declarada\n' "" ;; esac case "$needed" in *libc.so*) printf ' %-18s ↑ `libc.so` es la musl de zig: en el host son 255B de linker script ⇒ NO CORRE fuera del sandbox\n' "" ;; esac mienten=$((mienten + 1))