Current Stable Release
The current stable release of the sudo 1.9 branch is version
For the sudo 1.8 branch, see legacy releases
For full details of all changes, see the ChangeLog
file or view the commit history via
Major changes between version 1.9.7 and 1.9.6p1:
- The fuzz Makefile target now runs all the fuzzers for 8192
passes (can be overridden via the FUZZ_RUNS variable).
This makes it easier to run the fuzzers in-tree. To run a fuzzer
indefinitely, set FUZZ_RUNS=-1, e.g. make FUZZ_RUNS=-1 fuzz.
- Fixed fuzzing on FreeBSD where the ld.lld linker returns an
error by default when a symbol is multiply-defined.
- Added support for determining local IPv6 addresses on systems
that lack the getifaddrs() function. This now works on AIX,
HP-UX and Solaris (at least).
- Fixed a bug introduced in sudo 1.9.6 that caused sudo -V to
report a usage error. Also, when invoked as sudoedit, sudo now
allows a more restricted set of options that matches the usage
statement and documentation.
GitHub Issue #95.
- Fixed a crash in sudo_sendlog when the specified certificate
or key does not exist or is invalid.
- Fixed a compilation error when sudo is configured with the
- Sudo's limited support for SUCCESS=return entries in nsswitch.conf
is now documented.
- Sudo now requires autoconf 2.70 or higher to regenerate the
- sudo_logsrvd now has a relay mode which can be used to create
a hierarchy of log servers. By default, when a relay server is
defined, messages from the client are forwarded immediately to
the relay. However, if the store_first setting is enabled,
the log will be stored locally until the command completes and
- Sudo now links with OpenSSL by default if it is available unless
the --disable-openssl configure option is used or both the
--disable-log-client and --disable-log-server
configure options are specified.
- Fixed configure's Python version detection when the version minor
number is more than a single digit, for example Python 3.10.
- The sudo Python module tests now pass for Python 3.10.
- Sudo will now avoid changing the datasize resource limit
as long as the existing value is at least 1GB. This works around
a problem on 64-bit HP-UX where it is not possible to exactly
restore the original datasize limit.
- Fixed a race condition that could result in a hang when sudo is
executed by a process where the SIGCHLD handler is set to SIG_IGN.
This fixes the bug described by GitHub PR #98.
- Fixed an out-of-bounds read in sudoedit and visudo when the
EDITOR, VISUAL or SUDO_EDITOR environment variables end in an
unescaped backslash. Also fixed the handling of quote characters
that are escaped by a backslash.
GitHub Issue #99.
- Fixed a bug that prevented the log_server_verify sudoers
option from taking effect.
- The sudo_sendlog utility has a new -s option
to cause it to stop sending I/O records after a user-specified elapsed
time. This can be used to test the I/O log restart functionality
- Fixed a crash introduced in sudo 1.9.4 in sudo_logsrvd when
attempting to restart an interrupted I/O log transfer.
- The TLS connection timeout in the sudoers log client was previously
hard-coded to 10 seconds. It now uses the value of
- The configure script now outputs a summary of the user-configurable
options at the end, separate from output of configure script tests.
- Corrected the description of which groups may be specified via the
-g option in the Runas_Spec section.
Major changes between version 1.9.6p1 and 1.9.6:
- Fixed a regression introduced in sudo 1.9.6 that resulted in an
error message instead of a usage message when sudo is run with
Major changes between version 1.9.6 and 1.9.5p2:
- Fixed a sudo_sendlog compilation problem with the AIX xlC compiler.
- Fixed a regression introduced in sudo 1.9.4 where the
--disable-root-mailer configure option had no effect.
- Added a --disable-leaks configure option that avoids some
memory leaks on exit that would otherwise occur. This is intended
to be used with development tools that measure memory leaks. It
is not safe to use in production at this time.
- Plugged some memory leaks identified by oss-fuzz and ASAN.
- Fixed the handling of sudoOptions for an LDAP sudoRole
that contains multiple sudoCommands. Previously, some of the options
would only be applied to the first sudoCommand.
- Fixed a potential out of bounds read in the parsing of NOTBEFORE
and NOTAFTER sudoers command options (and their LDAP equivalents).
- The parser used for reading I/O log JSON files is now more
resilient when processing invalid JSON.
- Fixed typos that prevented make uninstall from working.
GitHub issue #87.
- Fixed a regression introduced in sudo 1.9.4 where the last line
in a sudoers file might not have a terminating NUL character
added if no newline was present.
- Integrated oss-fuzz and LLVM's libFuzzer with sudo. The new
--enable-fuzzer configure option can be combined with the
--enable-sanitizer option to build sudo with fuzzing support.
Multiple fuzz targets are available for fuzzing different parts
of sudo. Fuzzers are built and tested via make fuzz or as part
of make check (even when sudo is not built with fuzzing support).
Fuzzing support currently requires the LLVM clang compiler (not gcc).
- Fixed the --enable-static-sudoers configure option.
GitHub issue #92.
- Fixed a potential out of bounds read sudo when is run by a user
with more groups than the value of max_groups in sudo.conf.
- Added an admin_flag sudoers option to make the use of the
~/.sudo_as_admin_successful file configurable on systems where
sudo is build with the --enable-admin-flag configure option.
This mostly affects Ubuntu and its derivatives.
GitHub issue #56.
- The max_groups setting in sudo.conf is now limited to 1024.
This setting is obsolete and should no longer be needed.
- Fixed a bug in the tilde expansion of CHROOT=dir
and CWD=dir sudoers command options. A path
~/foo was expanded to /home/userfoo instead
of /home/user/foo. This also affects the
runchroot and runcwd Defaults settings.
- Fixed a bug on systems without a native getdelim(3) function
where very long lines could cause parsing of the sudoers file
to end prematurely.
- Fixed a potential integer overflow when converting the
timestamp_timeout and passwd_timeout sudoers settings to a
- The default for the group_source setting in sudo.conf is now
dynamic on macOS. Recent versions of macOS do not reliably
return all of a user's non-local groups via getgroups(2), even
when _DARWIN_UNLIMITED_GETGROUPS is defined.
- Fixed a potential use-after-free in the PAM conversation function.
- Fixed potential redefinition of sys/stat.h macros in sudo_compat.h.
Major changes between version 1.9.5p2 and 1.9.5p1:
- Fixed sudo's setprogname(3) emulation on systems
that don't provide it.
- Fixed a problem with the sudoers log server client where a partial
write to the server could result the sudo process consuming large
amounts of CPU time due to a cycle in the buffer queue.
- Added a missing dependency on libsudo_util in libsudo_eventlog.
Fixes a link error when building sudo statically.
- The user's KRB5CCNAME environment variable is now
preserved when performing PAM authentication. This fixes
GSSAPI authentication when the user has a non-default ccache.
- When invoked as sudoedit, the same set of command line options
are now accepted as for sudo -e. The -H
and -P options are now rejected for
sudoedit and sudo -e which matches the
sudo 1.7 behavior. This is part of the fix for CVE-2021-3156.
- Fixed a potential buffer overflow when unescaping backslashes
in the command's arguments. Normally, sudo escapes special
characters when running a command via a shell (sudo
-s or sudo -i). However, it was also possible
to run sudoedit with the -s or
-i flags in which case no escaping had
actually been done, making a buffer overflow possible. This
Major changes between version 1.9.5p1 and 1.9.5:
- Fixed a regression introduced in sudo 1.9.5 where the editor run
by sudoedit was set-user-ID root unless SELinux RBAC was in use.
The editor is now run with the user's real and effective user-IDs.
Major changes between version 1.9.5 and 1.9.4p2:
- Fixed a crash introduced in 1.9.4 when running sudo -i as an
unknown user. This is related to but distinct from
- If the lecture_file setting is enabled in sudoers, it must now
refer to a regular file or a symbolic link to a regular file.
- Fixed a potential use-after-free bug in sudo_logsrvd when the
server shuts down if there are existing connections from clients
that are only logging events and not session I/O data.
- Fixed a buffer size mismatch when serializing the list of IP
addresses for configured network interfaces. This bug is not
actually exploitable since the allocated buffer is large enough
to hold the list of addresses.
- If sudo is executed with a name other than sudo
or sudoedit, it will now fall back to
sudo as the program name. This affects
warning, help and usage messages as well as the matching
of Debug lines in the /etc/sudo.conf file.
Previously, it was possible for the invoking user to
manipulate the program name by setting argv to
an arbitrary value when executing sudo.
- Sudo now checks for failure when setting the close-on-exec flag
on open file descriptors. This should never fail but, if it
were to, there is the possibility of a file descriptor leak to
a child process (such as the command sudo runs).
- Fixed CVE-2021-23239,
a potential information leak in sudoedit
that could be used to test for the existence of directories not
normally accessible to the user in certain circumstances. When
creating a new file, sudoedit checks to make sure the parent
directory of the new file exists before running the editor.
However, a race condition exists if the invoking user can replace
(or create) the parent directory. If a symbolic link is created
in place of the parent directory, sudoedit will run the editor
as long as the target of the link exists. If the target of the
link does not exist, an error message will be displayed. The
race condition can be used to test for the existence of an
arbitrary directory. However, it cannot be used
to write to an arbitrary location.
- Fixed CVE-2021-23240,
a flaw in the temporary file handling of
sudoedit's SELinux RBAC support. On systems where SELinux is
enabled, a user with sudoedit permissions may be able to set the
owner of an arbitrary file to the user-ID of the target user.
On Linux kernels that support protected symlinks setting
/proc/sys/fs/protected_symlinks to 1 will prevent the bug from
being exploited. For more information, see
Symbolic link attack in SELinux-enabled sudoedit.
- Added writability checks for sudoedit when SELinux
RBAC is in use. This makes sudoedit behavior consistent
regardless of whether or not SELinux RBAC is in use.
Previously, the sudoedit_checkdir setting had no
effect for RBAC entries.
- A new sudoers option selinux can be used to disable sudo's
SELinux RBAC support.
- Quieted warnings from PVS Studio, clang analyzer, and cppcheck.
Added suppression annotations for PVS Studio false positives.
Major changes between version 1.9.4p2 and 1.9.4p1:
- Fixed a bug introduced in sudo 1.9.4p1 which could lead to a crash
if the sudoers file contains a runas user-specific Defaults entry.
Major changes between version 1.9.4p1 and 1.9.4:
- Sudo on macOS now supports users with more than 16 groups without
needing to set group_source to dynamic in sudo.conf.
Previously, only the first 15 were used when matching group-based
rules in sudoers.
- Fixed a regression introduced in version 1.9.4 where sudo would
not build when configured using the --without-sendmail option.
- Fixed a problem where if I/O logging was disabled and sudo was
unable to connect to sudo_logsrvd, the command would still be
allowed to run even when the ignore_logfile_errors sudoers
option was enabled.
- Fixed a crash introduced in version 1.9.4 when attempting to run
a command as a non-existent user.
- The installed sudo.conf file now has the default sudoers Plugin
lines commented out. This fixes a potential conflict when there
is both a system-installed version of sudo and a user-installed
GitHub Issue #75.
- Fixed a regression introduced in sudo 1.9.4 where sudo would run
the command as a child process even when a pseudo-terminal was
not in use and the pam_session and pam_setcred options were
GitHub Issue #76.
- Fixed a regression introduced in sudo 1.8.9 where the closefrom
sudoers option could not be set to a value of 3.
Major changes between version 1.9.4 and 1.9.3p1:
- The sudoers parser will now detect when an upper-case reserved
word is used when declaring an alias. Now instead of syntax
error, unexpected CHROOT, expecting ALIAS the message will be
syntax error, reserved word CHROOT used as an alias name.
- Better handling of sudoers files without a final newline.
The parser now adds a newline at end-of-file automatically which
removes the need for special cases in the parser.
- Fixed a regression introduced in sudo 1.9.1 in the sssd back-end
where an uninitialized pointer could be freed on an error path.
GitHub Issue #67.
- The core logging code is now shared between sudo_logsrvd and
the sudoers plugin.
- JSON log entries sent to syslog now use minimal JSON which
skips all non-essential whitespace.
- The sudoers plugin can now produce JSON-formatted logs. The
log_format sudoers option can be used to select sudo or json
format logs. The default is sudo format logs.
- The sudoers plugin and visudo now display the column number in
syntax error messages in addition to the line number.
- If I/O logging is not enabled but log_servers is set, the
sudoers plugin will now log accept events to sudo_logsrvd.
Previously, the accept event was only sent when I/O logging was
enabled. The sudoers plugin now sends reject and alert events too.
- The sudo logsrv protocol has been extended to allow an
AlertMessage to contain an optional array of
InfoMessage, as AcceptMessage and
RejectMessage already do.
- Fixed a bug in sudo_logsrvd where receipt of SIGHUP would
result in duplicate entries in the debug log when debugging was enabled.
- The visudo utility now supports EDITOR environment variables
that use single or double quotes in the command arguments.
- The PAM session modules now run when sudo is set-user-ID root,
which allows a module to determine the original user-ID.
- Fixed a regression introduced in sudo 1.8.24 in the LDAP back-end
where sudoNotBefore and sudoNotAfter were applied even when the
SUDOERS_TIMED setting was not present in ldap.conf.
- Sudo packages for macOS 11 now contain universal binaries that
support both Intel and Apple Silicon CPUs.
- For sudo_logsrvd, an empty value for the pid_file setting in
sudo_logsrvd.con will now disable the process ID file.
Major changes between version 1.9.3p1 and 1.9.3:
- Fixed a regression introduced in sudo 1.9.3 where the configure
script would not detect the crypt function if it
was present in the C library, not an additional library.
- Fixed a regression introduced in sudo 1.8.23 with shadow passwd
file authentication on OpenBSD. BSD authentication was not
- Sudo now logs when a user-specified command-line option is
rejected by a sudoers rule. Previously, these conditions were
written to the audit log, but the default sudo log file. Affected
command line arguments include -C (--close-from),
-D (--chdir), -R (--chroot),
-g (--group) and -u (--user).
Major changes between version 1.9.3 and 1.9.2:
- sudoedit will now prompt the user before overwriting
an existing file with one that is zero-length after editing.
- Fixed building the Python plugin on systems with a compiler that
doesn't support symbol hiding.
- Sudo now uses a linker script to hide symbols even when the
compiler has native symbol hiding support. This should make it
easier to detect omissions in the symbol exports file, regardless
of the platform.
- Fixed the libssl dependency in Debian packages for older releases
that use libssl1.0.0.
- sudo and visudo now provide more detailed
messages when a syntax error is detected in sudoers.
The offending line and token are now displayed. If the
parser was generated by GNU bison, additional information
about what token was expected is also displayed.
- Sudoers rules must now end in either a newline or the end-of-file.
Previously, it was possible to have multiple rules on a single
line, separated by white space. The use of an end-of-line
terminator makes it possible to display accurate error messages.
- Sudo no longer refuses to run if a syntax error in the sudoers
file is encountered. The entry with the syntax error will be
discarded and sudo will continue to parse the file. This makes
recovery from a syntax error less painful on systems where sudo
is the primary method of superuser access. The historic behavior
can be restored by add error_recovery=false to the sudoers
plugin's optional arguments in sudo.conf.
- Fixed the sample_approval plugin's symbol exports file for
systems where the compiler doesn't support symbol hiding.
- Fixed a regression introduced in sudo 1.9.1 where arguments to
the sudoers_policy plugin in sudo.conf
were not being applied. The sudoers file is now parsed by
the sudoers_audit plugin, which is loaded implicitly
when sudoers_policy is listed in sudo.conf.
Starting with sudo 1.9.3, if there are plugin arguments for
sudoers_policy but sudoers_audit is not
listed, those arguments will be applied to sudoers_audit
- The user's resource limits are now passed to sudo plugins in
the user_info list. A plugin cannot determine the limits
itself because sudo changes the limits while it runs to prevent
- It is now possible to set the working directory or change the
root directory on a per-command basis using the CWD
and CHROOT options. There are also new Defaults
settings, runchroot and runcwd, that can
be used to set the working directory or root directory on
a more global basis.
- New -D (--chdir) and -R
(--chroot) command line options can be used to set
the working directory or root directory if the sudoers file
allows it. This functionality is not enabled by default
and must be explicitly enabled in the sudoers file.
Major changes between version 1.9.2 and 1.9.1:
- Fixed package builds on RedHat Enterprise Linux 8.
- The configure script now uses pkg-config to find the openssl
cflags and libs where possible.
- The contents of the log.json I/O log file is now documented in
the sudoers manual.
- The sudoers plugin now properly exports the sudoers_audit symbol
on systems where the compiler lacks symbol visibility controls.
This caused a regression in 1.9.1 where a successful sudo command
was not logged due to the missing audit plugin.
- Fixed a regression introduced in 1.9.1 that can result in crash
when there is a syntax error in the sudoers file.
Major changes between version 1.9.1 and 1.9.0:
- Fixed an AIX-specific problem when I/O logging was enabled.
The terminal device was not being properly set to raw mode.
- Corrected handling of sudo_logsrvd connections without
associated I/O log data. This fixes support for RejectMessage
as well as AcceptMessage when the expect_iobufs flag is not
- Added an iolog_path entry to the JSON-format event
log produced by sudo_logsrvd. Previously, it was
only possible to determine the I/O log file an event belonged
to using sudo-format logs.
- Fixed the bundle IDs for sudo-logsrvd and sudo-python
- I/O log files produced by the sudoers plugin now clear the write
bits on the I/O log timing file when the log is complete. This
is consistent with how sudo_logsrvd indicates that a log is
- The sudoreplay utility has a new -F
(follow) command line option to allow replaying a session
that is still in progress, similar to tail -f.
- The @include and @includedir directives
can be used in sudoers instead of #include and
#includedir. In addition, include paths may now
have embedded white space by either using a double-quoted
string or escaping the space characters with a backslash.
- Fixed some Solaris 11.4 compilation errors.
- When running a command in a pty, sudo will no longer try to
suspend itself if the user's tty has been revoked (for instance
when the parent ssh daemon is killed). This fixes a bug where
sudo would continuously suspend the command (which would succeed),
then suspend itself (which would fail due to the missing tty)
and then resume the command.
- If sudo's event loop fails due to the tty being revoked,
remove the user's tty events and restart the event loop
(once). This fixes a problem when running sudo reboot
in a pty on some systems. When the event loop exited
unexpectedly, sudo would kill the command running in the
pty, which in the case of reboot, could lead to
the system being in a half-rebooted state.
- Fixed a regression introduced in sudo 1.8.23 in the LDAP and
SSSD back-ends where a missing sudoHost attribute
was treated as an ALL wildcard value. A
sudoRole with no sudoHost attribute is
now ignored as it was prior to version 1.8.23.
- The audit plugin API has been changed slightly. The sudo front-end
now audits an accept event itself after all approval plugins are
run and the I/O logging plugins (if any) are opened. This makes
it possible for an audit plugin to only log a single overall
accept event if desired.
- The sudoers plugin can now be loaded as an audit plugin. Logging
of successful commands is now performed in the audit plugin's
accept function. As a result, commands are now only logged if
allowed by sudoers and all approval plugins. Commands rejected
by an approval plugin are now also logged by the sudoers plugin.
- Romanian translation for sudo and sudoers from
- Fixed a regression introduced in sudo 1.9.0 where sudoedit
did not remove its temporary files after installing them.
- Fixed a regression introduced in sudo 1.9.0 where the
iolog_file setting in sudoers and
sudo_logsrvd.conf caused an error if the file name
ended in six or more X's.
Major changes between version 1.9.0 and 1.8.31p1:
- Fixed a test failure in the
strsig_test on FreeBSD.
- The maximum length of a conversation reply has been increased
from 255 to 1023 characters. This allows for longer user passwords.
- Sudo now includes a logging daemon, sudo_logsrvd, which can
be used to implement centralized logging of I/O logs.
TLS connections are supported when sudo is
configured with the --enable-openssl option.
For more information, see the
manuals as well as the log_servers setting in the
The --disable-log-server and --disable-log-client
configure options can be used to disable building the I/O
log server and/or remote I/O log support in the sudoers
- The new sudo_sendlog utility can be used to test
sudo_logsrvd or send existing sudo I/O logs to a
- It is now possible to write sudo plugins in Python 4 when
sudo is configured with the --enable-python option.
See the sudo_plugin_python
manual for details.
Sudo 1.9.0 comes with several Python example plugins that get
installed sudo's examples directory.
The sudo blog article What's
new in sudo 1.9: Python includes a simple tutorial on
writing python plugins.
- Sudo now supports an audit plugin type. An audit plugin
receives accept, reject, exit and error messages and can be used
to implement custom logging that is independent of the underlying
security policy. Multiple audit plugins may be specified in
the sudo.conf file. A sample audit plugin is included that
writes logs in JSON format.
- Sudo now supports an approval plugin type. An
approval plugin is run only after the main security policy
(such as sudoers) accepts a command to be run. The approval
policy may perform additional checks, potentially interacting
with the user. Multiple approval plugins may be specified
in the sudo.conf file. Only if all approval plugins succeed
will the command be allowed.
- Sudo's -S command line option now causes
the sudo conversation function to write to the standard
output or standard error instead of the terminal device.
- Fixed a bug where if a #include or #includedir directive was the
last line in sudoers and there was no final newline character, it
was silently ignored.
- It is now possible to use Cmd_Alias instead of
Cmnd_Alias in sudoers for people who find the
former more natural.
- The new pam_ruser and pam_rhost sudoers
settings can be used to enable or disable setting the PAM
remote user and/or host values during PAM session setup.
- More than one SHA-2 digest may now be specified for a single
command. Multiple digests must be separated by a comma.
- It is now possible to specify a SHA-2 digest in conjunction
with the ALL reserved word in a command specification.
This allows one to give permission to run any command that
matches the specified digest, regardless of its path.
- sudo and sudo_logsrvd now create
an extended I/O log info file in JSON format that contains
additional information about the command that was run, such
as the host name. The sudoreplay utility uses this file
in preference to the legacy log file.
- The sudoreplay utility can now match on a host
name in list mode. The list output also now includes the
host name if one is present in the log file.
- For sudo -i, if the target user's home directory does not
exist, sudo will now warn about the problem but run the command
in the current working directory. Previously, this was a fatal
Debian bug #598519.
- The command line arguments in the SUDO_COMMAND environment
variable are now truncated at 4096 characters. This avoids an
Argument list too long error when executing a command with a
large number of arguments.
Debian bug #596631.
- Sudo now properly ends the PAM transaction when the user
authenticates successfully but sudoers denies the command.
Debian bug #669687.
- The sudoers grammar in the manual now indicates that sudoedit
requires one or more arguments.
Debian bug #571621.
- When copying the edited files to the original path, sudoedit now
allocates any additional space needed before writing. Previously,
it could truncate the destination file if the file system was
- Fixed an issue where PAM session modules could be called with
the wrong user name when multiple users in the passwd database
share the the same user-ID.
Debian bug #734752.
- Sudo command line options that take a value may only be specified
once. This is to help guard against problems caused by poorly
written scripts that invoke sudo with user-controlled input.