Skip to content

Potential Undefined Behavior with Zero-Sized Allocations #3

@lewismosciski

Description

@lewismosciski

Hello,

We are developing a static analysis tool for Rust, and during our research, we discovered a potential undefined behavior pattern in this library.

The core issue is that user-provided input (size_bytes = 0) can lead to a call to the global allocator with a zero-sized Layout. Per the GlobalAlloc trait's safety contract, this is Undefined Behavior.

This problem is exposed through two public API functions.

NNL/src/device/cpu.rs

Lines 192 to 201 in 6ae0f59

pub fn new_aligned(size_bytes: usize) -> Result<Self> {
let float_count = size_bytes / std::mem::size_of::<f32>();
let aligned_size = (float_count + SIMD_WIDTH - 1) & !(SIMD_WIDTH - 1);
let total_bytes = aligned_size * std::mem::size_of::<f32>();
let layout = Layout::from_size_align(total_bytes, MEMORY_ALIGNMENT)
.map_err(|e| NnlError::device(format!("Invalid memory layout: {}", e)))?;
let ptr = unsafe {
let raw_ptr = alloc_zeroed(layout);

NNL/src/device/cpu.rs

Lines 217 to 223 in 6ae0f59

pub fn new(size_bytes: usize) -> Result<Self> {
let float_count = size_bytes / std::mem::size_of::<f32>();
let layout = Layout::array::<f32>(float_count)
.map_err(|e| NnlError::device(format!("Invalid memory layout: {}", e)))?;
let ptr = unsafe {
let raw_ptr = alloc(layout);

use nnl::device::cpu::CpuMemory;

fn main() {
    let _memory = CpuMemory::new_aligned(0);
}
ccuu@ccuu:~/rust/rtest/nnl_test$ cargo +nightly miri run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.15s
     Running `/home/ccuu/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/nnl_test`
error: Undefined Behavior: creating allocation with size 0
   --> /home/ccuu/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nnl-0.1.6/src/device/cpu.rs:201:27
    |
201 |             let raw_ptr = alloc_zeroed(layout);
    |                           ^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
    = note: inside `nnl::device::cpu::CpuMemory::new_aligned` at /home/ccuu/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nnl-0.1.6/src/device/cpu.rs:201:27: 201:47
use nnl::device::cpu::CpuMemory;

fn main() {
    let _memory = CpuMemory::new(0);
}
ccuu@ccuu:~/rust/rtest/nnl_test$ cargo +nightly miri run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.12s
     Running `/home/ccuu/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/nnl_test`
error: Undefined Behavior: creating allocation with size 0
   --> /home/ccuu/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nnl-0.1.6/src/device/cpu.rs:223:27
    |
223 |             let raw_ptr = alloc(layout);
    |                           ^^^^^^^^^^^^^ Undefined Behavior occurred here
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
    = note: inside `nnl::device::cpu::CpuMemory::new` at /home/ccuu/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nnl-0.1.6/src/device/cpu.rs:223:27: 223:40

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