Commit 8afe462
fix(lifecycle): two signal/restart races in the daemonless monitor + kill paths (#144)
From an adversarial concurrency audit. Both are real multi-actor races (the
monitor daemon and CLI processes coordinate only via the per-modify flock, which
does NOT span an await), with concrete interleavings.
1. (HIGH) Monitor health-restart resurrects a box the user explicitly stopped.
The unhealthy branch awaits graceful_stop (up to 10s) OUTSIDE any lock, then
unconditionally marks the box dead and re-boots it. If the user runs
`a3s-box stop` during that window (setting status=stopped, stopped_by_user),
the monitor erases the stop and resurrects the box. Fix: after the await,
re-validate the freshly-loaded record (new `health_restart_still_wanted`) and
ABORT the restart if it was stopped/stopped_by_user in the meantime.
2. (MED) `kill` fallback host-signal fires with no PID-identity re-check. After a
guest-delivery attempt that can block up to ~10s, the `!delivered` fallback
calls a bare `send_signal(pid)` with no re-check — the one-shot identity check
in require_live_pid is stale by then, so a concurrent force-kill that frees the
shim PID (and a kernel PID reuse) could route the signal to an unrelated host
process. Fix: re-check is_process_alive_with_identity immediately before the
host signal; refuse rather than blind-kill on mismatch.
Test: health_restart_still_wanted unit test (neuter-verified — forcing it true
makes the test fail on the stopped case). #2 reuses the existing identity check
(a defensive re-check, not cleanly unit-testable end-to-end). Full a3s-box-cli
lib suite (598) green; fmt + clippy clean.
Co-authored-by: Roy Lin <roylin@a3s.box>1 parent 3fcd059 commit 8afe462
2 files changed
Lines changed: 61 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
131 | 131 | | |
132 | 132 | | |
133 | 133 | | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
134 | 147 | | |
135 | 148 | | |
136 | 149 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
290 | 290 | | |
291 | 291 | | |
292 | 292 | | |
293 | | - | |
294 | | - | |
295 | | - | |
296 | | - | |
297 | | - | |
298 | | - | |
299 | | - | |
300 | | - | |
301 | | - | |
302 | | - | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
303 | 310 | | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
304 | 319 | | |
305 | 320 | | |
306 | 321 | | |
| |||
366 | 381 | | |
367 | 382 | | |
368 | 383 | | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
369 | 392 | | |
370 | 393 | | |
371 | 394 | | |
| |||
491 | 514 | | |
492 | 515 | | |
493 | 516 | | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
494 | 532 | | |
495 | 533 | | |
496 | 534 | | |
| |||
0 commit comments