{
  "claim_outcome": "negative_for_variant_or_bypass",
  "claim_block_reason": null,
  "variant_result": "no_bypass",
  "bypass_confirmed": false,
  "distinct_variant_confirmed": false,
  "validated_surface": "network_protocol",
  "evidence_scope": "production_path",
  "claimed_impact_class": "dos",
  "observed_impact_class": "dos",
  "additional_observed_impact_class": "heap_oob_read",
  "exploitability_confidence": "high",
  "attacker_controlled_input": "spec-compliant QPACK encoder-stream instructions (Set Dynamic Table Capacity + Insert) sent over a QUIC/HTTP3 unidirectional encoder stream by an unauthenticated remote client; three payload shapes tested (P1 original PoC, P2 alternate wrap state, P3 alternate grow factor)",
  "trigger_path": "quic-go client -> XQUIC demo_server QUIC/UDP -> HTTP3 control stream + QPACK encoder uni stream -> xqc_qpack_on_encoder_ins XQC_INS_TYPE_ENC_SET_DTABLE_CAP -> xqc_decoder_set_dtable_cap (xqc_decoder.c:243) -> xqc_dtable_set_capacity (xqc_dtable.c:602) -> xqc_ring_mem_resize both-truncated branch (xqc_ring_mem.c:129/139) -> heap OOB read + size_t underflow into memcpy",
  "end_to_end_target_reached": true,
  "sanitizer_used": true,
  "crash_observed": true,
  "oob_read_observed": true,
  "read_write_primitive_observed": false,
  "exploit_chain_demonstrated": false,
  "blocking_mitigation": "one-line fix ori_sz1 = rmem->capacity - soffset_ori in xqc_ring_mem_resize (no upstream patch exists; v1.9.4 is latest release). Mitigation: advertise SETTINGS_QPACK_MAX_TABLE_CAPACITY=0.",
  "fix_coverage_verdict": "complete",
  "fix_coverage_detail": "The one-line fix corrects the sole old-vs-new-capacity confusion (ori_sz1) in xqc_ring_mem_resize. It is consumed by both sub-branches of the only reachable (both-truncated) case, and applies to every caller (decoder Set Dynamic Table Capacity - the only attacker trigger; encoder SETTINGS path - covered but not triggerable since rmem->used==0 at SETTINGS time). No second independent capacity-confusion bug exists in the resize function or its xqc_ring_mem_copy helper. The other resize branches (continuous-new, continuous-old/truncated-new) are correct. Sub-branch A (new_sz1>=ori_sz1) is provably unreachable for any legal grow, so sub-branch B (the PoC path) is the only one that fires; both are fixed via the shared ori_sz1 line.",
  "tested_payloads": [
    {"name": "P1", "role": "original PoC", "init_cap": 64, "insert_count": 61, "final_cap": 65, "mcap": 128, "sidx": 122, "vuln": "crashed exit=134 asan_heap_oob_read_size_64", "fixed": "alive asan_clean"},
    {"name": "P2", "role": "alternate wrap state", "init_cap": 64, "insert_count": 59, "final_cap": 65, "mcap": 128, "sidx": 118, "vuln": "crashed exit=134 asan_heap_oob_read", "fixed": "alive asan_clean"},
    {"name": "P3", "role": "alternate grow factor", "init_cap": 64, "insert_count": 123, "final_cap": 200, "mcap": 256, "sidx": 246, "vuln": "crashed exit=134 asan_heap_oob_read_size_192", "fixed": "alive asan_clean"}
  ],
  "vulnerable_crashes": 3,
  "fixed_bypasses": 0,
  "alternate_entry_points_audited": [
    {"path": "encoder dtable via peer SETTINGS_QPACK_MAX_TABLE_CAPACITY (xqc_h3_conn.c:722 -> xqc_qpack_set_dtable_cap -> xqc_encoder_set_dtable_cap -> xqc_dtable_set_capacity -> xqc_ring_mem_resize)", "attacker_controlled": true, "triggerable_for_bug": false, "reason": "at SETTINGS-exchange time the encoder dtable is empty (rmem->used==0), so xqc_ring_mem_resize skips the copy block; SETTINGS can be sent only once; both-truncated grow precondition cannot be met", "covered_by_fix": true},
    {"path": "encoder dtable via local app API xqc_h3_set_qpack_dtable_cap (xqc_h3_conn.c:321)", "attacker_controlled": false, "triggerable_for_bug": false, "reason": "local application API, not attacker-controlled", "covered_by_fix": true},
    {"path": "QPACK encoder-stream INSERT_NAME_REF / INSERT_LITERAL / DUPLICATE", "attacker_controlled": true, "triggerable_for_bug": false, "reason": "these instructions evict entries but never call xqc_ring_mem_resize; only SET_DTABLE_CAP resizes", "covered_by_fix": "n/a"}
  ],
  "inferred": false,
  "notes": "No bypass: fixed (one-line ori_sz1 patch) ASAN-clean/alive on 3/3 payloads; vulnerable ASAN heap-buffer-overflow READ on 3/3. Alternate triggers P2/P3 reach the same sink on the vulnerable build but are blocked by the fix. Variant search bounded by single sink/single attacker trigger/single reachable sub-branch/single buggy line."
}
