Compare commits
No commits in common. "c8" and "c9" have entirely different histories.
|
@ -1 +1 @@
|
|||
SOURCES/sudo-1.8.29.tar.gz
|
||||
SOURCES/sudo-1.9.5p2.tar.gz
|
||||
|
|
|
@ -1 +1 @@
|
|||
fdce342856f1803478eb549479190370001dca95 SOURCES/sudo-1.8.29.tar.gz
|
||||
08bde247a1e08bc881eec43e09733f7ca06408f5 SOURCES/sudo-1.9.5p2.tar.gz
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
diff -up ./lib/eventlog/eventlog.c.covscan ./lib/eventlog/eventlog.c
|
||||
--- ./lib/eventlog/eventlog.c.covscan 2021-08-26 11:06:35.068915415 +0200
|
||||
+++ ./lib/eventlog/eventlog.c 2021-08-26 11:13:32.432472325 +0200
|
||||
@@ -1075,10 +1075,13 @@ do_logfile_sudo(const char *logline, con
|
||||
if (ferror(fp)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
"unable to write log file %s", logfile);
|
||||
- goto done;
|
||||
+ goto ddone;
|
||||
}
|
||||
ret = true;
|
||||
|
||||
+ddone:
|
||||
+ (void)free(full_line);
|
||||
+
|
||||
done:
|
||||
(void)sudo_lock_file(fileno(fp), SUDO_UNLOCK);
|
||||
evl_conf.close_log(EVLOG_FILE, fp);
|
||||
diff -up ./logsrvd/logsrvd.c.covscan ./logsrvd/logsrvd.c
|
||||
diff -up ./plugins/audit_json/audit_json.c.covscan ./plugins/audit_json/audit_json.c
|
||||
diff -up ./plugins/sudoers/ldap.c.covscan ./plugins/sudoers/ldap.c
|
||||
--- ./plugins/sudoers/ldap.c.covscan 2021-08-26 15:46:11.614179451 +0200
|
||||
+++ ./plugins/sudoers/ldap.c 2021-08-26 15:51:40.871812534 +0200
|
||||
@@ -443,6 +443,8 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMe
|
||||
goto done;
|
||||
}
|
||||
|
||||
+ free(cp);
|
||||
+
|
||||
/* Walk through options, appending to defs. */
|
||||
for (p = bv; *p != NULL; p++) {
|
||||
char *var, *val;
|
||||
diff -up ./plugins/sudoers/logging.c.covscan ./plugins/sudoers/logging.c
|
||||
diff -up ./plugins/sudoers/rcstr.c.covscan ./plugins/sudoers/rcstr.c
|
||||
diff -up ./src/utmp.c.covscan ./src/utmp.c
|
|
@ -1,11 +0,0 @@
|
|||
--- sudo-1.6.7p5/install-sh.strip 2005-07-21 14:28:25.000000000 +0200
|
||||
+++ sudo-1.6.7p5/install-sh 2005-07-21 14:29:18.000000000 +0200
|
||||
@@ -138,7 +138,7 @@
|
||||
fi
|
||||
;;
|
||||
X-s)
|
||||
- STRIPIT=true
|
||||
+ #STRIPIT=true
|
||||
;;
|
||||
X--)
|
||||
shift
|
|
@ -1,27 +0,0 @@
|
|||
From 44a602b49365969e56c63c9f12eda197e951302f Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Fri, 19 Aug 2016 14:07:35 +0200
|
||||
Subject: [PATCH 02/10] Added "Enviroment debugging" message
|
||||
|
||||
rebased from:
|
||||
Patch2: sudo-1.7.2p1-envdebug.patch
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 9feddfd..39a2d86 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1390,7 +1390,7 @@ AC_ARG_ENABLE(env_debug,
|
||||
[AS_HELP_STRING([--enable-env-debug], [Whether to enable environment debugging.])],
|
||||
[ case "$enableval" in
|
||||
yes) AC_MSG_RESULT(yes)
|
||||
- AC_DEFINE(ENV_DEBUG)
|
||||
+ AC_DEFINE(ENV_DEBUG, [], [Environment debugging.])
|
||||
;;
|
||||
no) AC_MSG_RESULT(no)
|
||||
;;
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
diff -up ./plugins/sudoers/cvtsudoers.c.legacy-processing ./plugins/sudoers/cvtsudoers.c
|
||||
--- ./plugins/sudoers/cvtsudoers.c.legacy-processing 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./plugins/sudoers/cvtsudoers.c 2019-10-30 13:32:43.309480623 +0100
|
||||
@@ -347,6 +347,15 @@ main(int argc, char *argv[])
|
||||
sudo_fatalx("error: unhandled input %d", input_format);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * cvtsudoers group filtering doesn't work if def_match_group_by_gid
|
||||
+ * is set to true by default (at compile-time). It cannot be set to false
|
||||
+ * because cvtsudoers doesn't apply the parsed Defaults.
|
||||
+ *
|
||||
+ * Related: sudo-1.8.23-legacy-group-processing.patch
|
||||
+ */
|
||||
+ def_match_group_by_gid = def_legacy_group_processing = false;
|
||||
+
|
||||
/* Apply filters. */
|
||||
filter_userspecs(&parsed_policy, conf);
|
||||
filter_defaults(&parsed_policy, conf);
|
||||
diff -up ./plugins/sudoers/defaults.c.legacy-processing ./plugins/sudoers/defaults.c
|
||||
--- ./plugins/sudoers/defaults.c.legacy-processing 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./plugins/sudoers/defaults.c 2019-10-30 13:32:43.309480623 +0100
|
||||
@@ -93,6 +93,7 @@ static struct early_default early_defaul
|
||||
{ I_FQDN },
|
||||
#endif
|
||||
{ I_MATCH_GROUP_BY_GID },
|
||||
+ { I_LEGACY_GROUP_PROCESSING },
|
||||
{ I_GROUP_PLUGIN },
|
||||
{ I_RUNAS_DEFAULT },
|
||||
{ I_SUDOERS_LOCALE },
|
||||
@@ -494,6 +495,8 @@ init_defaults(void)
|
||||
}
|
||||
|
||||
/* First initialize the flags. */
|
||||
+ def_legacy_group_processing = true;
|
||||
+ def_match_group_by_gid = true;
|
||||
#ifdef LONG_OTP_PROMPT
|
||||
def_long_otp_prompt = true;
|
||||
#endif
|
||||
diff -up ./plugins/sudoers/def_data.c.legacy-processing ./plugins/sudoers/def_data.c
|
||||
--- ./plugins/sudoers/def_data.c.legacy-processing 2019-10-30 13:32:43.309480623 +0100
|
||||
+++ ./plugins/sudoers/def_data.c 2019-10-30 13:37:25.914602825 +0100
|
||||
@@ -506,6 +506,10 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Log when a command is denied by sudoers"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "legacy_group_processing", T_FLAG,
|
||||
+ N_("Don't pre-resolve all group names"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up ./plugins/sudoers/def_data.h.legacy-processing ./plugins/sudoers/def_data.h
|
||||
--- ./plugins/sudoers/def_data.h.legacy-processing 2019-10-30 13:32:43.310480638 +0100
|
||||
+++ ./plugins/sudoers/def_data.h 2019-10-30 13:40:59.651713757 +0100
|
||||
@@ -232,6 +232,8 @@
|
||||
#define def_log_allowed (sudo_defs_table[I_LOG_ALLOWED].sd_un.flag)
|
||||
#define I_LOG_DENIED 116
|
||||
#define def_log_denied (sudo_defs_table[I_LOG_DENIED].sd_un.flag)
|
||||
+#define I_LEGACY_GROUP_PROCESSING 117
|
||||
+#define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up ./plugins/sudoers/def_data.in.legacy-processing ./plugins/sudoers/def_data.in
|
||||
--- ./plugins/sudoers/def_data.in.legacy-processing 2019-10-30 13:32:43.310480638 +0100
|
||||
+++ ./plugins/sudoers/def_data.in 2019-10-30 13:42:20.915896239 +0100
|
||||
@@ -366,3 +366,6 @@ log_allowed
|
||||
log_denied
|
||||
T_FLAG
|
||||
"Log when a command is denied by sudoers"
|
||||
+legacy_group_processing
|
||||
+ T_FLAG
|
||||
+ "Don't pre-resolve all group names"
|
||||
diff -up ./plugins/sudoers/sudoers.c.legacy-processing ./plugins/sudoers/sudoers.c
|
||||
--- ./plugins/sudoers/sudoers.c.legacy-processing 2019-10-28 13:28:53.000000000 +0100
|
||||
+++ ./plugins/sudoers/sudoers.c 2019-10-30 13:32:43.310480638 +0100
|
||||
@@ -221,6 +221,10 @@ sudoers_policy_init(void *info, char * c
|
||||
if (set_loginclass(runas_pw ? runas_pw : sudo_user.pw))
|
||||
ret = true;
|
||||
|
||||
+ if (!def_match_group_by_gid || !def_legacy_group_processing) {
|
||||
+ def_match_group_by_gid = false;
|
||||
+ def_legacy_group_processing = false;
|
||||
+ }
|
||||
cleanup:
|
||||
if (!restore_perms())
|
||||
ret = -1;
|
|
@ -1,60 +0,0 @@
|
|||
diff -up ./plugins/sudoers/def_data.c.nowait ./plugins/sudoers/def_data.c
|
||||
--- ./plugins/sudoers/def_data.c.nowait 2019-10-30 13:43:48.376168944 +0100
|
||||
+++ ./plugins/sudoers/def_data.c 2019-10-30 13:43:48.378168973 +0100
|
||||
@@ -510,6 +510,10 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Don't pre-resolve all group names"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "cmnd_no_wait", T_FLAG,
|
||||
+ N_("Don't fork and wait for the command to finish, just exec it"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up ./plugins/sudoers/def_data.h.nowait ./plugins/sudoers/def_data.h
|
||||
--- ./plugins/sudoers/def_data.h.nowait 2019-10-30 13:43:48.378168973 +0100
|
||||
+++ ./plugins/sudoers/def_data.h 2019-10-30 13:45:38.425770365 +0100
|
||||
@@ -234,6 +234,8 @@
|
||||
#define def_log_denied (sudo_defs_table[I_LOG_DENIED].sd_un.flag)
|
||||
#define I_LEGACY_GROUP_PROCESSING 117
|
||||
#define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag)
|
||||
+#define I_CMND_NO_WAIT 118
|
||||
+#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up ./plugins/sudoers/def_data.in.nowait ./plugins/sudoers/def_data.in
|
||||
--- ./plugins/sudoers/def_data.in.nowait 2019-10-30 13:43:48.376168944 +0100
|
||||
+++ ./plugins/sudoers/def_data.in 2019-10-30 13:43:48.379168987 +0100
|
||||
@@ -369,3 +369,6 @@ log_denied
|
||||
legacy_group_processing
|
||||
T_FLAG
|
||||
"Don't pre-resolve all group names"
|
||||
+cmnd_no_wait
|
||||
+ T_FLAG
|
||||
+ "Don't fork and wait for the command to finish, just exec it"
|
||||
diff -up ./plugins/sudoers/sudoers.c.nowait ./plugins/sudoers/sudoers.c
|
||||
--- ./plugins/sudoers/sudoers.c.nowait 2019-10-30 13:43:48.376168944 +0100
|
||||
+++ ./plugins/sudoers/sudoers.c 2019-10-30 13:43:48.379168987 +0100
|
||||
@@ -225,6 +225,20 @@ sudoers_policy_init(void *info, char * c
|
||||
def_match_group_by_gid = false;
|
||||
def_legacy_group_processing = false;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Emulate cmnd_no_wait option by disabling PAM session, PTY allocation
|
||||
+ * and I/O logging. This will cause sudo to execute the given command
|
||||
+ * directly instead of forking a separate process for it.
|
||||
+ */
|
||||
+ if (def_cmnd_no_wait) {
|
||||
+ def_pam_setcred = false;
|
||||
+ def_pam_session = false;
|
||||
+ def_use_pty = false;
|
||||
+ def_log_input = false;
|
||||
+ def_log_output = false;
|
||||
+ }
|
||||
+
|
||||
cleanup:
|
||||
if (!restore_perms())
|
||||
ret = -1;
|
|
@ -1,32 +0,0 @@
|
|||
diff -up sudo-1.8.23/doc/Makefile.in.sudoldapconfman sudo-1.8.23/doc/Makefile.in
|
||||
--- sudo-1.8.23/doc/Makefile.in.sudoldapconfman 2018-04-29 21:59:31.000000000 +0200
|
||||
+++ sudo-1.8.23/doc/Makefile.in 2018-05-17 13:56:24.693651178 +0200
|
||||
@@ -345,10 +345,16 @@ install-doc: install-dirs
|
||||
rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
|
||||
echo ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
|
||||
ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
|
||||
+ rm -f $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \
|
||||
+ echo ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \
|
||||
+ ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \
|
||||
else \
|
||||
rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
|
||||
echo ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
|
||||
ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
|
||||
+ rm -f $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \
|
||||
+ echo ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \
|
||||
+ ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \
|
||||
fi
|
||||
|
||||
install-plugin:
|
||||
@@ -363,8 +369,9 @@ uninstall:
|
||||
$(DESTDIR)$(mandirsu)/visudo.$(mansectsu) \
|
||||
$(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) \
|
||||
$(DESTDIR)$(mandirform)/sudoers.$(mansectform) \
|
||||
- $(DESTDIR)$(mandirform)/sudoers_timestamp.$(mansectform)
|
||||
- $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform)
|
||||
+ $(DESTDIR)$(mandirform)/sudoers_timestamp.$(mansectform) \
|
||||
+ $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform) \
|
||||
+ $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)
|
||||
|
||||
splint:
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
diff -up ./src/tgetpass.c.CVE-2019-18634 ./src/tgetpass.c
|
||||
--- ./src/tgetpass.c.CVE-2019-18634 2019-10-28 13:27:39.000000000 +0100
|
||||
+++ ./src/tgetpass.c 2020-02-05 14:08:27.516101197 +0100
|
||||
@@ -61,7 +61,7 @@ enum tgetpass_errval {
|
||||
static volatile sig_atomic_t signo[NSIG];
|
||||
|
||||
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
|
||||
@@ -125,6 +125,7 @@ tgetpass(const char *prompt, int timeout
|
||||
static char buf[SUDO_CONV_REPL_MAX + 1];
|
||||
int i, input, output, save_errno, ttyfd;
|
||||
bool need_restart, neednl = false;
|
||||
+ bool feedback = ISSET(flags, TGP_MASK);
|
||||
enum tgetpass_errval errval;
|
||||
debug_decl(tgetpass, SUDO_DEBUG_CONV)
|
||||
|
||||
@@ -180,7 +181,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);
|
||||
@@ -194,6 +195,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
|
||||
@@ -224,7 +228,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;
|
||||
|
||||
@@ -360,7 +364,7 @@ sudo_askpass(const char *askpass, const
|
||||
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;
|
||||
@@ -389,15 +393,15 @@ getln(int fd, char *buf, size_t bufsiz,
|
||||
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;
|
|
@ -1,169 +0,0 @@
|
|||
diff -up ./doc/sudoers.man.in.CVE-2019-19232 ./doc/sudoers.man.in
|
||||
--- ./doc/sudoers.man.in.CVE-2019-19232 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./doc/sudoers.man.in 2020-01-14 15:34:46.908027286 +0100
|
||||
@@ -2942,6 +2942,23 @@ This flag is
|
||||
\fIoff\fR
|
||||
by default.
|
||||
.TP 18n
|
||||
+runas_allow_unknown_id
|
||||
+If enabled, allow matching of runas user and group IDs that are
|
||||
+not present in the password or group databases.
|
||||
+In addition to explicitly matching unknown user or group IDs in a
|
||||
+\fRRunas_List\fR,
|
||||
+this option also allows the
|
||||
+\fBALL\fR
|
||||
+alias to match unknown IDs.
|
||||
+This flag is
|
||||
+\fIoff\fR
|
||||
+by default.
|
||||
+.sp
|
||||
+This setting is only supported by version 1.8.29 or higher.
|
||||
+Older versions of
|
||||
+\fBsudo\fR
|
||||
+always allowed matching of unknown user and group IDs.
|
||||
+.TP 18n
|
||||
runaspw
|
||||
If set,
|
||||
\fBsudo\fR
|
||||
diff -up ./doc/sudoers.mdoc.in.CVE-2019-19232 ./doc/sudoers.mdoc.in
|
||||
--- ./doc/sudoers.mdoc.in.CVE-2019-19232 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./doc/sudoers.mdoc.in 2020-01-14 15:34:46.908027286 +0100
|
||||
@@ -2768,6 +2768,22 @@ when running a command or editing a file
|
||||
This flag is
|
||||
.Em off
|
||||
by default.
|
||||
+.It runas_allow_unknown_id
|
||||
+If enabled, allow matching of runas user and group IDs that are
|
||||
+not present in the password or group databases.
|
||||
+In addition to explicitly matching unknown user or group IDs in a
|
||||
+.Li Runas_List ,
|
||||
+this option also allows the
|
||||
+.Sy ALL
|
||||
+alias to match unknown IDs.
|
||||
+This flag is
|
||||
+.Em off
|
||||
+by default.
|
||||
+.Pp
|
||||
+This setting is only supported by version 1.8.29 or higher.
|
||||
+Older versions of
|
||||
+.Nm sudo
|
||||
+always allowed matching of unknown user and group IDs.
|
||||
.It runaspw
|
||||
If set,
|
||||
.Nm sudo
|
||||
diff -up ./plugins/sudoers/defaults.c.CVE-2019-19232 ./plugins/sudoers/defaults.c
|
||||
--- ./plugins/sudoers/defaults.c.CVE-2019-19232 2020-01-14 15:34:46.902027246 +0100
|
||||
+++ ./plugins/sudoers/defaults.c 2020-01-14 15:34:46.909027293 +0100
|
||||
@@ -581,6 +581,7 @@ init_defaults(void)
|
||||
def_fdexec = digest_only;
|
||||
def_log_allowed = true;
|
||||
def_log_denied = true;
|
||||
+ def_runas_allow_unknown_id = false;
|
||||
|
||||
/* Syslog options need special care since they both strings and ints */
|
||||
#if (LOGGING & SLOG_SYSLOG)
|
||||
diff -up ./plugins/sudoers/def_data.c.CVE-2019-19232 ./plugins/sudoers/def_data.c
|
||||
--- ./plugins/sudoers/def_data.c.CVE-2019-19232 2020-01-14 15:34:46.908027286 +0100
|
||||
+++ ./plugins/sudoers/def_data.c 2020-01-14 15:40:19.441555509 +0100
|
||||
@@ -514,6 +514,10 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Don't fork and wait for the command to finish, just exec it"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "runas_allow_unknown_id", T_FLAG,
|
||||
+ N_("Allow the use of unknown runas user and/or group ID"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up ./plugins/sudoers/def_data.h.CVE-2019-19232 ./plugins/sudoers/def_data.h
|
||||
--- ./plugins/sudoers/def_data.h.CVE-2019-19232 2020-01-14 15:34:46.909027293 +0100
|
||||
+++ ./plugins/sudoers/def_data.h 2020-01-14 15:41:33.658012401 +0100
|
||||
@@ -236,6 +236,8 @@
|
||||
#define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag)
|
||||
#define I_CMND_NO_WAIT 118
|
||||
#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag)
|
||||
+#define I_RUNAS_ALLOW_UNKNOWN_ID 119
|
||||
+#define def_runas_allow_unknown_id (sudo_defs_table[I_RUNAS_ALLOW_UNKNOWN_ID].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up ./plugins/sudoers/def_data.in.CVE-2019-19232 ./plugins/sudoers/def_data.in
|
||||
--- ./plugins/sudoers/def_data.in.CVE-2019-19232 2020-01-14 15:34:46.909027293 +0100
|
||||
+++ ./plugins/sudoers/def_data.in 2020-01-14 15:42:42.176481484 +0100
|
||||
@@ -372,3 +372,6 @@ legacy_group_processing
|
||||
cmnd_no_wait
|
||||
T_FLAG
|
||||
"Don't fork and wait for the command to finish, just exec it"
|
||||
+runas_allow_unknown_id
|
||||
+ T_FLAG
|
||||
+ "Allow the use of unknown runas user and/or group ID"
|
||||
diff -up ./plugins/sudoers/sudoers.c.CVE-2019-19232 ./plugins/sudoers/sudoers.c
|
||||
--- ./plugins/sudoers/sudoers.c.CVE-2019-19232 2020-01-14 15:34:46.905027266 +0100
|
||||
+++ ./plugins/sudoers/sudoers.c 2020-01-14 15:34:46.910027299 +0100
|
||||
@@ -105,6 +105,8 @@ static char *prev_user;
|
||||
static char *runas_user;
|
||||
static char *runas_group;
|
||||
static struct sudo_nss_list *snl;
|
||||
+static bool unknown_runas_uid;
|
||||
+static bool unknown_runas_gid;
|
||||
|
||||
#ifdef __linux__
|
||||
static struct rlimit nproclimit;
|
||||
@@ -354,6 +356,22 @@ sudoers_policy_main(int argc, char * con
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Defer uid/gid checks until after defaults have been updated. */
|
||||
+ if (unknown_runas_uid && !def_runas_allow_unknown_id) {
|
||||
+ audit_failure(NewArgc, NewArgv, N_("unknown user: %s"),
|
||||
+ runas_pw->pw_name);
|
||||
+ sudo_warnx(U_("unknown user: %s"), runas_pw->pw_name);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (runas_gr != NULL) {
|
||||
+ if (unknown_runas_gid && !def_runas_allow_unknown_id) {
|
||||
+ audit_failure(NewArgc, NewArgv, N_("unknown group: %s"),
|
||||
+ runas_gr->gr_name);
|
||||
+ sudo_warnx(U_("unknown group: %s"), runas_gr->gr_name);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Look up the timestamp dir owner if one is specified.
|
||||
*/
|
||||
@@ -1167,12 +1185,15 @@ set_runaspw(const char *user, bool quiet
|
||||
struct passwd *pw = NULL;
|
||||
debug_decl(set_runaspw, SUDOERS_DEBUG_PLUGIN)
|
||||
|
||||
+ unknown_runas_uid = false;
|
||||
if (*user == '#') {
|
||||
const char *errstr;
|
||||
uid_t uid = sudo_strtoid(user + 1, &errstr);
|
||||
if (errstr == NULL) {
|
||||
- if ((pw = sudo_getpwuid(uid)) == NULL)
|
||||
+ if ((pw = sudo_getpwuid(uid)) == NULL) {
|
||||
+ unknown_runas_uid = true;
|
||||
pw = sudo_fakepwnam(user, user_gid);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (pw == NULL) {
|
||||
@@ -1198,12 +1219,15 @@ set_runasgr(const char *group, bool quie
|
||||
struct group *gr = NULL;
|
||||
debug_decl(set_runasgr, SUDOERS_DEBUG_PLUGIN)
|
||||
|
||||
+ unknown_runas_gid = false;
|
||||
if (*group == '#') {
|
||||
const char *errstr;
|
||||
gid_t gid = sudo_strtoid(group + 1, &errstr);
|
||||
if (errstr == NULL) {
|
||||
- if ((gr = sudo_getgrgid(gid)) == NULL)
|
||||
+ if ((gr = sudo_getgrgid(gid)) == NULL) {
|
||||
+ unknown_runas_gid = true;
|
||||
gr = sudo_fakegrnam(group);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (gr == NULL) {
|
|
@ -1,439 +0,0 @@
|
|||
diff -up ./config.h.in.CVE-2019-19234 ./config.h.in
|
||||
--- ./config.h.in.CVE-2019-19234 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./config.h.in 2020-01-14 15:53:40.506988064 +0100
|
||||
@@ -334,6 +334,9 @@
|
||||
/* Define to 1 if you have the `getuserattr' function. */
|
||||
#undef HAVE_GETUSERATTR
|
||||
|
||||
+/* Define to 1 if you have the `getusershell' function. */
|
||||
+#undef HAVE_GETUSERSHELL
|
||||
+
|
||||
/* Define to 1 if you have the `getutid' function. */
|
||||
#undef HAVE_GETUTID
|
||||
|
||||
diff -up ./configure.ac.CVE-2019-19234 ./configure.ac
|
||||
--- ./configure.ac.CVE-2019-19234 2020-01-14 15:53:40.496987995 +0100
|
||||
+++ ./configure.ac 2020-01-14 15:53:40.509988084 +0100
|
||||
@@ -2562,6 +2562,10 @@ AC_CHECK_FUNCS([getdelim], [], [
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_getdelim)
|
||||
COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }getdelim_test"
|
||||
])
|
||||
+AC_CHECK_FUNCS([getusershell], [], [
|
||||
+ AC_LIBOBJ(getusershell)
|
||||
+ SUDO_APPEND_COMPAT_EXP(sudo_getusershell)
|
||||
+])
|
||||
AC_CHECK_FUNCS([reallocarray], [], [
|
||||
AC_LIBOBJ(reallocarray)
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_reallocarray)
|
||||
diff -up ./configure.CVE-2019-19234 ./configure
|
||||
--- ./configure.CVE-2019-19234 2019-10-28 13:29:14.000000000 +0100
|
||||
+++ ./configure 2020-01-14 15:53:40.509988084 +0100
|
||||
@@ -19395,6 +19395,32 @@ esac
|
||||
fi
|
||||
done
|
||||
|
||||
+for ac_func in getusershell
|
||||
+do :
|
||||
+ ac_fn_c_check_func "$LINENO" "getusershell" "ac_cv_func_getusershell"
|
||||
+if test "x$ac_cv_func_getusershell" = xyes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define HAVE_GETUSERSHELL 1
|
||||
+_ACEOF
|
||||
+
|
||||
+else
|
||||
+
|
||||
+ case " $LIBOBJS " in
|
||||
+ *" getusershell.$ac_objext "* ) ;;
|
||||
+ *) LIBOBJS="$LIBOBJS getusershell.$ac_objext"
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+
|
||||
+ for _sym in sudo_getusershell; do
|
||||
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
|
||||
+"
|
||||
+ done
|
||||
+
|
||||
+
|
||||
+fi
|
||||
+done
|
||||
+
|
||||
for ac_func in reallocarray
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray"
|
||||
diff -up ./doc/sudoers.man.in.CVE-2019-19234 ./doc/sudoers.man.in
|
||||
--- ./doc/sudoers.man.in.CVE-2019-19234 2020-01-14 15:53:40.503988043 +0100
|
||||
+++ ./doc/sudoers.man.in 2020-01-14 15:53:40.510988091 +0100
|
||||
@@ -2959,6 +2959,28 @@ Older versions of
|
||||
\fBsudo\fR
|
||||
always allowed matching of unknown user and group IDs.
|
||||
.TP 18n
|
||||
+runas_check_shell
|
||||
+.br
|
||||
+If enabled,
|
||||
+\fBsudo\fR
|
||||
+will only run commands as a user whose shell appears in the
|
||||
+\fI/etc/shells\fR
|
||||
+file, even if the invoking user's
|
||||
+\fRRunas_List\fR
|
||||
+would otherwise permit it.
|
||||
+If no
|
||||
+\fI/etc/shells\fR
|
||||
+file is present, a system-dependent list of built-in default shells is used.
|
||||
+On many operating systems, system users such as
|
||||
+\(lqbin\(rq,
|
||||
+do not have a valid shell and this flag can be used to prevent
|
||||
+commands from being run as those users.
|
||||
+This flag is
|
||||
+\fIoff\fR
|
||||
+by default.
|
||||
+.sp
|
||||
+This setting is only supported by version 1.8.29 or higher.
|
||||
+.TP 18n
|
||||
runaspw
|
||||
If set,
|
||||
\fBsudo\fR
|
||||
diff -up ./doc/sudoers.mdoc.in.CVE-2019-19234 ./doc/sudoers.mdoc.in
|
||||
--- ./doc/sudoers.mdoc.in.CVE-2019-19234 2020-01-14 15:53:40.504988050 +0100
|
||||
+++ ./doc/sudoers.mdoc.in 2020-01-14 15:53:40.510988091 +0100
|
||||
@@ -2784,6 +2784,26 @@ This setting is only supported by versio
|
||||
Older versions of
|
||||
.Nm sudo
|
||||
always allowed matching of unknown user and group IDs.
|
||||
+.It runas_check_shell
|
||||
+If enabled,
|
||||
+.Nm sudo
|
||||
+will only run commands as a user whose shell appears in the
|
||||
+.Pa /etc/shells
|
||||
+file, even if the invoking user's
|
||||
+.Li Runas_List
|
||||
+would otherwise permit it.
|
||||
+If no
|
||||
+.Pa /etc/shells
|
||||
+file is present, a system-dependent list of built-in default shells is used.
|
||||
+On many operating systems, system users such as
|
||||
+.Dq bin ,
|
||||
+do not have a valid shell and this flag can be used to prevent
|
||||
+commands from being run as those users.
|
||||
+This flag is
|
||||
+.Em off
|
||||
+by default.
|
||||
+.Pp
|
||||
+This setting is only supported by version 1.8.29 or higher.
|
||||
.It runaspw
|
||||
If set,
|
||||
.Nm sudo
|
||||
diff -up ./include/sudo_compat.h.CVE-2019-19234 ./include/sudo_compat.h
|
||||
--- ./include/sudo_compat.h.CVE-2019-19234 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./include/sudo_compat.h 2020-01-14 15:53:40.511988098 +0100
|
||||
@@ -407,6 +407,17 @@ __dso_public ssize_t sudo_getdelim(char
|
||||
# undef getdelim
|
||||
# define getdelim(_a, _b, _c, _d) sudo_getdelim((_a), (_b), (_c), (_d))
|
||||
#endif /* HAVE_GETDELIM */
|
||||
+#ifndef HAVE_GETUSERSHELL
|
||||
+__dso_public char *sudo_getusershell(void);
|
||||
+# undef getusershell
|
||||
+# define getusershell() sudo_getusershell()
|
||||
+__dso_public void sudo_setusershell(void);
|
||||
+# undef setusershell
|
||||
+# define setusershell() sudo_setusershell()
|
||||
+__dso_public void sudo_endusershell(void);
|
||||
+# undef endusershell
|
||||
+# define endusershell() sudo_endusershell()
|
||||
+#endif /* HAVE_GETUSERSHELL */
|
||||
#ifndef HAVE_UTIMENSAT
|
||||
__dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag);
|
||||
# undef utimensat
|
||||
diff -up ./lib/util/getusershell.c.CVE-2019-19234 ./lib/util/getusershell.c
|
||||
--- ./lib/util/getusershell.c.CVE-2019-19234 2020-01-14 15:53:40.511988098 +0100
|
||||
+++ ./lib/util/getusershell.c 2020-01-14 15:53:40.511988098 +0100
|
||||
@@ -0,0 +1,138 @@
|
||||
+/*
|
||||
+ * SPDX-License-Identifier: ISC
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#define DEFAULT_TEXT_DOMAIN "sudo"
|
||||
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
|
||||
+
|
||||
+#include "sudo_compat.h"
|
||||
+#include "sudo_debug.h"
|
||||
+#include "sudo_util.h"
|
||||
+
|
||||
+static char **allowed_shells, **current_shell;
|
||||
+static char *default_shells[] = {
|
||||
+ "/bin/sh",
|
||||
+ "/bin/ksh",
|
||||
+ "/bin/ksh93",
|
||||
+ "/bin/bash",
|
||||
+ "/bin/dash",
|
||||
+ "/bin/zsh",
|
||||
+ "/bin/csh",
|
||||
+ "/bin/tcsh",
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static char **
|
||||
+read_shells(void)
|
||||
+{
|
||||
+ size_t maxshells = 16, nshells = 0;
|
||||
+ size_t linesize = 0;
|
||||
+ char *line = NULL;
|
||||
+ FILE *fp;
|
||||
+ debug_decl(read_shells, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ if ((fp = fopen("/etc/shells", "r")) == NULL)
|
||||
+ goto bad;
|
||||
+
|
||||
+ free(allowed_shells);
|
||||
+ allowed_shells = reallocarray(NULL, maxshells, sizeof(char *));
|
||||
+ if (allowed_shells == NULL)
|
||||
+ goto bad;
|
||||
+
|
||||
+ while (sudo_parseln(&line, &linesize, NULL, fp, PARSELN_CONT_IGN) != -1) {
|
||||
+ if (nshells + 1 >= maxshells) {
|
||||
+ char **new_shells;
|
||||
+
|
||||
+ new_shells = reallocarray(NULL, maxshells + 16, sizeof(char *));
|
||||
+ if (new_shells == NULL)
|
||||
+ goto bad;
|
||||
+ allowed_shells = new_shells;
|
||||
+ maxshells += 16;
|
||||
+ }
|
||||
+ if ((allowed_shells[nshells] = strdup(line)) == NULL)
|
||||
+ goto bad;
|
||||
+ nshells++;
|
||||
+ }
|
||||
+ allowed_shells[nshells] = NULL;
|
||||
+
|
||||
+ free(line);
|
||||
+ fclose(fp);
|
||||
+ debug_return_ptr(allowed_shells);
|
||||
+bad:
|
||||
+ free(line);
|
||||
+ if (fp != NULL)
|
||||
+ fclose(fp);
|
||||
+ while (nshells != 0)
|
||||
+ free(allowed_shells[--nshells]);
|
||||
+ free(allowed_shells);
|
||||
+ allowed_shells = NULL;
|
||||
+ debug_return_ptr(default_shells);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sudo_setusershell(void)
|
||||
+{
|
||||
+ debug_decl(setusershell, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ current_shell = read_shells();
|
||||
+
|
||||
+ debug_return;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sudo_endusershell(void)
|
||||
+{
|
||||
+ debug_decl(endusershell, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ if (allowed_shells != NULL) {
|
||||
+ char **shell;
|
||||
+
|
||||
+ for (shell = allowed_shells; *shell != NULL; shell++)
|
||||
+ free(*shell);
|
||||
+ free(allowed_shells);
|
||||
+ allowed_shells = NULL;
|
||||
+ }
|
||||
+ current_shell = NULL;
|
||||
+
|
||||
+ debug_return;
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+sudo_getusershell(void)
|
||||
+{
|
||||
+ debug_decl(getusershell, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ if (current_shell == NULL)
|
||||
+ current_shell = read_shells();
|
||||
+
|
||||
+ debug_return_str(*current_shell++);
|
||||
+}
|
||||
diff -up ./lib/util/Makefile.in.CVE-2019-19234 ./lib/util/Makefile.in
|
||||
--- ./lib/util/Makefile.in.CVE-2019-19234 2019-10-28 13:28:53.000000000 +0100
|
||||
+++ ./lib/util/Makefile.in 2020-01-14 15:53:40.511988098 +0100
|
||||
@@ -678,6 +678,18 @@ gettime.i: $(srcdir)/gettime.c $(incdir)
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
gettime.plog: gettime.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gettime.c --i-file $< --output-file $@
|
||||
+getusershell.lo: $(srcdir)/getusershell.c $(incdir)/compat/stdbool.h \
|
||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
|
||||
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getusershell.c
|
||||
+getusershell.i: $(srcdir)/getusershell.c $(incdir)/compat/stdbool.h \
|
||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
|
||||
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
+ $(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
+getusershell.plog: getusershell.i
|
||||
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getusershell.c --i-file $< --output-file $@
|
||||
gidlist.lo: $(srcdir)/gidlist.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||
diff -up ./MANIFEST.CVE-2019-19234 ./MANIFEST
|
||||
--- ./MANIFEST.CVE-2019-19234 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./MANIFEST 2020-01-14 15:53:40.506988064 +0100
|
||||
@@ -103,6 +103,7 @@ lib/util/getgrouplist.c
|
||||
lib/util/gethostname.c
|
||||
lib/util/getopt_long.c
|
||||
lib/util/gettime.c
|
||||
+lib/util/getusershell.c
|
||||
lib/util/gidlist.c
|
||||
lib/util/glob.c
|
||||
lib/util/inet_ntop.c
|
||||
diff -up ./mkdep.pl.CVE-2019-19234 ./mkdep.pl
|
||||
--- ./mkdep.pl.CVE-2019-19234 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./mkdep.pl 2020-01-14 15:53:40.511988098 +0100
|
||||
@@ -116,7 +116,7 @@ sub mkdep {
|
||||
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
||||
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
||||
$makefile =~ s:\@DIGEST\@:digest.lo digest_openssl.lo digest_gcrypt.lo:;
|
||||
- $makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getdelim.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo str2sig.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo utimens.lo vsyslog.lo pipe2.lo:;
|
||||
+ $makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getdelim.lo getopt_long.lo getusershell.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo str2sig.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo utimens.lo vsyslog.lo pipe2.lo:;
|
||||
|
||||
# Parse OBJS lines
|
||||
my %objs;
|
||||
diff -up ./plugins/sudoers/check.c.CVE-2019-19234 ./plugins/sudoers/check.c
|
||||
--- ./plugins/sudoers/check.c.CVE-2019-19234 2019-10-28 13:27:45.000000000 +0100
|
||||
+++ ./plugins/sudoers/check.c 2020-01-14 15:53:40.511988098 +0100
|
||||
@@ -333,3 +333,28 @@ get_authpw(int mode)
|
||||
|
||||
debug_return_ptr(pw);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Returns true if the specified shell is allowed by /etc/shells, else false.
|
||||
+ */
|
||||
+bool
|
||||
+check_user_shell(const struct passwd *pw)
|
||||
+{
|
||||
+ const char *shell;
|
||||
+ debug_decl(check_user_shell, SUDOERS_DEBUG_AUTH)
|
||||
+
|
||||
+ if (!def_runas_check_shell)
|
||||
+ debug_return_bool(true);
|
||||
+
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "%s: checking /etc/shells for %s", __func__, pw->pw_shell);
|
||||
+
|
||||
+ setusershell();
|
||||
+ while ((shell = getusershell()) != NULL) {
|
||||
+ if (strcmp(shell, pw->pw_shell) == 0)
|
||||
+ debug_return_bool(true);
|
||||
+ }
|
||||
+ endusershell();
|
||||
+
|
||||
+ debug_return_bool(false);
|
||||
+}
|
||||
diff -up ./plugins/sudoers/def_data.c.CVE-2019-19234 ./plugins/sudoers/def_data.c
|
||||
--- ./plugins/sudoers/def_data.c.CVE-2019-19234 2020-01-14 15:53:40.504988050 +0100
|
||||
+++ ./plugins/sudoers/def_data.c 2020-01-14 15:53:40.511988098 +0100
|
||||
@@ -518,6 +518,10 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Allow the use of unknown runas user and/or group ID"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "runas_check_shell", T_FLAG,
|
||||
+ N_("Only permit running commands as a user with a valid shell"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up ./plugins/sudoers/def_data.h.CVE-2019-19234 ./plugins/sudoers/def_data.h
|
||||
--- ./plugins/sudoers/def_data.h.CVE-2019-19234 2020-01-14 15:53:40.512988105 +0100
|
||||
+++ ./plugins/sudoers/def_data.h 2020-01-14 15:58:06.927808982 +0100
|
||||
@@ -238,6 +238,8 @@
|
||||
#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag)
|
||||
#define I_RUNAS_ALLOW_UNKNOWN_ID 119
|
||||
#define def_runas_allow_unknown_id (sudo_defs_table[I_RUNAS_ALLOW_UNKNOWN_ID].sd_un.flag)
|
||||
+#define I_RUNAS_CHECK_SHELL 120
|
||||
+#define def_runas_check_shell (sudo_defs_table[I_RUNAS_CHECK_SHELL].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up ./plugins/sudoers/def_data.in.CVE-2019-19234 ./plugins/sudoers/def_data.in
|
||||
--- ./plugins/sudoers/def_data.in.CVE-2019-19234 2020-01-14 15:53:40.505988057 +0100
|
||||
+++ ./plugins/sudoers/def_data.in 2020-01-14 15:53:40.512988105 +0100
|
||||
@@ -375,3 +375,7 @@ cmnd_no_wait
|
||||
runas_allow_unknown_id
|
||||
T_FLAG
|
||||
"Allow the use of unknown runas user and/or group ID"
|
||||
+runas_check_shell
|
||||
+ T_FLAG
|
||||
+ "Only permit running commands as a user with a valid shell"
|
||||
+
|
||||
diff -up ./plugins/sudoers/sudoers.c.CVE-2019-19234 ./plugins/sudoers/sudoers.c
|
||||
--- ./plugins/sudoers/sudoers.c.CVE-2019-19234 2020-01-14 15:53:40.505988057 +0100
|
||||
+++ ./plugins/sudoers/sudoers.c 2020-01-14 15:53:40.512988105 +0100
|
||||
@@ -273,7 +273,7 @@ sudoers_policy_main(int argc, char * con
|
||||
/* Not an audit event. */
|
||||
sudo_warnx(U_("sudoers specifies that root is not allowed to sudo"));
|
||||
goto bad;
|
||||
- }
|
||||
+ }
|
||||
|
||||
if (!set_perms(PERM_INITIAL))
|
||||
goto bad;
|
||||
@@ -412,6 +412,13 @@ sudoers_policy_main(int argc, char * con
|
||||
goto bad;
|
||||
}
|
||||
|
||||
+ /* Check runas user's shell. */
|
||||
+ if (!check_user_shell(runas_pw)) {
|
||||
+ log_warningx(SLOG_RAW_MSG, N_("invalid shell for user %s: %s"),
|
||||
+ runas_pw->pw_name, runas_pw->pw_shell);
|
||||
+ goto bad;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* We don't reset the environment for sudoedit or if the user
|
||||
* specified the -E command line flag and they have setenv privs.
|
||||
diff -up ./plugins/sudoers/sudoers.h.CVE-2019-19234 ./plugins/sudoers/sudoers.h
|
||||
--- ./plugins/sudoers/sudoers.h.CVE-2019-19234 2020-01-14 15:53:40.502988036 +0100
|
||||
+++ ./plugins/sudoers/sudoers.h 2020-01-14 15:53:40.512988105 +0100
|
||||
@@ -264,6 +264,7 @@ int find_path(const char *infile, char *
|
||||
|
||||
/* check.c */
|
||||
int check_user(int validate, int mode);
|
||||
+bool check_user_shell(const struct passwd *pw);
|
||||
bool user_is_exempt(void);
|
||||
|
||||
/* prompt.c */
|
|
@ -1,154 +0,0 @@
|
|||
From 4b6de608c25a6ffbdb507be958e12f814b43077c Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Wed, 4 Dec 2019 12:38:22 -0700
|
||||
Subject: [PATCH] Only update the time stamp entry after the approval function
|
||||
has succeeded. Bug #910
|
||||
|
||||
---
|
||||
plugins/sudoers/check.c | 59 +++++++++++++++++++----------------------
|
||||
1 file changed, 27 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c
|
||||
index db8e05161..ea1d89085 100644
|
||||
--- a/plugins/sudoers/check.c
|
||||
+++ b/plugins/sudoers/check.c
|
||||
@@ -51,6 +51,7 @@ static bool display_lecture(int);
|
||||
static struct passwd *get_authpw(int);
|
||||
|
||||
struct getpass_closure {
|
||||
+ int tstat;
|
||||
void *cookie;
|
||||
struct passwd *auth_pw;
|
||||
};
|
||||
@@ -89,27 +90,20 @@ getpass_resume(int signo, void *vclosure)
|
||||
* or -1 on fatal error.
|
||||
*/
|
||||
static int
|
||||
-check_user_interactive(int validated, int mode, struct passwd *auth_pw)
|
||||
+check_user_interactive(int validated, int mode, struct getpass_closure *closure)
|
||||
{
|
||||
struct sudo_conv_callback cb, *callback = NULL;
|
||||
- struct getpass_closure closure;
|
||||
- int status = TS_ERROR;
|
||||
int ret = -1;
|
||||
char *prompt;
|
||||
bool lectured;
|
||||
debug_decl(check_user_interactive, SUDOERS_DEBUG_AUTH)
|
||||
|
||||
- /* Setup closure for getpass_{suspend,resume} */
|
||||
- closure.auth_pw = auth_pw;
|
||||
- closure.cookie = NULL;
|
||||
- sudo_pw_addref(closure.auth_pw);
|
||||
-
|
||||
/* Open, lock and read time stamp file if we are using it. */
|
||||
if (!ISSET(mode, MODE_IGNORE_TICKET)) {
|
||||
/* Open time stamp file and check its status. */
|
||||
- closure.cookie = timestamp_open(user_name, user_sid);
|
||||
- if (timestamp_lock(closure.cookie, closure.auth_pw))
|
||||
- status = timestamp_status(closure.cookie, closure.auth_pw);
|
||||
+ closure->cookie = timestamp_open(user_name, user_sid);
|
||||
+ if (timestamp_lock(closure->cookie, closure->auth_pw))
|
||||
+ closure->tstat = timestamp_status(closure->cookie, closure->auth_pw);
|
||||
|
||||
/* Construct callback for getpass function. */
|
||||
memset(&cb, 0, sizeof(cb));
|
||||
@@ -120,7 +114,7 @@ check_user_interactive(int validated, int mode, struct passwd *auth_pw)
|
||||
callback = &cb;
|
||||
}
|
||||
|
||||
- switch (status) {
|
||||
+ switch (closure->tstat) {
|
||||
case TS_FATAL:
|
||||
/* Fatal error (usually setuid failure), unsafe to proceed. */
|
||||
goto done;
|
||||
@@ -144,32 +138,22 @@ check_user_interactive(int validated, int mode, struct passwd *auth_pw)
|
||||
}
|
||||
|
||||
/* XXX - should not lecture if askpass helper is being used. */
|
||||
- lectured = display_lecture(status);
|
||||
+ lectured = display_lecture(closure->tstat);
|
||||
|
||||
/* Expand any escapes in the prompt. */
|
||||
prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt,
|
||||
- closure.auth_pw->pw_name);
|
||||
+ closure->auth_pw->pw_name);
|
||||
if (prompt == NULL)
|
||||
goto done;
|
||||
|
||||
- ret = verify_user(closure.auth_pw, prompt, validated, callback);
|
||||
+ ret = verify_user(closure->auth_pw, prompt, validated, callback);
|
||||
if (ret == true && lectured)
|
||||
(void)set_lectured(); /* lecture error not fatal */
|
||||
free(prompt);
|
||||
break;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Only update time stamp if user was validated.
|
||||
- * Failure to update the time stamp is not a fatal error.
|
||||
- */
|
||||
- if (ret == true && ISSET(validated, VALIDATE_SUCCESS) && status != TS_ERROR)
|
||||
- (void)timestamp_update(closure.cookie, closure.auth_pw);
|
||||
done:
|
||||
- if (closure.cookie != NULL)
|
||||
- timestamp_close(closure.cookie);
|
||||
- sudo_pw_delref(closure.auth_pw);
|
||||
-
|
||||
debug_return_int(ret);
|
||||
}
|
||||
|
||||
@@ -180,7 +164,7 @@ done:
|
||||
int
|
||||
check_user(int validated, int mode)
|
||||
{
|
||||
- struct passwd *auth_pw;
|
||||
+ struct getpass_closure closure = { TS_ERROR };
|
||||
int ret = -1;
|
||||
bool exempt = false;
|
||||
debug_decl(check_user, SUDOERS_DEBUG_AUTH)
|
||||
@@ -189,9 +173,9 @@ check_user(int validated, int mode)
|
||||
* Init authentication system regardless of whether we need a password.
|
||||
* Required for proper PAM session support.
|
||||
*/
|
||||
- if ((auth_pw = get_authpw(mode)) == NULL)
|
||||
+ if ((closure.auth_pw = get_authpw(mode)) == NULL)
|
||||
goto done;
|
||||
- if (sudo_auth_init(auth_pw) == -1)
|
||||
+ if (sudo_auth_init(closure.auth_pw) == -1)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
@@ -222,15 +206,26 @@ check_user(int validated, int mode)
|
||||
}
|
||||
}
|
||||
|
||||
- ret = check_user_interactive(validated, mode, auth_pw);
|
||||
+ ret = check_user_interactive(validated, mode, &closure);
|
||||
|
||||
done:
|
||||
if (ret == true) {
|
||||
/* The approval function may disallow a user post-authentication. */
|
||||
- ret = sudo_auth_approval(auth_pw, validated, exempt);
|
||||
+ ret = sudo_auth_approval(closure.auth_pw, validated, exempt);
|
||||
+
|
||||
+ /*
|
||||
+ * Only update time stamp if user validated and was approved.
|
||||
+ * Failure to update the time stamp is not a fatal error.
|
||||
+ */
|
||||
+ if (ret == true && closure.tstat != TS_ERROR) {
|
||||
+ if (ISSET(validated, VALIDATE_SUCCESS))
|
||||
+ (void)timestamp_update(closure.cookie, closure.auth_pw);
|
||||
+ }
|
||||
}
|
||||
- sudo_auth_cleanup(auth_pw);
|
||||
- sudo_pw_delref(auth_pw);
|
||||
+ timestamp_close(closure.cookie);
|
||||
+ sudo_auth_cleanup(closure.auth_pw);
|
||||
+ if (closure.auth_pw != NULL)
|
||||
+ sudo_pw_delref(closure.auth_pw);
|
||||
|
||||
debug_return_int(ret);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
From 5472b1751645f750e42a0ba6daac667983b1a56c Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@sudo.ws>
|
||||
Date: Fri, 24 Jan 2020 11:13:55 -0700
|
||||
Subject: [PATCH] Fix crash in sudo 1.8.30 when suspending sudo at the password
|
||||
prompt. The closure pointer in sudo_conv_callback was being filled in with a
|
||||
struct getpass_closure ** instead of a struct getpass_closure *. The bug was
|
||||
introduced in the fix for Bug #910; previously the closure variable was a
|
||||
struct getpass_closure, not a pointer. Fix from Michael Norton; Bug #914.
|
||||
|
||||
---
|
||||
plugins/sudoers/check.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c
|
||||
index 72e87eef6..9b03c7a05 100644
|
||||
--- a/plugins/sudoers/check.c
|
||||
+++ b/plugins/sudoers/check.c
|
||||
@@ -108,7 +108,7 @@ check_user_interactive(int validated, int mode, struct getpass_closure *closure)
|
||||
/* Construct callback for getpass function. */
|
||||
memset(&cb, 0, sizeof(cb));
|
||||
cb.version = SUDO_CONV_CALLBACK_VERSION;
|
||||
- cb.closure = &closure;
|
||||
+ cb.closure = closure;
|
||||
cb.on_suspend = getpass_suspend;
|
||||
cb.on_resume = getpass_resume;
|
||||
callback = &cb;
|
||||
--
|
||||
2.25.1
|
||||
|
|
@ -1,206 +0,0 @@
|
|||
diff -up ./plugins/sudoers/policy.c.heap-buffer ./plugins/sudoers/policy.c
|
||||
--- ./plugins/sudoers/policy.c.heap-buffer 2019-10-28 13:28:52.000000000 +0100
|
||||
+++ ./plugins/sudoers/policy.c 2021-01-20 11:38:06.481807015 +0100
|
||||
@@ -100,10 +100,11 @@ parse_bool(const char *line, int varlen,
|
||||
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;
|
||||
int flags = 0;
|
||||
debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN)
|
||||
|
||||
@@ -332,6 +333,12 @@ sudoers_policy_deserialize_info(void *v,
|
||||
#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_gid = (gid_t)-1;
|
||||
user_sid = (pid_t)-1;
|
||||
user_uid = (gid_t)-1;
|
||||
diff -up ./plugins/sudoers/sudoers.c.heap-buffer ./plugins/sudoers/sudoers.c
|
||||
--- ./plugins/sudoers/sudoers.c.heap-buffer 2021-01-20 11:34:57.523317977 +0100
|
||||
+++ ./plugins/sudoers/sudoers.c 2021-01-20 12:08:01.331553520 +0100
|
||||
@@ -451,7 +451,7 @@ sudoers_policy_main(int argc, char * con
|
||||
|
||||
/* 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;
|
||||
|
||||
@@ -834,8 +834,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))
|
||||
@@ -873,7 +873,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
|
||||
@@ -881,10 +882,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 -up ./plugins/sudoers/timestamp.c.heap-buffer ./plugins/sudoers/timestamp.c
|
||||
--- ./plugins/sudoers/timestamp.c.heap-buffer 2021-01-20 12:11:28.218774128 +0100
|
||||
+++ ./plugins/sudoers/timestamp.c 2021-01-20 12:20:41.772324808 +0100
|
||||
@@ -652,8 +652,8 @@ timestamp_lock(void *vcookie, struct pas
|
||||
} 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 -up ./src/parse_args.c.heap-buffer ./src/parse_args.c
|
||||
--- ./src/parse_args.c.heap-buffer 2021-01-20 11:35:18.231043445 +0100
|
||||
+++ ./src/parse_args.c 2021-01-20 12:26:31.290591673 +0100
|
||||
@@ -124,7 +124,10 @@ 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 DEFAULT_VALID_FLAGS (MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_PRESERVE_GROUPS|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
|
||||
@@ -269,6 +272,7 @@ parse_args(int argc, char **argv, int *n
|
||||
progname = "sudoedit";
|
||||
mode = MODE_EDIT;
|
||||
sudo_settings[ARG_SUDOEDIT].value = "true";
|
||||
+ valid_flags = EDIT_VALID_FLAGS;
|
||||
}
|
||||
|
||||
/* Load local IP addresses and masks. */
|
||||
@@ -360,7 +364,7 @@ parse_args(int argc, char **argv, int *n
|
||||
usage_excl(1);
|
||||
mode = MODE_EDIT;
|
||||
sudo_settings[ARG_SUDOEDIT].value = "true";
|
||||
- valid_flags = MODE_NONINTERACTIVE;
|
||||
+ valid_flags = EDIT_VALID_FLAGS;
|
||||
break;
|
||||
case 'g':
|
||||
assert(optarg != NULL);
|
||||
@@ -371,6 +375,7 @@ parse_args(int argc, char **argv, int *n
|
||||
break;
|
||||
case 'H':
|
||||
sudo_settings[ARG_SET_HOME].value = "true";
|
||||
+ SET(flags, MODE_RESET_HOME);
|
||||
break;
|
||||
case 'h':
|
||||
if (optarg == NULL) {
|
||||
@@ -421,7 +426,7 @@ parse_args(int argc, char **argv, int *n
|
||||
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);
|
||||
@@ -429,6 +434,7 @@ parse_args(int argc, char **argv, int *n
|
||||
break;
|
||||
case 'P':
|
||||
sudo_settings[ARG_PRESERVE_GROUPS].value = "true";
|
||||
+ SET(flags, MODE_PRESERVE_GROUPS);
|
||||
break;
|
||||
case 'p':
|
||||
/* An empty prompt is allowed. */
|
||||
@@ -478,7 +484,7 @@ parse_args(int argc, char **argv, int *n
|
||||
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)
|
||||
@@ -505,7 +511,7 @@ parse_args(int argc, char **argv, int *n
|
||||
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;
|
||||
@@ -568,23 +574,24 @@ parse_args(int argc, char **argv, int *n
|
||||
/*
|
||||
* For shell mode we need to rewrite argv
|
||||
*/
|
||||
- if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {
|
||||
+ if (ISSET(flags, MODE_SHELL|MODE_LOGIN_SHELL) && ISSET(mode, MODE_RUN)) {
|
||||
char **av, *cmnd = NULL;
|
||||
int ac = 1;
|
||||
|
||||
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 != '$')
|
|
@ -1,90 +0,0 @@
|
|||
From 06b46ae226fecd4188af372ac0ccd7aa582e21c8 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Wed, 17 Aug 2016 10:12:11 +0200
|
||||
Subject: [PATCH] Sudo logs username root instead of realuser
|
||||
|
||||
RHEL7 sudo logs username root instead of realuser in /var/log/secure
|
||||
|
||||
Rebased from:
|
||||
Patch50: sudo-1.8.6p7-logsudouser.patch
|
||||
|
||||
Resolves:
|
||||
rhbz#1312486
|
||||
---
|
||||
plugins/sudoers/logging.c | 14 +++++++-------
|
||||
plugins/sudoers/sudoers.h | 1 +
|
||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c
|
||||
index 45cae67..74b2220 100644
|
||||
--- a/plugins/sudoers/logging.c
|
||||
+++ b/plugins/sudoers/logging.c
|
||||
@@ -104,7 +104,7 @@ do_syslog(int pri, char *msg)
|
||||
* Log the full line, breaking into multiple syslog(3) calls if necessary
|
||||
*/
|
||||
fmt = _("%8s : %s");
|
||||
- maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
|
||||
+ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(sudo_user_name));
|
||||
for (p = msg; *p != '\0'; ) {
|
||||
len = strlen(p);
|
||||
if (len > maxlen) {
|
||||
@@ -120,7 +120,7 @@ do_syslog(int pri, char *msg)
|
||||
save = *tmp;
|
||||
*tmp = '\0';
|
||||
|
||||
- mysyslog(pri, fmt, user_name, p);
|
||||
+ mysyslog(pri, fmt, sudo_user_name, p);
|
||||
|
||||
*tmp = save; /* restore saved character */
|
||||
|
||||
@@ -128,11 +128,11 @@ do_syslog(int pri, char *msg)
|
||||
for (p = tmp; *p == ' '; p++)
|
||||
continue;
|
||||
} else {
|
||||
- mysyslog(pri, fmt, user_name, p);
|
||||
+ mysyslog(pri, fmt, sudo_user_name, p);
|
||||
p += len;
|
||||
}
|
||||
fmt = _("%8s : (command continued) %s");
|
||||
- maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
|
||||
+ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(sudo_user_name));
|
||||
}
|
||||
|
||||
sudoers_setlocale(oldlocale, NULL);
|
||||
@@ -179,10 +179,10 @@ do_logfile(const char *msg)
|
||||
timestr = "invalid date";
|
||||
if (def_log_host) {
|
||||
len = asprintf(&full_line, "%s : %s : HOST=%s : %s",
|
||||
- timestr, user_name, user_srunhost, msg);
|
||||
+ timestr, sudo_user_name, user_srunhost, msg);
|
||||
} else {
|
||||
len = asprintf(&full_line, "%s : %s : %s",
|
||||
- timestr, user_name, msg);
|
||||
+ timestr, sudo_user_name, msg);
|
||||
}
|
||||
if (len == -1) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
@@ -746,7 +746,7 @@ send_mail(const char *fmt, ...)
|
||||
|
||||
if ((timestr = get_timestr(time(NULL), def_log_year)) == NULL)
|
||||
timestr = "invalid date";
|
||||
- (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, timestr, user_name);
|
||||
+ (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, timestr, sudo_user_name);
|
||||
va_start(ap, fmt);
|
||||
(void) vfprintf(mail, fmt, ap);
|
||||
va_end(ap);
|
||||
diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
|
||||
index cfd5abb..c69a043 100644
|
||||
--- a/plugins/sudoers/sudoers.h
|
||||
+++ b/plugins/sudoers/sudoers.h
|
||||
@@ -180,6 +180,7 @@ struct sudo_user {
|
||||
/*
|
||||
* Shortcuts for sudo_user contents.
|
||||
*/
|
||||
+#define sudo_user_name (sudo_user.pw->pw_name)
|
||||
#define user_name (sudo_user.name)
|
||||
#define user_uid (sudo_user.uid)
|
||||
#define user_gid (sudo_user.gid)
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
diff -up ./plugins/sudoers/editor.c.other ./plugins/sudoers/editor.c
|
||||
--- ./plugins/sudoers/editor.c.other 2023-01-16 17:37:04.659967300 +0100
|
||||
+++ ./plugins/sudoers/editor.c 2023-01-16 17:40:35.944400376 +0100
|
||||
@@ -39,6 +39,82 @@
|
||||
#include "sudoers.h"
|
||||
|
||||
/*
|
||||
+ * Non-destructive word-split that handles single and double quotes and
|
||||
+ * escaped white space. Quotes are only recognized at the start of a word.
|
||||
+ * They are treated as normal characters inside a word.
|
||||
+ */
|
||||
+static const char *
|
||||
+wordsplit(const char *str, const char *endstr, const char **last)
|
||||
+{
|
||||
+ const char *cp;
|
||||
+ debug_decl(wordsplit, SUDO_DEBUG_UTIL);
|
||||
+
|
||||
+ /* If no str specified, use last ptr (if any). */
|
||||
+ if (str == NULL) {
|
||||
+ str = *last;
|
||||
+ /* Consume end quote if present. */
|
||||
+ if (*str == '"' || *str == '\'')
|
||||
+ str++;
|
||||
+ }
|
||||
+
|
||||
+ /* Skip leading white space characters. */
|
||||
+ while (str < endstr && (*str == ' ' || *str == '\t'))
|
||||
+ str++;
|
||||
+
|
||||
+ /* Empty string? */
|
||||
+ if (str >= endstr) {
|
||||
+ *last = endstr;
|
||||
+ debug_return_ptr(NULL);
|
||||
+ }
|
||||
+
|
||||
+ /* If word is quoted, skip to end quote and return. */
|
||||
+ if (*str == '"' || *str == '\'') {
|
||||
+ const char *endquote = memchr(str + 1, *str, endstr - str);
|
||||
+ if (endquote != NULL) {
|
||||
+ *last = endquote;
|
||||
+ debug_return_const_ptr(str + 1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Scan str until we encounter white space. */
|
||||
+ for (cp = str; cp < endstr; cp++) {
|
||||
+ if (*cp == '\\') {
|
||||
+ /* quoted char, do not interpret */
|
||||
+ cp++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (*cp == ' ' || *cp == '\t') {
|
||||
+ /* end of word */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ *last = cp;
|
||||
+ debug_return_const_ptr(str);
|
||||
+}
|
||||
+
|
||||
+/* Copy len chars from string, collapsing chars escaped with a backslash. */
|
||||
+static char *
|
||||
+copy_arg(const char *src, size_t len)
|
||||
+{
|
||||
+ const char *src_end = src + len;
|
||||
+ char *copy, *dst;
|
||||
+ debug_decl(copy_arg, SUDOERS_DEBUG_UTIL);
|
||||
+
|
||||
+ if ((copy = malloc(len + 1)) != NULL) {
|
||||
+ for (dst = copy; src < src_end; ) {
|
||||
+ if (*src == '\\') {
|
||||
+ src++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ *dst++ = *src++;
|
||||
+ }
|
||||
+ *dst = '\0';
|
||||
+ }
|
||||
+
|
||||
+ debug_return_ptr(copy);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Search for the specified editor in the user's PATH, checking
|
||||
* the result against allowlist if non-NULL. An argument vector
|
||||
* suitable for execve() is allocated and stored in argv_out.
|
||||
@@ -52,7 +128,7 @@ static char *
|
||||
resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
|
||||
int *argc_out, char ***argv_out, char * const *allowlist)
|
||||
{
|
||||
- char **nargv, *editor, *editor_path = NULL;
|
||||
+ char **nargv = NULL, *editor = NULL, *editor_path = NULL;
|
||||
const char *cp, *ep, *tmp;
|
||||
const char *edend = ed + edlen;
|
||||
struct stat user_editor_sb;
|
||||
@@ -64,14 +140,12 @@ resolve_editor(const char *ed, size_t ed
|
||||
* The EDITOR and VISUAL environment variables may contain command
|
||||
* line args so look for those and alloc space for them too.
|
||||
*/
|
||||
- cp = sudo_strsplit(ed, edend, " \t", &ep);
|
||||
+ cp = wordsplit(ed, edend, &ep);
|
||||
if (cp == NULL)
|
||||
debug_return_str(NULL);
|
||||
- editor = strndup(cp, (size_t)(ep - cp));
|
||||
- if (editor == NULL) {
|
||||
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
- debug_return_str(NULL);
|
||||
- }
|
||||
+ editor = copy_arg(cp, ep - cp);
|
||||
+ if (editor == NULL)
|
||||
+ goto oom;
|
||||
|
||||
/* If we can't find the editor in the user's PATH, give up. */
|
||||
if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, allowlist) != FOUND) {
|
||||
@@ -81,30 +155,22 @@ resolve_editor(const char *ed, size_t ed
|
||||
}
|
||||
|
||||
/* Count rest of arguments and allocate editor argv. */
|
||||
- for (nargc = 1, tmp = ep; sudo_strsplit(NULL, edend, " \t", &tmp) != NULL; )
|
||||
+ for (nargc = 1, tmp = ep; wordsplit(NULL, edend, &tmp) != NULL; )
|
||||
nargc++;
|
||||
if (nfiles != 0)
|
||||
nargc += nfiles + 1;
|
||||
nargv = reallocarray(NULL, nargc + 1, sizeof(char *));
|
||||
- if (nargv == NULL) {
|
||||
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
- free(editor);
|
||||
- free(editor_path);
|
||||
- debug_return_str(NULL);
|
||||
- }
|
||||
+ if (nargv == NULL)
|
||||
+ goto oom;
|
||||
|
||||
/* Fill in editor argv (assumes files[] is NULL-terminated). */
|
||||
nargv[0] = editor;
|
||||
- for (nargc = 1; (cp = sudo_strsplit(NULL, edend, " \t", &ep)) != NULL; nargc++) {
|
||||
- nargv[nargc] = strndup(cp, (size_t)(ep - cp));
|
||||
- if (nargv[nargc] == NULL) {
|
||||
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
- free(editor_path);
|
||||
- while (nargc--)
|
||||
- free(nargv[nargc]);
|
||||
- free(nargv);
|
||||
- debug_return_str(NULL);
|
||||
- }
|
||||
+ editor = NULL;
|
||||
+ for (nargc = 1; (cp = wordsplit(NULL, edend, &ep)) != NULL; nargc++) {
|
||||
+ /* Copy string, collapsing chars escaped with a backslash. */
|
||||
+ nargv[nargc] = copy_arg(cp, ep - cp);
|
||||
+ if (nargv[nargc] == NULL)
|
||||
+ goto oom;
|
||||
}
|
||||
if (nfiles != 0) {
|
||||
nargv[nargc++] = "--";
|
||||
@@ -116,6 +182,16 @@ resolve_editor(const char *ed, size_t ed
|
||||
*argc_out = nargc;
|
||||
*argv_out = nargv;
|
||||
debug_return_str(editor_path);
|
||||
+oom:
|
||||
+ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
+ free(editor);
|
||||
+ free(editor_path);
|
||||
+ if (nargv != NULL) {
|
||||
+ while (nargc--)
|
||||
+ free(nargv[nargc]);
|
||||
+ free(nargv);
|
||||
+ }
|
||||
+ debug_return_str(NULL);
|
||||
}
|
||||
|
||||
/*
|
|
@ -1,57 +0,0 @@
|
|||
diff -up ./plugins/sudoers/editor.c.whitelist ./plugins/sudoers/editor.c
|
||||
--- ./plugins/sudoers/editor.c.whitelist 2023-01-16 17:31:58.108335076 +0100
|
||||
+++ ./plugins/sudoers/editor.c 2023-01-16 17:33:37.375547672 +0100
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
/*
|
||||
* Search for the specified editor in the user's PATH, checking
|
||||
- * the result against whitelist if non-NULL. An argument vector
|
||||
+ * the result against allowlist if non-NULL. An argument vector
|
||||
* suitable for execve() is allocated and stored in argv_out.
|
||||
* If nfiles is non-zero, files[] is added to the end of argv_out.
|
||||
*
|
||||
@@ -50,7 +50,7 @@
|
||||
*/
|
||||
static char *
|
||||
resolve_editor(const char *ed, size_t edlen, int nfiles, char **files,
|
||||
- int *argc_out, char ***argv_out, char * const *whitelist)
|
||||
+ int *argc_out, char ***argv_out, char * const *allowlist)
|
||||
{
|
||||
char **nargv, *editor, *editor_path = NULL;
|
||||
const char *cp, *ep, *tmp;
|
||||
@@ -74,7 +74,7 @@ resolve_editor(const char *ed, size_t ed
|
||||
}
|
||||
|
||||
/* If we can't find the editor in the user's PATH, give up. */
|
||||
- if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, whitelist) != FOUND) {
|
||||
+ if (find_path(editor, &editor_path, &user_editor_sb, getenv("PATH"), 0, allowlist) != FOUND) {
|
||||
free(editor);
|
||||
errno = ENOENT;
|
||||
debug_return_str(NULL);
|
||||
@@ -130,7 +130,7 @@ resolve_editor(const char *ed, size_t ed
|
||||
*/
|
||||
char *
|
||||
find_editor(int nfiles, char **files, int *argc_out, char ***argv_out,
|
||||
- char * const *whitelist, const char **env_editor, bool env_error)
|
||||
+ char * const *allowlist, const char **env_editor, bool env_error)
|
||||
{
|
||||
char *ev[3], *editor_path = NULL;
|
||||
unsigned int i;
|
||||
@@ -149,7 +149,7 @@ find_editor(int nfiles, char **files, in
|
||||
if (editor != NULL && *editor != '\0') {
|
||||
*env_editor = editor;
|
||||
editor_path = resolve_editor(editor, strlen(editor),
|
||||
- nfiles, files, argc_out, argv_out, whitelist);
|
||||
+ nfiles, files, argc_out, argv_out, allowlist);
|
||||
if (editor_path != NULL)
|
||||
break;
|
||||
if (errno != ENOENT)
|
||||
@@ -169,7 +169,7 @@ find_editor(int nfiles, char **files, in
|
||||
for (cp = sudo_strsplit(def_editor, def_editor_end, ":", &ep);
|
||||
cp != NULL; cp = sudo_strsplit(NULL, def_editor_end, ":", &ep)) {
|
||||
editor_path = resolve_editor(cp, (size_t)(ep - cp), nfiles,
|
||||
- files, argc_out, argv_out, whitelist);
|
||||
+ files, argc_out, argv_out, allowlist);
|
||||
if (editor_path != NULL)
|
||||
break;
|
||||
if (errno != ENOENT)
|
|
@ -1,19 +1,19 @@
|
|||
diff -up ./plugins/sudoers/editor.c.cve ./plugins/sudoers/editor.c
|
||||
--- ./plugins/sudoers/editor.c.cve 2023-01-16 17:52:37.074066664 +0100
|
||||
+++ ./plugins/sudoers/editor.c 2023-01-16 17:58:06.603774304 +0100
|
||||
@@ -132,7 +132,7 @@ resolve_editor(const char *ed, size_t ed
|
||||
const char *cp, *ep, *tmp;
|
||||
--- ./plugins/sudoers/editor.c.cve 2021-01-09 21:12:16.000000000 +0100
|
||||
+++ ./plugins/sudoers/editor.c 2023-01-17 13:57:05.598949058 +0100
|
||||
@@ -126,7 +126,7 @@ resolve_editor(const char *ed, size_t ed
|
||||
const char *tmp, *cp, *ep = NULL;
|
||||
const char *edend = ed + edlen;
|
||||
struct stat user_editor_sb;
|
||||
- int nargc;
|
||||
+ int nargc = 0;
|
||||
debug_decl(resolve_editor, SUDOERS_DEBUG_UTIL)
|
||||
debug_decl(resolve_editor, SUDOERS_DEBUG_UTIL);
|
||||
|
||||
/*
|
||||
@@ -149,9 +149,7 @@ resolve_editor(const char *ed, size_t ed
|
||||
|
||||
@@ -144,9 +144,7 @@ resolve_editor(const char *ed, size_t ed
|
||||