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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions