bug: configure an OS whose /etc is assembled at boot without breaking it - #771
Draft
Paco Huelsz (frhuelsz) wants to merge 2 commits into
Draft
bug: configure an OS whose /etc is assembled at boot without breaking it#771Paco Huelsz (frhuelsz) wants to merge 2 commits into
Paco Huelsz (frhuelsz) wants to merge 2 commits into
Conversation
`useradd` creates /etc/passwd from scratch when none is present, holding only the users it was asked to add. On an image that assembles /etc at boot rather than shipping it, Trident runs inside a chroot where that file is not there yet, so the database it creates replaces the real one: the installed system loses every account it had, root included. Azure Container Linux does exactly this. Configuring a single user left the system with a 43-byte /etc/passwd, and it failed to boot -- systemd-tmpfiles could not resolve the `core` user, `initrd-setup-root.service` failed, and the boot ended in an emergency shell. Refuse instead. Without an existing database there is nothing meaningful to add users to, so say so rather than producing one that cannot boot. This does not make user configuration work on such an image; it stops it destroying the system while a proper fix is made. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Azure Container Linux ships no /etc on its root filesystem. Its initrd assembles one at boot as an overlay: the factory contents on the sealed /usr as the lower layer, the root filesystem's own /etc as the upper. Servicing runs before any of that. A chroot into the new root therefore sees an empty /etc, so anything rewriting a file the image provides writes a replacement rather than an edit, and at boot that replacement becomes the upper layer and hides the factory file. Configuring a single user was enough to leave the system with a /etc/passwd holding only that user, and no way to boot. Mount the same overlay before entering the chroot, so servicing sees what the booted system will. Writes still land in the root filesystem's /etc exactly as before, so nothing changes for configuration that only adds files -- hostname, netplan, kernel modules, systemd units, arbitrary additional files all behaved correctly already, because overlayfs merges directories. What changes is that modifying a file the image provides now copies it up from the factory version first, so it stays complete. That covers more than the user database: any configuration that rewrites a file from the factory /etc, such as the SELinux configuration, was subject to the same hazard. Applied to both servicing paths that chroot, clean install and A/B update. Images that do not use this layout are unaffected: the overlay is mounted only for ACL, and only when the factory directory is present. The layout is described in sysdefs, alongside the other ACL definitions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 1 pipeline(s). There may be pipelines that require an authorized user to comment /azp run to run. |
Paco Huelsz (frhuelsz)
changed the base branch from
main
to
user/frhuelsz/inline-verity
September 3, 2026 01:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔍 Description
bug. Two fixes for configuring an OS whose
/etcis assembled at boot rather than shipped in the image. Azure Container Linux does this; configuring a single user was enough to make an installed system unbootable.🤔 Rationale
ACL ships no
/etcon its root filesystem. Its initrd assembles one at boot as an overlay: the factory contents on the sealed/usras the lower layer, the root filesystem's own/etcas the upper.Servicing runs before any of that. A chroot into the new root sees an empty
/etc, so anything that rewrites a file the image provides writes a replacement rather than an edit. At boot that replacement becomes the upper layer and hides the factory file.Configuring one user left the installed system with a 43-byte
/etc/passwdcontaining only that user — noroot, nocore:and the boot ended in an emergency shell:
1. Refuse when there is no user database
useraddcreates/etc/passwdfrom scratch when none exists. Without an existing database there is nothing meaningful to add users to, so refuse rather than produce one that cannot boot. This does not make the feature work; it stops it destroying the system.Worth keeping even with the overlay fix below: it is distro-agnostic, and it turns any future recurrence into a clear message rather than an unbootable machine.
2. Give servicing the same
/etcthe system boots withMount the same overlay before entering the chroot, so servicing sees what the booted system will.
Why this is lower-risk than it looks: the overlay's upper layer is the root filesystem's
/etc— exactly where Trident already writes. So the on-disk result is unchanged for everything that already worked.hostname,netplan,modules,servicesandadditionalFilesonly add files, and overlayfs merges directories. What changes is that modifying a file the image provides now copies it up from the factory version first, so it stays complete.It also fixes more than users: any configuration rewriting a factory
/etcfile was subject to the same hazard,/etc/selinux/configamong them.Applied to both paths that chroot — clean install and A/B update. Images not using this layout are unaffected: the overlay is mounted only for ACL, and only when the factory directory is present.
📝 Checks
Verified on a real ACL image via
make run-netlaunch, installing and booting in QEMU/KVM.Before — install fails, or bricks:
After — install succeeds and the system boots:
Confirmed the overlay is unmounted and its work directory removed; the
/.etc-workpresent at runtime is ACL's own, recreated by the initrd (findmntshows the live/etcoverlay using it).Automated: 22 test suites pass,
cargo fmt --checkclean,cargo clippyintroduces no new warnings.📌 Follow-ups
TODO:
matrix:!in shadow), so key-based SSH is refused by PAM. That is deliberate — Trident locks accounts with no password configured — but it meanssshPublicKeysalone does not yield a usable login. Worth documenting rather than changing.🗒️ Notes
Opened as a draft pending #754.
Found while surveying which
osfeatures work on ACL. The same survey showshostname,netplan,modules,servicesandadditionalFilesalready work, andkernelCommandLinefails cleanly because it is implemented via/etc/default/grub, which a systemd-boot/UKI image does not have.