summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/sudo
diff options
context:
space:
mode:
authorChangqing Li <changqing.li@windriver.com>2019-10-22 10:47:11 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-10-23 16:30:36 +0100
commitff408c97933fa6dd6d7b10f8ecbf1b346ca5e018 (patch)
tree2f7b18b9740fb5f8c588af62dfd8b527ba61c45f /meta/recipes-extended/sudo
parent3d4645df48d731ea67888a5f2a58d958c31bd97b (diff)
downloadpoky-ff408c97933fa6dd6d7b10f8ecbf1b346ca5e018.tar.gz
sudo: fix CVE-2019-14287
In Sudo before 1.8.28, an attacker with access to a Runas ALL sudoer account can bypass certain policy blacklists and session PAM modules, and can cause incorrect logging, by invoking sudo with a crafted user ID. For example, this allows bypass of !root configuration, and USER= logging, for a "sudo -u \#$((0xffffffff))" command. (From OE-Core rev: 4e11cd561f2bdaa6807cf02ee7c9870881826308) Signed-off-by: Changqing Li <changqing.li@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended/sudo')
-rw-r--r--meta/recipes-extended/sudo/sudo/CVE-2019-14287-1.patch178
-rw-r--r--meta/recipes-extended/sudo/sudo/CVE-2019-14287-2.patch112
-rw-r--r--meta/recipes-extended/sudo/sudo_1.8.27.bb2
3 files changed, 292 insertions, 0 deletions
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2019-14287-1.patch b/meta/recipes-extended/sudo/sudo/CVE-2019-14287-1.patch
new file mode 100644
index 0000000000..2a11e3f7ec
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2019-14287-1.patch
@@ -0,0 +1,178 @@
1From f752ae5cee163253730ff7cdf293e34a91aa5520 Mon Sep 17 00:00:00 2001
2From: "Todd C. Miller" <Todd.Miller@sudo.ws>
3Date: Thu, 10 Oct 2019 10:04:13 -0600
4Subject: [PATCH] Treat an ID of -1 as invalid since that means "no change".
5 Fixes CVE-2019-14287. Found by Joe Vennix from Apple Information Security.
6
7Upstream-Status: Backport [https://github.com/sudo-project/sudo/commit/f752ae5cee163253730ff7cdf293e34a91aa5520]
8CVE: CVE-2019-14287
9
10Signed-off-by: Changqing Li <changqing.li@windriver.com>
11
12---
13 lib/util/strtoid.c | 100 ++++++++++++++++++++++++++++-------------------------
14 1 files changed, 53 insertions(+), 46 deletions(-)
15
16diff --git a/lib/util/strtoid.c b/lib/util/strtoid.c
17index 2dfce75..6b3916b 100644
18--- a/lib/util/strtoid.c
19+++ b/lib/util/strtoid.c
20@@ -49,6 +49,27 @@
21 #include "sudo_util.h"
22
23 /*
24+ * Make sure that the ID ends with a valid separator char.
25+ */
26+static bool
27+valid_separator(const char *p, const char *ep, const char *sep)
28+{
29+ bool valid = false;
30+ debug_decl(valid_separator, SUDO_DEBUG_UTIL)
31+
32+ if (ep != p) {
33+ /* check for valid separator (including '\0') */
34+ if (sep == NULL)
35+ sep = "";
36+ do {
37+ if (*ep == *sep)
38+ valid = true;
39+ } while (*sep++ != '\0');
40+ }
41+ debug_return_bool(valid);
42+}
43+
44+/*
45 * Parse a uid/gid in string form.
46 * If sep is non-NULL, it contains valid separator characters (e.g. comma, space)
47 * If endp is non-NULL it is set to the next char after the ID.
48@@ -62,36 +83,33 @@ sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr
49 char *ep;
50 id_t ret = 0;
51 long long llval;
52- bool valid = false;
53 debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
54
55 /* skip leading space so we can pick up the sign, if any */
56 while (isspace((unsigned char)*p))
57 p++;
58- if (sep == NULL)
59- sep = "";
60+
61+ /* While id_t may be 64-bit signed, uid_t and gid_t are 32-bit unsigned. */
62 errno = 0;
63 llval = strtoll(p, &ep, 10);
64- if (ep != p) {
65- /* check for valid separator (including '\0') */
66- do {
67- if (*ep == *sep)
68- valid = true;
69- } while (*sep++ != '\0');
70+ if ((errno == ERANGE && llval == LLONG_MAX) || llval > (id_t)UINT_MAX) {
71+ errno = ERANGE;
72+ if (errstr != NULL)
73+ *errstr = N_("value too large");
74+ goto done;
75 }
76- if (!valid) {
77+ if ((errno == ERANGE && llval == LLONG_MIN) || llval < INT_MIN) {
78+ errno = ERANGE;
79 if (errstr != NULL)
80- *errstr = N_("invalid value");
81- errno = EINVAL;
82+ *errstr = N_("value too small");
83 goto done;
84 }
85- if (errno == ERANGE) {
86- if (errstr != NULL) {
87- if (llval == LLONG_MAX)
88- *errstr = N_("value too large");
89- else
90- *errstr = N_("value too small");
91- }
92+
93+ /* Disallow id -1, which means "no change". */
94+ if (!valid_separator(p, ep, sep) || llval == -1 || llval == (id_t)UINT_MAX) {
95+ if (errstr != NULL)
96+ *errstr = N_("invalid value");
97+ errno = EINVAL;
98 goto done;
99 }
100 ret = (id_t)llval;
101@@ -108,30 +126,15 @@ sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr
102 {
103 char *ep;
104 id_t ret = 0;
105- bool valid = false;
106 debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
107
108 /* skip leading space so we can pick up the sign, if any */
109 while (isspace((unsigned char)*p))
110 p++;
111- if (sep == NULL)
112- sep = "";
113+
114 errno = 0;
115 if (*p == '-') {
116 long lval = strtol(p, &ep, 10);
117- if (ep != p) {
118- /* check for valid separator (including '\0') */
119- do {
120- if (*ep == *sep)
121- valid = true;
122- } while (*sep++ != '\0');
123- }
124- if (!valid) {
125- if (errstr != NULL)
126- *errstr = N_("invalid value");
127- errno = EINVAL;
128- goto done;
129- }
130 if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
131 errno = ERANGE;
132 if (errstr != NULL)
133@@ -144,28 +147,31 @@ sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr
134 *errstr = N_("value too small");
135 goto done;
136 }
137- ret = (id_t)lval;
138- } else {
139- unsigned long ulval = strtoul(p, &ep, 10);
140- if (ep != p) {
141- /* check for valid separator (including '\0') */
142- do {
143- if (*ep == *sep)
144- valid = true;
145- } while (*sep++ != '\0');
146- }
147- if (!valid) {
148+
149+ /* Disallow id -1, which means "no change". */
150+ if (!valid_separator(p, ep, sep) || lval == -1) {
151 if (errstr != NULL)
152 *errstr = N_("invalid value");
153 errno = EINVAL;
154 goto done;
155 }
156+ ret = (id_t)lval;
157+ } else {
158+ unsigned long ulval = strtoul(p, &ep, 10);
159 if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
160 errno = ERANGE;
161 if (errstr != NULL)
162 *errstr = N_("value too large");
163 goto done;
164 }
165+
166+ /* Disallow id -1, which means "no change". */
167+ if (!valid_separator(p, ep, sep) || ulval == UINT_MAX) {
168+ if (errstr != NULL)
169+ *errstr = N_("invalid value");
170+ errno = EINVAL;
171+ goto done;
172+ }
173 ret = (id_t)ulval;
174 }
175 if (errstr != NULL)
176--
1772.7.4
178
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2019-14287-2.patch b/meta/recipes-extended/sudo/sudo/CVE-2019-14287-2.patch
new file mode 100644
index 0000000000..453a8b09a4
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2019-14287-2.patch
@@ -0,0 +1,112 @@
1From 396bc57feff3e360007634f62448b64e0626390c Mon Sep 17 00:00:00 2001
2From: "Todd C. Miller" <Todd.Miller@sudo.ws>
3Date: Thu, 10 Oct 2019 10:04:13 -0600
4Subject: [PATCH] Add sudo_strtoid() tests for -1 and range errors. Also adjust
5 testsudoers/test5 which relied upon gid -1 parsing.
6
7Upstream-Status: Backport [https://github.com/sudo-project/sudo/commit/396bc57]
8CVE: CVE-2019-14287
9
10Signed-off-by: Changqing Li <changqing.li@windriver.com>
11
12---
13 lib/util/regress/atofoo/atofoo_test.c | 36 ++++++++++++++++------
14 plugins/sudoers/regress/testsudoers/test5.out.ok | 2 +-
15 plugins/sudoers/regress/testsudoers/test5.sh | 2 +-
16 3 files changed, 29 insertions(+), 11 deletions(-)
17
18diff --git a/lib/util/regress/atofoo/atofoo_test.c b/lib/util/regress/atofoo/atofoo_test.c
19index 031a7ed..fb41c1a 100644
20--- a/lib/util/regress/atofoo/atofoo_test.c
21+++ b/lib/util/regress/atofoo/atofoo_test.c
22@@ -26,6 +26,7 @@
23 #else
24 # include "compat/stdbool.h"
25 #endif
26+#include <errno.h>
27
28 #include "sudo_compat.h"
29 #include "sudo_util.h"
30@@ -80,15 +81,20 @@ static struct strtoid_data {
31 id_t id;
32 const char *sep;
33 const char *ep;
34+ int errnum;
35 } strtoid_data[] = {
36- { "0,1", 0, ",", "," },
37- { "10", 10, NULL, NULL },
38- { "-2", -2, NULL, NULL },
39+ { "0,1", 0, ",", ",", 0 },
40+ { "10", 10, NULL, NULL, 0 },
41+ { "-1", 0, NULL, NULL, EINVAL },
42+ { "4294967295", 0, NULL, NULL, EINVAL },
43+ { "4294967296", 0, NULL, NULL, ERANGE },
44+ { "-2147483649", 0, NULL, NULL, ERANGE },
45+ { "-2", -2, NULL, NULL, 0 },
46 #if SIZEOF_ID_T != SIZEOF_LONG_LONG
47- { "-2", (id_t)4294967294U, NULL, NULL },
48+ { "-2", (id_t)4294967294U, NULL, NULL, 0 },
49 #endif
50- { "4294967294", (id_t)4294967294U, NULL, NULL },
51- { NULL, 0, NULL, NULL }
52+ { "4294967294", (id_t)4294967294U, NULL, NULL, 0 },
53+ { NULL, 0, NULL, NULL, 0 }
54 };
55
56 static int
57@@ -104,11 +110,23 @@ test_strtoid(int *ntests)
58 (*ntests)++;
59 errstr = "some error";
60 value = sudo_strtoid(d->idstr, d->sep, &ep, &errstr);
61- if (errstr != NULL) {
62- if (d->id != (id_t)-1) {
63- sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
64+ if (d->errnum != 0) {
65+ if (errstr == NULL) {
66+ sudo_warnx_nodebug("FAIL: %s: missing errstr for errno %d",
67+ d->idstr, d->errnum);
68+ errors++;
69+ } else if (value != 0) {
70+ sudo_warnx_nodebug("FAIL: %s should return 0 on error",
71+ d->idstr);
72+ errors++;
73+ } else if (errno != d->errnum) {
74+ sudo_warnx_nodebug("FAIL: %s: errno mismatch, %d != %d",
75+ d->idstr, errno, d->errnum);
76 errors++;
77 }
78+ } else if (errstr != NULL) {
79+ sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
80+ errors++;
81 } else if (value != d->id) {
82 sudo_warnx_nodebug("FAIL: %s != %u", d->idstr, (unsigned int)d->id);
83 errors++;
84diff --git a/plugins/sudoers/regress/testsudoers/test5.out.ok b/plugins/sudoers/regress/testsudoers/test5.out.ok
85index 5e319c9..cecf700 100644
86--- a/plugins/sudoers/regress/testsudoers/test5.out.ok
87+++ b/plugins/sudoers/regress/testsudoers/test5.out.ok
88@@ -4,7 +4,7 @@ Parse error in sudoers near line 1.
89 Entries for user root:
90
91 Command unmatched
92-testsudoers: test5.inc should be owned by gid 4294967295
93+testsudoers: test5.inc should be owned by gid 4294967294
94 Parse error in sudoers near line 1.
95
96 Entries for user root:
97diff --git a/plugins/sudoers/regress/testsudoers/test5.sh b/plugins/sudoers/regress/testsudoers/test5.sh
98index 9e690a6..94d585c 100755
99--- a/plugins/sudoers/regress/testsudoers/test5.sh
100+++ b/plugins/sudoers/regress/testsudoers/test5.sh
101@@ -24,7 +24,7 @@ EOF
102
103 # Test group writable
104 chmod 664 $TESTFILE
105-./testsudoers -U $MYUID -G -1 root id <<EOF
106+./testsudoers -U $MYUID -G -2 root id <<EOF
107 #include $TESTFILE
108 EOF
109
110--
1112.7.4
112
diff --git a/meta/recipes-extended/sudo/sudo_1.8.27.bb b/meta/recipes-extended/sudo/sudo_1.8.27.bb
index 9d2d6bd429..8b3be55c20 100644
--- a/meta/recipes-extended/sudo/sudo_1.8.27.bb
+++ b/meta/recipes-extended/sudo/sudo_1.8.27.bb
@@ -3,6 +3,8 @@ require sudo.inc
3SRC_URI = "http://www.sudo.ws/sudo/dist/sudo-${PV}.tar.gz \ 3SRC_URI = "http://www.sudo.ws/sudo/dist/sudo-${PV}.tar.gz \
4 ${@bb.utils.contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \ 4 ${@bb.utils.contains('DISTRO_FEATURES', 'pam', '${PAM_SRC_URI}', '', d)} \
5 file://0001-Include-sys-types.h-for-id_t-definition.patch \ 5 file://0001-Include-sys-types.h-for-id_t-definition.patch \
6 file://CVE-2019-14287-1.patch \
7 file://CVE-2019-14287-2.patch \
6 " 8 "
7 9
8PAM_SRC_URI = "file://sudo.pam" 10PAM_SRC_URI = "file://sudo.pam"