#!/usr/bin/env bash # Repro: 755 maintainer scripts must pass; 644 must fail as not executable. set -euo pipefail root=$(cd "$(dirname "$0")" && pwd) verify=$root/verify_deb.sh scratch=$(mktemp -d) trap 'rm -rf -- "$scratch"' EXIT make_deb_755() { local dest=$1 local pkg=$scratch/pkg-755 rm -rf "$pkg" mkdir -p "$pkg/DEBIAN" "$pkg/usr/bin" printf '#!/bin/sh\nexit 0\n' >"$pkg/usr/bin/noop" chmod 755 "$pkg/usr/bin/noop" cat >"$pkg/DEBIAN/control" <<'EOF' Package: verify-deb-fixture Version: 0.0.1 Architecture: amd64 Maintainer: test Description: fixture for verify_deb.sh permission check EOF printf '#!/bin/sh\nexit 0\n' >"$pkg/DEBIAN/postinst" chmod 755 "$pkg/DEBIAN/postinst" dpkg-deb --build "$pkg" "$dest" >/dev/null } # dpkg-deb --build rejects 644 maintainer scripts; strip the execute bit in the # control tarball so verify_deb.sh still sees a real packaged 644 postinst. make_deb_644_from() { local src=$1 dest=$2 local work=$scratch/mutate rm -rf "$work" mkdir -p "$work/control" cp "$src" "$dest" ( cd "$work" && ar x "$dest" ) zstd -d -c "$work/control.tar.zst" | tar -C "$work/control" -xf - chmod 644 "$work/control/postinst" tar -C "$work/control" -cf - . | zstd -c >"$work/control.tar.zst" ( cd "$work" && ar r "$dest" control.tar.zst ) } ok_deb=$scratch/verify-deb-fixture_0.0.1_amd64.deb bad_deb=$scratch/verify-deb-fixture-noexec_0.0.1_amd64.deb make_deb_755 "$ok_deb" make_deb_644_from "$ok_deb" "$bad_deb" ok_out=$scratch/ok.out bad_out=$scratch/bad.out set +e "$verify" "$ok_deb" 0.0.1 amd64 >"$ok_out" 2>&1 ok_rc=$? "$verify" "$bad_deb" 0.0.1 amd64 >"$bad_out" 2>&1 bad_rc=$? set -e fail=0 if [[ $ok_rc -ne 0 ]] || ! grep -q 'VERIFY: OK' "$ok_out"; then echo "FAIL: 755 postinst should be treated as executable" >&2 cat "$ok_out" >&2 fail=1 fi if [[ $bad_rc -eq 0 ]] || ! grep -q 'not executable' "$bad_out"; then echo "FAIL: 644 postinst should fail as not executable" >&2 cat "$bad_out" >&2 fail=1 fi if ((fail)); then exit 1 fi echo "test_verify_deb.sh: OK"