Skip to content

Commit 8422961

Browse files
author
Roy Lin
committed
docs(changelog): record post-2.3.0 security/concurrency/operability hardening
Fill the empty [Unreleased] section with the three post-2.3.0 audits merged to main (#131-#146): untrusted-input security (CRITICAL digest path-traversal, whiteout host-delete, decompression bombs, CRI seccomp confinement), daemonless lifecycle concurrency races, and 24 operability findings. Docs-only.
1 parent ff34027 commit 8422961

1 file changed

Lines changed: 57 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,63 @@ All notable changes to A3S Box will be documented in this file.
44

55
## [Unreleased]
66

7+
Post-2.3.0 hardening: three adversarial audits — production-operability (24
8+
findings), untrusted-input security (4), and concurrency/atomicity (4) — all
9+
fixed and validated on real microVMs. No breaking API changes.
10+
11+
### Security
12+
13+
Image extraction runs **host-side before the microVM boots**, so a malicious
14+
image's reach here bypasses VM isolation:
15+
16+
- **Arbitrary host file write via registry digest path-traversal (CRITICAL).** The
17+
manifest digest (`Docker-Content-Digest`, returned verbatim by the registry)
18+
flowed into `Path::join` unvalidated, so `sha256:../../../../<path>` wrote the
19+
attacker-shaped manifest to an arbitrary host path on `pull` in the default
20+
config (signature policy is Skip by default; the box runtime often runs as
21+
root). Digests are now validated as canonical `sha256:<64-hex>` at the trust
22+
boundary before any path use.
23+
- **Arbitrary host file/dir deletion via whiteout symlink escape.** A layer
24+
whiteout whose parent was an absolute symlink (e.g. `esc -> /etc`) deleted host
25+
files/dirs through it. Whiteout parents are now confined within the extraction
26+
target.
27+
- **Host disk exhaustion via decompression bomb.** Layer pull and build
28+
`ADD`/`COPY` auto-extract streamed gzip/zstd/bzip2/xz with no decompressed-size
29+
cap. Bounded by `A3S_BOX_MAX_LAYER_BYTES` (16 GiB) and
30+
`A3S_BOX_MAX_BUILD_EXTRACT_BYTES` (4 GiB), env-overridable.
31+
- **CRI seccomp `localhostProfile` path confinement.** The attacker-set pod field
32+
was read off disk unconfined (an arbitrary host-file open oracle); it is now
33+
confined to `A3S_BOX_SECCOMP_PROFILE_ROOT` (default `/var/lib/kubelet/seccomp`),
34+
rejecting `..` and out-of-root paths.
35+
36+
### Fixed
37+
38+
- **Daemonless lifecycle concurrency races** (the `monitor` daemon, CLI
39+
processes, and CRI server coordinate via a per-write flock that does not span an
40+
`await`):
41+
- The monitor no longer resurrects a box the user `stop`ped during its
42+
up-to-10s health-restart window.
43+
- A user `restart` and the monitor's auto-restart can no longer both boot the
44+
same box (now serialized by a per-box boot lock); previously the second record
45+
write overwrote the first's PID, orphaning an untracked VM.
46+
- `kill`'s host-signal fallback re-checks PID start-time identity before
47+
signalling, so a reused PID is never signalled.
48+
- The warm pool no longer leaks a VM pushed into the idle set during shutdown
49+
drain.
50+
- **Operability (24 findings)** across crash-recovery, upgrade-compat,
51+
disk-pressure, concurrency, network-lifecycle, and config-validation — e.g.
52+
PID-reuse liveness via start-time identity, corrupt-store quarantine instead of
53+
a hard fail, durable (fsync'd) state writes, bounded snapshot / build-cache /
54+
CRI-log growth, atomic CRI network attach, stable bridge IPs across stop/start,
55+
and fail-closed `--cpus` / `--memory-swap` validation.
56+
57+
### Changed
58+
59+
- New operator-tunable caps (generous defaults, env-overridable), documented in
60+
the Environment variables table: `A3S_BOX_MAX_LAYER_BYTES`,
61+
`A3S_BOX_MAX_BUILD_EXTRACT_BYTES`, `A3S_BOX_SECCOMP_PROFILE_ROOT`,
62+
`A3S_BOX_MAX_SNAPSHOTS` / `A3S_BOX_MAX_SNAPSHOT_BYTES`.
63+
764
## [2.3.0] — 2026-06-16
865

966
A security and hardening release closing a 35-finding adversarial audit (plus

0 commit comments

Comments
 (0)