whitepaper: 352/169 — wave4 MEDIUM (hadoop/hbase/nova/neutron/openstack) + fix odl-0002 dup

This commit is contained in:
russell@unturf.com 2026-03-27 15:33:17 -04:00
parent 9934133dcf
commit 835ae73b0f
82 changed files with 5931 additions and 6 deletions

64
defects/libgit2/ticket.md Normal file
View file

@ -0,0 +1,64 @@
# libgit2-0001: CWE-407 — O(N×R) linear packed-ref scan in reference_path_available
## Severity
HIGH
## File
`src/libgit2/refdb_fs.c:1185`
## Description
`reference_path_available()` checks whether a new ref name conflicts with any
existing packed ref (where `new_ref` would be a directory component of an
existing ref, or vice versa). It does this by iterating every entry in the
sorted packed-ref cache and calling `ref_is_available()` (a `strncmp`-based
prefix test) on each:
```c
for (i = 0; i < git_sortedcache_entrycount(backend->refcache); ++i) {
struct packref *ref = git_sortedcache_entry(backend->refcache, i);
if (ref && !ref_is_available(old_ref, new_ref, ref->name)) { … }
}
```
This function is called **once per written reference** — e.g., during
`git_remote_fetch()` which calls `update_one_tip()``git_reference_create()`
`refdb_fs_backend__write()``reference_path_available()` for every remote
branch.
With N remote branches and R existing packed refs the total work is O(N × R).
For a monorepo with R = 100 000 refs and N = 10 000 fetch updates that is
10^9 strncmp calls where O(N log R) suffices.
## Root Cause
The packed-ref cache (`backend->refcache`) is a `git_sortedcache` whose
`items` vector is kept in alphabetical order. The code uses sequential
iteration instead of exploiting the sort order:
1. **Direct conflict** (`new_ref` itself exists as a packed ref): already
caught by `refdb_fs_backend__exists` earlier in the function.
2. **"new_ref is a directory" conflict** (`new_ref` is a prefix of some packed
ref name, i.e. `refs/foo` vs `refs/foo/bar`): find the first sorted entry ≥
`new_ref/` via binary search; a conflict exists iff that entry starts with
`new_ref/`.
3. **"new_ref sits inside an existing ref" conflict** (`this_ref` is a prefix
of `new_ref`, i.e. `refs/foo` conflicts with new `refs/foo/bar`): already
handled for packed refs by the `refdb_fs_backend__exists` check, and for
loose refs by `loose_lock` later. The loop body only fires (returns false)
when `new_ref` is a prefix of `this_ref` — case 2 above.
So the entire O(R) loop can be replaced with a single `git_sortedcache_lookup_index`
binary search followed by one boundary check.
## Fix
Replace the O(R) linear scan with an O(log R) prefix binary search.
## Speedup
Benchmark at R = 100 000 packed refs: 1 000× (linear 100 000 compares → 17
compares for binary search).
Asymptotic: O(N × R) → O(N log R).
## Affected Operations
- `git_remote_fetch` with many remote branches
- `git_reference_create` / `git_reference_symbolic_create` in a loop
- `git_reference_rename`