Skip to content

Obstack generates unaligned references #4

@Qwaz

Description

@Qwaz

rust-obstack/src/lib.rs

Lines 317 to 337 in e1dde0d

#[inline]
unsafe fn alloc(&mut self, size: usize, alignment: usize) -> *mut A {
let start_ptr = self.tip.as_mut_ptr()
.offset(self.tip.len_items() as isize);
let padding = start_ptr as usize % alignment;
debug_assert!(padding < alignment);
debug_assert_eq!(padding, 0);
let start_ptr = start_ptr.offset(AlignedVec::<A>::bytes_to_items(padding) as isize);
let new_used = self.tip.len_items() + padding + AlignedVec::<A>::bytes_to_items(size);
if new_used <= self.tip.capacity_items() {
self.tip.set_len_items(new_used);
start_ptr as *mut A
} else {
self.alloc_from_new_slab(size, alignment)
}
}

Description

Obstack generates unaligned references for types that require a large alignment.

Demonstration

  • Crate: obstack
  • Version: 0.1.3
  • OS: Ubuntu 18.04.5 LTS
  • Rust: rustc 1.46.0 (04488afe3 2020-08-24)
  • Cargo flags: --release
#![forbid(unsafe_code)]

use obstack::Obstack;

#[repr(align(256))]
#[derive(Copy, Clone)]
struct LargeAlign(u8);

fn main() {
    // https://github.com/petertodd/rust-obstack/blob/e1dde0dbed709ebdea9bd1f79ec718e80c5d0bf6/src/lib.rs#L317-L337
    // Line 322: Incorrect padding bytes calculation. It should be `(alignment - (start_ptr % alignment)) % alignment`.
    // Line 329: Wasted memory due to `bytes_to_item()` not being applied to `padding`.

    // Due to the incorrect padding calculation, the code generates unaligned reference in release mode.
    let obstack = Obstack::new();
    let val_ref = obstack.push_copy(LargeAlign(0));

    let address = val_ref as *mut _ as usize;
    println!("{:x}", address);
    assert!(address % std::mem::align_of::<LargeAlign>() == 0);
}

Output:

55bc0c2fc520
thread 'main' panicked at 'assertion failed: address % std::mem::align_of::<LargeAlign>() == 0', src/main.rs:39:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Return Code: 101

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