Blockstream / Blockstream/Jade

Possible infinite busy-loop in serial writer if the transport reports 0 bytes written repeatedly

Open
#319 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
496
Forks
127
PR merge metrics
No merged PRs in 30d

Description

## Summary

`write_serial()` (`main/serial.c:150-174`) loops until all bytes are written, but only treats a return of `-1` as an error:

```c
int written = 0;
while (written != length) {
const int wrote = tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, msg + written, length - written);
// or on ESP32: uart_write_bytes(UART_NUM_0, msg + written, length - written);
if (wrote == -1) {
return false;
}
written += wrote;
}
```

If the transport returns `0` repeatedly — e.g. `tinyusb_cdcacm_write_queue()` when the USB-CDC TX buffer is full and no host is reading (cable unplugged, or host app killed mid-transfer), or `uart_write_bytes()` with a full TX ring buffer — the loop spins forever with no delay and no timeout, causing the task watchdog to fire (device reboot) or a permanent hang. Note the `fwrite()` path (USB-JTAG serial on ESP32-S3) never returns `-1`, so any short write/error there already spins forever today.

`write_ble()` (`main/ble/ble.c:308-334`) has the correct pattern: bounded retries (~2s) then return `false`. And `jade_process_get_out_message()` (`main/process.c:467-469`) documents that a failed write drops the message (the host times out and retries), so returning `false` is safe and recoverable.

## Suggested fix

Mirror the BLE approach in `write_serial()`: retry with a bounded timeout (with a small delay between attempts), then return `false` after e.g. ~2s of consecutive zero-writes. The success path (`wrote > 0`) is unchanged; the only behavior change is on a stuck link, where dropping the message (host retry) replaces a watchdog reboot.

## Verification

Confirmed still present on current `master` (as of 2026-08-04): `main/serial.c:156` unchanged. The exact trigger needs hardware confirmation of the driver return value (0 vs -1) when the device is disconnected mid-write.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.