You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#1166 stops the crash by parsing remote stub data with a non-throwing helper that returns 0 on malformed input. That means a corrupt packet silently becomes a valid-looking answer — a bad thread id turns into thread 0, and we then show the user the wrong thread's registers with no indication anything is wrong. Accepted deliberately to keep the fix local during feature freeze.
The session should instead end deliberately, reporting the offending field and data. An attempt at that was dropped from #1166 (commit f7a1961); review of it showed what a real implementation needs:
Wider catch boundary than ExecuteAdapterAndWait.NotifyStopped runs after it returns and refreshes caches; HandleSpontaneousAdapterStop has no boundary; WorkerThreadMain runs tasks bare, so an escape is std::terminate; InvokeBackendCommand reaches monitor-command decoding directly from the API/FFI.
Real transport teardown. A synthetic TargetExited only updates BN-side state. The teardown lives in the adapter (m_socket->Kill(), delete m_rspConnector, InvalidateCache). Also m_adapter is never reset on any session end today, so CreateDebugAdapter reuses it.
RAII on the stop channel. An exception between setting and clearing m_inAdapterWait leaves a stale pending stop that swallows later adapter events.
Ignore unrecognized stop-reply fields.PacketToUnorderedMap parses every key:value as hex, but the spec requires unknown pairs be ignored and defines non-hex values we advertise support for (replaylog:begin, exec:<hex pathname>, fork/vforkpPID.TID). Parsing only the keys we consume is both spec-correct and smaller.
PacketToUnorderedMap: T05thread:1:garbage; splits into three tokens and falls through to packet_map[key] = 0; values are truncated to 16 chars before validation, so trailing garbage disappears.
GdbMiAdapter::ReadMemory checks from_chars().ec but not full consumption, so "aZ" parses as 0x0a; odd-length replies truncate; hard errors return an all-zero buffer indistinguishable from valid memory.
Follow-up to #1164 / #1166.
#1166 stops the crash by parsing remote stub data with a non-throwing helper that returns
0on malformed input. That means a corrupt packet silently becomes a valid-looking answer — a bad thread id turns into thread 0, and we then show the user the wrong thread's registers with no indication anything is wrong. Accepted deliberately to keep the fix local during feature freeze.The session should instead end deliberately, reporting the offending field and data. An attempt at that was dropped from #1166 (commit
f7a1961); review of it showed what a real implementation needs:ExecuteAdapterAndWait.NotifyStoppedruns after it returns and refreshes caches;HandleSpontaneousAdapterStophas no boundary;WorkerThreadMainruns tasks bare, so an escape isstd::terminate;InvokeBackendCommandreaches monitor-command decoding directly from the API/FFI.TargetExitedonly updates BN-side state. The teardown lives in the adapter (m_socket->Kill(),delete m_rspConnector,InvalidateCache). Alsom_adapteris never reset on any session end today, soCreateDebugAdapterreuses it.m_inAdapterWaitleaves a stale pending stop that swallows later adapter events.PacketToUnorderedMapparses everykey:valueas hex, but the spec requires unknown pairs be ignored and defines non-hex values we advertise support for (replaylog:begin,exec:<hex pathname>,fork/vforkpPID.TID). Parsing only the keys we consume is both spec-correct and smaller.Outstanding regardless of the exception work:
esrevenadapter.cppstill uses rawstd::stoull(:1797,:2249,:2251) andstd::stoi(:2309) — the call sites Malformed remote stub data can crash via unguarded std::stoi/stoull #1164 describes.PacketToUnorderedMap:T05thread:1:garbage;splits into three tokens and falls through topacket_map[key] = 0; values are truncated to 16 chars before validation, so trailing garbage disappears.GdbMiAdapter::ReadMemorychecksfrom_chars().ecbut not full consumption, so"aZ"parses as0x0a; odd-length replies truncate; hard errors return an all-zero buffer indistinguishable from valid memory.