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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Per-process and per-thread entropy for the free-list XOR key.
//!
//! The free-list XOR key is split into two independent components:
//!
//! - **Process key** (`PROCESS_KEY`): one random value chosen at first use and
//! shared across all threads. An adversary that reads one thread's TLS seed
//! still cannot predict the process key.
//! - **TLS seed** (`get_tls_seed`): a per-thread random value produced
//! independently from the process key so that knowing the process key is not
//! sufficient to predict any particular thread's key material.
//!
//! Both values exclude `0` (replaced by a fixed fallback) so the XOR key is
//! always non-trivially mixed into every free-list pointer.
//!
//! This module is the single source of truth for key entropy; callers
//! (`initialize_segment_keys`) read from here and nowhere else.
use ;
thread_cached!
// ── Process key ───────────────────────────────────────────────────────────────
/// Process-wide random component of the free-list XOR key.
///
/// Combined with the per-thread seed in `initialize_segment_keys` so that
/// knowing one thread's TLS seed is insufficient to predict another thread's
/// free-list keys (defense in depth against information-disclosure chains).
///
/// Initialized lazily on the first call to [`get_process_key`] using the same
/// `RandomState` entropy source as [`get_tls_seed`]. Reads after initialization
/// are relaxed loads — the acquire/release pairing at initialization is
/// sufficient: no allocator operation can race on the raw pointer value once
/// it is committed.
static PROCESS_KEY: AtomicUsize = new;
// Fallback bit patterns are stable on 64-bit and truncated on 32-bit (WASM).
const PROCESS_KEY_FALLBACK: usize = 0xABCD_ABCD_ABCD_ABCDu64 as usize;
const TLS_SEED_FALLBACK: usize = 0xDEAD_BEEF_FACE_FEEDu64 as usize;
/// Returns the process-wide component of the free-list XOR key, initializing
/// it once on the first call.
///
/// `0` is excluded and replaced by `PROCESS_KEY_FALLBACK` so the key is always
/// non-trivially mixed into every free-list pointer.
pub
/// Cold initialization path — called exactly once per process.
// ── TLS seed ──────────────────────────────────────────────────────────────────
/// Returns the per-thread component of the free-list XOR key, initializing it
/// on the first call for this thread.
///
/// `0` is excluded and replaced by `TLS_SEED_FALLBACK`.
pub