Skip to content

ThreadSanitizer detected data race on getrandom 0.1.7 upgrade #68

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

Closed
dekellum opened this issue Jul 30, 2019 · 4 comments
Closed

ThreadSanitizer detected data race on getrandom 0.1.7 upgrade #68

dekellum opened this issue Jul 30, 2019 · 4 comments

Comments

@dekellum
Copy link
Contributor

dekellum commented Jul 30, 2019

This may well be a false positive with TSAN and false issue, but I figured I'd report it just in case its real. This was originally detected via Tokio's TSAN CI tests, in tokio-rs/tokio#1358 (comment) .

I went ahead and created a minimized, out of tokio tree, repro for this here:

https://github.com/dekellum/rng-tsan-min-repro

See the README for repro-steps. I have reproduced with these two rustc --versions:

rustc 1.38.0-nightly (83e4eed16 2019-07-14)
rustc 1.38.0-nightly (4560cb830 2019-07-28)

See test.out for failing output form ThreadSanitizer:

WARNING: ThreadSanitizer: data race (pid=28325)
  Read of size 8 at 0x559290ec6050 by thread T3:
    #0 lazy_static::lazy::Lazy<T>::get /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.3.0/src/inline_lazy.rs:35 (rng_tsan_min_repro-6bc72839c6f31b66+0x1235d8)
    #1 <c2_chacha::guts::init_chacha::IMPL as core::ops::deref::Deref>::deref::__stability /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/c2-chacha-0.2.2/<::lazy_static::__lazy_static_internal macros>:17 (rng_tsan_min_repro-6bc72839c6f31b66+0x1235d8)
    #2 <c2_chacha::guts::init_chacha::IMPL as core::ops::deref::Deref>::deref /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/c2-chacha-0.2.2/<::lazy_static::__lazy_static_internal macros>:19 (rng_tsan_min_repro-6bc72839c6f31b66+0x1235d8)
    #3 c2_chacha::guts::init_chacha /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.7.0/<::ppv_lite86::x86_64::dispatch_light128 macros>:35 (rng_tsan_min_repro-6bc72839c6f31b66+0xd7a30)
    #4 c2_chacha::guts::ChaCha::new /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/c2-chacha-0.2.2/src/guts.rs:60 (rng_tsan_min_repro-6bc72839c6f31b66+0xd7a30)
    #5 <rand_chacha::chacha::ChaCha20Core as rand_core::SeedableRng>::from_seed /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/rand_chacha-0.2.1/src/chacha.rs:94 (rng_tsan_min_repro-6bc72839c6f31b66+0xd7a30)
    #6 rand_core::SeedableRng::from_rng /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/rand_core-0.5.0/src/lib.rs:359 (rng_tsan_min_repro-6bc72839c6f31b66+0xd835a)
    #7 rand::rngs::thread::THREAD_RNG_KEY::__init /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.7.0/src/rngs/thread.rs:64 (rng_tsan_min_repro-6bc72839c6f31b66+0xde031)
    #8 core::ops::function::FnOnce::call_once /rustc/4560cb830fce63fcffdc4558f4281aaac6a3a1ba/src/libcore/ops/function.rs:235 (rng_tsan_min_repro-6bc72839c6f31b66+0xdb1b7)
    #9 std::thread::local::lazy::LazyKeyInner<T>::initialize /rustc/4560cb830fce63fcffdc4558f4281aaac6a3a1ba/src/libstd/thread/local.rs:285 (rng_tsan_min_repro-6bc72839c6f31b66+0xd73ae)
    #10 std::thread::local::fast::Key<T>::try_initialize /rustc/4560cb830fce63fcffdc4558f4281aaac6a3a1ba/src/libstd/thread/local.rs:426 (rng_tsan_min_repro-6bc72839c6f31b66+0xde5bd)
    #11 std::thread::local::fast::Key<T>::get /rustc/4560cb830fce63fcffdc4558f4281aaac6a3a1ba/src/libstd/thread/local.rs:411 (rng_tsan_min_repro-6bc72839c6f31b66+0xde79c)
    #12 rand::rngs::thread::THREAD_RNG_KEY::__getit /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.7.0/<::std::thread::local::__thread_local_inner macros>:28 (rng_tsan_min_repro-6bc72839c6f31b66+0xde279)
    #13 std::thread::local::LocalKey<T>::try_with /rustc/4560cb830fce63fcffdc4558f4281aaac6a3a1ba/src/libstd/thread/local.rs:254 (rng_tsan_min_repro-6bc72839c6f31b66+0xde3a1)
    #14 std::thread::local::LocalKey<T>::with /rustc/4560cb830fce63fcffdc4558f4281aaac6a3a1ba/src/libstd/thread/local.rs:234 (rng_tsan_min_repro-6bc72839c6f31b66+0xde2ed)
    #15 rand::rngs::thread::thread_rng /home/david/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.7.0/src/rngs/thread.rs:81 (rng_tsan_min_repro-6bc72839c6f31b66+0xddefd)
    #16 rng_tsan_min_repro::tests::hammer::{{closure}}::{{closure}} /home/david/src/rng-tsan-min-repo/src/lib.rs:13 (rng_tsan_min_repro-6bc72839c6f31b66+0x20496)
[...]

This can be made to go away, by downgrading the getrandom crate:

cargo update -p getrandom --precise 0.1.6

In #52 (included in 0.1.7), some internal state access is relaxed by replacing lazy_static with custom code? I can only guess, that increased concurrency in getrandom has somehow exposed an issue in rand_chacha?

Downgrading rand_chacha from 0.2.1 to 0.2.0 makes no difference however.

If on the other hand this is a false positive from ThreadSanitizer, then this is an unfortunately broad way to suppress it:

# See https://github.com/dekellum/rng-tsan-min-repro
race:lazy_static::lazy::Lazy<T>::get
@newpavlov
Copy link
Member

I don't think it's the getrandom crate issue, replacing code with the following one does not trigger the warning:

let mut buf = [0u8; 128];
getrandom(&mut buf);
let ms = (buf[0] % 9) as u64 + 3;
thread::sleep(Duration::from_millis(ms));

While this code results in the same data race warning:

let mut rng = ChaCha8Rng::seed_from_u64(i);
let ms = rng.next_u64() % 9 as u64 + 3;
thread::sleep(Duration::from_millis(ms));

IIUC rand_chacha internally checks availability of SIMD instructions and there is could be an issue in the code which caches check results.

@dekellum
Copy link
Contributor Author

Thanks. So would you suggest I also report this there?

@newpavlov
Copy link
Member

I guess you should report it to c2-chacha repository: https://github.com/cryptocorrosion/cryptocorrosion

@dekellum
Copy link
Contributor Author

dekellum commented Aug 1, 2019

I can actually reproduce something similar with only lazy_static, (even c2-chacha removed):

https://github.com/dekellum/rng-tsan-min-repro/tree/lazy-static

Thanks again for your help with this. Its been educational at least.

@dekellum dekellum closed this as completed Aug 1, 2019
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