Skip to content

hisn 0.4.2

Choose a tag to compare

@github-actions github-actions released this 09 Nov 23:13
· 92 commits to main since this release
5f7bba2

hisn v0.4.2

0.4.2 closes the findings of a code audit of 0.4.1. It adds no features. Profiles that used to panic or hang the supervisor at run time are now rejected when they load, readiness probes can no longer outlive their timeout, a cancelled exec no longer keeps running, and session.json updates are safe across processes.

Upgrade notes

  • A profile that loaded under 0.4.1 can now be rejected. This affects stop.grace or a readiness timeout above 86400 s, NUL bytes in exec strings, and any use of ready.tcp.
  • ready.tcp was accepted before but never became ready, so a profile using it always timed out. It now fails at load with E_NOT_SUPPORTED.
  • A ready.command probe that hangs is no longer retried. It is killed when ready.timeout expires and startup fails.
  • The control-socket protocol, ls --json output, the supervisor.pid format and exit codes are unchanged.

Changed

  • Profile validation. stop.grace and readiness timeout are capped at 86400 s. NUL bytes in host_services.exec, ready.command and service argv are rejected. ready.tcp is rejected as not implemented.
  • Readiness probes are bounded by ready.timeout. A ready.command probe gets the time remaining until the readiness deadline. At the deadline the probe and its process group are killed and startup fails. A slow probe that finishes within the timeout now succeeds.
  • session.json is written under a lock. Every read-modify-write (set_state, record_member, touch_lease) takes an exclusive flock on session.json.lock in the session directory, in the supervisor and in hisn stop.

Fixed

  • Cancelled exec kept running. If a client disconnected before hisn sent started, the program was never signalled and the session could not idle out while it ran. The exec is now cancelled.
  • Supervisor panics from profile values. A very large grace or timeout overflowed the deadline arithmetic, and a NUL byte in an exec string panicked at start. Both are now load-time errors.
  • Host-service stop race. SIGKILL is never sent to a pid that was already reaped, and an interrupted wait no longer cuts the stop grace short.
  • Readiness reported too early. An interrupted wait on a ready.command probe was treated as success. The wait result is now checked.
  • Lost session.json updates. The supervisor and hisn stop could overwrite each other's changes.

Hardening

  • Host-service and readiness-probe children do no allocation between fork and exec. Readiness probes close inherited descriptors and die with the supervisor.
  • The SSH agent proxy computes key fingerprints with the sha2 crate. Its output is unchanged.

Internal

  • Removed dead code: session::mode_of, ServiceHandle.name, init::raw_fd, a stale #[allow(clippy::too_many_arguments)] and an unused parameter.
  • Leak test L33 passes --no-tty, so the suite also passes when run directly on a terminal.

Verified

On the release host (Fedora 45, x86_64): unit tests 406 passed, 0 failed. Leak suite 307 passed, 0 failed, 9 skipped, 1 weak. The exec-cancel and readiness-timeout checks pass end to end.

The portable subset of the leak suite runs in CI. The host-only checks (user namespaces, rootfs, attach, leases) are covered by the host result above. The aarch64 binary is built and started (--version) but has not been leak-tested.

Binaries

The glibc binaries (hisn-x86_64-linux-gnu, hisn-aarch64-linux-gnu) are dynamically linked and built natively on Ubuntu 22.04, so they need glibc 2.35 or newer. The musl binary (hisn-x86_64-linux-musl) is statically linked. Verify with sha256sum -c SHA256SUMS. See README, "Verifying a build".