Skip to content

Potential unsoundness in SFMT::pop64 #37

@shinmao

Description

@shinmao

The source of unsoundness

Hi, we are the PhD researchers from SunLab. We found that pop64 might have unsound implementation.

sfmt/src/lib.rs

Lines 81 to 89 in 7767d23

fn pop64(&mut self) -> u64 {
let p = self.state.as_ptr() as *const u32;
let val = unsafe {
let p = p.offset(self.idx as isize);
*(p as *const u64) // reinterpret cast [u32; 2] -> u64
};
self.idx += 2;
val
}

At line 85, p is aligned to 4 bytes as u32, but it was cast to u64 with stronger alignment requirement. Misaligned pointer dereference could lead to undefined behavior in safe function.

To reproduce the bug

use sfmt::SFMT;
use rand_core::{SeedableRng, RngCore};

fn main() {
    let sd: [u8; 4] = [10; 4];
    let mut smt = SFMT::from_seed(sd);
    let tmp = smt.next_u64();
    let tmp1 = smt.next_u64();
    let tmp1_addr = tmp1 as *mut u64 as usize;
    println!("{:x}", tmp1_addr);
    assert!(tmp1_addr % std::mem::align_of::<u64>() == 0);
}

to run with cargo run

thread 'main' panicked at 'assertion failed: tmp1_addr % std::mem::align_of::<u64>() == 0', src/main.rs:12:5

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