{"id":"GHSA-xqmp-fxgv-xvq5","summary":"libp2p-gossipsub: Remote crash via unchecked Instant overflow in heartbeat backoff expiry handling","details":"## Description\n### Summary\nThe Rust libp2p Gossipsub implementation contains a remotely reachable panic in `backoff` expiry handling.  \nAfter a peer sends a crafted `PRUNE` control message with an attacker-controlled, near-maximum `backoff` value, the value is accepted and stored as an `Instant` near the representable upper bound. On a later heartbeat, the implementation performs unchecked `Instant + Duration` arithmetic (`backoff_time + slack`), which can overflow and panic with:\n`overflow when adding duration to instant`\nThis issue is reachable from any Gossipsub peer over normal `TCP + Noise + mplex/yamux` connectivity and requires no further authentication beyond becoming a protocol peer.\n### Attack Scenario\nAn attacker that can establish a libp2p Gossipsub session with a target node can crash the target by sending crafted `PRUNE` control data:\n1. Establish a standard libp2p session (`TCP + Noise`) and negotiate a stream multiplexer (`mplex`/`yamux`).\n2. Open a Gossipsub stream and send an RPC containing `ControlPrune` with a very large `backoff` (chosen near boundary conditions, e.g. `~ i64::MAX - victim_uptime_seconds`; example observed: `9223372036854674580` for ~28h uptime).\n3. The value is parsed from protobuf and passed through `Behaviour::handle_prune()` into mesh/backoff update logic.\n4. Initial storage path uses checked addition (`Instant::now().checked_add(...)`), so the malicious near-max value is retained.\n5. On the next heartbeat (typically within ~43–74s), expiry logic computes `backoff_time + slack` using unchecked addition, which overflows and panics.\n### Impact\nRemote unauthenticated denial of service (critical).  \nAny application exposing an affected `libp2p-gossipsub` listener can be crashed by a network-reachable peer that sends crafted `PRUNE` backoff values. The crash is triggered during heartbeat processing (not immediately at PRUNE parse time), and can be repeated by reconnecting and replaying the message.\n\n### Differences from CVE-2026-33040\nThis advisory is related to CVE-2026-33040 but it is not the same defect. CVE-2026-33040 addressed overflow during backoff insertion by adding checked arithmetic when converting PRUNE backoff into an Instant. The issue in this advisory occurs at a different location and at a different time: a near-maximum backoff can still be stored successfully, and the crash happens later in the heartbeat path when slack is added to that stored Instant using unchecked arithmetic.  This report covers a distinct secondary overflow path in heartbeat expiry handling that remained reachable after the original insertion-side hardening.\n\nThis vulnerability was originally reported by the Security team of the Ethereum Foundation.","aliases":["CVE-2026-34219"],"modified":"2026-04-06T23:34:56.143916Z","published":"2026-03-30T13:04:03Z","database_specific":{"github_reviewed":true,"github_reviewed_at":"2026-03-30T13:04:03Z","nvd_published_at":"2026-03-31T16:16:31Z","cwe_ids":["CWE-190","CWE-617"],"severity":"HIGH"},"references":[{"type":"WEB","url":"https://github.com/libp2p/rust-libp2p/security/advisories/GHSA-xqmp-fxgv-xvq5"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34219"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-gc42-3jg7-rxr2"},{"type":"PACKAGE","url":"https://github.com/libp2p/rust-libp2p"}],"affected":[{"package":{"name":"libp2p-gossipsub","ecosystem":"crates.io","purl":"pkg:cargo/libp2p-gossipsub"},"ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"0.49.4"}]}],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-xqmp-fxgv-xvq5/GHSA-xqmp-fxgv-xvq5.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H"},{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N"}]}