Patch to Root CausePart 2 of 2
CVE-2025-32463 in 60 seconds
sudo normally checks policy before it runs a command as root. CVE-2025-32463 let a local user make
sudo enter a user-selected root directory while privileged path, identity, and policy work was
still happening. On systems using /etc/nsswitch.conf, the new root could contain attacker-controlled
name-service configuration that caused sudo to load an attacker-controlled shared library as root.
The attack path was:
local user with access to sudo
-> select an attacker-controlled directory with sudo -R / --chroot
-> sudo enters that filesystem before sudoers evaluation finishes
-> privileged NSS lookup reads the attacker's /etc/nsswitch.conf
-> libc loads a selected name-service module
-> attacker-controlled code runs as root before command authorization can protect the boundary
This explains the surprising impact: the requested command did not need to be permitted in
sudoers. The dangerous code-loading step happened while sudo was still deciding whether the
request should be authorized.
What are chroot, NSS, and sudo -R?
chroot() changes the filesystem root a process sees. It is useful for selecting an execution
environment, but it is not a security boundary when an untrusted user controls the directory and a
privileged process continues interpreting files inside it.
NSS, the Name Service Switch, tells libc where to resolve users, groups, hosts, and other names.
/etc/nsswitch.conf selects providers, and some providers are implemented as shared libraries.
sudo -R exposed a user-selected root-directory feature when policy allowed it. The vulnerability
was that the selected root became active early enough to influence privileged NSS behavior before
that policy decision was safely complete.
What happened?
Sudo 1.9.14 changed path handling so the user-specified root could be entered with chroot() while
the sudoers file was still being evaluated. A local user could prepare an /etc/nsswitch.conf
below that root and steer a later name-service lookup toward an arbitrary shared library. Because
the lookup occurred in the privileged sudo process, the library loaded with root privileges.
Sudo 1.9.17p1 reverted the early-root design, returned to prefixing the selected root during path resolution, and deprecated the chroot feature. The fix restores the order of operations: an untrusted filesystem must not become part of privileged interpretation before authorization is complete.
Who was actually affected?
The upstream disclosure identifies sudo 1.9.14 through 1.9.17 inclusive. Exploitation required a
local user able to invoke the affected sudo path, a system supporting /etc/nsswitch.conf, and a
vulnerable build. It did not require the eventual command to appear in sudoers, because the library
load could occur during evaluation.
Sudo 1.9.17p1 fixes the bug. Distribution package versions may include backports, so defenders should verify the vendor advisory and changelog for the installed package rather than relying only on the upstream version string.
What I verified
- The fix reverts the early
pivot_rootdesign and returns to prefixing the selected root while resolving command paths. - Before that revert,
runchrootflowed through checks such assudo_goodpath()andfind_path()while privileged identity and policy work was still in progress. - The upstream patch states that passwd and group lookups cannot safely happen after changing root
and names crafted
nsswitch.conflibrary loading as CVE-2025-32463’s consequence. - I compared those code changes with the project advisory and public disclosure timeline.
- This is a static reproduction of the dangerous ordering and its fix. I did not load a custom shared object or claim a live privilege-escalation reproduction.
Deep dive: the bug is a sequence, not a dangerous file
It is tempting to describe the vulnerability as “a malicious nsswitch.conf.” That is only the
last visible input. A normal program reading configuration from its own root filesystem is not
automatically vulnerable. The dangerous sequence is:
- a privileged program accepts a root directory chosen by an unprivileged caller;
- that directory becomes active while policy and identity work is still happening;
- libc name-service resolution consults configuration below the new root;
- the configuration influences module loading inside the privileged process;
- attacker-controlled code executes before authorization provides a meaningful boundary.
The root cause is therefore not “NSS is unsafe.” NSS is doing what it was designed to do: read the configuration associated with the current root and load the selected service modules. The mistake is giving an untrusted caller control of that root while a privileged process can still trigger those behaviors.
The 1.9.14 regression changed when paths were resolved
The coordinated oss-security disclosure says the affected range begins with sudo 1.9.14.
That release changed path handling so paths could be resolved via chroot() using the
user-specified root directory while the sudoers file was still being evaluated.
That ordering is the crucial regression. A user-selected chroot may look like an execution property: “run the eventual command inside this filesystem.” In the vulnerable implementation, it also became an interpretation property: “use this filesystem while deciding identities, paths, and policy.” Those are not equivalent capabilities.
This explains why a rule review alone cannot disprove exposure. The public advisory states that
arbitrary commands could run even when they were not listed in sudoers. The bypass is not a
clever match against an allowed command. It operates beneath the abstraction administrators
normally audit.
NSS is the bridge from configuration to code
Name Service Switch allows libc to resolve users, groups, hosts, and other records through
configured sources. /etc/nsswitch.conf selects those sources. Some selections correspond to
shared objects loaded by the process.
The vulnerable sudo process did not merely read attacker-controlled text. It performed a privileged lookup whose implementation could be selected by that text. This is a useful general research pattern:
When privileged code enters an attacker-controlled namespace, inventory every implicit interpreter, loader, resolver, and configuration search—not only the file named in the patch.
The same reasoning applies to locale catalogs, dynamic loader configuration, PAM stacks, plugin discovery, certificate stores, and language runtimes. Chroot changes path visibility; it does not automatically make the visible files trustworthy.
What the fix changes
The public disclosure says sudo 1.9.17p1 reverts the 1.9.14 change and marks the chroot feature as deprecated. This is stronger than filtering one suspicious NSS token. It removes the precondition that allowed user-controlled filesystem state to participate in policy evaluation.
The deprecation matters. The maintainers explicitly describe user-selected chroot support as error-prone and not widely used. That is an architectural conclusion: if a feature repeatedly forces privileged interpretation into an untrusted namespace, restricting or removing the feature can be safer than accumulating local checks.
Evidence matrix
| Question | What I checked | Confidence | What remains unknown |
|---|---|---|---|
| Which versions are affected? | I matched the disclosure’s 1.9.14–1.9.17 range to the 1.9.17p1 tag diff. | High | Distribution backports require vendor-specific package checks. |
| What attacker position is required? | I confirmed the affected route is local and begins with a user-selected chroot path. | High | Exact prerequisites vary with build options, policy, and platform NSS behavior. |
| Why does authorization fail? | I traced the selected root into path checks performed before privileged resolution had finished. | High | Private discovery traces and original exploit-development steps are not public here. |
| Does the fix block one filename? | I verified that the fix reverts the broader path-resolution design rather than filtering one name. | High | Future feature removal timing is a release-management decision. |
| Was it exploited? | I checked the public catalog status; I did not infer actors or victims from it. | High | Public records do not identify every victim, actor, or exploitation method. |
| Is the base score settled? | NVD shows 7.8 High while the CNA contribution is 9.3 Critical. | High | The disagreement depends on privilege and scope assumptions. |
The score disagreement is worth preserving instead of averaging away. NVD models a local user with low privileges and unchanged scope. The CNA vector models no privileges and changed scope. Both agree on low attack complexity, no user interaction, and complete confidentiality, integrity, and availability impact. For remediation, the affected version and reachable local attack surface matter more than choosing the more dramatic label.
Safe validation without building an exploit
An exposure check should answer three separate questions.
First, record the installed package version and the distribution’s security status. A package
version string older than 1.9.17p1 is not conclusive when vendors backport fixes; the vendor
advisory and package changelog are the correct comparison points.
Second, inspect whether the installed sudo build exposes the chroot option and whether local policy permits relevant invocation paths. This establishes reachability without attempting library loading.
Third, compare vulnerable and fixed builds under observation. A safe regression harness can use an inert directory tree and trace filesystem access. The assertion is structural: the fixed build must not consult name-service configuration below the user-selected root while making the privileged policy decision. No custom shared object or root shell is needed to verify that the dangerous lookup disappeared.
Useful negative controls include:
- the same request against 1.9.17p1;
- the same inert tree with no
etc/nsswitch.conf; - a request without a user-selected root;
- a distribution package documented as backported even if its upstream version looks older.
These controls prevent a common reporting mistake: treating the presence of a command-line option or an old-looking version as proof of exploitation.
My conclusion
Upgrade to sudo 1.9.17p1 or the distribution package that explicitly backports the fix. Until the update is complete, reduce local account exposure and remove unnecessary policy paths that permit user-selected root directories. Detection should focus on unexpected use of sudo’s chroot option, unusual filesystem trees prepared by local users, and privileged processes loading name-service modules from non-system locations.
My conclusion is that the crafted file was only the last step; the real defect was entering a user-controlled filesystem view before privileged resolution had finished. Once that ordering was reversed, NSS no longer received attacker-selected configuration during the authorization path.
Evidence used for this analysis
Version and exploitation status can change; follow the linked vendor records.
The author completed a technical review. This does not, by itself, claim lab reproduction.
