Skip to content

Panic in git2-rs Reference::is_valid_name() on Null Byte Input #1218

@N0zoM1z0

Description

@N0zoM1z0

Panic in git2-rs Reference::is_valid_name() on Null Byte Input

git2_001_reference_nullbyte_panic.zip

Summary

The git2 crate (Rust bindings for libgit2) contains a denial-of-service vulnerability where Reference::is_valid_name() panics when given a string containing null bytes. This affects all versions including the latest 0.20.4.

  • Crate: git2
  • Affected Versions: <= 0.20.4 (latest at time of report)
  • Severity: Medium (Denial of Service via panic)
  • Attack Vector: Local/Network - any application accepting user input for reference name validation

Details

Root Cause

The Reference::is_valid_name() function in src/reference.rs uses CString::new(refname).unwrap() to convert a Rust string to a C string:

// git2-0.20.4/src/reference.rs:68-70
pub fn is_valid_name(refname: &str) -> bool {
    crate::init();
    let refname = CString::new(refname).unwrap();  // <-- PANIC HERE
    // ...
}

CString::new() returns an Err(NulError) when the input contains null bytes (byte value 0), because C strings cannot contain null bytes. The .unwrap() call causes an immediate panic.

Crash Input

  • Bytes: [44, 0, 3] (hex: 0x2c 0x00 0x03)
  • String representation: ",\x00\x03"
  • Base64: LAAD

Stack Trace

thread '<unnamed>' panicked at git2-0.20.4/src/reference.rs:70:45:
called `Result::unwrap()` on an `Err` value: NulError(1, [44, 0, 3])

#20 git2::reference::Reference::is_valid_name
#21 fuzz_generic /coverage_fuzz.rs:734

Impact

Attack Scenarios

  1. Git Hosting Services: Web services accepting reference names from users could be crashed by sending crafted input containing null bytes.

  2. CI/CD Pipelines: Build systems validating git references could be disrupted.

CVSS 3.1 Score

  • AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H = 7.5 (High)
  • Network-accessible, low complexity, no privileges required, causes availability impact (DoS)

Reproduction

Prerequisites

# Ensure Rust is installed
rustc --version  # >= 1.70 recommended

Steps

  1. Clone or navigate to the reproduction directory:
cd git2_001_reference_nullbyte_panic
  1. Run the reproduction:
cargo run --release
  1. Expected output (panic):
Testing Reference::is_valid_name with input: ",\0\u{3}"
Bytes: [44, 0, 3]
thread 'main' panicked at git2-0.20.4/src/reference.rs:70:45:
called `Result::unwrap()` on an `Err` value: NulError(1, [44, 0, 3])

Alternative: Direct Test

use git2::Reference;

fn main() {
    // This will panic
    let _ = Reference::is_valid_name("test\x00input");
}

Affected Functions

The following git2 functions likely have the same vulnerability pattern (using CString::new().unwrap()):

  • Reference::is_valid_name()
  • Tag::is_valid_name() (confirmed: src/tag.rs:22)
  • Remote::is_valid_name() (confirmed: src/remote.rs:96)

Recommended Fix

The library should handle null bytes gracefully by returning false instead of panicking:

pub fn is_valid_name(refname: &str) -> bool {
    crate::init();
    let refname = match CString::new(refname) {
        Ok(s) => s,
        Err(_) => return false,  // Null bytes make it invalid
    };
    // ... rest of function
}

Workarounds

Applications using git2 can work around this by checking for null bytes before calling is_valid_name():

fn safe_is_valid_name(name: &str) -> bool {
    if name.contains('\0') {
        return false;
    }
    git2::Reference::is_valid_name(name)
}

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions