| 
11 | 11 | use self::Entry::*;  | 
12 | 12 | use self::VacantEntryState::*;  | 
13 | 13 | 
 
  | 
 | 14 | +use cell::Cell;  | 
14 | 15 | use borrow::Borrow;  | 
15 | 16 | use cmp::max;  | 
16 | 17 | use fmt::{self, Debug};  | 
@@ -2049,24 +2050,21 @@ impl RandomState {  | 
2049 | 2050 |         // many hash maps are created on a thread. To solve this performance  | 
2050 | 2051 |         // trap we cache the first set of randomly generated keys per-thread.  | 
2051 | 2052 |         //  | 
2052 |  | -        // In doing this, however, we lose the property that all hash maps have  | 
2053 |  | -        // nondeterministic iteration order as all of those created on the same  | 
2054 |  | -        // thread would have the same hash keys. This property has been nice in  | 
2055 |  | -        // the past as it allows for maximal flexibility in the implementation  | 
2056 |  | -        // of `HashMap` itself.  | 
2057 |  | -        //  | 
2058 |  | -        // The constraint here (if there even is one) is just that maps created  | 
2059 |  | -        // on the same thread have the same iteration order, and that *may* be  | 
2060 |  | -        // relied upon even though it is not a documented guarantee at all of  | 
2061 |  | -        // the `HashMap` type. In any case we've decided that this is reasonable  | 
2062 |  | -        // for now, so caching keys thread-locally seems fine.  | 
2063 |  | -        thread_local!(static KEYS: (u64, u64) = {  | 
 | 2053 | +        // Later in #36481 it was discovered that exposing a deterministic  | 
 | 2054 | +        // iteration order allows a form of DOS attack. To counter that we  | 
 | 2055 | +        // increment one of the seeds on every RandomState creation, giving  | 
 | 2056 | +        // every corresponding HashMap a different iteration order.  | 
 | 2057 | +        thread_local!(static KEYS: Cell<(u64, u64)> = {  | 
2064 | 2058 |             let r = rand::OsRng::new();  | 
2065 | 2059 |             let mut r = r.expect("failed to create an OS RNG");  | 
2066 |  | -            (r.gen(), r.gen())  | 
 | 2060 | +            Cell::new((r.gen(), r.gen()))  | 
2067 | 2061 |         });  | 
2068 | 2062 | 
 
  | 
2069 |  | -        KEYS.with(|&(k0, k1)| RandomState { k0: k0, k1: k1 })  | 
 | 2063 | +        KEYS.with(|keys| {  | 
 | 2064 | +            let (k0, k1) = keys.get();  | 
 | 2065 | +            keys.set((k0.wrapping_add(1), k1));  | 
 | 2066 | +            RandomState { k0: k0, k1: k1 }  | 
 | 2067 | +        })  | 
2070 | 2068 |     }  | 
2071 | 2069 | }  | 
2072 | 2070 | 
 
  | 
 | 
0 commit comments