Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .claude/blackboard.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 2026-10-13 — `cargo-careful` red since #355: the libc probe was ASan's `malloc`

- **Cause:** `cpu_guard::tests::an_address_in_libc_is_not_in_the_main_executable` used `malloc` as its libc address. CI's `cargo-careful` job runs `-Zcareful-sanitizer` (AddressSanitizer), which interposes `malloc` with an interceptor linked into the executable, so the address really is in the main image there. Red on every master merge from #355 (where the test landed) through #361; green at #354.
- **Change:** the test probes glibc's `gnu_get_libc_version`, which no sanitizer replaces. The guard itself is unchanged.
- **Measured here:** scratch crate with `-Zsanitizer=address`: `malloc` in main image `true`, `gnu_get_libc_version` `false`, own function `true` (plain build: false/false/true). `cargo +nightly careful test -Zcareful-sanitizer`: new test passes; with `malloc` restored it fails at `cpu_guard.rs:712`, as in CI. Plain build: 14/14 `cpu_guard` tests.

## 2026-10-13 — CI compiles both production tiers: x86-64-v4 and Sapphire Rapids

- **Change:** `tier4-avx512-check` in `ci.yaml` is now a two-entry matrix, `x86-64-v4` (`.cargo/config-v4.toml`) and `sapphirerapids` (`.cargo/config-avx512.toml`). Each entry runs both `cargo check` feature sets and the asm-only codegen witness. Neither is executed: GitHub's runners are mostly v3. `config-avx512.toml` gains `-Dwarnings`, matching `config-v4.toml`, so both entries gate warnings and the witness script (which word-splits `CARGO_ARGS`) needs no extra quoted `--config`. The job sets `CARGO_PROFILE_{DEV,TEST}_DEBUG=0`: with `--target`, build scripts take the profile's debug level.
Expand Down
20 changes: 13 additions & 7 deletions src/cpu_guard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,11 +692,16 @@ mod tests {
assert!(guard_is_in_main_executable());
}

/// Can-stay-silent half: an address in a loaded system library (libc's
/// `malloc`) is not in the main executable. Without this the lookup
/// could be `true` everywhere and the library case would never happen.
/// Assumes libc is a shared object (the default dynamic linux-gnu
/// build): with `+crt-static`, `malloc` is inside the executable.
/// Can-stay-silent half: an address in a loaded system library (glibc's
/// `gnu_get_libc_version`) is not in the main executable. Without this
/// the lookup could be `true` everywhere and the library case would never
/// happen. Assumes libc is a shared object (the default dynamic linux-gnu
/// build): with `+crt-static`, libc is inside the executable.
///
/// Not `malloc`: a sanitizer interposes it with its own copy linked into
/// the executable, so under `cargo careful -Zcareful-sanitizer` (ASan)
/// `malloc` really is in the main image. No sanitizer replaces
/// `gnu_get_libc_version`.
#[cfg(all(
not(miri),
target_arch = "x86_64",
Expand All @@ -707,9 +712,10 @@ mod tests {
#[test]
fn an_address_in_libc_is_not_in_the_main_executable() {
extern "C" {
fn malloc(size: usize) -> *mut core::ffi::c_void;
fn gnu_get_libc_version() -> *const core::ffi::c_char;
}
assert!(!main_image::contains(malloc as unsafe extern "C" fn(usize) -> *mut core::ffi::c_void as usize));
let in_libc = gnu_get_libc_version as unsafe extern "C" fn() -> *const core::ffi::c_char as usize;
assert!(!main_image::contains(in_libc));
}

#[test]
Expand Down
Loading