java-topology/whitepaper/outreach/libgit2.md

73 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.