Skip to content

RCVR_CMD_INFO sends three bytes of uninitialised stack to an unauthenticated caller; the client prints them as the flash size #140

Description

@Kartikey1306

recovery_handle_info() in core/recovery.c builds its response in a struct that is not __attribute__((packed)) — unlike rcvr_packet_t fifteen lines above it — and never zeroes it. Only the six named members are assigned, then eos_hal_uart_send(&info, sizeof(info)) transmits the whole object.

Measured, not argued:

sizeof(info) == 24   offsetof(flash_size) == 4

so bytes 1–3 are padding the code never writes. RCVR_CMD_INFO is not in cmd_requires_auth(), so any client on the UART can ask, repeatedly, before authenticating. With the struct poisoned to 0xA5 and filled exactly as the firmware fills it:

wire[0..8]: AA A5 A5 A5 00 00 10 00

Three bytes of whatever the previous call left on the stack, to an unauthenticated caller.

The repo's own client, tools/uart_recovery.py, reads 1 + 4*5 = 21 bytes and unpacks '<IIIII' from response[1:21] — it has always expected the packed layout. So it decodes flash_size = 0x00A5A5A5 (the leaked bytes, printed as "Flash size"), every slot address one word off, and leaves three surplus bytes in the serial buffer to desynchronise whatever command follows.

grep -rn "CMD_INFO\|handle_info" tests/ is empty. Nothing has ever exercised this command.

Raised by the automated review of #131 (finding 1, P1, pre-existing). Fix in #139: pack the struct and memset it — which makes the firmware send what the client always read, a repair rather than a format change — plus a test that drives RCVR_CMD_INFO through the sim_ops harness with the output buffer poisoned first.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions