#!/usr/bin/env bash # Determine the recursive NEEDED closure of startplasma-x11 inside the # extra-rootfs and intersect it with the corruption lists (TRUNCATED / # NOT-ELF). Emits the repair package list. set -uo pipefail IMG="${1:?img}" WORK=/home/deshab/repair_scan rm -rf "$WORK"; mkdir -p "$WORK" L=$(losetup --find --show --partscan "$IMG") sleep 0.3 M=$(mktemp -d) mount -o ro "${L}p1" "$M" || exit 1 R="$WORK/root" mkdir -p "$R" mount -o loop,ro "$M/boot/linux-extra-rootfs.img" "$R" || exit 1 # 1) NEEDED closure walk (pure userspace, no guest needed) python3 - "$R" <<'PY' > "$WORK/closure.txt" import os, struct, sys root = sys.argv[1] libdirs = [os.path.join(root, d) for d in ("usr/lib", "lib", "usr/lib64")] def find(name): for d in libdirs: p = os.path.join(d, name) if os.path.isfile(p): return p return None def needed(path): try: with open(path, "rb") as f: hdr = f.read(64) if hdr[:4] != b"\x7fELF": return [] e_phoff = struct.unpack_from(" %s" % (os.path.basename(p), n)) if q: queue.append(q) PY sort -u "$WORK/closure.txt" > "$WORK/closure_sorted.txt" # unique lib names in the closure awk '{print $NF}' "$WORK/closure_sorted.txt" | sort -u > "$WORK/closure_libs.txt" # 2) corruption lists grep -E 'TRUNCATED|NOT-ELF' /home/deshab/elfscan_native.txt | awk '{print $NF}' | sort -u > "$WORK/bad_libs.txt" # 3) intersection: bad libs that are actually on the Plasma path comm -12 "$WORK/closure_libs.txt" "$WORK/bad_libs.txt" > "$WORK/bad_on_path.txt" echo "=== closure libs: $(wc -l < "$WORK/closure_libs.txt") ===" echo "=== bad libs total: $(wc -l < "$WORK/bad_libs.txt") ===" echo "=== BAD ON PLASMA PATH: $(wc -l < "$WORK/bad_on_path.txt") ===" cat "$WORK/bad_on_path.txt" # closure edges referencing bad libs echo "=== edges into bad libs ===" grep -F -f "$WORK/bad_on_path.txt" "$WORK/closure_sorted.txt" | head -40 umount "$R" umount "$M"; rmdir "$M"; losetup -d "$L"