Nothing couples emission of TAG_SYMBOL_BASENAME to the fact_minor_min declaration that is supposed to bracket it #280
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#280
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Split out of #277, whose disclosure fix landed in
d5547cc. This half was NOT fixed there — it has a different fix location and deserves its own decision.The claim
crates/abi/src/frame.rsargues thatTAG_SYMBOL_BASENAME(0x8004) is the one optional tag that cannot degrade safely, because the field it annotates — a symbol'sname— has no absent encoding. An older host skipping it does not thin the answer; it stores the guest's PLACEHOLDER as if it were a name. The doc's word is that it MISLEADS, which is worse than degrading and worse than refusing._prdoc/guides/80-threat-model.md§4.2c states the mitigation as a property of the system:It is a property of a COOPERATING package
Manifest::validaterefusesfact_minor_min > ABI_MINOR— a package cannot ask for a host newer than the one it meets. Nothing anywhere ties EMISSION of the tag to the DECLARATION.A third-party package that calls
Encoder::symbol_basenamewhile declaring[abi] fact_minor_min = 0installs happily on a host atABI_MINOR = 1, whose decoder takes thet if t >= TAG_OPTIONAL_BASE => continuearm and stores the placeholder verbatim as a symbol name. That is precisely the case the bracket is documented as preventing.Nothing in the tree grades this.
Dashboard.expectedsays so itself: "The expectation format has no field for the annotation itself (ExpectSymbolisdeny_unknown_fields), so this table cannot assert that the tag was attached." The tag's presence is graded only by the daemon e2e; the ABI bracket is graded nowhere.Scope
No shipped package is affected.
de.h-dv.sveltedeclaresfact_minor_min = 2correctly, and it is the only emitter. This is a trap for a well-meaning third-party author, and — more importantly — a sentence in the threat model that reads as a system property when it is a convention.The related finding from the same review:
crates/guest/src/frame.rs'sABI_MINORis 0, so a guest stamps minor 0 into every frame it writes while those frames may carry a minor-2 record.frame.rs's "an older parent meeting a newer worker is the refused case" therefore never fires for this tag, because the worker never declares itself newer.wire_parity.rsrecords the non-move as deliberate (moving it movesPINNED_REV), and09305a3shows that pin does get moved when needed — so "it is expensive" is not the whole answer.Where the fix belongs
plugin check's conformance leg. It is the one place that holds BOTH the decodedValidatedFacts— henceSymbol::name_is_basename— and theManifest. A package whose frame carries the tag while its manifest declaresfact_minor_min < 2should fail conformance, which means it can never reachplugin enable(which requires the verdict).Two alternatives worth weighing rather than assuming:
validate. Cleanest in principle — the decoder knows the tag arrived. It does not know the manifest:abi::validatetakes(body, src, limits, grants)and has no manifest by design, for the same reason it refuses a received line. Handing it one would be the wrong shape.plugin pack. Catches it at authoring time, which is friendlier. But packing does not decode a frame, so it would have to run the extractor — which is whatplugin checkis for.(1) is the tempting one and (2) is the friendly one; the conformance leg is probably right because it already executes the package and already gates
enable.Also from #277, and NOT a defect — a decision someone should make
Should
GrantSpec::Requestedgrantderived_namesat all by default?plugin addwith no--grantresolves it to whatever the manifest asked for. Afterd5547ccthe confirmation screen NAMES it, so the reported hole is closed. Every other high-authority answer in this tree is opt-in, so "everything the manifest asked for, including this" is now defensible but no longer obviously right. Changing it is a behaviour change for anyone scriptingplugin add, which is why it was not bundled into the disclosure fix.plugin addgrantsderived_namesby default and never names it on the screen the operator answers #277