We cannot perform passwd/group lookups _after_ changing the root
directory. This does mean that symbolic links in a path are not
currently handled properly when matching chroot()ed commands.
Fixes a local privilege escalation vulnerability where a user could
craft their own nsswitch.conf file to load a shared library of their
choosing and run arbitrary code. CVE-2025-32463
Reported by Rich Mirch @ Stratascale Cyber Research Unit (CRU).
Checking for setid commands in intercept mode after command matching
allows us to log a proper error message. Previously, we simply
ignored setid commands when matching and the only indication of why
was in the debug logs.
We rely on the include path to find many of these headers. It
especially doesn't make sense to use #include "foo.h" for headers
in the top-level include directory.
We now pass a pointer to the context where necessary. There are a
few cases where we need to request the context from sudoers via
sudoers_get_context() for the plugin API functions. If the plugin
API was able to pass around a closure pointer this would not be
necessary.
privs. Previously, only root or a user with the ability to run any
command as either root or the target user on the current host could
use the -U option. For "sudo -l [-U otheruser] command", NewArgv[0]
is now set to "list" (just like "sudo -l") and the actual command
to be checked starts with NewArgv[1].
In command_matches_all(), if the command is fully-qualified and
open_cmnd() return false, only treat it as an error if we are able
to stat(2) the command. For "sudo ALL" a non-existent command is
not an error.
For command_matches_all() we should only perform the setid check
if the file exists and intercept is enabled. Otherwise, we can end
up returning an error if the fully-qualified command does not exist.
Fixes a regression introduced in sudo 1.9.0 with the support for
digests in conjunction with "sudo ALL".
With this change, a shell in intercept mode cannot run a setuid or
setgid binary by default. On most systems, the dynamic loader will
ignore LD_PRELOAD for setuid/setgid binaries such as sudo which
would effectively disable intercept mode.
Previously we needed to include headers required by the various
sudo*h files. Now those files are more self-sufficient and we
should only include headers needed by code in the various .c files.
We still want to match the command even if it doesn't exist so that the
NOPASSWD flag on sudoers entries with non-existant paths works as expected.
Bug #888.