fix: bump h2 0.4.14 -> 0.4.18 (RUSTSEC-2026-0258) - #259
Conversation
h2 v0.4.14 is vulnerable to a denial-of-service via unbounded empty DATA frames, patched in v0.4.16. Transitive via hickory-resolver -> iroh/mesh-llm, not a direct dependency. Clean cargo update -p h2 with zero cascading changes to other dependencies. Fixes #258 Signed-off-by: Serina Mcfall <serina.mcfall@gmail.com>
Review pipeline — PR #259Stages run: Not applicable, declared rather than faked:
Findings1. Medium — the commit message states the opposite of what the diff does
The message reads "Clean cargo update -p h2 with zero cascading changes to other dependencies." The diff changes which Attributed edge-by-edge from
The PR body corrects this in its "Correction to this commit's own message" section — so the disclosure exists and I am not reporting an undisclosed change. The defect is where the correction lives. This repo squash-merges, and GitHub composes the squash commit body from the PR's commit messages, not from the PR body. So the false sentence is the version that lands in Concrete failure: someone bisecting a Windows-only regression six months from now runs Fix, and it needs no force-push: whoever merges edits the squash commit body in the merge box to drop that sentence and paste the correction in its place. Amending the pushed commit would mean force-pushing during review, which 2. Medium — the disclosure that makes this auditable names four crates that are not in the diff, and omits ten that arePR body, "Correction to this commit's own message" The correction names Concrete failure: the correction's whole purpose is to let a reviewer verify the churn is inert. A reviewer who does the obvious thing — grep the diff for the named crates — finds four of them absent, and cannot tell whether the disclosure is stale, whether the diff was re-pushed, or whether the claim was never checked. The list is what a reader is asked to trust, and it does not survive being checked. Worth stating plainly: the underlying claim that the churn is inert holds up. All five Fix: replace the crate list with the table above, or drop the enumeration and state the invariant that actually carries the argument — no package entry, checksum or crate set changed, only 15 intra-lockfile edges among 3. Low — missing
|
ciaran-slow
left a comment
There was a problem hiding this comment.
Comment review recording the pipeline result. Not an approval and not a change-request — the merge decision is unchanged by this.
Reviewed via the full pipeline (review-code / review-tests / review-a11y / review-adjudicate / review-final) — detail in my comment on this PR.
No blocking findings. The h2 bump does what #258 asked: 0.4.14 → 0.4.18 at Cargo.lock:3341, past the 0.4.16 fix for RUSTSEC-2026-0258, with cargo deny check reporting advisories ok. The scoped cargo update -p h2 was the right instrument and the windows-sys churn is genuinely inert — all five windows-sys package entries, every checksum and the whole crate set are unchanged; only 15 intra-lockfile edges moved.
Two Medium items, neither blocking:
- For the author: the "Correction" section in the PR body names four crates that are not in this diff (
terminal_size,same-file,native-tls,fs4), saysrustix x3where there is one, and omits ten that did change. The conclusion is right; the evidence offered for it does not survive being checked. Please replace the list with the real one. - At merge time, not for the author: commit
765746534's message says "zero cascading changes to other dependencies", which the diff contradicts. We squash-merge, so that sentence — not the PR body's correction — is what lands inlaunchpad's history on a security patch. Whoever merges should drop it from the squash body. No force-push needed.
Neither item requires a change to the code, and this PR unblocks the RUSTSEC Security failure that was hitting every Rust-touching PR.
Summary
Bumps
h2from 0.4.14 to 0.4.18 viacargo update -p h2, resolving RUSTSEC-2026-0258 (denial-of-service via unbounded empty DATA frames).h2is a transitive dependency (viahickory-resolver->iroh/mesh-llm-*, not used directly by this repo), and this advisory was failing the Security CI check on every Rust-touching PR, including #257 and #260.Related issue
Closes #258
Issue type
Task
Agent provenance
Objective
Clear the pre-existing, unrelated Security CI failure (RUSTSEC-2026-0258/h2) that blocks every Rust-touching PR right now.
Impacted components
Cargo.lock
Approach and rejected alternatives
Ran
cargo update -p h2rather than a broadercargo update(which would touch unrelated dependencies well beyond what this advisory needs) or hand-editing the lockfile (error-prone, and-pis cargo's own supported path for a scoped bump). Did not considerdeny.tomlignore-listing the advisory — a real upstream fix exists (v0.4.16+), and that convention is reserved for advisories with none.What this diff actually changes — corrected, and re-derived from the diff
Two earlier descriptions of this diff were wrong. Both are retracted here.
The commit message (
765746534) says "zero cascading changes to other dependencies." That is false. The diff is 18 changed lines: 2 forh2itself (version + checksum) and 16windows-sysdependency edges.An earlier revision of this PR body attempted to correct that and introduced its own errors: it named
terminal_size,same-file,native-tlsandfs4. None of the four appears in this diff, andterminal_sizeandfs4do not exist anywhere in this project's lockfile — they were written from recall, not read from the diff. It also said "rustixx3" (there are 2rustixedges) and omitted ten crates that are genuinely present. That revision is retracted in full and replaced by the table below, which was extracted mechanically from the diff.The complete, verified set — 16 edges across 15 distinct crates (
rustixappears twice, at 0.38.44 and 1.1.4):anstyle-query1.1.5,anstyle-wincon3.0.11,socket20.6.3,termina0.3.3,uds_windows1.2.1dirs-sys0.5.0,nu-ansi-term0.50.3colored3.1.1,errno0.3.14,quinn-udp0.5.14,rustix0.38.44,rustix1.1.4,rustls-platform-verifier0.7.0,seize0.5.1,tempfile3.27.0,winapi-util0.1.11Why cargo re-resolved these during a scoped
-p h2bump. Each of these crates declares a wide range forwindows-sys, and several already-vendored majors satisfy it — e.g.winapi-utilasks for>=0.48.0, <=0.61.*,errnofor>=0.52, <0.62,socket2for>=0.60, <0.62. A scopedcargo update -p h2still triggers a whole-graph re-resolve, and the resolver re-unifies each of those ranges onto an already-present version. Every move above lands on a version that crate's own declared range permits, and every one of these is a[target."cfg(windows)".dependencies]edge — compiled out entirely on Linux and macOS builds.Why the commit message got it wrong (root cause, stated so it is not repeated): cargo's own summary for this operation is
Locking 1 package to latest compatible version / Updating h2 v0.4.14 -> v0.4.18. That line counts package version changes only and is silent about dependency-edge re-unification. "Zero cascading changes" was written from cargo's summary instead of from the 18-line diff.Verification
Command run — the churn is settled, deterministic and reproducible:
Raw output:
What that establishes, in order:
origin/launchpad's lockfile is already settled (a full re-resolve changes nothing, so this diff is not swept-up drift); an independentcargo update -p h2from a clean checkout produces a byte-identical lockfile to this PR's, so the 16 edges are a deterministic consequence of the scoped bump rather than an artefact of one machine; and no package was added, removed, or had its entry rewritten — all fivewindows-sysentries survive unchanged and the crate count is identical at 1050.Also passing on CI for this exact lockfile:
Security(cargo deny check→advisories ok),Rust Lint,Unit Tests, bothServer Cross-Compiletargets, andWindows Rust (x86_64-pc-windows-msvc)— the last being the one that would actually exercise thesecfg(windows)edges.Not verified
The
spinyanked-crate warning (spin0.9.8 / 0.10.0, transitive viairoh/mesh-llm-*) is untouched by this PR and still warns; it iswarning[yanked], not an error, and does not failcargo deny check— but it is not fixed here and remains outstanding. I did not run the desktop, mobile or E2E suites locally, relying on CI for those. I did not audit h2 0.4.18's own changelog beyond confirming it is past the 0.4.16 fix version for this advisory, so I cannot speak to unrelated behavioural changes between 0.4.14 and 0.4.18. I did not verify runtime behaviour on a real Windows host — thecfg(windows)claim rests on the manifests' own target gating plus CI'sWindows Rustjob compiling clean, not on a Windows runtime test.An earlier revision of this section claimed local verification was impossible because a private git dependency (
tlongwell-block/rust-s3) failed ssh-agent authentication. That was a real wall but not an absolute one:CARGO_NET_GIT_FETCH_WITH_CLI=trueroutes the fetch through the git CLI, which authenticates fine, and all the local evidence above was gathered that way.Security implications
This fixes a security issue (RUSTSEC-2026-0258, h2 DoS via unbounded empty DATA frames) rather than introducing exposure.
Cargo.lockonly — no production code changed. The 16windows-sysedge moves are all within the ranges those crates declare and are all Windows-target-gated; none crosses awindows-sysmajor boundary that its dependent did not already permit.Escalations
One item for whoever merges. This repo squash-merges, and GitHub composes the squash commit body from the branch's commit messages — not from this PR body. So the false "zero cascading changes to other dependencies" sentence is the version that would land in
launchpad's permanent history, while this correction is the version that would not. Amending the pushed commit would require a force-push during review, whichlaunchpad/AGENTS.md§6 forbids, so this is deliberately left as a merge-time action rather than a change on the branch: please replace that sentence in the squash commit body at merge time. Suggested replacement, which fits in a commit body: