Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential unsoundness in SFMT::pop64 #37

Open
shinmao opened this issue Aug 26, 2023 · 1 comment
Open

Potential unsoundness in SFMT::pop64 #37

shinmao opened this issue Aug 26, 2023 · 1 comment

Comments

@shinmao
Copy link

shinmao commented Aug 26, 2023

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
@riking
Copy link

riking commented Feb 27, 2024

This is also found at https://asan.saethlin.dev/ub?crate=sfmt&version=0.7.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants