Add USB maturity proof scripts
This commit is contained in:
Executable
+42
@@ -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"
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user