Summary
Several ARC and flow-control opcode handlers parse fields (channel counts, buffer offsets) directly out of attacker-controlled UDP/TCP packet bytes and then index into the packet buffer using those fields — without first checking that the buffer is actually long enough. Rust panics on out-of-bounds slice/array indexing, and nothing supervises these tokio tasks, so a single malformed packet from anyone on the LAN (no authentication required) permanently kills the task handling that server. The daemon keeps running, but that subsystem stays dead until the whole process is restarted.
Affected locations
| File |
Opcode |
Issue |
inferno_aoip/src/device_server/flows_control_server.rs |
0x0100 (request flow) |
Channel count and offset fields read from the packet are used to index into it without checking the payload is long enough |
inferno_aoip/src/device_server/flows_control_server.rs |
0x0102 (update flow) |
No length check at all — any packet shorter than 8 bytes panics immediately on c[0..6] |
inferno_aoip/src/device_server/arc_server.rs |
0x3014 (netaudio unsubscribe) |
Channel index is read straight from the packet with no length or range check, then indexed directly into the channel vector |
inferno_aoip/src/device_server/arc_server.rs |
delete_multicast_tx_flow |
Indexes content[0]/content[1] and slices content[4..] with no length check |
Impact
- Flow control server (
0x0100/0x0102) — TX flow request/update stops working for everyone until restart.
- netaudio unsubscribe (
0x3014) — RX channel subscription handling dies.
delete_multicast_tx_flow — TX multicast management dies.
All are triggerable pre-auth by any device on the same network segment, with a single crafted packet.
Suggested fix
Add explicit length/bounds validation before each indexing operation (matching the pattern the 0x0100 handler already uses for its first field, just not extended far enough) — log and drop the malformed packet instead of indexing blind. Also worth considering: wrap these per-connection request handlers in a supervisor/catch_unwind boundary so a future parsing bug degrades to a dropped packet rather than a silent, permanent subsystem outage.
Possible follow-up
The same "parse offset from untrusted packet, then index without bounds-checking" pattern may exist elsewhere in code that touches raw network input (mdns_client.rs, flows_rx.rs packet-header parsing, channels_subscriber.rs remote-advertisement handling) — worth an equivalent audit.
Summary
Several ARC and flow-control opcode handlers parse fields (channel counts, buffer offsets) directly out of attacker-controlled UDP/TCP packet bytes and then index into the packet buffer using those fields — without first checking that the buffer is actually long enough. Rust panics on out-of-bounds slice/array indexing, and nothing supervises these
tokiotasks, so a single malformed packet from anyone on the LAN (no authentication required) permanently kills the task handling that server. The daemon keeps running, but that subsystem stays dead until the whole process is restarted.Affected locations
inferno_aoip/src/device_server/flows_control_server.rs0x0100(request flow)inferno_aoip/src/device_server/flows_control_server.rs0x0102(update flow)c[0..6]inferno_aoip/src/device_server/arc_server.rs0x3014(netaudio unsubscribe)inferno_aoip/src/device_server/arc_server.rsdelete_multicast_tx_flowcontent[0]/content[1]and slicescontent[4..]with no length checkImpact
0x0100/0x0102) — TX flow request/update stops working for everyone until restart.0x3014) — RX channel subscription handling dies.delete_multicast_tx_flow— TX multicast management dies.All are triggerable pre-auth by any device on the same network segment, with a single crafted packet.
Suggested fix
Add explicit length/bounds validation before each indexing operation (matching the pattern the
0x0100handler already uses for its first field, just not extended far enough) — log and drop the malformed packet instead of indexing blind. Also worth considering: wrap these per-connection request handlers in a supervisor/catch_unwindboundary so a future parsing bug degrades to a dropped packet rather than a silent, permanent subsystem outage.Possible follow-up
The same "parse offset from untrusted packet, then index without bounds-checking" pattern may exist elsewhere in code that touches raw network input (
mdns_client.rs,flows_rx.rspacket-header parsing,channels_subscriber.rsremote-advertisement handling) — worth an equivalent audit.