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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
//! Doctor probe: install provenance of the running binary (issue #4033).
//!
//! Why: doctor observed liveness and file state but never binary versioning or
//! install source, so a stale path-installed binary passed every check while
//! serving code the operator believed had been replaced. See
//! [`crate::core::binary_provenance`] for the measured incident.
//!
//! What: [`check_binary_provenance`] resolves the running executable and cargo's
//! `$CARGO_HOME/.crates2.json` ledger, then hands both to
//! [`check_binary_provenance_with`], which is pure over its inputs. This file is
//! only I/O: exe resolution, `CARGO_HOME` resolution, one file read, and a real
//! filesystem probe for the path-install source. READ-ONLY — it never installs,
//! moves, or deletes anything.
//!
//! Test: `provenance_is_unknown_without_a_ledger`,
//! `provenance_is_unknown_without_an_exe`,
//! `provenance_reports_the_ledger_verdict`,
//! `provenance_is_unknown_for_a_downloader_replaced_cargo_install`,
//! `provenance_fails_when_the_running_binary_is_older_than_the_ledger`; the full
//! verdict table lives in `core::binary_provenance`'s own tests.
use std::path::{Path, PathBuf};
use crate::core::binary_provenance::{parse_cargo_installs, provenance_report};
use crate::core::doctor::{CheckStatus, DoctorCheck};
/// Name of this check as it appears in `tm doctor` output.
const CHECK_NAME: &str = "binary_provenance";
/// Probe where the running binary came from and whether that source survives.
///
/// Why: see the module doc — "is what's running what you think it is?" is the
/// observation doctor's health model lacked (#4033).
/// What: resolves `std::env::current_exe()` and the cargo install-ledger path,
/// reads the ledger, and delegates to [`check_binary_provenance_with`]. The
/// running version is this binary's compiled-in `CARGO_PKG_VERSION`.
/// Test: the pure core is covered below; this wrapper is exe + file resolution.
pub(super) fn check_binary_provenance() -> DoctorCheck {
let exe = std::env::current_exe().ok();
let cargo_home = cargo_home_dir();
let ledger_raw = cargo_home
.as_ref()
.and_then(|h| std::fs::read_to_string(h.join(".crates2.json")).ok());
check_binary_provenance_with(
exe.as_deref(),
cargo_home.as_deref(),
ledger_raw.as_deref(),
env!("CARGO_PKG_VERSION"),
)
}
/// Pure core of [`check_binary_provenance`].
///
/// Why: taking the executable path and the raw ledger text as parameters makes
/// every branch testable without mutating `CARGO_HOME` — an env mutation that
/// would race the rest of the suite under `cargo test`'s thread pool.
/// What: `Unknown` when the executable cannot be resolved (nothing to attribute)
/// or when `ledger_raw` is `None`/unparseable (nothing to attribute it to);
/// otherwise the verdict from [`provenance_report`], with a real
/// `Path::exists` probe for a path install's source directory.
/// Test: `provenance_is_unknown_without_a_ledger`,
/// `provenance_is_unknown_without_an_exe`,
/// `provenance_reports_the_ledger_verdict`.
fn check_binary_provenance_with(
exe: Option<&Path>,
cargo_home: Option<&Path>,
ledger_raw: Option<&str>,
running_version: &str,
) -> DoctorCheck {
let Some((exe, bin_name)) = exe.and_then(|p| {
let name = p.file_name()?.to_str()?.to_owned();
Some((p, name))
}) else {
return DoctorCheck::new(
CHECK_NAME,
CheckStatus::Unknown,
"the running executable's path could not be resolved — install provenance \
cannot be verified (issue #4033)",
);
};
// #4622 review HIGH-2: the ledger record is matched by BASENAME, so the
// check also needs the directory cargo installs into, to confirm the running
// binary IS that file rather than a same-named copy shadowing it on PATH.
let Some(cargo_home) = cargo_home else {
return DoctorCheck::new(
CHECK_NAME,
CheckStatus::Unknown,
format!(
"no `$CARGO_HOME` or home directory resolved — cannot tell whether the \
running `{bin_name}` is a cargo install (issue #4033)"
),
);
};
let ledger = ledger_raw.and_then(parse_cargo_installs);
let (status, message) = provenance_report(
&bin_name,
running_version,
exe,
&cargo_home.join("bin"),
ledger.as_deref(),
&|dir| dir.exists(),
);
DoctorCheck::new(CHECK_NAME, status, message)
}
/// Resolve `$CARGO_HOME` (the base for both the ledger and `bin/`).
///
/// Why: `CARGO_HOME` is routinely relocated (rustup layouts, CI images, the
/// prebuilt installer), and reading only `~/.cargo` would report `Unknown` on
/// every such host — an honest answer, but a needlessly uninformative one when
/// the real ledger is one env var away.
/// What: `$CARGO_HOME` when set and non-empty, else `~/.cargo`, else `None`.
/// The ledger is `<base>/.crates2.json` and the install directory `<base>/bin`.
/// Test: exercised live by `run_doctor`; the branches it feeds are covered by
/// `provenance_is_unknown_without_a_ledger` and
/// `provenance_is_unknown_without_a_cargo_home`.
fn cargo_home_dir() -> Option<PathBuf> {
match std::env::var("CARGO_HOME") {
Ok(h) if !h.is_empty() => Some(PathBuf::from(h)),
_ => Some(dirs::home_dir()?.join(".cargo")),
}
}
#[cfg(test)]
mod tests {
use super::*;
/// A host with no cargo ledger must report UNKNOWN, never `Ok`.
///
/// Why: the #4033 rule in its smallest form — a probe that could not
/// determine provenance has not confirmed it.
/// Test: this test.
#[test]
fn provenance_is_unknown_without_a_ledger() {
let check = check_binary_provenance_with(
Some(Path::new("/usr/local/bin/tm")),
Some(Path::new("/home/x/.cargo")),
None,
"1.3.1",
);
assert_eq!(
check.status,
CheckStatus::Unknown,
"message: {}",
check.message
);
assert_eq!(check.name, CHECK_NAME);
}
/// No `$CARGO_HOME` (and no home directory) means the check cannot tell
/// whether the running binary is a cargo install — UNKNOWN, not a pass.
#[test]
fn provenance_is_unknown_without_a_cargo_home() {
let check = check_binary_provenance_with(
Some(Path::new("/usr/local/bin/tm")),
None,
Some("{}"),
"1.3.1",
);
assert_eq!(check.status, CheckStatus::Unknown, "{}", check.message);
}
/// #4622 review HIGH-2 at the CHECK level: a binary shadowing the cargo
/// install must not inherit its provenance, even when versions agree.
#[test]
fn provenance_is_unknown_for_a_shadowing_binary() {
let ledger = r#"{"installs":{
"trusty-mpm 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)":
{"bins":["tm"]}}}"#;
let check = check_binary_provenance_with(
Some(Path::new("/Users/x/.local/bin/tm")),
Some(Path::new("/Users/x/.cargo")),
Some(ledger),
"1.3.1",
);
assert_eq!(
check.status,
CheckStatus::Unknown,
"message: {}",
check.message
);
assert!(check.message.contains(".local/bin/tm"), "{}", check.message);
}
/// #4964 at the CHECK level: after Phase 3 the prebuilt downloader writes
/// into `$CARGO_HOME/bin`, so a clean cargo-free upgrade leaves a NEWER
/// binary at the path a stale ledger record names. That must not read as a
/// health failure.
///
/// Why: this is the false positive #4964's mapping pass found. The path
/// match now succeeds (the file IS at the cargo path), the versions
/// disagree, and the pre-#4964 check answered `Fail` — on exactly the
/// upgrade Phases 1 and 3 exist to produce.
/// Test: this test.
#[test]
fn provenance_is_unknown_for_a_downloader_replaced_cargo_install() {
let ledger = r#"{"installs":{
"trusty-mpm 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)":
{"bins":["tm"]}}}"#;
let check = check_binary_provenance_with(
Some(Path::new("/Users/x/.cargo/bin/tm")),
Some(Path::new("/Users/x/.cargo")),
Some(ledger),
"1.4.0",
);
assert_ne!(
check.status,
CheckStatus::Fail,
"a successful no-cargo upgrade must not fail doctor: {}",
check.message
);
assert_eq!(
check.status,
CheckStatus::Unknown,
"message: {}",
check.message
);
assert!(check.message.contains("NEWER"), "{}", check.message);
}
/// The control for the case above: reverse the two versions and the same
/// inputs must still FAIL. An older binary on top of a newer install is the
/// #4033 defect, and #4964 does not soften it.
#[test]
fn provenance_fails_when_the_running_binary_is_older_than_the_ledger() {
let ledger = r#"{"installs":{
"trusty-mpm 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)":
{"bins":["tm"]}}}"#;
let check = check_binary_provenance_with(
Some(Path::new("/Users/x/.cargo/bin/tm")),
Some(Path::new("/Users/x/.cargo")),
Some(ledger),
"1.3.1",
);
assert_eq!(check.status, CheckStatus::Fail, "{}", check.message);
assert!(check.message.contains("OLDER"), "{}", check.message);
}
/// An unresolvable executable is also UNKNOWN, not a pass.
#[test]
fn provenance_is_unknown_without_an_exe() {
let check = check_binary_provenance_with(
None,
Some(Path::new("/home/x/.cargo")),
Some("{}"),
"1.3.1",
);
assert_eq!(check.status, CheckStatus::Unknown);
}
/// The LIVE check, run against this machine's real cargo ledger, must
/// report UNKNOWN for the test binary.
///
/// Why: this is the #4033 rule exercised end-to-end on real state rather
/// than fixtures. A `cargo test` binary lives in `target/debug/deps/` and is
/// not something cargo installed, so its provenance genuinely cannot be
/// verified — and the check must say so instead of reporting `Ok`. A
/// regression that made an unrecorded binary read as healthy would flip this
/// to `Ok` and fail here.
/// Test: this test (prints the live message under `--nocapture`).
#[test]
fn live_check_reports_unknown_for_an_uninstalled_binary() {
let check = check_binary_provenance();
println!(
"LIVE binary_provenance -> {:?}: {}",
check.status, check.message
);
assert_eq!(
check.status,
CheckStatus::Unknown,
"a binary cargo never installed must be UNKNOWN, not Ok: {}",
check.message
);
}
/// The wrapper must pass the ledger verdict through unchanged.
///
/// Why: proves the plumbing (bin-name derivation from the exe path, ledger
/// parse, delegation) actually reaches the decision table rather than
/// short-circuiting on one of the `Unknown` guards.
/// Test: this test.
#[test]
fn provenance_reports_the_ledger_verdict() {
let ledger = r#"{"installs":{
"trusty-mpm 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)":
{"bins":["tm"]}}}"#;
let check = check_binary_provenance_with(
Some(Path::new("/Users/x/.cargo/bin/tm")),
Some(Path::new("/Users/x/.cargo")),
Some(ledger),
"1.3.1",
);
assert_eq!(check.status, CheckStatus::Ok, "message: {}", check.message);
assert!(check.message.contains("crates.io"), "{}", check.message);
}
}