-
Notifications
You must be signed in to change notification settings - Fork 4
/
0030-cache.rs
61 lines (49 loc) · 1.51 KB
/
0030-cache.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*!
```rudra-poc
[target]
crate = "cache"
version = "0.2.0"
[[target.peer]]
crate = "crossbeam-utils"
version = "0.8.0"
[report]
issue_url = "https://github.com/krl/cache/issues/1"
issue_date = 2020-11-24
rustsec_url = "https://github.com/RustSec/advisory-db/pull/704"
rustsec_id = "RUSTSEC-2020-0128"
[[bugs]]
analyzer = "SendSyncVariance"
bug_class = "SendSyncVariance"
bug_count = 2
rudra_report_locations = ["src/lib.rs:85:1: 85:36", "src/lib.rs:86:1: 86:36"]
```
!*/
#![forbid(unsafe_code)]
use std::rc::Rc;
const NUM_CLONES: usize = 1000000;
use cache::*;
use crossbeam_utils::thread;
fn main() {
let rc = Rc::new(true);
let cache = Cache::new(1, 4096);
cache.insert(0, rc.clone());
// We demonstrate the issue by racing the non-atomic reference counter type `Rc` between two threads.
thread::scope(|s| {
let child = s.spawn(|_| {
// &Rc<bool> sent to another thread
let smuggled = cache.get::<Rc<bool>>(&0).unwrap();
for _ in 0..NUM_CLONES {
std::mem::forget(smuggled.clone());
}
});
// if `child.join().unwrap()` is here, the program succeeds
for _ in 0..NUM_CLONES {
std::mem::forget(rc.clone());
}
child.join().unwrap();
// We made NUM_CLONES on both threads plus initial 2 reference.
// But in reality we'll see that the strong_count varies across every run due to data race.
assert_eq!(Rc::strong_count(&rc), 2 * NUM_CLONES + 2);
})
.unwrap();
}