mirror of
https://github.com/vicliu624/trail-mate.git
synced 2026-08-22 02:29:44 +00:00
102 lines
3.2 KiB
Python
102 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Prevent USB MSC callbacks from widening a shared-SPI transaction."""
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
USB_RUNTIME = REPO_ROOT / "platform/esp/arduino_common/src/platform_ui_usb_support_runtime.cpp"
|
|
SD_RUNTIME = REPO_ROOT / "platform/esp/arduino_common/src/storage/sd_card_runtime.cpp"
|
|
|
|
|
|
def section(source: str, start: str, end: str) -> str:
|
|
start_at = source.find(start)
|
|
end_at = source.find(end, start_at)
|
|
if start_at < 0 or end_at < 0:
|
|
raise ValueError(f"could not locate section from {start} to {end}")
|
|
return source[start_at:end_at]
|
|
|
|
|
|
def require(text: str, fragment: str, message: str) -> None:
|
|
if fragment not in text:
|
|
raise ValueError(message)
|
|
|
|
|
|
def forbid(text: str, fragment: str, message: str) -> None:
|
|
if fragment in text:
|
|
raise ValueError(message)
|
|
|
|
|
|
def main() -> int:
|
|
try:
|
|
usb_source = USB_RUNTIME.read_text(encoding="utf-8")
|
|
sd_source = SD_RUNTIME.read_text(encoding="utf-8")
|
|
read_callback = section(
|
|
usb_source,
|
|
"int32_t usbReadCallback(",
|
|
"int32_t usbWriteCallback(",
|
|
)
|
|
write_callback = section(
|
|
usb_source,
|
|
"int32_t usbWriteCallback(",
|
|
"bool usbStartStopCallback(",
|
|
)
|
|
|
|
for fragment in (
|
|
"UsbMscBusGate",
|
|
"SharedSpiCoordinator",
|
|
"BusAcquireRequest",
|
|
"BusAccessToken",
|
|
"ScopedBusAccessToken",
|
|
"shared_spi_coordinator()",
|
|
):
|
|
forbid(
|
|
usb_source,
|
|
fragment,
|
|
f"USB MSC must not acquire shared SPI directly: {fragment}",
|
|
)
|
|
|
|
require(
|
|
usb_source,
|
|
"sd_set_external_block_owner_active(\n true);",
|
|
"USB MSC must retain its semantic external-owner state",
|
|
)
|
|
require(
|
|
read_callback,
|
|
"storage::sd_read_raw(",
|
|
"USB MSC reads must delegate every sector to the SD runtime",
|
|
)
|
|
require(
|
|
write_callback,
|
|
"storage::sd_write_raw(",
|
|
"USB MSC writes must delegate every sector to the SD runtime",
|
|
)
|
|
require(
|
|
usb_source,
|
|
"uint8_t s_usb_msc_sector_scratch[512];",
|
|
"USB MSC partial-sector work must use bounded static scratch storage",
|
|
)
|
|
for raw_operation in ("bool sd_read_raw(", "bool sd_write_raw("):
|
|
raw_section = section(sd_source, raw_operation, "} // namespace")
|
|
require(
|
|
raw_section,
|
|
"SdRuntimeOperationGuard",
|
|
f"{raw_operation} must stay inside the SD runtime logical guard",
|
|
)
|
|
require(
|
|
raw_section,
|
|
"s_sdfat.card()->",
|
|
f"{raw_operation} must use the SdFat driver physical boundary",
|
|
)
|
|
except (OSError, ValueError) as error:
|
|
print(f"Shared SPI USB MSC boundary check failed: {error}", file=sys.stderr)
|
|
return 1
|
|
|
|
print("Shared SPI USB MSC boundary check passed.")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|