Skip to content

Conversation

@weebl2000
Copy link
Contributor

Severity: High

Summary

The onContactResponse handler in the companion radio firmware copies peer response data into out_frame without checking whether the data fits. The out_frame buffer is MAX_FRAME_SIZE + 1 (173 bytes), but peer responses can be up to MAX_PACKET_PAYLOAD (184 bytes).

Three code paths are affected — status response, telemetry response, and binary response. Each writes a small header (6-8 bytes) then copies len - 4 bytes of response data. When len is close to 184, the total write reaches 188 bytes, overflowing the buffer by 15 bytes.

How this can be exploited

A malicious peer that you've logged into (repeater, room server) can send an oversized status or telemetry response. The companion radio node receives and decrypts it successfully (the peer has a valid shared secret), then copies the response into the undersized out_frame buffer on the stack.

This corrupts adjacent stack variables and the return address. On ESP32, this causes a crash/reboot at minimum, and could potentially be leveraged for code execution. An attacker could use this to:

  • Repeatedly crash a target node by sending large responses whenever it connects
  • Deny service to the companion radio user — each login attempt triggers the overflow and reboots the device
  • Potentially execute arbitrary code if the attacker can control the overflow contents precisely

Users would see their device crash or reboot every time it connects to a specific repeater or room server.

Fix

Cap the memcpy length to the remaining space in out_frame before copying, in all three affected code paths. Oversized responses are truncated rather than overflowing.

Test plan

  • Normal status/telemetry/binary responses still work
  • Large responses are truncated gracefully
  • Build tested on Heltec_v3_companion_radio_ble

The onContactResponse handler copies peer response data into out_frame
(MAX_FRAME_SIZE + 1 bytes) without checking whether the data fits. A
peer response with len close to MAX_PACKET_PAYLOAD (184) writes up to
188 bytes into the 173-byte buffer, overflowing by 15 bytes.

This affects the status response, telemetry response, and binary
response code paths. A malicious peer can trigger the overflow by
sending a large response payload, corrupting the stack.

Cap each memcpy to the remaining space in out_frame before copying.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant