qemu and build: review fixes across the rig driver, boot script, and fetch helpers
Bounded waits and validated arguments in run.sh and ui-drive.sh, a seeded settings directory and root-only staged rootfs permissions with their own tests, qmp.py and imgtools.py hardening, the fetch scripts checking what they download, and ASCII typography throughout. Each fix carries its test under qemu/tests or tests/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N3G6m9Aw5RyVY4ZowtKzEj
This commit is contained in:
@@ -12,6 +12,14 @@
|
||||
# Same shape as fetch-kernel-tarball.sh, deliberately: a version bump edits this
|
||||
# file and the pin beside it, nothing else. FAILS CLOSED on a missing pin.
|
||||
#
|
||||
# Not wired into build-firmware.sh or CI yet -- tools/build-firmware.sh stages
|
||||
# sdk-patches/buildroot/ onto whatever buildroot tree the vendor SDK already
|
||||
# has, it does not yet extract this pinned tarball over it. Exercised today by
|
||||
# tests/fetch-buildroot-tarball/run-fetch-buildroot-tarball-tests.sh and by
|
||||
# running the script by hand; wiring it into the real build path is a separate
|
||||
# change (it has to reconcile the pristine tree with the existing SDK buildroot
|
||||
# checkout first).
|
||||
#
|
||||
# Usage: fetch-buildroot-tarball.sh <destination-path>
|
||||
set -euo pipefail
|
||||
|
||||
@@ -43,7 +51,11 @@ fi
|
||||
|
||||
for attempt in 1 2 3; do
|
||||
echo "== fetching buildroot-$BRVER (attempt $attempt)"
|
||||
if curl -fsSL --retry 2 -o "$TB" "$URL" && verify; then
|
||||
# --retry only re-fires once curl decides a transfer has failed; a connection
|
||||
# that opens and then stalls (blackholed route, hung proxy) never reaches
|
||||
# that decision and would otherwise block forever. --connect-timeout bounds
|
||||
# the handshake, --max-time bounds the whole request.
|
||||
if curl -fsSL --retry 2 --connect-timeout 20 --max-time 120 -o "$TB" "$URL" && verify; then
|
||||
echo "buildroot-$BRVER: sha256 verified"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
+18
-1
@@ -26,7 +26,11 @@ while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--check) MODE="check"; shift ;;
|
||||
--fetch) MODE="fetch"; shift ;;
|
||||
-h|--help) sed -n '2,18p' "$0"; exit 0 ;;
|
||||
# Print the header comment (line 1 is the shebang, so start at 2) and
|
||||
# stop at the first line of code rather than a hardcoded line count --
|
||||
# a fixed range silently starts printing code again the next time the
|
||||
# header comment grows or shrinks.
|
||||
-h|--help) awk '/^set /{exit} NR>1{print}' "$0"; exit 0 ;;
|
||||
*) DIR="$1"; shift ;;
|
||||
esac
|
||||
done
|
||||
@@ -34,6 +38,19 @@ done
|
||||
[ -r "$MANIFEST" ] || { echo "FATAL: no manifest at $MANIFEST" >&2; exit 1; }
|
||||
command -v git >/dev/null || { echo "FATAL: git not on PATH" >&2; exit 1; }
|
||||
|
||||
# A stalled clone (dead peer, wedged proxy) must not hang this script forever
|
||||
# with no way for a caller to tell "still working" from "wedged" -- the
|
||||
# luckfox-pico tree alone is ~21 GB, so a plain wall-clock timeout would also
|
||||
# abort a clone that is merely slow. Abort only on a stall instead: git's http
|
||||
# transport already aborts a transfer whose average speed drops below
|
||||
# LOW_SPEED_LIMIT bytes/sec for LOW_SPEED_TIME seconds straight, so a slow but
|
||||
# progressing clone is never penalized. Both are overridable for a link that
|
||||
# is legitimately slow.
|
||||
: "${WARDEN_VENDOR_LOW_SPEED_LIMIT:=1000}"
|
||||
: "${WARDEN_VENDOR_LOW_SPEED_TIME:=60}"
|
||||
export GIT_HTTP_LOW_SPEED_LIMIT="$WARDEN_VENDOR_LOW_SPEED_LIMIT"
|
||||
export GIT_HTTP_LOW_SPEED_TIME="$WARDEN_VENDOR_LOW_SPEED_TIME"
|
||||
|
||||
if [ -z "$DIR" ]; then
|
||||
DIR="${WARDEN_VENDOR_DIR:-$HOME/projects/scada/flare-edge}"
|
||||
fi
|
||||
|
||||
+25
-13
@@ -42,7 +42,12 @@ while [ $# -gt 0 ]; do
|
||||
# displays it on an ordinary boot.
|
||||
--logo-verbose) LOGO_VERBOSE="${2:?}"; shift 2 ;;
|
||||
--resource-tool) RTOOL="${2:?}"; shift 2 ;;
|
||||
-h|--help) sed -n '2,25p' "$0"; exit 0 ;;
|
||||
# Print the header comment (line 1 is the shebang, so start at 2) and
|
||||
# stop at the first line of code rather than a hardcoded line count --
|
||||
# a fixed range silently starts printing code again the next time the
|
||||
# header comment grows or shrinks (see build/fetch-vendor.sh's own
|
||||
# --help, which had this exact bug).
|
||||
-h|--help) awk '/^set /{exit} NR>1{print}' "$0"; exit 0 ;;
|
||||
*) echo "FATAL: unknown argument '$1'" >&2; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
@@ -52,6 +57,11 @@ done
|
||||
[ -n "$OUT" ] || { echo "FATAL: --out is required" >&2; exit 1; }
|
||||
command -v mkimage >/dev/null || {
|
||||
echo "FATAL: mkimage not on PATH (Debian/Ubuntu: u-boot-tools)" >&2; exit 1; }
|
||||
# fdtget backs the post-build alignment assertions below (the whole point of
|
||||
# which is that a misaligned image boots fine in CI and fails on a panel), so
|
||||
# its absence must fail the build rather than silently skip those checks.
|
||||
command -v fdtget >/dev/null || {
|
||||
echo "FATAL: fdtget not on PATH (Debian/Ubuntu: device-tree-compiler)" >&2; exit 1; }
|
||||
|
||||
# resource_tool is a Rockchip host tool. It has no free-standing source here, so
|
||||
# it is taken from the vendor SDK when one is present rather than vendored as a
|
||||
@@ -160,11 +170,6 @@ ITS
|
||||
# vendor's -p value -- the absolute position of the first payload -- not an
|
||||
# alignment.
|
||||
#
|
||||
# The flag is feature-detected because the SDK vendors mkimage 2017.09,
|
||||
# which has no -B at all and dies with "invalid option -- 'B'". Its packer
|
||||
# already 512-aligns, so omitting the flag there is correct rather than a
|
||||
# fallback. project/build.sh prepends the SDK tool dir to PATH, so that
|
||||
# binary IS what a build inside the SDK environment resolves.
|
||||
# A -B-capable mkimage is REQUIRED, not preferred. The SDK vendors 2017.09,
|
||||
# which has no -B, and project/build.sh:64 puts it first on PATH -- so the
|
||||
# wrong one is what a build inside the SDK environment picks up. Measured:
|
||||
@@ -198,16 +203,24 @@ echo "== FIT (external data, -E -p 0x800 -B 0x200) using $MKIMAGE"
|
||||
|
||||
# Assert what U-Boot actually requires, on every build: the failure is silent --
|
||||
# a misread offset does not fail the build, it fails on a panel, and sometimes
|
||||
# only as a missing logo.
|
||||
_meta="$(od -An -tu4 -j4 -N4 --endian=big "$WORKDIR/boot.img" | tr -d ' ')"
|
||||
if [ $(( _meta % 512 )) -ne 0 ]; then
|
||||
echo "FATAL: FIT metadata is $_meta bytes, not a multiple of 512;" >&2
|
||||
# only as a missing logo. Computed once and reused below (the embedded-data-FIT
|
||||
# check further down needs the same value) so a future fix to how this is read
|
||||
# cannot land in one check and not the other.
|
||||
meta="$(od -An -tu4 -j4 -N4 --endian=big "$WORKDIR/boot.img" | tr -d ' ')"
|
||||
if [ $(( meta % 512 )) -ne 0 ]; then
|
||||
echo "FATAL: FIT metadata is $meta bytes, not a multiple of 512;" >&2
|
||||
echo " FIT_ALIGN would round it up and every payload reads late" >&2
|
||||
exit 1
|
||||
fi
|
||||
for _n in fdt kernel resource; do
|
||||
_pos="$(fdtget -t u "$WORKDIR/boot.img" "/images/$_n" data-position 2>/dev/null || true)"
|
||||
[ -n "$_pos" ] || continue
|
||||
# fdtget's presence is checked up front; a failure here means the FIT this
|
||||
# script just built is malformed, not that the field is legitimately
|
||||
# absent (mkimage -E gives every one of these images a data-position). Fail
|
||||
# loud rather than treat an empty read as nothing to check.
|
||||
if ! _pos="$(fdtget -t u "$WORKDIR/boot.img" "/images/$_n" data-position 2>&1)"; then
|
||||
echo "FATAL: fdtget could not read /images/$_n data-position: $_pos" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ $(( _pos % 512 )) -ne 0 ]; then
|
||||
echo "FATAL: /images/$_n data-position $_pos is not 512-aligned;" >&2
|
||||
echo " U-Boot's truncating block divide would read the wrong offset" >&2
|
||||
@@ -218,7 +231,6 @@ done
|
||||
# A FIT whose metadata swelled to the size of the whole image is an
|
||||
# embedded-data build, which this U-Boot rejects. Catch it here rather than on
|
||||
# a panel that will not come back.
|
||||
meta="$(od -An -tu4 -j4 -N4 --endian=big "$WORKDIR/boot.img" | tr -d ' ')"
|
||||
total="$(stat -c %s "$WORKDIR/boot.img")"
|
||||
if [ "${meta:-0}" -ge 4096 ] || [ "${meta:-0}" -ge "$total" ]; then
|
||||
echo "FATAL: FIT metadata is ${meta} bytes of a ${total}-byte image: that is an" >&2
|
||||
|
||||
@@ -1351,7 +1351,14 @@ CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
|
||||
CONFIG_NETFILTER_XT_NAT=y
|
||||
CONFIG_NETFILTER_XT_TARGET_MASQUERADE=y
|
||||
CONFIG_NF_DEFRAG_IPV4=y
|
||||
CONFIG_NF_CONNTRACK_IPV4=y
|
||||
# No NF_CONNTRACK_IPV4 symbol here -- IPv4 conntrack has been unconditional in
|
||||
# NF_CONNTRACK's core since well before 6.18 (net/ipv4/netfilter/Kconfig has no
|
||||
# such config). Only stale arch defconfigs (e.g. keystone_defconfig) still set
|
||||
# it; Kconfig drops an unknown symbol with no warning, so it looked live but
|
||||
# did nothing. Left out on purpose so this file does not claim a gate that
|
||||
# does not exist. If a future kernel bump reintroduces a real symbol by this
|
||||
# name, catch it by diffing the expanded .config, not by functional test alone
|
||||
# -- see PORT-STATUS.md's own history of a silent-drop hiding a real gap.
|
||||
CONFIG_IP_NF_IPTABLES=y
|
||||
# 6.18 SPLIT THE LEGACY TABLES OUT. IP_NF_FILTER and IP_NF_NAT depend on
|
||||
# IP_NF_IPTABLES_LEGACY, which did not exist in 5.10 -- so copying the vendor
|
||||
|
||||
Reference in New Issue
Block a user