Skip to content

Easy to run out of randomness on Android #804

Closed

Description

@mmastrac

Background

What is your motivation?

When creating a number of threads quickly on Android without having accessed a thread rng previously, it's possible to get a panic like so:

Panic! PanicInfo { payload: Any, message: Some(could not initialize thread_rng: All entropy sources failed (permanently unavailable); cause: OS RNG not yet seeded (not ready yet); cause: Try again (os error 11)), location: Location { file: "/Users/matt/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.6.5/src/rngs/thread.rs", line: 80, col: 17 } }

What type of application is this? (E.g. cryptography, game, numerical simulation)

Mobile application

Activity

  1. dhardy commented on May 23, 2019

    @dhardy
    Member

    That's not something I've heard before. Could you do a little more diagnosis please — reproduce the issue by getting bytes with the new getrandom crate, check which method is being used and what the actual error is (it could be the getrandom syscall or reading /dev/random or /dev/urandom).

  2. mmastrac commented on May 23, 2019

    @mmastrac
    Author

    I'm currently fighting some fires, but I can look into this more when my plate clears. Looking into the 0.6.5 source, it looks like linux_android might be using /dev/random to test to see if randomness is initialized. At least on my x86_64 SDK simulator (specifically SDK 24 w/google services), I'm able to easily get /dev/random to block using a simple dd if=/dev/random bs=1 count=128 and running it a couple of times.

    https://github.com/rust-random/rand/blob/0.6.5/rand_os/src/linux_android.rs#L72

    I'll dig into this when I have a chance to build a testing executable that I can push to the simulator, but my theory is that the threads are starting up when /dev/random is exhausted (but /dev/urandom is fine) and blocking because they think that randomness is not available when it actually is.

    This probably won't be an issue w/the getrandom crate because it does the test once and only once.

  3. dhardy commented on May 23, 2019

    @dhardy
    Member

    We could potentially fix that by using a mutex instead of an atomic bool. It might even be faster, but could also be an issue if the first thread gets stopped at the wrong time.

  4. mmastrac commented on May 23, 2019

    @mmastrac
    Author

    Here's a minimized testcase for Android:

    src/main.rs

    use futures_cpupool::*;
    use rand;
    use rand::Rng;
    
    fn main() {
        let pool = Builder::new()
    	.after_start(|| {
    		rand::thread_rng().gen::<i32>();
    	})
    	.pool_size(100).create();
    
        std::thread::sleep_ms(5000);
    }
    

    Cargo.toml

    [package]
    name = "rand_test"
    version = "0.1.0"
    edition = "2018"
    
    [dependencies]
    futures-cpupool = "0.1.8"
    rand = "0.6.5"
    

    Build with cargo build --target=i686-linux-android and adb push to /data/local/tmp.

    This will occasionally die w/ this error:

    thread '<unnamed>' panicked at 'could not initialize thread_rng: All entropy sources failed (permanently unavailable); cause: OS RNG not yet seeded (not ready yet); cause: Try again (os error 11)', /Users/matt/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.6.5/src/rngs/thread.rs:80:17
    
  5. newpavlov commented on May 28, 2019

    @newpavlov
    Member

    I think the next version which will use getrandom will fix this issue, especially with rust-random/getrandom#14. With this PR initialization will be done only once per application execution, regardless of number of spawned threads. Also getrandom does not use non-blocking API, so EAGAIN (os error 11) should never happen.

  6. vks commented on Jul 3, 2019

    @vks
    Contributor

    @mmastrac Does this issue persist with getrandom >= 0.1.5?

  7. dhardy commented on Sep 14, 2019

    @dhardy
    Member

    I believe this issue is solved in getrandom and in rand 0.7.x.

    If this is not the case, or if you would like to see a back-port to 0.6.x, please comment (or, in the latter case, preferably open a PR).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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