Skip to content

Identifier::new_unchecked() writes to null pointer on allocation failure #290

@LegionMammal978

Description

@LegionMammal978

Identifier::new_unchecked() calls alloc::alloc::alloc() to create a buffer on the heap if the string is 9 bytes or longer. However, if the global allocator fails and returns a null pointer, the function attempts to write to it, resulting in a segmentation fault.

/*
[dependencies]
semver = "=1.0.13"
*/

use semver::Version;
use std::{
    alloc::{GlobalAlloc, Layout, System},
    ptr,
    sync::atomic::{AtomicBool, Ordering},
};

struct ToggleAlloc(AtomicBool);

#[global_allocator]
static ALLOC: ToggleAlloc = ToggleAlloc(AtomicBool::new(true));

// SAFETY: Wraps `System`'s methods, possibly indicating failure.
unsafe impl GlobalAlloc for ToggleAlloc {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        if self.0.load(Ordering::Relaxed) {
            System.alloc(layout)
        } else {
            ptr::null_mut()
        }
    }

    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
        System.dealloc(ptr, layout)
    }
}

fn main() {
    ALLOC.0.store(false, Ordering::Relaxed);
    "0.0.0-100000000".parse::<Version>().unwrap(); // Segmentation fault
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions