Skip to content

Fix argv injection in _create_user and gpasswd loop#4473

Merged
svartkanin merged 2 commits intoarchlinux:masterfrom
Softer:fix-argv-injection-useradd-gpasswd
Apr 26, 2026
Merged

Fix argv injection in _create_user and gpasswd loop#4473
svartkanin merged 2 commits intoarchlinux:masterfrom
Softer:fix-argv-injection-useradd-gpasswd

Conversation

@Softer
Copy link
Copy Markdown
Contributor

@Softer Softer commented Apr 24, 2026

Same class of bug as #4443, two sibling call sites that were missed back then. _create_user and the gpasswd loop interpolate user.username and group into f-strings that reach SysCommand(f'arch-chroot -S {target} {cmd}'), where shlex.split parses the payload as argv. A username like --uid 0 or -G wheel,root is accepted as useradd/gpasswd flags and gives trivial escalation. Vector is the same as #4443: custom install.py, plugins, tampered --config JSON.

Changes

_create_user now builds an argv list and calls run(). Failures are logged via debug(), and the SystemError re-raise is kept so guided install still aborts.

The gpasswd loop gets the same switch. Also wrapped it in try/except with debug() - previously a failing gpasswd was silently ignored.

Use argv list with run() instead of f-string interpolation into
SysCommand, add debug logging on failure.
@Softer Softer requested a review from Torxed as a code owner April 24, 2026 10:29
Comment thread archinstall/lib/installer.py Outdated
Address svartkanin's review on archlinux#4473: factor the
['arch-chroot', '-S', str(self.target), ...] boilerplate into a
private Installer._chroot_argv() helper, and migrate the seven
existing argv-form call sites to it (useradd, gpasswd, chpasswd,
chsh, chown, snapper-create-config, grub-install).

Two related hardening tweaks while in the area:

- Raise gpasswd failure log from debug() to warn(). The group-add
  loop has no return-False feedback channel for the caller, so a
  silent debug() means a half-configured user looks like a
  successful install.

- Add `--` end-of-options separator for useradd and chown so a
  username or path starting with `-` cannot smuggle flags. The TUI
  validates usernames, but parse_arguments() in models/users.py
  does not, so config.json is the residual hole; this closes it
  for these two sites at zero cost.
@svartkanin svartkanin merged commit 9e05260 into archlinux:master Apr 26, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants