Multiple denial-of-service vectors in gix-pack: unchecked array indexing causes panics on crafted delta data, and uncapped attacker-controlled size headers enable OOM process kills. Both are triggered by malicious pack data received during clone/fetch.
Bug 1: Unchecked array indexing in delta application (CWE-248)
The apply() function in gix-pack/src/data/delta.rs (lines 33-87) reads delta instructions using unchecked data[i] indexing at 7 locations (lines 41, 45, 49, 53, 57, 61, 65). The command byte's bits indicate how many additional bytes follow, but if the delta data is truncated, the index panics:
pub(crate) fn apply(base: &[u8], mut target: &mut [u8], data: &[u8]) -> Result<(), apply::Error> {
let mut i = 0;
while let Some(cmd) = data.get(i) { // first byte: safely checked
i += 1;
match cmd {
cmd if cmd & 0b1000_0000 != 0 => {
let (mut ofs, mut size): (u32, u32) = (0, 0);
if cmd & 0b0000_0001 != 0 {
ofs = u32::from(data[i]); // PANIC: no bounds check
i += 1;
}
// ... 6 more unchecked data[i] at lines 45, 49, 53, 57, 61, 65
Lines 83-84 use assert_eq! (not debug_assert_eq!) that panics in both debug and release builds:
assert_eq!(i, data.len());
assert_eq!(target.len(), 0);
A second location in parse_header_info() (gix-pack/src/data/entry/decode.rs:116-129) also panics on truncated input via unchecked data[0] and data[i].
Note: PR #2059 (merged 2025-06-25) fixed the explicit panic!() for command code 0. The unchecked array indexing is a distinct class that remains unfixed.
Bug 2: Uncapped allocation from attacker-controlled size headers (CWE-770)
Pack entry headers and delta headers encode object sizes as LEB128-encoded u64 values. These sizes are used to allocate buffers before validating the actual data, with no upper...
0.69.0Exploitability
AV:NAC:LAT:NPR:NUI:NVulnerable System
VC:NVI:NVA:HSubsequent System
SC:NSI:NSA:N8.7/CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N