200 lines
6.2 KiB
Diff
200 lines
6.2 KiB
Diff
From 807e17ceedf2500aeca67b37f62463ee112d63c4 Mon Sep 17 00:00:00 2001
|
|
From: Todd C. Miller <Todd.Miller@sudo.ws>
|
|
Date: Mon, 09 Dec 2019 17:14:06 -0700
|
|
Subject: [PATCH] Fix CVE-2019-19234
|
|
|
|
Add a new flag "allow_unknown_runas_id" to control matching of unknown IDs.
|
|
Previous, sudo would always allow unknown user or group IDs if the
|
|
sudoers entry permitted it. This included the "ALL" alias.
|
|
With this change, the admin must explicitly enable support for unknown IDs.
|
|
|
|
---
|
|
doc/sudoers.man.in | 17 +++++++++++++++++
|
|
doc/sudoers.mdoc.in | 16 ++++++++++++++++
|
|
plugins/sudoers/def_data.c | 4 ++++
|
|
plugins/sudoers/def_data.h | 2 ++
|
|
plugins/sudoers/def_data.in | 3 +++
|
|
plugins/sudoers/defaults.c | 1 +
|
|
plugins/sudoers/sudoers.c | 28 ++++++++++++++++++++++++++--
|
|
7 files changed, 69 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in
|
|
index e2470b5..45a600f 100644
|
|
--- a/doc/sudoers.man.in
|
|
+++ b/doc/sudoers.man.in
|
|
@@ -2869,6 +2869,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.30 or higher.
|
|
+Older versions of
|
|
+\fBsudo\fR
|
|
+always allowed matching of unknown user and group IDs.
|
|
+.TP 18n
|
|
runaspw
|
|
If set,
|
|
\fBsudo\fR
|
|
diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
|
|
index 2053b5d..6a511d9 100644
|
|
--- a/doc/sudoers.mdoc.in
|
|
+++ b/doc/sudoers.mdoc.in
|
|
@@ -2698,6 +2698,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.30 or higher.
|
|
+Older versions of
|
|
+.Nm sudo
|
|
+always allowed matching of unknown user and group IDs.
|
|
.It runaspw
|
|
If set,
|
|
.Nm sudo
|
|
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
|
|
index 07e3433..97eaf79 100644
|
|
--- a/plugins/sudoers/def_data.c
|
|
+++ b/plugins/sudoers/def_data.c
|
|
@@ -494,6 +494,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
|
N_("Ignore case when matching group names"),
|
|
NULL,
|
|
}, {
|
|
+ "runas_allow_unknown_id", T_FLAG,
|
|
+ N_("Allow the use of unknown runas user and/or group ID"),
|
|
+ NULL,
|
|
+ }, {
|
|
NULL, 0, NULL
|
|
}
|
|
};
|
|
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
|
|
index 65f10c3..55878c9 100644
|
|
--- a/plugins/sudoers/def_data.h
|
|
+++ b/plugins/sudoers/def_data.h
|
|
@@ -226,6 +226,8 @@
|
|
#define def_case_insensitive_user (sudo_defs_table[I_CASE_INSENSITIVE_USER].sd_un.flag)
|
|
#define I_CASE_INSENSITIVE_GROUP 113
|
|
#define def_case_insensitive_group (sudo_defs_table[I_CASE_INSENSITIVE_GROUP].sd_un.flag)
|
|
+#define I_RUNAS_ALLOW_UNKNOWN_ID 114
|
|
+#define def_runas_allow_unknown_id (sudo_defs_table[I_RUNAS_ALLOW_UNKNOWN_ID].sd_un.flag)
|
|
|
|
enum def_tuple {
|
|
never,
|
|
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
|
|
index 99d4360..cf0eead 100644
|
|
--- a/plugins/sudoers/def_data.in
|
|
+++ b/plugins/sudoers/def_data.in
|
|
@@ -357,3 +357,6 @@ case_insensitive_user
|
|
case_insensitive_group
|
|
T_FLAG
|
|
"Ignore case when matching group names"
|
|
+runas_allow_unknown_id
|
|
+ T_FLAG
|
|
+ "Allow the use of unknown runas user and/or group ID"
|
|
diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c
|
|
index 4c8c262..d5b1d9c 100644
|
|
--- a/plugins/sudoers/defaults.c
|
|
+++ b/plugins/sudoers/defaults.c
|
|
@@ -574,6 +574,7 @@ init_defaults(void)
|
|
def_sudoedit_checkdir = true;
|
|
def_iolog_mode = S_IRUSR|S_IWUSR;
|
|
def_fdexec = digest_only;
|
|
+ def_runas_allow_unknown_id = false;
|
|
|
|
/* Syslog options need special care since they both strings and ints */
|
|
#if (LOGGING & SLOG_SYSLOG)
|
|
diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
|
|
index 1267949..b393d70 100644
|
|
--- a/plugins/sudoers/sudoers.c
|
|
+++ b/plugins/sudoers/sudoers.c
|
|
@@ -101,6 +101,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;
|
|
@@ -332,6 +334,22 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
|
}
|
|
}
|
|
|
|
+ /* 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.
|
|
*/
|
|
@@ -1124,12 +1142,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, NULL, NULL, &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) {
|
|
@@ -1155,12 +1176,15 @@ set_runasgr(const char *group, bool quiet)
|
|
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, NULL, NULL, &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.8.3.1
|
|
|