feat(ipc): wire-protocol version handshake — refuse a skewed cef_host#18
Merged
Merged
Conversation
… instead of silently mis-parsing Architecture-audit follow-up (finding #4): the framed kOp protocol had no version negotiation — opReady carried a single ad-hoc-flag byte, so a plugin paired with a protocol-skewed host (a FLUTTER_CEF_HOST override, a stale from-source build, a stale embedded copy) mis-parsed or silently dropped frames: frozen/blank tiles with zero breadcrumb. The content-hash distribution keeps the pair matched on the normal path; this closes the bypass vectors. - cef_host (main.mm): opReady's payload is now [readyFlags, kCefHostProtocolVersion]. Pre-handshake hosts sent 1 byte and read as v0. Unknown opcodes in the reader are now logged once per opcode via SendLog (previously a silent `default: break`) — a newer-plugin/older-host frame drop leaves a breadcrumb. - CefProfileHost.swift: expected-version constant beside the opcode table (bump BOTH on any wire change); the opReady arm refuses a mismatched host BEFORE flushing any queued create, clears pendingCreates, and fires onProtocolMismatch — reusing the F.5 refuse-at-ready pattern. - FlutterCefPlugin.swift: the host-death teardown is extracted to failHost(_:reason:) and shared; onProtocolMismatch fails every attached session with processGone("protocolMismatch(host=vN)") and tears the host down. Deliberately NO auto-respawn (it would re-resolve the same binary and loop); the consumer's bounded recovery surfaces it. Validated live with the example app: v1 plugin + v0 host (the currently-published prebuilt) is REFUSED at the handshake ("wire-protocol version 0 != expected 1", zero renders); v1 plugin + from-source v1 host renders flutter.dev normally; Dart unit suite green. NOTE: changes native/cef_host -> new content hash. After merge, publish the new artifact (work_canvas `make publish-cef-host`) and bump the consumer pin (picks up #17's fetch codesign-verify as well). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Architecture-audit follow-up (finding #4): the framed kOp protocol had no version negotiation — a plugin paired with a protocol-skewed host (
FLUTTER_CEF_HOSToverride, stale from-source build, stale embedded copy) mis-parsed or silently dropped frames: frozen/blank tiles with zero breadcrumb.Changes
opReadypayload is now[readyFlags, kCefHostProtocolVersion](pre-handshake hosts sent 1 byte → read as v0). Unknown opcodes in the reader now log once per opcode via SendLog instead of a silentdefault: break.onProtocolMismatch.failHost(_:reason:)and shared; a mismatch fails every attached session withprocessGone("protocolMismatch(host=vN)")and tears the host down. Deliberately no auto-respawn (it would re-resolve the same binary and loop).Validated (live, example app)
wire-protocol version 0 != expected 1, zero renders ✅Post-merge:
native/cef_hostchanged → new content hash. Run work_canvasmake publish-cef-host, thenmake pin-cef(the bump also delivers #17's codesign-verified fetch to consumers).🤖 Generated with Claude Code