Skip to content

Fix salt-minion supervisor leaving a privileged parent process (#68115)#69435

Open
dwoz wants to merge 1 commit into
saltstack:3006.xfrom
dwoz:fix/issue-68115
Open

Fix salt-minion supervisor leaving a privileged parent process (#68115)#69435
dwoz wants to merge 1 commit into
saltstack:3006.xfrom
dwoz:fix/issue-68115

Conversation

@dwoz

@dwoz dwoz commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

salt_minion() and salt_proxy() in salt/scripts.py fork a long-lived
keepalive child that becomes the actual minion (and drops privileges to
the configured user inside Minion._real_start). The parent
supervisor process, however, retained root forever — it only forwards
signals and restarts the child on SALT_KEEPALIVE exits, but it stayed
at the head of the otherwise-unprivileged minion process tree.

After the keepalive child has been spawned, the parent now parses the
minion (or proxy) config and calls salt.utils.verify.check_user() to
drop to the configured user. The child has already been forked at that
point, so it still inherits root and can do its own verify_env chowns
and pidfile setup before its own check_user call. The drop only
happens on the first iteration of the keepalive loop; later iterations
fork from the now-unprivileged parent and reuse directories created by
the first child.

What issues does this PR fix or reference?

Fixes #68115

Previous Behavior

With user: salt (or any non-root user) in the minion config, the
ps output showed a root-owned salt-minion process sitting at the
head of a tree of salt-owned MinionKeepAlive / MinionManager
children. The root parent never did anything that required root, but
its presence defeated the security expectation of user:.

New Behavior

The parent supervisor drops to the configured user immediately after
spawning the keepalive child. The entire salt-minion process tree is
owned by the configured user. Same for salt-proxy.

Merge requirements satisfied?

  • Docs (no documented behavior change; existing user: docs now
    match reality)
  • Changelog (changelog/68115.fixed.md)
  • Tests written/updated (tests/pytests/unit/test_scripts.py)

Commits signed with GPG?

No

@dwoz dwoz requested a review from a team as a code owner June 12, 2026 00:50
@dwoz dwoz added this to the Sulphur v3006.26 milestone Jun 12, 2026
@dwoz dwoz added the test:full Run the full test suite label Jun 12, 2026
@dwoz dwoz force-pushed the fix/issue-68115 branch from 447ac79 to 505426e Compare June 14, 2026 02:09
`salt_minion()` and `salt_proxy()` fork a long-lived keepalive child
that becomes the actual minion (and drops privileges to the configured
`user` inside `Minion._real_start`). The parent supervisor process,
however, retained root forever -- it only forwards signals and restarts
the child on SALT_KEEPALIVE exits, yet it stayed at the head of the
otherwise-unprivileged minion process tree.

After the keepalive child has been spawned, parse the minion (or proxy)
config in the parent and call `salt.utils.verify.check_user()` so the
supervisor itself drops to the configured user. The child has already
been forked at that point, so it still inherits root and can do its own
`verify_env` chowns and pidfile setup before its own `check_user` call.
Only drop on the first iteration of the keepalive loop; later iterations
fork from the now-unprivileged parent and reuse directories created by
the first child.

Fixes saltstack#68115
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:full Run the full test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant