# libgit2 — CWE-407 Disclosure Brief **2026-03-27 · Patch available — awaiting upstream merge** ## Finding One O(n²) defect in libgit2's filesystem reference backend. `ref_available()` performs an O(R) packed-ref list scan per path segment check — called at 17 sites — causing O(R²) total overhead for repositories with many references. Patch ready for upstream review. ## The Defects **libgit2-0001 (PATCHED — HIGH):** `src/libgit2/refs.c` ```c /* git_refdb_backend_fs.ref_available() — per segment per path check: */ /* Called at 17 sites */ static int ref_available(git_refdb_backend *_backend, const char *refname, ...) { /* O(R) packed-ref list scan per segment */ git_sortedcache_rlock(backend->refcache); size_t i; for (i = 0; i < git_sortedcache_entrycount(backend->refcache); i++) { struct packref *ref = git_sortedcache_entry(backend->refcache, i); if (is_prefix_of(ref->name, refname)) { ... } } /* O(R²) total across 17 call sites */ } ``` O(R) packed-ref scan per path segment check, at 17 call sites. **O(R²) total**. **Measured ratio: 17 sites.** ## Complexity Proof For R packed references: - Per `ref_available()` call: O(R) scan - 17 call sites per ref operation: O(17×R) per operation - R operations: O(R²) total - Fixed: binary search on sorted refs → O(R × log R) - **17 call sites measured.** ## Impact All libgit2 users and all software built on libgit2: GitHub's Rugged (Ruby), pygit2 (Python), git2go (Go), NodeGit, libgit2sharp (.NET), and Git GUI clients. Repositories with many references (many branches, many tags — common in large monorepos and CI/CD systems) hit O(R²) during reference creation, renaming, and deletion. libgit2 is the foundation of most non-C Git tooling. ## The Fix Use binary search on the sorted reference cache instead of linear scan: ```c /* Before */ for (i = 0; i < git_sortedcache_entrycount(backend->refcache); i++) { struct packref *ref = git_sortedcache_entry(backend->refcache, i); if (is_prefix_of(ref->name, refname)) { ... } } /* After */ /* CWE-407 fix: binary search on sorted refcache for O(log R) per check. */ size_t pos; int error = git_sortedcache_lookup_raw(backend->refcache, &pos, refname); /* Binary search gives insertion point; check neighbors for prefix overlap */ ``` ## Patch `defects/libgit2/patch/libgit2-0001-refs-binary-search.patch` ## What We Ask 1. Confirm receipt and assign a GitHub Security Advisory or issue reference. 2. Validate the patch against your reference backend test suite. 3. Assess CVE eligibility — affects all 17 ref_available call sites in large repositories. 4. Coordinate a disclosure date — we are targeting 90 days from first contact. Contact: see cover email. This brief is confidential until coordinated disclosure.