Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package sudo.17020 for openSUSE:Leap:15.2:Update checked in at 2021-10-11 18:06:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2:Update/sudo.17020 (Old) and /work/SRC/openSUSE:Leap:15.2:Update/.sudo.17020.new.2443 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "sudo.17020" Mon Oct 11 18:06:40 2021 rev:1 rq:923601 version:1.8.27 Changes: -------- New Changes file: --- /dev/null 2021-09-30 08:29:43.195243981 +0200 +++ /work/SRC/openSUSE:Leap:15.2:Update/.sudo.17020.new.2443/sudo.changes 2021-10-11 18:06:43.937794591 +0200 @@ -0,0 +1,2359 @@ +------------------------------------------------------------------- +Mon Jul 12 13:56:30 UTC 2021 - Jason Sikes <jsikes@suse.com> + +- Update to 1.8.27 + - jsc#SLE-17083 + - Rebased the following patches: + sudo-1.8.22-CVE-2019-18634.patch + sudo-1.8.22-fix_listpw.patch + sudo-1.8.22-pam_xauth.patch + sudo-CVE-2019-14287.patch + sudo-CVE-2021-23239.patch + sudo-CVE-2021-23240.patch + sudo-CVE-2021-3156.patch + sudo-fix-bsc-1180687.patch + sudo-sudoers.patch + - Deleted sudoers2ldif-env.patch + - Added from SLE-12-SP5: + * sudo-1.8.27-ipa_hostname.patch + * sudo-1.8.27-ldap-respect-SUDOERS_TIMED.patch + - Major changes between version 1.8.27 and 1.8.26: + * Fixes and clarifications to the sudo plugin documentation. + * The sudo manuals no longer require extensive post-processing to hide + system-specific features. Conditionals in the roff source are now used + instead. This fixes corruption of the sudo manual on systems without BSD + login classes. Bug #861. + * If an I/O logging plugin is configured but the plugin does not actually + log any I/O, sudo will no longer force the command to be run in a pseudo-tty. + * In visudo, it is now possible to specify the path to sudoers without + using the -f option. Bug #864. + * Fixed a bug introduced in sudo 1.8.22 where the utmp (or utmpx) file + would not be updated when a command was run in a pseudo-tty. Bug #865. + * Sudo now sets the silent flag when opening the PAM session except when + running a shell via sudo -s or sudo -i. This prevents the pam_lastlog + module from printing the last login information for each sudo command. + Bug #867. + - Major changes between version 1.8.26 and 1.8.25p1: + * Fixed a bug in cvtsudoers when converting to JSON format when alias + expansion is enabled. Bug #853. + * Sudo no long sets the USERNAME environment variable when running + commands. This is a non-standard environment variable that was set on + some older Linux systems. + * Sudo now treats the LOGNAME and USER environment variables (as well as + the LOGIN variable on AIX) as a single unit. If one is preserved or removed + from the environment using env_keep, env_check or env_delete, so is the + other. + * Added support for OpenLDAP's TLS_REQCERT setting in ldap.conf. + * Sudo now logs when the command was suspended and resumed in the I/O logs. + This information is used by sudoreplay to skip the time suspended when + replaying the session unless the new -S flag is used. + * Fixed documentation problems found by the igor utility. Bug #854. + * Sudo now prints a warning message when there is an error or end of file + while reading the password instead of exiting silently. + * Fixed a bug in the sudoers LDAP back-end parsing the command_timeout, + role, type, privs and limitprivs sudoOptions. This also affected cvtsudoers + conversion from LDIF to sudoers or JSON. + * Fixed a bug that prevented timeout settings in sudoers from functioning + unless a timeout was also specified on the command line. + * Asturian translation for sudo from translationproject.org. + * When generating LDIF output, cvtsudoers can now be configured to pad the + sudoOrder increment such that the start order is used as a prefix. Bug #856. + * If the user specifies a group via sudo's -g option that matches any of + the target user's groups, it is now allowed even if no groups are present + in the Runas_Spec. Previously, it was only allowed if it matched the target + user's primary group. + * The sudoers LDAP back-end now supports negated sudoRunAsUser and + sudoRunAsGroup entries. + * Sudo now provides a proper error message when the "fqdn" sudoers option + is set and it is unable to resolve the local host name. Bug #859. + * Portuguese translation for sudo and sudoers from translationproject.org. + * Sudo now includes sudoers LDAP schema for the on-line configuration + supported by OpenLDAP. + - Major changes between version 1.8.25p1 and 1.8.25: + * Fixed a bug introduced in sudo 1.8.25 that caused a crash on systems that + have the poll() function but not the ppoll() function. Bug #851. + - Major changes between version 1.8.25 and 1.8.24: + * Fixed a bug introduced in sudo 1.8.20 that broke formatting of I/O log + timing file entries on systems without a C99-compatible snprintf() + function. Our replacement snprintf() doesn't support floating point so we + can't use the %f format directive. + * I/O log timing file entries now use a monotonic timer and include + nanosecond precision. A monotonic timer that does not increment while the + system is sleeping is used where available. + * When sudo runs a command in a pseudo-tty, the slave device is now closed + in the main process immediately after starting the monitor process. This + removes the need for an AIX-specific workaround that was added in sudo 1.8.24. + * Fixed a bug displaying timeout values the "sudo -V" output. The value + displayed was 3600 times the actual value. Bug #846. + * The testsudoers utility now supports querying an LDIF-format policy. + * Fixed a regression introduced in sudo 1.8.24 where the LDAP and SSSD + backends evaluated the rules in reverse sudoOrder. Bug #849. + - Major changes between version 1.8.24 and 1.8.23: + * The LDAP and SSS back-ends now use the same rule evaluation code as the + sudoers file backend. This builds on the work in sudo 1.8.23 where the + formatting functions for sudo -l output were shared. The handling of + negated commands in SSS and LDAP is unchanged. + * Fixed a regression introduced in 1.8.23 where sudo -i could not be used + in conjunction with --preserve-env=VARIABLE. Bug #835. + * cvtsudoers can now parse base64-encoded attributes in LDIF files. + * Random insults are now more random. + * Added SUDO_CONV_PREFER_TTY flag for conversation function to tell sudo to + try writing to /dev/tty first. Can be used in conjunction with SUDO_CONV_ + INFO_MSG and SUDO_CONV_ERROR_MSG. + * Fixed typos in the OpenLDAP sudo schema. Bugs #839 and #840. Bug #839 and + bug #840. + * Fixed a race condition when building with parallel make. Bug #842. + * Fixed a duplicate free when netgroup_base in ldap.conf is set to an + invalid value. + * On systems using PAM, sudo now ignores the PAM_NEW_AUTHTOK_REQD and + PAM_AUTHTOK_EXPIRED errors from PAM account management if authentication is + disabled for the user. This fixes a regression introduced in sudo 1.8.23. + Bug #843. + * Fixed an ambiguity in the sudoers manual in the description and + definition of User, Runas, Host, and Cmnd Aliases. Bug #834. + * Fixed a bug that resulted in only the first window size change event + being logged. + * Fixed a compilation problem on systems that define O_PATH or O_SEARCH in + fnctl.h but do not define O_DIRECTORY. Bug #844. + - Major changes between version 1.8.23 and 1.8.22: + * PAM account management modules and BSD auth approval modules are now run + even when no password is required. + * For kernel-based time stamps, if no terminal is present, fall back to + parent-pid style time stamps. + * The new cvtsudoers utility replaces both the sudoers2ldif script and the + visudo -x functionality. It can read a file in either sudoers or LDIF + format and produce JSON, LDIF or sudoers output. It is also possible to + filter the generated output file by user, group or host name. + * The file, ldap and sss sudoers backends now share a common set of + formatting functions for "sudo -l" output, which is also used by the + cvtsudoers utility. + * The /run directory is now used in preference to /var/run if it exists. + Bug #822. + * More accurate descriptions of the --with-rundir and --with-vardir + configure options. Bug #823. + * The setpassent() and setgroupent() functions are now used on systems that + support them to keep the passwd and group database open. Sudo performs a + lot of passwd and group lookups so it can be beneficial to avoid opening + and closing the files each time. + * The new case_insensitive_user and case_insensitive_group sudoers options + can be used to control whether sudo does case-sensitive matching of users + and groups in sudoers. Case insensitive matching is now the default. + * Fixed a bug on some systems where sudo could hang on command exit when + I/O logging was enabled. Bug #826. + * Fixed a problem with the process start time test in make check when run + in a Linux container. The test now uses the "btime" field in /proc/stat to + get the system start time instead of using /proc/uptime, which is the + container uptime. Bug #829. + * When determining which temporary directory to use, sudoedit now checks + the directory for writability before using it. Previously, sudoedit only + performed an existence check. Bug #827. + * Sudo now includes an optional set of Monty Python-inspired insults. + * Chinese (Taiwan) translation for sudo from translationproject.org. + +------------------------------------------------------------------- +Fri Apr 16 03:05:25 UTC 2021 - Simon Lees <sflees@suse.de> + +- Tenable Scan reports sudo is still vulnerable to CVE-2021-3156 + [bsc#1183936] + +------------------------------------------------------------------- +Wed Feb 10 22:20:37 UTC 2021 - Kristyna Streitova <kstreitova@suse.com> + +- Add sudo-1.8.27-ipa_hostname.patch to fix special handling of + ipa_hostname that was lost in sudo 1.8.24. + We now include the long and short hostname in sudo parser container + [bsc#1181371] + +------------------------------------------------------------------- +Thu Jan 28 08:07:14 UTC 2021 - Jason Sikes <jsikes@suse.com> + +- Restore sudo ldap behavior to ignore expire dates when SUDOERS_TIMED + option is not set in /etc/ldap.conf + * [bsc#1176473] + * Added sudo-1.8.27-ldap-respect-SUDOERS_TIMED.patch + From: https://www.sudo.ws/repos/sudo/rev/d1e1bb5a6cc1 + +------------------------------------------------------------------- +Sat Jan 23 04:50:14 UTC 2021 - Simon Lees <sflees@suse.de> + +- Fix Heap-based buffer overflow in Sudo [bsc#1181090,CVE-2021-3156] + * sudo-CVE-2021-3156.patch +- Possible Dir Existence Test due to Race Condition in `sudoedit` + [bsc#1180684,CVE-2021-23239] + * sudo-CVE-2021-23239.patch +- Possible Symlink Attack in SELinux Context in `sudoedit` [bsc#1180685, + CVE-2021-23240] + * sudo-CVE-2021-23240.patch +- User Could Enable Debug Settings not Intended for it [bsc#1180687] + * sudo-fix-bsc-1180687.patch + +------------------------------------------------------------------- +Mon Nov 16 19:09:20 UTC 2020 - Kristyna Streitova <kstreitova@suse.com> + +- add sudo-1.8.22-pam_xauth.patch to stay setuid until just before + executing the command. Fixes a problem with pam_xauth which + checks effective and real uids to get the real identity of the + user [bsc#1174593] + ++++ 2162 more lines (skipped) ++++ between /dev/null ++++ and /work/SRC/openSUSE:Leap:15.2:Update/.sudo.17020.new.2443/sudo.changes New: ---- README.SUSE README_313276.test fate_313276_test.sh sudo-1.8.22-CVE-2019-18634.patch sudo-1.8.22-fix_listpw.patch sudo-1.8.22-pam_xauth.patch sudo-1.8.27-ipa_hostname.patch sudo-1.8.27-ldap-respect-SUDOERS_TIMED.patch sudo-1.8.27.tar.gz sudo-1.8.27.tar.gz.sig sudo-CVE-2019-14287.patch sudo-CVE-2021-23239.patch sudo-CVE-2021-23240.patch sudo-CVE-2021-3156.patch sudo-fix-bsc-1180687.patch sudo-i.pamd sudo-sudoers.patch sudo.changes sudo.keyring sudo.pamd sudo.spec ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sudo.spec ++++++ # # spec file for package sudo # # Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.opensuse.org/ # Name: sudo Version: 1.8.27 Release: 0 Summary: Execute some commands as root License: ISC Group: System/Base Url: https://www.sudo.ws/ Source0: https://sudo.ws/sudo/dist/%{name}-%{version}.tar.gz Source1: https://sudo.ws/sudo/dist/%{name}-%{version}.tar.gz.sig Source2: %{name}.keyring Source3: sudo.pamd Source4: sudo-i.pamd Source5: README.SUSE Source6: fate_313276_test.sh Source7: README_313276.test # PATCH-OPENSUSE: the "SUSE" branding of the default sudo config Patch1: sudo-sudoers.patch Patch2: sudo-CVE-2019-14287.patch Patch3: sudo-1.8.22-CVE-2019-18634.patch Patch4: sudo-1.8.22-fix_listpw.patch Patch5: sudo-1.8.22-pam_xauth.patch Patch6: sudo-CVE-2021-23239.patch Patch7: sudo-CVE-2021-23240.patch Patch8: sudo-fix-bsc-1180687.patch Patch9: sudo-CVE-2021-3156.patch Patch10: sudo-1.8.27-ipa_hostname.patch Patch11: sudo-1.8.27-ldap-respect-SUDOERS_TIMED.patch BuildRequires: audit-devel BuildRequires: cyrus-sasl-devel BuildRequires: groff BuildRequires: libselinux-devel BuildRequires: openldap2-devel BuildRequires: pam-devel BuildRequires: systemd-rpm-macros BuildRequires: zlib-devel Requires(pre): coreutils Requires(pre): permissions %description Sudo is a command that allows users to execute some commands as root. The %{_sysconfdir}/sudoers file (edited with 'visudo') specifies which users have access to sudo and which commands they can run. Sudo logs all its activities to syslogd, so the system administrator can keep an eye on things. Sudo asks for the password for initializing a check period of a given time N (where N is defined at installation and is set to 5 minutes by default). %package devel Summary: Header files needed for sudo plugin development Group: Development/Libraries/C and C++ Requires: %{name} = %{version} %description devel These header files are needed for building of sudo plugins. %package test Summary: Tests for the package Group: Development/Tools/Other Requires: %{name} = %{version} %description test Tests for fate#313276 %prep %setup -q %autopatch -p1 %build %ifarch s390 s390x %{sparc} F_PIE=-fPIE %else F_PIE=-fpie %endif export CFLAGS="%{optflags} -Wall $F_PIE -DLDAP_DEPRECATED" export LDFLAGS="-pie" %configure \ --libexecdir=%{_libexecdir}/sudo \ --docdir=%{_docdir}/%{name} \ --with-noexec=%{_libexecdir}/sudo/sudo_noexec.so \ --enable-tmpfiles.d=%{_tmpfilesdir} \ --with-pam \ --with-pam-login \ --with-ldap \ --with-selinux \ --with-linux-audit \ --with-logfac=auth \ --with-all-insults \ --with-ignore-dot \ --with-tty-tickets \ --enable-shell-sets-home \ --enable-warnings \ --with-sendmail=%{_sbindir}/sendmail \ --with-sudoers-mode=0440 \ --with-env-editor \ --without-secure-path \ --with-passprompt="[sudo] password for %%p: " \ --with-rundir=%{_localstatedir}/lib/sudo \ --with-sssd make %{?_smp_mflags} %install %make_install install_uid=`id -u` install_gid=`id -g` install -d -m 755 %{buildroot}%{_sysconfdir}/pam.d install -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/pam.d/sudo install -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/pam.d/sudo-i rm -f %{buildroot}%{_bindir}/sudoedit ln -sf %{_bindir}/sudo %{buildroot}%{_bindir}/sudoedit install -d -m 755 %{buildroot}%{_sysconfdir}/openldap/schema install -m 644 doc/schema.OpenLDAP %{buildroot}%{_sysconfdir}/openldap/schema/sudo.schema install -m 644 %{SOURCE5} %{buildroot}%{_docdir}/%{name}/ rm -f %{buildroot}%{_docdir}/%{name}/sample.pam rm -f %{buildroot}%{_docdir}/%{name}/sample.syslog.conf rm -f %{buildroot}%{_docdir}/%{name}/schema.OpenLDAP rm -f %{buildroot}%{_sysconfdir}/sudoers.dist %find_lang %{name} %find_lang sudoers cat sudoers.lang >> %{name}.lang # tests install -d -m 755 %{buildroot}%{_localstatedir}/lib/tests/sudo install -m 755 %{SOURCE6} %{buildroot}%{_localstatedir}/lib/tests/sudo install -m 755 %{SOURCE7} %{buildroot}%{_localstatedir}/lib/tests/sudo install -d %{buildroot}%{_docdir}/%{name}-test install -m 644 %{buildroot}%{_docdir}/%{name}/LICENSE %{buildroot}%{_docdir}/%{name}-test/LICENSE rm -fv %{buildroot}%{_docdir}/%{name}/LICENSE %post chmod 0440 %{_sysconfdir}/sudoers %if 0%{?suse_version} <= 1130 %run_permissions %else %set_permissions %{_bindir}/sudo %endif %tmpfiles_create %{_tmpfilesdir}/sudo.conf %verifyscript %verify_permissions -e %{_bindir}/sudo %files -f %{name}.lang %license doc/LICENSE %doc %{_docdir}/%{name} %{_mandir}/man1/cvtsudoers.1%{ext_man} %{_mandir}/man5/sudoers.5%{ext_man} %{_mandir}/man5/sudo.conf.5%{ext_man} %{_mandir}/man5/sudoers.ldap.5%{ext_man} %{_mandir}/man5/sudoers_timestamp.5%{ext_man} %{_mandir}/man8/sudo.8%{ext_man} %{_mandir}/man8/sudoedit.8%{ext_man} %{_mandir}/man8/sudoreplay.8%{ext_man} %{_mandir}/man8/visudo.8%{ext_man} %config(noreplace) %attr(0440,root,root) %{_sysconfdir}/sudoers %dir %{_sysconfdir}/sudoers.d %config(noreplace) %{_sysconfdir}/pam.d/sudo %config(noreplace) %{_sysconfdir}/pam.d/sudo-i %attr(4755,root,root) %{_bindir}/sudo %dir %{_sysconfdir}/openldap %dir %{_sysconfdir}/openldap/schema %attr(0444,root,root) %config %{_sysconfdir}/openldap/schema/sudo.schema %{_bindir}/sudoedit %{_bindir}/sudoreplay %{_bindir}/cvtsudoers %{_sbindir}/visudo %dir %{_libexecdir}/%{name} %{_libexecdir}/%{name}/sesh %{_libexecdir}/%{name}/sudo_noexec.so %{_libexecdir}/%{name}/sudoers.so %{_libexecdir}/%{name}/group_file.so %{_libexecdir}/%{name}/system_group.so %{_libexecdir}/%{name}/libsudo_util.so.* %attr(0711,root,root) %dir %ghost %{_localstatedir}/lib/%{name} %attr(0700,root,root) %dir %ghost %{_localstatedir}/lib/%{name}/ts %dir %{_tmpfilesdir} %{_tmpfilesdir}/sudo.conf %files devel %doc plugins/sample/sample_plugin.c %{_includedir}/sudo_plugin.h %{_mandir}/man8/sudo_plugin.8* %attr(0644,root,root) %{_libexecdir}/%{name}/libsudo_util.so %{_libexecdir}/%{name}/*.la %files test %{_localstatedir}/lib/tests %{_docdir}/%{name}-test/ %changelog ++++++ README.SUSE ++++++ In the default (ie unconfigured) configuration sudo asks for root password. This allows to use an ordinary user account for administration of a freshly installed system. When configuring sudo, please make sure to delete the two following lines: Defaults targetpw # ask for the password of the target user i.e. root %users ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'! ++++++ README_313276.test ++++++ To verify that sudo works with SSSD, there's has to be a working LDAP server where the sudoers file will be saved, local running SSSD and sudo configured to use the SSSD plugin. The sudoers file has to be stored in LDAP. A [sudo] service has to be configured in /etc/sssd/sssd.conf Sudo needs to be instructed to use SSSD, this is done in /etc/nsswitch.conf, by adding a line "sudoers: files sss" Related material: /usr/share/doc/packages/sudo/README.LDAP provides a guide how to make sudo work with LDAP. man sudoers.ldap(5) describes the LDAP-based sudoers file man sssd-ldap(5) describes the LDAP sudo options. ++++++ fate_313276_test.sh ++++++ #!/bin/sh if [ $(id -u) -ne 0 ]; then printf "Please run the test as root.\n" exit 1 fi if sudo -V | grep -q -- --with-sssd; then printf "OK: Sudo has support for SSSD compiled in.\n" exit 0 fi printf "Error: SSSD support isn't compiled in.\n" exit 1 ++++++ sudo-1.8.22-CVE-2019-18634.patch ++++++ From fa8ffeb17523494f0e8bb49a25e53635f4509078 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" <Todd.Miller@sudo.ws> Date: Wed, 29 Jan 2020 20:15:21 -0700 Subject: [PATCH] Fix a buffer overflow when pwfeedback is enabled and input is a not a tty. In getln() if the user enters ^U (erase line) and the write(2) fails, the remaining buffer size is reset but the current pointer is not. While here, fix an incorrect break for erase when write(2) fails. Also disable pwfeedback when input is not a tty as it cannot work. CVE-2019-18634 Credit: Joe Vennix from Apple Information Security. diff --git a/src/tgetpass.c b/src/tgetpass.c index 76b0c8b..5eb9f49 100644 --- a/src/tgetpass.c +++ b/src/tgetpass.c @@ -60,7 +60,7 @@ static volatile sig_atomic_t signo[NSIG]; static bool tty_present(void); static void tgetpass_handler(int); -static char *getln(int, char *, size_t, int, enum tgetpass_errval *); +static char *getln(int, char *, size_t, bool, enum tgetpass_errval *); static char *sudo_askpass(const char *, const char *); static int @@ -123,6 +123,7 @@ tgetpass(const char *prompt, int timeout, int flags, static const char *askpass; static char buf[SUDO_CONV_REPL_MAX + 1]; int i, input, output, save_errno, neednl = 0, need_restart; + bool feedback = ISSET(flags, TGP_MASK); enum tgetpass_errval errval; debug_decl(tgetpass, SUDO_DEBUG_CONV) @@ -170,7 +171,7 @@ restart: */ if (!ISSET(flags, TGP_ECHO)) { for (;;) { - if (ISSET(flags, TGP_MASK)) + if (feedback) neednl = sudo_term_cbreak(input); else neednl = sudo_term_noecho(input); @@ -184,6 +185,9 @@ restart: } } } + /* Only use feedback mode when we can disable echo. */ + if (!neednl) + feedback = false; /* * Catch signals that would otherwise cause the user to end @@ -209,7 +213,7 @@ restart: if (timeout > 0) alarm(timeout); - pass = getln(input, buf, sizeof(buf), ISSET(flags, TGP_MASK), &errval); + pass = getln(input, buf, sizeof(buf), feedback, &errval); alarm(0); save_errno = errno; @@ -345,7 +349,7 @@ sudo_askpass(const char *askpass, const char *prompt) extern int sudo_term_eof, sudo_term_erase, sudo_term_kill; static char * -getln(int fd, char *buf, size_t bufsiz, int feedback, +getln(int fd, char *buf, size_t bufsiz, bool feedback, enum tgetpass_errval *errval) { size_t left = bufsiz; @@ -374,15 +378,15 @@ getln(int fd, char *buf, size_t bufsiz, int feedback, while (cp > buf) { if (write(fd, "\b \b", 3) == -1) break; - --cp; + cp--; } + cp = buf; left = bufsiz; continue; } else if (c == sudo_term_erase) { if (cp > buf) { - if (write(fd, "\b \b", 3) == -1) - break; - --cp; + ignore_result(write(fd, "\b \b", 3)); + cp--; left++; } continue; ++++++ sudo-1.8.22-fix_listpw.patch ++++++ rom ecc9c366e469988c736629cbe88348c40dcfa31a Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" <Todd.Miller@sudo.ws> Date: Tue, 22 Jan 2019 06:41:16 -0700 Subject: [PATCH] Fix listpw=never and verifypw=never. Bug #869 diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c index fb781f5..d073b36 100644 --- a/plugins/sudoers/parse.c +++ b/plugins/sudoers/parse.c @@ -60,7 +60,7 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, debug_decl(sudoers_lookup_pseudo, SUDOERS_DEBUG_PARSER) pwcheck = (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple; - nopass = (pwcheck == all) ? true : false; + nopass = (pwcheck == never) ? true : false; if (list_pw == NULL) SET(validated, FLAG_NO_CHECK); ++++++ sudo-1.8.22-pam_xauth.patch ++++++ diff --git a/src/sudo.c b/src/sudo.c index c81f946..fbf4bc4 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -288,9 +288,6 @@ main(int argc, char *argv[], char *envp[]) SET(command_details.flags, CD_LOGIN_SHELL); if (ISSET(sudo_mode, MODE_BACKGROUND)) SET(command_details.flags, CD_BACKGROUND); - /* Become full root (not just setuid) so user cannot kill us. */ - if (setuid(ROOT_UID) == -1) - sudo_warn("setuid(%d)", ROOT_UID); if (ISSET(command_details.flags, CD_SUDOEDIT)) { status = sudo_edit(&command_details); } else { ++++++ sudo-1.8.27-ipa_hostname.patch ++++++ ++++ 1063 lines (skipped) ++++++ sudo-1.8.27-ldap-respect-SUDOERS_TIMED.patch ++++++ Index: sudo-1.8.27/plugins/sudoers/ldap.c =================================================================== --- sudo-1.8.27.orig/plugins/sudoers/ldap.c +++ sudo-1.8.27/plugins/sudoers/ldap.c @@ -1188,12 +1188,14 @@ ldap_to_sudoers(LDAP *ld, struct ldap_re goto cleanup; /* Get sudoNotBefore / sudoNotAfter */ - notbefore = sudo_ldap_get_values_len(ld, entry, "sudoNotBefore", &rc); - if (rc == LDAP_NO_MEMORY) + if (ldap_conf.timed) { + notbefore = sudo_ldap_get_values_len(ld, entry, "sudoNotBefore", &rc); + if (rc == LDAP_NO_MEMORY) goto cleanup; - notafter = sudo_ldap_get_values_len(ld, entry, "sudoNotAfter", &rc); - if (rc == LDAP_NO_MEMORY) + notafter = sudo_ldap_get_values_len(ld, entry, "sudoNotAfter", &rc); + if (rc == LDAP_NO_MEMORY) goto cleanup; + } /* Parse sudoOptions. */ opts = sudo_ldap_get_values_len(ld, entry, "sudoOption", &rc); ++++++ sudo-CVE-2019-14287.patch ++++++ Treat an ID of -1 as invalid since that means "no change". Fixes CVE-2019-14287. Found by Joe Vennix from Apple Information Security. diff --git a/lib/util/regress/atofoo/atofoo_test.c b/lib/util/regress/atofoo/atofoo_test.c index 1ad78eb..071123f 100644 --- a/lib/util/regress/atofoo/atofoo_test.c +++ b/lib/util/regress/atofoo/atofoo_test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Todd C. Miller <Todd.Miller@sudo.ws> + * Copyright (c) 2014-2019 Todd C. Miller <Todd.Miller@sudo.ws> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -24,6 +24,7 @@ #else # include "compat/stdbool.h" #endif +#include <errno.h> #include "sudo_compat.h" #include "sudo_util.h" @@ -78,10 +79,15 @@ static struct strtoid_data { id_t id; const char *sep; const char *ep; + int errnum; } strtoid_data[] = { - { "0,1", 0, ",", "," }, - { "10", 10, NULL, NULL }, - { "-2", -2, NULL, NULL }, + { "0,1", 0, ",", ",", 0 }, + { "10", 10, NULL, NULL, 0 }, + { "-1", 0, NULL, NULL, EINVAL }, + { "4294967295", 0, NULL, NULL, EINVAL }, + { "4294967296", 0, NULL, NULL, ERANGE }, + { "-2147483649", 0, NULL, NULL, ERANGE }, + { "-2", -2, NULL, NULL, 0 }, #if SIZEOF_ID_T != SIZEOF_LONG_LONG { "-2", (id_t)4294967294U, NULL, NULL }, #endif @@ -102,11 +108,23 @@ test_strtoid(int *ntests) (*ntests)++; errstr = "some error"; value = sudo_strtoid(d->idstr, d->sep, &ep, &errstr); - if (errstr != NULL) { - if (d->id != (id_t)-1) { - sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr); + if (d->errnum != 0) { + if (errstr == NULL) { + sudo_warnx_nodebug("FAIL: %s: missing errstr for errno %d", + d->idstr, d->errnum); + errors++; + } else if (value != 0) { + sudo_warnx_nodebug("FAIL: %s should return 0 on error", + d->idstr); + errors++; + } else if (errno != d->errnum) { + sudo_warnx_nodebug("FAIL: %s: errno mismatch, %d != %d", + d->idstr, errno, d->errnum); errors++; } + } else if (errstr != NULL) { + sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr); + errors++; } else if (value != d->id) { sudo_warnx_nodebug("FAIL: %s != %u", d->idstr, (unsigned int)d->id); errors++; diff --git a/lib/util/strtoid.c b/lib/util/strtoid.c index 2339a88..6797074 100644 --- a/lib/util/strtoid.c +++ b/lib/util/strtoid.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 Todd C. Miller <Todd.Miller@sudo.ws> + * Copyright (c) 2013-2019 Todd C. Miller <Todd.Miller@sudo.ws> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -46,6 +46,27 @@ #include "sudo_debug.h" #include "sudo_util.h" +/* + * Make sure that the ID ends with a valid separator char. + */ +static bool +valid_separator(const char *p, const char *ep, const char *sep) +{ + bool valid = false; + debug_decl(valid_separator, SUDO_DEBUG_UTIL) + + if (ep != p) { + /* check for valid separator (including '\0') */ + if (sep == NULL) + sep = ""; + do { + if (*ep == *sep) + valid = true; + } while (*sep++ != '\0'); + } + debug_return_bool(valid); +} + /* * Parse a uid/gid in string form. * If sep is non-NULL, it contains valid separator characters (e.g. comma, space) @@ -60,36 +81,33 @@ sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr char *ep; id_t ret = 0; long long llval; - bool valid = false; debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL) /* skip leading space so we can pick up the sign, if any */ while (isspace((unsigned char)*p)) p++; - if (sep == NULL) - sep = ""; + + /* While id_t may be 64-bit signed, uid_t and gid_t are 32-bit unsigned. */ errno = 0; llval = strtoll(p, &ep, 10); - if (ep != p) { - /* check for valid separator (including '\0') */ - do { - if (*ep == *sep) - valid = true; - } while (*sep++ != '\0'); + if ((errno == ERANGE && llval == LLONG_MAX) || llval > (id_t)UINT_MAX) { + errno = ERANGE; + if (errstr != NULL) + *errstr = N_("value too large"); + goto done; } - if (!valid) { + if ((errno == ERANGE && llval == LLONG_MIN) || llval < INT_MIN) { + errno = ERANGE; if (errstr != NULL) - *errstr = N_("invalid value"); - errno = EINVAL; + *errstr = N_("value too small"); goto done; } - if (errno == ERANGE) { - if (errstr != NULL) { - if (llval == LLONG_MAX) - *errstr = N_("value too large"); - else - *errstr = N_("value too small"); - } + + /* Disallow id -1, which means "no change". */ + if (!valid_separator(p, ep, sep) || llval == -1 || llval == (id_t)UINT_MAX) { + if (errstr != NULL) + *errstr = N_("invalid value"); + errno = EINVAL; goto done; } ret = (id_t)llval; @@ -106,30 +124,15 @@ sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr { char *ep; id_t ret = 0; - bool valid = false; debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL) /* skip leading space so we can pick up the sign, if any */ while (isspace((unsigned char)*p)) p++; - if (sep == NULL) - sep = ""; + errno = 0; if (*p == '-') { long lval = strtol(p, &ep, 10); - if (ep != p) { - /* check for valid separator (including '\0') */ - do { - if (*ep == *sep) - valid = true; - } while (*sep++ != '\0'); - } - if (!valid) { - if (errstr != NULL) - *errstr = N_("invalid value"); - errno = EINVAL; - goto done; - } if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) { errno = ERANGE; if (errstr != NULL) @@ -142,28 +145,31 @@ sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr *errstr = N_("value too small"); goto done; } - ret = (id_t)lval; - } else { - unsigned long ulval = strtoul(p, &ep, 10); - if (ep != p) { - /* check for valid separator (including '\0') */ - do { - if (*ep == *sep) - valid = true; - } while (*sep++ != '\0'); - } - if (!valid) { + + /* Disallow id -1, which means "no change". */ + if (!valid_separator(p, ep, sep) || lval == -1) { if (errstr != NULL) *errstr = N_("invalid value"); errno = EINVAL; goto done; } + ret = (id_t)lval; + } else { + unsigned long ulval = strtoul(p, &ep, 10); if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) { errno = ERANGE; if (errstr != NULL) *errstr = N_("value too large"); goto done; } + + /* Disallow id -1, which means "no change". */ + if (!valid_separator(p, ep, sep) || ulval == UINT_MAX) { + if (errstr != NULL) + *errstr = N_("invalid value"); + errno = EINVAL; + goto done; + } ret = (id_t)ulval; } if (errstr != NULL) diff --git a/plugins/sudoers/regress/testsudoers/test5.out.ok b/plugins/sudoers/regress/testsudoers/test5.out.ok index 5e319c9..cecf700 100644 --- a/plugins/sudoers/regress/testsudoers/test5.out.ok +++ b/plugins/sudoers/regress/testsudoers/test5.out.ok @@ -4,7 +4,7 @@ Parse error in sudoers near line 1. Entries for user root: Command unmatched -testsudoers: test5.inc should be owned by gid 4294967295 +testsudoers: test5.inc should be owned by gid 4294967294 Parse error in sudoers near line 1. Entries for user root: diff --git a/plugins/sudoers/regress/testsudoers/test5.sh b/plugins/sudoers/regress/testsudoers/test5.sh index 9e690a6..94d585c 100755 --- a/plugins/sudoers/regress/testsudoers/test5.sh +++ b/plugins/sudoers/regress/testsudoers/test5.sh @@ -24,7 +24,7 @@ EOF # Test group writable chmod 664 $TESTFILE -./testsudoers -U $MYUID -G -1 root id <<EOF +./testsudoers -U $MYUID -G -2 root id <<EOF #include $TESTFILE EOF ++++++ sudo-CVE-2021-23239.patch ++++++ # HG changeset patch # User Todd C. Miller <Todd.Miller@sudo.ws> # Date 1609953360 25200 # Node ID ea19d0073c02951bbbf35342dd63304da83edce8 # Parent f1ca39a0d87089d005b78a2556e2b1a2dc17f672 Fix potential directory existing info leak in sudoedit. When creating a new file, sudoedit checks to make sure the parent directory exists so it can provide the user with a sensible error message. However, this could be used to test for the existence of directories not normally accessible to the user by pointing to them with a symbolic link when the parent directory is controlled by the user. Problem reported by Matthias Gerstner of SUSE. diff --git a/src/sudo_edit.c b/src/sudo_edit.c index 44b4fb3..888b277 100644 --- a/src/sudo_edit.c +++ b/src/sudo_edit.c @@ -567,14 +567,33 @@ sudo_edit_create_tfiles(struct command_details *command_details, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details); if (ofd != -1 || errno == ENOENT) { if (ofd == -1) { - /* New file, verify parent dir exists unless in cwd. */ + /* + * New file, verify parent dir exists unless in cwd. + * This fails early so the user knows ahead of time if the + * edit won't succeed. Additional checks are performed + * when copying the temporary file back to the origin. + */ char *slash = strrchr(files[i], '/'); if (slash != NULL && slash != files[i]) { - int serrno = errno; + const int sflags = command_details->flags; + const int serrno = errno; + int dfd; + + /* + * The parent directory is allowed to be a symbolic + * link as long as *its* parent is not writable. + */ *slash = '\0'; - if (stat(files[i], &sb) == 0 && S_ISDIR(sb.st_mode)) { - memset(&sb, 0, sizeof(sb)); - rc = 0; + SET(command_details->flags, CD_SUDOEDIT_FOLLOW); + dfd = sudo_edit_open(files[i], DIR_OPEN_FLAGS, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, command_details); + command_details->flags = sflags; + if (dfd != -1) { + if (fstat(dfd, &sb) == 0 && S_ISDIR(sb.st_mode)) { + memset(&sb, 0, sizeof(sb)); + rc = 0; + } + close(dfd); } *slash = '/'; errno = serrno; ++++++ sudo-CVE-2021-23240.patch ++++++ # HG changeset patch # User Todd C. Miller <Todd.Miller@sudo.ws> # Date 1609953360 25200 # Node ID 8fcb36ef422a251fe33738a347551439944a4a37 # Parent ea19d0073c02951bbbf35342dd63304da83edce8 Add security checks before using temp files for SELinux RBAC sudoedit. Otherwise, it may be possible for the user running sudoedit to replace the newly-created temporary files with a symbolic link and have sudoedit set the owner of an arbitrary file. Problem reported by Matthias Gerstner of SUSE. diff --git a/src/Makefile.in b/src/Makefile.in index 099193c..88a7bb7 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -118,7 +118,7 @@ SHELL = @SHELL@ PROGS = @PROGS@ -OBJS = conversation.o env_hooks.o exec.o exec_common.o exec_monitor.o \ +OBJS = conversation.o copy_file.o env_hooks.o exec.o exec_common.o exec_monitor.o \ exec_nopty.o exec_pty.o get_pty.o hooks.o net_ifs.o load_plugins.o \ parse_args.o preserve_fds.o signal.o sudo.o sudo_edit.o \ tcsetpgrp_nobg.o tgetpass.o ttyname.o utmp.o @SUDO_OBJS@ @@ -127,7 +127,7 @@ IOBJS = $(OBJS:.o=.i) sesh.i POBJS = $(IOBJS:.i=.plog) -SESH_OBJS = sesh.o exec_common.o +SESH_OBJS = sesh.o copy_file.o exec_common.o CHECK_NOEXEC_OBJS = check_noexec.o exec_common.o @@ -326,6 +326,24 @@ conversation.i: $(srcdir)/conversation.c $(incdir)/compat/stdbool.h \ $(CC) -E -o $@ $(CPPFLAGS) $< conversation.plog: conversation.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/conversation.c --i-file $< --output-file $@ +copy_file.o: $(srcdir)/copy_file.c $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ + $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \ + $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \ + $(top_builddir)/pathnames.h + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/copy_file.c +copy_file.i: $(srcdir)/copy_file.c $(incdir)/compat/stdbool.h \ + $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_event.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \ + $(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \ + $(incdir)/sudo_util.h $(srcdir)/sudo.h $(top_builddir)/config.h \ + $(top_builddir)/pathnames.h + $(CC) -E -o $@ $(CPPFLAGS) $< +copy_file.plog: copy_file.i + rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/copy_file.c --i-file $< --output-file $@ env_hooks.o: $(srcdir)/env_hooks.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ $(incdir)/sudo_debug.h $(incdir)/sudo_dso.h \ @@ -579,7 +597,7 @@ selinux.plog: selinux.i sesh.o: $(srcdir)/sesh.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \ $(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \ - $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo_exec.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo_exec.h $(srcdir)/sudo_edit.h \ $(top_builddir)/config.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sesh.c sesh.i: $(srcdir)/sesh.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ @@ -642,7 +660,7 @@ sudo_edit.o: $(srcdir)/sudo_edit.c $(incdir)/compat/stdbool.h \ $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \ $(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \ - $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \ + $(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h $(srcdir)/sudo_edit.h \ $(top_builddir)/config.h $(top_builddir)/pathnames.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_edit.c sudo_edit.i: $(srcdir)/sudo_edit.c $(incdir)/compat/stdbool.h \ diff --git a/src/sesh.c b/src/sesh.c index 873748e..79565f3 100644 --- a/src/sesh.c +++ b/src/sesh.c @@ -41,6 +41,7 @@ #include "sudo_gettext.h" /* must be included before sudo_compat.h */ #include "sudo_compat.h" +#include "sudo_edit.h" #include "sudo_fatal.h" #include "sudo_conf.h" #include "sudo_debug.h" @@ -132,7 +133,7 @@ main(int argc, char *argv[], char *envp[]) static int sesh_sudoedit(int argc, char *argv[]) { - int i, oflags_dst, post, ret = SESH_ERR_FAILURE; + int i, oflags_src, oflags_dst, post, ret = SESH_ERR_FAILURE; int fd_src = -1, fd_dst = -1, follow = 0; ssize_t nread, nwritten; struct stat sb; @@ -176,10 +177,12 @@ sesh_sudoedit(int argc, char *argv[]) debug_return_int(SESH_ERR_BAD_PATHS); /* - * Use O_EXCL if we are not in the post editing stage - * so that it's ensured that the temporary files are - * created by us and that we are not opening any symlinks. + * In the pre-editing stage, use O_EXCL to ensure that the temporary + * files are created by us and that we are not opening any symlinks. + * In the post-editing stage, use O_NOFOLLOW so we don't follow symlinks + * when opening the temporary files. */ + oflags_src = O_RDONLY|(post ? O_NONBLOCK|O_NOFOLLOW : follow); oflags_dst = O_WRONLY|O_TRUNC|O_CREAT|(post ? follow : O_EXCL); for (i = 0; i < argc - 1; i += 2) { const char *path_src = argv[i]; @@ -189,7 +192,7 @@ sesh_sudoedit(int argc, char *argv[]) * doesn't exist, that's OK, we'll create an empty * destination file. */ - if ((fd_src = open(path_src, O_RDONLY|follow, S_IRUSR|S_IWUSR)) < 0) { + if ((fd_src = open(path_src, oflags_src, S_IRUSR|S_IWUSR)) < 0) { if (errno != ENOENT) { sudo_warn("%s", path_src); if (post) { @@ -199,6 +202,14 @@ sesh_sudoedit(int argc, char *argv[]) goto cleanup_0; } } + if (post) { + /* Make sure the temporary file is safe and has the proper owner. */ + if (!sudo_check_temp_file(fd_src, path_src, geteuid(), &sb)) { + ret = SESH_ERR_SOME_FILES; + goto nocleanup; + } + fcntl(fd_src, F_SETFL, fcntl(fd_src, F_GETFL, 0) & ~O_NONBLOCK); + } if ((fd_dst = open(path_dst, oflags_dst, post ? (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) : (S_IRUSR|S_IWUSR))) < 0) { diff --git a/src/sudo_edit.c b/src/sudo_edit.c index 888b277..679c0b0 100644 --- a/src/sudo_edit.c +++ b/src/sudo_edit.c @@ -252,8 +252,10 @@ sudo_edit_mktemp(const char *ofile, char **tfile) } else { len = asprintf(tfile, "%s/%s.XXXXXXXX", edit_tmpdir, cp); } - if (len == -1) - sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + if (len == -1) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + debug_return_int(-1); + } tfd = mkstemps(*tfile, suff ? strlen(suff) : 0); sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, "%s -> %s, fd %d", ofile, *tfile, tfd); @@ -784,11 +786,11 @@ selinux_edit_create_tfiles(struct command_details *command_details, struct tempfile *tf, char *files[], int nfiles) { char **sesh_args, **sesh_ap; - int i, rc, sesh_nargs; + int i, error, sesh_nargs, ret = -1; struct stat sb; struct command_details saved_command_details; debug_decl(selinux_edit_create_tfiles, SUDO_DEBUG_EDIT) - + /* Prepare selinux stuff (setexeccon) */ if (selinux_setup(command_details->selinux_role, command_details->selinux_type, NULL, -1) != 0) @@ -801,12 +803,12 @@ selinux_edit_create_tfiles(struct command_details *command_details, memcpy(&saved_command_details, command_details, sizeof(struct command_details)); command_details->command = _PATH_SUDO_SESH; command_details->flags |= CD_SUDOEDIT_COPY; - + sesh_nargs = 4 + (nfiles * 2) + 1; sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *)); if (sesh_args == NULL) { sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - debug_return_int(-1); + goto done; } *sesh_ap++ = "sesh"; *sesh_ap++ = "-e"; @@ -831,8 +833,7 @@ selinux_edit_create_tfiles(struct command_details *command_details, if (tfd == -1) { sudo_warn("mkstemps"); free(tfile); - free(sesh_args); - debug_return_int(-1); + goto done; } /* Helper will re-create temp file with proper security context. */ close(tfd); @@ -844,8 +845,8 @@ selinux_edit_create_tfiles(struct command_details *command_details, /* Run sesh -e [-h] 0 <o1> <t1> ... <on> <tn> */ command_details->argv = sesh_args; - rc = run_command(command_details); - switch (rc) { + error = run_command(command_details); + switch (error) { case SESH_SUCCESS: break; case SESH_ERR_BAD_PATHS: @@ -853,26 +854,40 @@ selinux_edit_create_tfiles(struct command_details *command_details, case SESH_ERR_NO_FILES: sudo_fatalx(U_("sesh: unable to create temporary files")); default: - sudo_fatalx(U_("sesh: unknown error %d"), rc); + sudo_fatalx(U_("sesh: unknown error %d"), error); } /* Restore saved command_details. */ command_details->command = saved_command_details.command; command_details->flags = saved_command_details.flags; command_details->argv = saved_command_details.argv; - - /* Chown to user's UID so they can edit the temporary files. */ + for (i = 0; i < nfiles; i++) { - if (chown(tf[i].tfile, user_details.uid, user_details.gid) != 0) { - sudo_warn("unable to chown(%s) to %d:%d for editing", - tf[i].tfile, user_details.uid, user_details.gid); - } + int tfd = open(tf[i].tfile, O_RDONLY|O_NONBLOCK|O_NOFOLLOW); + if (tfd == -1) { + sudo_warn(U_("unable to open %s"), tf[i].tfile); + goto done; + } + if (!sudo_check_temp_file(tfd, tf[i].tfile, command_details->uid, NULL)) { + close(tfd); + goto done; + } + if (fchown(tfd, user_details.uid, user_details.gid) != 0) { + sudo_warn("unable to chown(%s) to %d:%d for editing", + tf[i].tfile, user_details.uid, user_details.gid); + close(tfd); + goto done; + } + close(tfd); } + ret = nfiles; + + done: /* Contents of tf will be freed by caller. */ free(sesh_args); - return (nfiles); + debug_return_int(ret); } static int @@ -880,12 +895,13 @@ selinux_edit_copy_tfiles(struct command_details *command_details, struct tempfile *tf, int nfiles, struct timespec *times) { char **sesh_args, **sesh_ap; - int i, rc, sesh_nargs, ret = 1; + int i, error, sesh_nargs, ret = 1; + int tfd = -1; struct command_details saved_command_details; struct timespec ts; struct stat sb; debug_decl(selinux_edit_copy_tfiles, SUDO_DEBUG_EDIT) - + /* Prepare selinux stuff (setexeccon) */ if (selinux_setup(command_details->selinux_role, command_details->selinux_type, NULL, -1) != 0) @@ -898,7 +914,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details, memcpy(&saved_command_details, command_details, sizeof(struct command_details)); command_details->command = _PATH_SUDO_SESH; command_details->flags |= CD_SUDOEDIT_COPY; - + sesh_nargs = 3 + (nfiles * 2) + 1; sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *)); if (sesh_args == NULL) { @@ -911,34 +927,42 @@ selinux_edit_copy_tfiles(struct command_details *command_details, /* Construct args for sesh -e 1 */ for (i = 0; i < nfiles; i++) { - if (stat(tf[i].tfile, &sb) == 0) { - mtim_get(&sb, ts); - if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) { - /* - * If mtime and size match but the user spent no measurable - * time in the editor we can't tell if the file was changed. - */ - if (sudo_timespeccmp(×[0], ×[1], !=)) { - sudo_warnx(U_("%s unchanged"), tf[i].ofile); - unlink(tf[i].tfile); - continue; - } + if (tfd != -1) + close(tfd); + if ((tfd = open(tf[i].tfile, O_RDONLY|O_NONBLOCK|O_NOFOLLOW)) == -1) { + sudo_warn(U_("unable to open %s"), tf[i].tfile); + continue; + } + if (!sudo_check_temp_file(tfd, tf[i].tfile, user_details.uid, &sb)) + continue; + mtim_get(&sb, ts); + if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) { + /* + * If mtime and size match but the user spent no measurable + * time in the editor we can't tell if the file was changed. + */ + if (sudo_timespeccmp(×[0], ×[1], !=)) { + sudo_warnx(U_("%s unchanged"), tf[i].ofile); + unlink(tf[i].tfile); + continue; } } *sesh_ap++ = tf[i].tfile; *sesh_ap++ = tf[i].ofile; - if (chown(tf[i].tfile, command_details->uid, command_details->gid) != 0) { + if (fchown(tfd, command_details->uid, command_details->gid) != 0) { sudo_warn("unable to chown(%s) back to %d:%d", tf[i].tfile, command_details->uid, command_details->gid); } } *sesh_ap = NULL; + if (tfd != -1) + close(tfd); if (sesh_ap - sesh_args > 3) { /* Run sesh -e 1 <t1> <o1> ... <tn> <on> */ command_details->argv = sesh_args; - rc = run_command(command_details); - switch (rc) { + error = run_command(command_details); + switch (error) { case SESH_SUCCESS: ret = 0; break; @@ -951,7 +975,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details, sudo_warnx(U_("contents of edit session left in %s"), edit_tmpdir); break; default: - sudo_warnx(U_("sesh: unknown error %d"), rc); + sudo_warnx(U_("sesh: unknown error %d"), error); break; } } @@ -976,7 +1000,7 @@ sudo_edit(struct command_details *command_details) { struct command_details saved_command_details; char **nargv = NULL, **ap, **files = NULL; - int errors, i, ac, nargc, rc; + int errors, i, ac, nargc, ret; int editor_argc = 0, nfiles = 0; struct timespec times[2]; struct tempfile *tf = NULL; @@ -1022,7 +1046,7 @@ sudo_edit(struct command_details *command_details) #ifdef HAVE_SELINUX if (ISSET(command_details->flags, CD_RBAC_ENABLED)) nfiles = selinux_edit_create_tfiles(command_details, tf, files, nfiles); - else + else #endif nfiles = sudo_edit_create_tfiles(command_details, tf, files, nfiles); if (nfiles <= 0) @@ -1061,7 +1085,7 @@ sudo_edit(struct command_details *command_details) command_details->ngroups = user_details.ngroups; command_details->groups = user_details.groups; command_details->argv = nargv; - rc = run_command(command_details); + ret = run_command(command_details); if (sudo_gettime_real(×[1]) == -1) { sudo_warn(U_("unable to read the clock")); goto cleanup; @@ -1090,7 +1114,7 @@ sudo_edit(struct command_details *command_details) free(tf[i].tfile); free(tf); free(nargv); - debug_return_int(rc); + debug_return_int(errors); cleanup: /* Clean up temp files and return. */ diff --git a/src/sudo_exec.h b/src/sudo_exec.h index c8c7941..91a2e8c 100644 --- a/src/sudo_exec.h +++ b/src/sudo_exec.h @@ -81,6 +81,7 @@ */ struct command_details; struct command_status; +struct stat; /* exec.c */ void exec_cmnd(struct command_details *details, int errfd); Index: sudo-1.8.22/src/copy_file.c =================================================================== --- /dev/null +++ sudo-1.8.22/src/copy_file.c @@ -0,0 +1,40 @@ +#include <config.h> + +#include <sys/stat.h> + +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +#include "sudo.h" + +#ifdef HAVE_SELINUX +bool +sudo_check_temp_file(int tfd, const char *tfile, uid_t uid, struct stat *sb) +{ + struct stat sbuf; + debug_decl(sudo_check_temp_file, SUDO_DEBUG_UTIL); + + if (sb == NULL) + sb = &sbuf; + + if (fstat(tfd, sb) == -1) { + sudo_warn(U_("unable to stat %s"), tfile); + debug_return_bool(false); + } + if (!S_ISREG(sb->st_mode)) { + sudo_warnx(U_("%s: not a regular file"), tfile); + debug_return_bool(false); + } + if ((sb->st_mode & ALLPERMS) != (S_IRUSR|S_IWUSR)) { + sudo_warnx(U_("%s: bad file mode: 0%o"), tfile, sb->st_mode & ALLPERMS); + debug_return_bool(false); + } + if (sb->st_uid != uid) { + sudo_warnx(U_("%s is owned by uid %u, should be %u"), + tfile, (unsigned int)sb->st_uid, (unsigned int)uid); + debug_return_bool(false); + } + debug_return_bool(true); +} +#endif /* SELINUX */ Index: sudo-1.8.22/src/sudo_edit.h =================================================================== --- /dev/null +++ sudo-1.8.22/src/sudo_edit.h @@ -0,0 +1,7 @@ + +#ifndef SUDO_EDIT_H +#define SUDO_EDIT_H + +bool sudo_check_temp_file(int tfd, const char *tname, uid_t uid, struct stat *sb); + +#endif ++++++ sudo-CVE-2021-3156.patch ++++++ # HG changeset patch # Parent 2dbbab94d4b60ae05cb2aebf5bad1b9e18cdbb11 Reset valid_flags to MODE_NONINTERACTIVE for sudoedit. This is consistent with how the -e option is handled. Also reject -H and -P flags for sudoedit as was done in sudo 1.7. Found by Qualys. diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c index 09cf401..e2dd7c8 100644 --- a/plugins/sudoers/policy.c +++ b/plugins/sudoers/policy.c @@ -98,10 +98,11 @@ parse_bool(const char *line, int varlen, int *flags, int fval) int sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group) { + const int edit_mask = MODE_EDIT|MODE_IGNORE_TICKET|MODE_NONINTERACTIVE; struct sudoers_policy_open_info *info = v; - char * const *cur; const char *p, *errstr, *groups = NULL; const char *remhost = NULL; + char * const *cur; bool uid_set = false, gid_set = false; int flags = 0; debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN) @@ -331,6 +332,12 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group) #endif } + /* Sudo front-end should restrict mode flags for sudoedit. */ + if (ISSET(flags, MODE_EDIT) && (flags & edit_mask) != flags) { + sudo_warnx(U_("invalid mode flags from sudo front end: 0x%x"), flags); + goto bad; + } + user_umask = (mode_t)-1; for (cur = info->user_info; *cur != NULL; cur++) { if (MATCHES(*cur, "user=")) { diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 1267949..5f10653 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -404,7 +404,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */ /* XXX - causes confusion when root is not listed in sudoers */ - if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) { + if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT) && prev_user != NULL) { if (user_uid == 0 && strcmp(prev_user, "root") != 0) { struct passwd *pw; @@ -784,8 +784,8 @@ set_cmnd(void) if (user_cmnd == NULL) user_cmnd = NewArgv[0]; - if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { - if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) { + if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) { + if (!ISSET(sudo_mode, MODE_EDIT)) { if (def_secure_path && !user_is_exempt()) path = def_secure_path; if (!set_perms(PERM_RUNAS)) @@ -823,7 +823,8 @@ set_cmnd(void) sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); debug_return_int(-1); } - if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { + if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL) && + ISSET(sudo_mode, MODE_RUN)) { /* * When running a command via a shell, the sudo front-end * escapes potential meta chars. We unescape non-spaces @@ -831,10 +832,22 @@ set_cmnd(void) */ for (to = user_args, av = NewArgv + 1; (from = *av); av++) { while (*from) { - if (from[0] == '\\' && !isspace((unsigned char)from[1])) + if (from[0] == '\\' && from[1] != '\0' && + !isspace((unsigned char)from[1])) { from++; + } + if (size - (to - user_args) < 1) { + sudo_warnx(U_("internal error, %s overflow"), + __func__); + debug_return_int(NOT_FOUND_ERROR); + } *to++ = *from++; } + if (size - (to - user_args) < 1) { + sudo_warnx(U_("internal error, %s overflow"), + __func__); + debug_return_int(NOT_FOUND_ERROR); + } *to++ = ' '; } *--to = '\0'; diff --git a/plugins/sudoers/timestamp.c b/plugins/sudoers/timestamp.c index 5930103..ea81c3e 100644 --- a/plugins/sudoers/timestamp.c +++ b/plugins/sudoers/timestamp.c @@ -650,8 +650,8 @@ timestamp_lock(void *vcookie, struct passwd *pw) } else if (entry.type != TS_LOCKEXCL) { /* Old sudo record, convert it to TS_LOCKEXCL. */ entry.type = TS_LOCKEXCL; - memset((char *)&entry + offsetof(struct timestamp_entry, type), 0, - nread - offsetof(struct timestamp_entry, type)); + memset((char *)&entry + offsetof(struct timestamp_entry, flags), 0, + nread - offsetof(struct timestamp_entry, flags)); if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1) debug_return_bool(false); } diff --git a/src/parse_args.c b/src/parse_args.c index d9bbe06..5250f23 100644 --- a/src/parse_args.c +++ b/src/parse_args.c @@ -122,6 +122,9 @@ struct environment { * Default flags allowed when running a command. */ #define DEFAULT_VALID_FLAGS (MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_SHELL) +#define EDIT_VALID_FLAGS MODE_NONINTERACTIVE +#define LIST_VALID_FLAGS (MODE_NONINTERACTIVE|MODE_LONG_LIST) +#define VALIDATE_VALID_FLAGS MODE_NONINTERACTIVE /* Option number for the --host long option due to ambiguity of the -h flag. */ #define OPT_HOSTNAME 256 @@ -265,6 +268,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, progname = "sudoedit"; mode = MODE_EDIT; sudo_settings[ARG_SUDOEDIT].value = "true"; + valid_flags = EDIT_VALID_FLAGS; } /* Load local IP addresses and masks. */ @@ -350,7 +354,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, usage_excl(1); mode = MODE_EDIT; sudo_settings[ARG_SUDOEDIT].value = "true"; - valid_flags = MODE_NONINTERACTIVE; + valid_flags = EDIT_VALID_FLAGS; break; case 'g': if (*optarg == '\0') @@ -360,6 +364,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, break; case 'H': sudo_settings[ARG_SET_HOME].value = "true"; + SET(flags, MODE_RESET_HOME); break; case 'h': if (optarg == NULL) { @@ -409,7 +414,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, usage_excl(1); } mode = MODE_LIST; - valid_flags = MODE_NONINTERACTIVE|MODE_LONG_LIST; + valid_flags = LIST_VALID_FLAGS; break; case 'n': SET(flags, MODE_NONINTERACTIVE); @@ -417,6 +422,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, break; case 'P': sudo_settings[ARG_PRESERVE_GROUPS].value = "true"; + SET(flags, MODE_PRESERVE_GROUPS); break; case 'p': /* An empty prompt is allowed. */ @@ -460,7 +466,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, if (mode && mode != MODE_VALIDATE) usage_excl(1); mode = MODE_VALIDATE; - valid_flags = MODE_NONINTERACTIVE; + valid_flags = VALIDATE_VALID_FLAGS; break; case 'V': if (mode && mode != MODE_VERSION) @@ -487,7 +493,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, if (!mode) { /* Defer -k mode setting until we know whether it is a flag or not */ if (sudo_settings[ARG_IGNORE_TICKET].value != NULL) { - if (argc == 0 && !(flags & (MODE_SHELL|MODE_LOGIN_SHELL))) { + if (argc == 0 && !ISSET(flags, MODE_SHELL|MODE_LOGIN_SHELL)) { mode = MODE_INVALIDATE; /* -k by itself */ sudo_settings[ARG_IGNORE_TICKET].value = NULL; valid_flags = 0; @@ -557,16 +563,16 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, if (argc != 0) { /* shell -c "command" */ char *src, *dst; - size_t cmnd_size = (size_t) (argv[argc - 1] - argv[0]) + - strlen(argv[argc - 1]) + 1; + size_t size = 0; - cmnd = dst = reallocarray(NULL, cmnd_size, 2); - if (cmnd == NULL) + for (av = argv; *av != NULL; av++) + size += strlen(*av) + 1; + if (size == 0 || (cmnd = reallocarray(NULL, size, 2)) == NULL) sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); if (!gc_add(GC_PTR, cmnd)) exit(1); - for (av = argv; *av != NULL; av++) { + for (dst = cmnd, av = argv; *av != NULL; av++) { for (src = *av; *src != '\0'; src++) { /* quote potential meta characters */ if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$') ++++++ sudo-fix-bsc-1180687.patch ++++++ # HG changeset patch # User Todd C. Miller <Todd.Miller@sudo.ws> # Date 1609953360 25200 # Node ID 1d32c53859f99c63c60f23a40001bd80dc555f07 # Parent b0cae3ac8e46a85f1592f178e6e7c22fe4257a5c For sudo, only allow "sudo" or "sudoedit" as the program name. The program name is also used when matching Debug lines in sudo.conf. We don't want the user to be able to influence sudo.conf Debug matching. The string "sudoedit" is treated the same as "sudo" in sudo.conf. Problem reported by Matthias Gerstner of SUSE. diff --git a/include/sudo_util.h b/include/sudo_util.h index 96cac16..c7bb8b0 100644 --- a/include/sudo_util.h +++ b/include/sudo_util.h @@ -215,6 +215,7 @@ __dso_public ssize_t sudo_parseln_v2(char **buf, size_t *bufsize, unsigned int * /* progname.c */ __dso_public void initprogname(const char *); +__dso_public void initprogname2(const char *, const char * const *); /* secure_path.c */ #define SUDO_PATH_SECURE 0 diff --git a/lib/util/progname.c b/lib/util/progname.c index ffe946c..6f188a8 100644 --- a/lib/util/progname.c +++ b/lib/util/progname.c @@ -37,10 +37,11 @@ #ifdef HAVE_GETPROGNAME void -initprogname(const char *name) +initprogname2(const char *name, const char * const * allowed) { # ifdef HAVE_SETPROGNAME const char *progname; + int i; /* Fall back on "name" if getprogname() returns an empty string. */ if ((progname = getprogname()) != NULL && *progname != '\0') @@ -50,6 +51,18 @@ initprogname(const char *name) if (name[0] == 'l' && name[1] == 't' && name[2] == '-' && name[3] != '\0') name += 3; + /* Check allow list if present (first element is the default). */ + if (allowed != NULL) { + for (i = 0; ; i++) { + if (allowed[i] == NULL) { + name = allowed[0]; + break; + } + if (strcmp(allowed[i], name) == 0) + break; + } + } + /* Update internal progname if needed. */ if (name != progname) setprogname(name); @@ -62,8 +75,9 @@ initprogname(const char *name) static const char *progname = ""; void -initprogname(const char *name) +initprogname2(const char *name, const char * const * allowed) { + int i; # ifdef HAVE___PROGNAME extern const char *__progname; @@ -81,6 +95,18 @@ initprogname(const char *name) if (progname[0] == 'l' && progname[1] == 't' && progname[2] == '-' && progname[3] != '\0') progname += 3; + + /* Check allow list if present (first element is the default). */ + if (allowed != NULL) { + for (i = 0; ; i++) { + if (allowed[i] == NULL) { + progname = allowed[0]; + break; + } + if (strcmp(allowed[i], progname) == 0) + break; + } + } } const char * @@ -89,3 +115,9 @@ sudo_getprogname(void) return progname; } #endif /* !HAVE_GETPROGNAME */ + +void +initprogname(const char *name) +{ + initprogname2(name, NULL); +} diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index 510c34c..d69d3f2 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -1,4 +1,5 @@ @COMPAT_EXP@initprogname +initprogname2 sudo_arc4random_uniform sudo_conf_askpass_path_v1 sudo_conf_clear_paths_v1 diff --git a/src/sudo.c b/src/sudo.c index fbf4bc4..d9e2687 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -315,7 +315,7 @@ main(int argc, char *argv[], char *envp[]) sa.sa_handler = SIG_DFL; sigaction(WTERMSIG(status), &sa, NULL); sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, - WTERMSIG(status) | 128); + WTERMSIG(status) | 128); kill(getpid(), WTERMSIG(status)); } sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, @@ -326,7 +326,10 @@ main(int argc, char *argv[], char *envp[]) int os_init_common(int argc, char *argv[], char *envp[]) { - initprogname(argc > 0 ? argv[0] : "sudo"); + const char * const allowed_prognames[] = { "sudo", "sudoedit", NULL }; + + /* Only allow "sudo" or "sudoedit" as the program name. */ + initprogname2(argc > 0 ? argv[0] : "sudo", allowed_prognames); #ifdef STATIC_SUDOERS_PLUGIN preload_static_symbols(); #endif ++++++ sudo-i.pamd ++++++ #%PAM-1.0 auth include common-auth account include common-account password include common-password session optional pam_keyinit.so force revoke session include common-session # session optional pam_xauth.so ++++++ sudo-sudoers.patch ++++++ diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in index 2053b5d..dfbef79 100644 --- a/doc/sudoers.mdoc.in +++ b/doc/sudoers.mdoc.in @@ -1952,7 +1952,7 @@ is present in the .Em env_keep list. This flag is -.Em off +.Em on by default. .It authenticate If set, users must authenticate themselves via a password (or other @@ -2340,7 +2340,7 @@ If set, .Nm sudo will insult users when they enter an incorrect password. This flag is -.Em @insults@ +.Em off by default. .It log_host If set, the host name will be logged in the (non-syslog) @@ -2904,7 +2904,7 @@ database as an argument to the .Fl u option. This flag is -.Em off +.Em on by default. .It tty_tickets If set, users must authenticate on a per-tty basis. diff --git a/plugins/sudoers/sudoers.in b/plugins/sudoers/sudoers.in index 6216dfd..b87fc65 100644 --- a/plugins/sudoers/sudoers.in +++ b/plugins/sudoers/sudoers.in @@ -32,30 +32,23 @@ ## ## Defaults specification ## -## You may wish to keep some of the following environment variables -## when running commands via sudo. -## -## Locale settings -# Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET" -## -## Run X applications through sudo; HOME is used to find the -## .Xauthority file. Note that other programs use HOME to find -## configuration files and this may lead to privilege escalation! -# Defaults env_keep += "HOME" -## -## X11 resource path settings -# Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH" -## -## Desktop path settings -# Defaults env_keep += "QTDIR KDEDIR" -## -## Allow sudo-run commands to inherit the callers' ConsoleKit session -# Defaults env_keep += "XDG_SESSION_COOKIE" -## -## Uncomment to enable special input methods. Care should be taken as -## this may allow users to subvert the command being run via sudo. -# Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER" -## +## Prevent environment variables from influencing programs in an +## unexpected or harmful way (CVE-2005-2959, CVE-2005-4158, CVE-2006-0151) +Defaults always_set_home +## Path that will be used for every command run from sudo +Defaults secure_path="/usr/sbin:/usr/bin:/sbin:/bin" +Defaults env_reset +## Change env_reset to !env_reset in previous line to keep all environment variables +## Following list will no longer be nevessary after this change +Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_ATIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE" +## Comment out the preceding line and uncomment the following one if you need +## to use special input methods. This may allow users to compromise the root +## account if they are allowed to run commands without authentication. +#Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_ATIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE" + +## Do not insult users when they enter an incorrect password. +Defaults !insults + ## Uncomment to use a hard-coded PATH instead of the user's to find commands # Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ## @@ -66,9 +59,15 @@ ## sudoreplay and reboot. Use sudoreplay to play back logged sessions. # Defaults log_output # Defaults!/usr/bin/sudoreplay !log_output -# Defaults!/usr/local/bin/sudoreplay !log_output # Defaults!REBOOT !log_output +## In the default (unconfigured) configuration, sudo asks for the root password. +## This allows use of an ordinary user account for administration of a freshly +## installed system. When configuring sudo, delete the two +## following lines: +Defaults targetpw # ask for the password of the target user i.e. root +ALL ALL=(ALL) ALL # WARNING! Only use this together with 'Defaults targetpw'! + ## ## Runas alias specification ## @@ -84,14 +83,6 @@ root ALL=(ALL) ALL ## Same thing without a password # %wheel ALL=(ALL) NOPASSWD: ALL -## Uncomment to allow members of group sudo to execute any command -# %sudo ALL=(ALL) ALL - -## Uncomment to allow any user to run sudo if they know the password -## of the user they are running the command as (root by default). -# Defaults targetpw # Ask for the password of the target user -# ALL ALL=(ALL) ALL # WARNING: only use this together with 'Defaults targetpw' - ## Read drop-in files from @sysconfdir@/sudoers.d ## (the '#' here does not indicate a comment) #includedir @sysconfdir@/sudoers.d ++++++ sudo.keyring ++++++ pub 1024D/0x5A89DFA27EE470C4 2002-10-02 uid [ unknown] Todd C. Miller <Todd.Miller@courtesan.com> sub 1024g/0x4ACA1697D017E72F 2002-10-02 pub 4096R/0xA9F4C021CEA470FB 2017-12-03 uid [ unknown] Todd C. Miller <Todd.Miller@sudo.ws> sub 4096R/0x8BBF1A6CF4565623 2017-12-03 -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2 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 =bkRz -----END PGP PUBLIC KEY BLOCK----- ++++++ sudo.pamd ++++++ #%PAM-1.0 auth include common-auth account include common-account password include common-password session optional pam_keyinit.so revoke session include common-session # session optional pam_xauth.so