From 42d701e25f2624c8cc816a65b41c698ce1c6c019 Mon Sep 17 00:00:00 2001 From: Pierre Warnier Date: Wed, 22 Apr 2026 10:27:46 +0200 Subject: [PATCH 1/2] docs: backfill CHANGELOG and SECURITY-HARDENING for review rounds CHANGELOG [Unreleased]: - Add Security section with review round 2 fixes (PAM zeroization, initgroups, SignalBlocker scoping, UmaskGuard !Send/!Sync, targeted newgrp hardening, atomic_write retry, crypt thread-safety docs, centralized hardening, println panic fix, unwind table suppression) - Update 0.1.0 test count from 460+ to 580+, fuzz targets from 4 to 6 SECURITY-HARDENING.md: - Add 7 implemented items from review round 2 --- CHANGELOG.md | 18 +++++++++++++++++- docs/SECURITY-HARDENING.md | 7 +++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0437948..da437fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `passwd`/`chfn`/`chsh`/`newgrp` are setuid-root; the other 10 are `0755`. The previous multicall install is available as `make install-multicall`. +### Security + +- PAM password buffers zeroed immediately after use (`zeroize`) +- `initgroups()` called in newgrp before exec (prevents supplementary group leak) +- `SignalBlocker` scoped to file-mutation critical sections only; dropped before + long-running operations (home deletion, recursive chown, skel copy) +- `UmaskGuard` marked `!Send`/`!Sync` via `PhantomData>` (thread-safety) +- `newgrp` uses targeted hardening (`suppress_core_dumps` + `sanitized_env`) + instead of `harden_process()` to avoid leaking `RLIMIT_FSIZE` to exec'd shell +- `atomic_write` retries once on stale temp file from prior crash +- `crypt(3)` wrapper documented as non-thread-safe (uses global state) +- Centralized hardening utilities in `shadow_core::hardening` (deduplicated + from per-tool copies) +- `println!`/`eprintln!` replaced with non-panicking writes (#141) +- Unwind tables suppressed in release builds (`-C force-unwind-tables=no`, #143) + ### Fixed - Password hash validation rejects `:`, `\n`, `\r` (field injection prevention) @@ -55,7 +71,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Recursive chown on UID change (usermod) - Proper date validation with leap year and month-length rules - GNU-compatible output and exit codes for all tools -- 460+ unit tests, property-based tests (proptest), 4 fuzz targets +- 580+ unit tests, property-based tests (proptest), 6 fuzz targets - Integration tests for 14 tools - Docker test matrix: Debian (glibc), Alpine (musl), Fedora (SELinux) - CI gates: fmt, clippy, test, MSRV (1.94.0), cargo-deny diff --git a/docs/SECURITY-HARDENING.md b/docs/SECURITY-HARDENING.md index b4042de..e5d6814 100644 --- a/docs/SECURITY-HARDENING.md +++ b/docs/SECURITY-HARDENING.md @@ -25,6 +25,13 @@ Techniques adopted from OpenBSD and best practices for setuid-root tools. - [x] O_CLOEXEC on file descriptors (#50) - [x] Umask reset (#51 — `UmaskGuard` RAII) - [x] Landlock filesystem restriction (#41 — `apply_landlock()` in passwd) +- [x] PAM password buffer zeroization (immediate `zeroize` after use) +- [x] `initgroups()` in newgrp (prevent supplementary group leak across exec) +- [x] `UmaskGuard` `!Send`/`!Sync` (`PhantomData>` — prevent cross-thread umask corruption) +- [x] `atomic_write` retry on stale temp file from prior crash +- [x] `SignalBlocker` scoped to critical sections only (dropped before long-running ops) +- [x] Centralized hardening in `shadow_core::hardening` (deduplicated across tools) +- [x] Targeted hardening in newgrp (no `RLIMIT_FSIZE` leak to exec'd shell) ## Not Yet Implemented From 87a5c1bbe0b198c45609e27620c7751fde240128 Mon Sep 17 00:00:00 2001 From: Pierre Warnier Date: Wed, 22 Apr 2026 11:41:17 +0200 Subject: [PATCH 2/2] docs: fix CHANGELOG wording for unwind table suppression --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da437fb..74cf81b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Centralized hardening utilities in `shadow_core::hardening` (deduplicated from per-tool copies) - `println!`/`eprintln!` replaced with non-panicking writes (#141) -- Unwind tables suppressed in release builds (`-C force-unwind-tables=no`, #143) +- Unwind tables suppressed via `-C force-unwind-tables=no` (#143) ### Fixed