Build: Verify SHA-256 checksums when installing s6-overlay & yt-dlp

Stage each download in a temporary file and verify it against the SHA-256 published by the upstream release (s6-overlay per-asset .sha256, yt-dlp SHA2-256SUMS) before installing. Abort on mismatch and warn when no manifest is published so older pinned tags still install.
This commit is contained in:
Michael Mayer 2026-06-10 18:25:05 +00:00
parent 88321bcda9
commit e232ea7de7
2 changed files with 74 additions and 9 deletions

View file

@ -77,11 +77,46 @@ echo "--------------------------------------------------------------------------
# Create the destination directory if it does not already exist.
mkdir -p "${S6_OVERLAY_DESTDIR}"
# Download and install the s6-overlay release from GitHub.
echo "Extracting \"$S6_NOARCH_URL\" to \"$S6_OVERLAY_DESTDIR\"..."
curl -fsSL "$S6_NOARCH_URL" | tar -C "${S6_OVERLAY_DESTDIR}" -Jxp
# Stage downloads in a temporary directory that is removed on exit.
S6_TMPDIR=$(mktemp -d)
trap 'rm -rf "${S6_TMPDIR}"' EXIT
echo "Extracting \"$S6_BINARY_URL\" to \"$S6_OVERLAY_DESTDIR\"..."
curl -fsSL "$S6_BINARY_URL" | tar -C "${S6_OVERLAY_DESTDIR}" -Jxp
# verify_sha256 checks a file against the SHA-256 published next to the release
# asset (<url>.sha256), aborting on mismatch. It soft-fails when no checksum is
# published so pinned older tags without a manifest still install.
verify_sha256() {
local url="$1" file="$2" sumfile="$3" expected actual
if ! curl -fsSL "${url}.sha256" -o "${sumfile}" 2>/dev/null; then
echo "Warning: no published checksum at ${url}.sha256; skipping verification." 1>&2
return 0
fi
expected=$(awk '{print $1}' "${sumfile}")
if command -v sha256sum >/dev/null 2>&1; then
actual=$(sha256sum "${file}" | awk '{print $1}')
else
actual=$(shasum -a 256 "${file}" | awk '{print $1}')
fi
if [[ ${expected} != "${actual}" ]]; then
echo "Error: SHA-256 mismatch for $(basename "${file}")." 1>&2
echo " expected: ${expected}" 1>&2
echo " actual: ${actual}" 1>&2
exit 1
fi
echo "Checksum OK ($(basename "${file}"): ${actual})."
}
# download_and_extract fetches a release tarball, verifies it, then extracts it.
download_and_extract() {
local url="$1" name="$2" archive="${S6_TMPDIR}/${2}"
echo "Downloading \"${url}\"..."
curl -fsSL "${url}" -o "${archive}"
verify_sha256 "${url}" "${archive}" "${archive}.sha256"
echo "Extracting \"${name}\" to \"${S6_OVERLAY_DESTDIR}\"..."
tar -C "${S6_OVERLAY_DESTDIR}" -Jxp -f "${archive}"
}
# Download, verify, and install the s6-overlay release from GitHub.
download_and_extract "$S6_NOARCH_URL" "$ARCHIVE_NOARCH"
download_and_extract "$S6_BINARY_URL" "$ARCHIVE_BINARY"
echo "Done."

View file

@ -167,6 +167,7 @@ fi
TAG_NAME=""
ASSET_NAME=""
ASSET_URL=""
CHECKSUM_URL=""
while IFS= read -r release; do
tag=$(echo "$release" | jq -r '.tag_name // empty')
@ -178,6 +179,8 @@ while IFS= read -r release; do
TAG_NAME=$tag
ASSET_NAME=$candidate
ASSET_URL=$url
# yt-dlp publishes one SHA2-256SUMS manifest per release listing every asset.
CHECKSUM_URL=$(echo "$release" | jq -r '.assets[]? | select(.name == "SHA2-256SUMS") | .browser_download_url' | head -n1)
break 2
fi
done
@ -205,10 +208,37 @@ echo "DESTBIN : ${DESTBIN}"
echo "--------------------------------------------------------------------------------"
echo "Downloading the yt-dlp binary to \"${DESTBIN}\"..."
mkdir -p "${DESTDIR}"
curl --fail --silent --show-error --location "${GITHUB_URL}" -o "${DESTBIN}"
mkdir -p "${DESTDIR}/bin"
tmp_bin=$(mktemp)
trap 'rm -f "${tmp_bin}" "${tmp_bin}.sums"' EXIT
curl --fail --silent --show-error --location "${GITHUB_URL}" -o "${tmp_bin}"
echo "Changing permissions of \"${DESTBIN}\" to 755..."
chmod 755 "${DESTBIN}"
# Verify the binary against the release SHA2-256SUMS manifest before installing.
# Soft-fail when no manifest is published so older pinned tags still install.
if [[ -n ${CHECKSUM_URL} && ${CHECKSUM_URL} != "null" ]] &&
curl --fail --silent --show-error --location "${CHECKSUM_URL}" -o "${tmp_bin}.sums" 2>/dev/null; then
expected=$(awk -v n="${ASSET_NAME}" '$2 == n {print $1}' "${tmp_bin}.sums")
if [[ -z ${expected} ]]; then
echo "Error: ${ASSET_NAME} not listed in SHA2-256SUMS; refusing to install." 1>&2
exit 1
fi
if command -v sha256sum >/dev/null 2>&1; then
actual=$(sha256sum "${tmp_bin}" | awk '{print $1}')
else
actual=$(shasum -a 256 "${tmp_bin}" | awk '{print $1}')
fi
if [[ ${expected} != "${actual}" ]]; then
echo "Error: SHA-256 mismatch for yt-dlp (${ASSET_NAME})." 1>&2
echo " expected: ${expected}" 1>&2
echo " actual: ${actual}" 1>&2
exit 1
fi
echo "Checksum OK (${actual})."
else
echo "Warning: no published checksum for ${ASSET_NAME}; skipping verification." 1>&2
fi
echo "Installing yt-dlp to \"${DESTBIN}\" with permissions 755..."
install -m 755 "${tmp_bin}" "${DESTBIN}"
echo "Done."