Skip to content

random_seed is UB #2

@nico-abram

Description

@nico-abram

Here:

temporary/src/lib.rs

Lines 143 to 146 in 6821517

fn random_seed(_: &Path, _: &str) -> [u64; 2] {
use std::mem::uninitialized as rand;
unsafe { [rand::<u64>() ^ 0x12345678, rand::<u64>() ^ 0x87654321] }
}

According to the std::mem::uninitialized docs this is UB: https://doc.rust-lang.org/std/mem/fn.uninitialized.html

As the assume_init documentation explains, the Rust compiler assumes that values are properly initialized. As a consequence, calling e.g. mem::uninitialized::() causes immediate undefined behavior for returning a bool that is not definitely either true or false. Worse, truly uninitialized memory like what gets returned here is special in that the compiler knows that it does not have a fixed value. This makes it undefined behavior to have uninitialized data in a variable even if that variable has an integer type. (Notice that the rules around uninitialized integers are not finalized yet, but until they are, it is advisable to avoid them.)

This crate could possibly give you an easy way to get a real entropy source, if desireable: https://github.com/rust-random/getrandom

Otherwise, you could just use hardcoded values like [0 ^0x12345678, 0 ^ 0x87654321]

If you still want a hacky inbetween, maybe consider using a function address and relying on ASLR being enabled (Like random_seed as usize as u64).

Also notice that sometimes the compiler just replaces uninitialized() with a fixed value (Like 0), so it would be no better than a fixed value entropy-wise despite being UB.

EDIT: Maybe it could also be replaced with inline asm to read the stack, but that would require a different asm block for each ISA and not a real source of entropy.

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