G1: NEW-C — add length guard to STATUS_RESPONSE push handler

Why: parse_status with offset=8 reads up through data[56:60]
(the rx_airtime field), so a full STATUS_RESPONSE push frame is
60 bytes: 1 type + 1 reserved + 6 pubkey + 52 status fields. The
push handler in handle_rx previously called parse_status with no
length check at all, so a short frame would slice through empty
data and silently produce zeros for every missing field. HA sensor
telemetry would silently report all-zero status — same class as N07.

The BINARY_RESPONSE STATUS path at the bottom of handle_rx already
gates parse_status with `len(response_data) >= 52` on its
offset-stripped buffer; this commit adds the equivalent gate for
the push path: `if len(data) < 60: log + return`. The `return`
short-circuits cleanly out of the umbrella try block without
dispatching a STATUS_RESPONSE event for the bogus parse.

Refs: Forensics report finding NEW-C (S3)
This commit is contained in:
Matthew Wolter 2026-04-11 18:21:27 -07:00
parent 3273c3489c
commit a571eff4ce

View file

@ -569,6 +569,15 @@ class MessageReader:
)
elif packet_type_value == PacketType.STATUS_RESPONSE.value:
# parse_status with offset=8 reads up through data[56:60]
# (rx_airtime field), so the full payload is 60 bytes:
# 1 type + 1 reserved + 6 pubkey + 52 status fields. The
# BINARY_RESPONSE STATUS path below gates with `>= 52` on
# the offset-stripped buffer; this gate is the equivalent
# for the push path with the 8-byte header included.
if len(data) < 60:
logger.debug(f"STATUS_RESPONSE push frame too short ({len(data)} bytes < 60), skipping parse")
return
res = parse_status(data, offset=8)
data_hex = data[8:].hex()
logger.debug(f"Status response: {data_hex}")