Add USB maturity proof scripts

This commit is contained in:
2026-04-18 21:38:30 +01:00
parent a152f3e646
commit 387df2a179
3 changed files with 101 additions and 4 deletions
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# Run the bounded USB maturity proof helpers in sequence.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
usage() {
cat <<'USAGE'
Usage: test-usb-maturity-qemu.sh [config]
Run the bounded USB maturity proof helpers in sequence.
Defaults to redbear-desktop.
Checks run:
- xHCI interrupt mode
- full USB stack proof
- USB storage bounded readback proof
USAGE
}
for arg in "$@"; do
case "$arg" in
--help|-h|help)
usage
exit 0
;;
esac
done
config="${1:-redbear-desktop}"
echo ">>> Running xHCI interrupt proof"
bash "$SCRIPT_DIR/test-xhci-irq-qemu.sh" --check "$config"
echo ">>> Running full USB stack proof"
bash "$SCRIPT_DIR/test-usb-qemu.sh" --check "$config"
echo ">>> Running USB storage readback proof"
bash "$SCRIPT_DIR/test-usb-storage-qemu.sh" "$config"
echo "All bounded USB maturity checks passed for $config"
+32 -3
View File
@@ -6,6 +6,25 @@
set -euo pipefail set -euo pipefail
seed_usb_image() {
local image_path="$1"
python3 - "$image_path" <<'PY'
import base64
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
payload = (b"REDBEAR-USB-FULL-STACK-CHECK\0" * 32)[:512]
payload = payload.ljust(512, b'\0')
with path.open("r+b") as fh:
fh.seek(0)
fh.write(payload)
print(base64.b64encode(payload).decode("ascii"))
PY
}
find_uefi_firmware() { find_uefi_firmware() {
local candidates=( local candidates=(
"/usr/share/ovmf/x64/OVMF.4m.fd" "/usr/share/ovmf/x64/OVMF.4m.fd"
@@ -37,8 +56,9 @@ Checks performed:
1. xHCI controller initializes and reports interrupt mode 1. xHCI controller initializes and reports interrupt mode
2. USB HID driver spawns for keyboard/tablet 2. USB HID driver spawns for keyboard/tablet
3. USB SCSI driver spawns for mass storage 3. USB SCSI driver spawns for mass storage
4. BOS descriptor fetched (or gracefully skipped for USB 2) 4. USB storage sector-0 readback matches a seeded host pattern
5. No panics or crash-class errors in USB daemons 5. BOS descriptor fetched (or gracefully skipped for USB 2)
6. No panics or crash-class errors in USB daemons
USAGE USAGE
} }
@@ -84,6 +104,8 @@ if [[ ! -f "$usb_img" ]]; then
truncate -s 64M "$usb_img" truncate -s 64M "$usb_img"
fi fi
expected_sector_b64="$(seed_usb_image "$usb_img")"
pkill -f "qemu-system-x86_64.*$image" 2>/dev/null || true pkill -f "qemu-system-x86_64.*$image" 2>/dev/null || true
sleep 1 sleep 1
@@ -136,7 +158,7 @@ else
failures=$((failures + 1)) failures=$((failures + 1))
fi fi
# Check 3: USB SCSI driver spawn # Check 3: USB SCSI driver spawn + bounded data readback
if grep -q "USB SCSI driver spawned" "$log_file"; then if grep -q "USB SCSI driver spawned" "$log_file"; then
echo " [PASS] USB SCSI driver spawned" echo " [PASS] USB SCSI driver spawned"
else else
@@ -144,6 +166,13 @@ else
failures=$((failures + 1)) failures=$((failures + 1))
fi fi
if grep -Fq "DISK CONTENT: $expected_sector_b64" "$log_file"; then
echo " [PASS] USB storage sector readback matched seeded pattern"
else
echo " [FAIL] USB storage sector readback did not match seeded pattern" >&2
failures=$((failures + 1))
fi
# Check 4: BOS descriptor handling (info or debug log) # Check 4: BOS descriptor handling (info or debug log)
if grep -q "BOS:" "$log_file"; then if grep -q "BOS:" "$log_file"; then
echo " [PASS] BOS descriptor processing active" echo " [PASS] BOS descriptor processing active"
+27 -1
View File
@@ -3,6 +3,25 @@
set -euo pipefail set -euo pipefail
seed_usb_image() {
local image_path="$1"
python3 - "$image_path" <<'PY'
import base64
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
payload = (b"REDBEAR-USB-STORAGE-CHECK\0" * 32)[:512]
payload = payload.ljust(512, b'\0')
with path.open("r+b") as fh:
fh.seek(0)
fh.write(payload)
print(base64.b64encode(payload).decode("ascii"))
PY
}
find_uefi_firmware() { find_uefi_firmware() {
local candidates=( local candidates=(
"/usr/share/ovmf/x64/OVMF.4m.fd" "/usr/share/ovmf/x64/OVMF.4m.fd"
@@ -66,6 +85,8 @@ if [[ ! -f "$usb_img" ]]; then
truncate -s 64M "$usb_img" truncate -s 64M "$usb_img"
fi fi
expected_sector_b64="$(seed_usb_image "$usb_img")"
pkill -f "qemu-system-x86_64.*$image" 2>/dev/null || true pkill -f "qemu-system-x86_64.*$image" 2>/dev/null || true
sleep 1 sleep 1
@@ -101,9 +122,14 @@ if ! grep -q "USB SCSI driver spawned" "$log_file"; then
exit 1 exit 1
fi fi
if ! grep -Fq "DISK CONTENT: $expected_sector_b64" "$log_file"; then
echo "ERROR: USB storage sector 0 readback did not match the seeded pattern; see $log_file" >&2
exit 1
fi
if grep -q "panic\|usbscsid: .*IO ERROR\|usbscsid: startup failed\|usbscsid: event queue error\|usbscsid: scheme tick failed\|bulk .* endpoint stalled" "$log_file"; then if grep -q "panic\|usbscsid: .*IO ERROR\|usbscsid: startup failed\|usbscsid: event queue error\|usbscsid: scheme tick failed\|bulk .* endpoint stalled" "$log_file"; then
echo "ERROR: USB storage path hit a crash/error; see $log_file" >&2 echo "ERROR: USB storage path hit a crash/error; see $log_file" >&2
exit 1 exit 1
fi fi
echo "USB mass-storage autospawn detected in $log_file" echo "USB mass-storage readback verified in $log_file"