Skip to content

Potential unsoundness in SFMT::pop64 #37

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
    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