summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-extended/sudo/sudo/CVE-2019-14287_p1.patch170
-rw-r--r--meta/recipes-extended/sudo/sudo/CVE-2019-14287_p2.patch98
-rw-r--r--meta/recipes-extended/sudo/sudo_1.8.23.bb2
3 files changed, 270 insertions, 0 deletions
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2019-14287_p1.patch b/meta/recipes-extended/sudo/sudo/CVE-2019-14287_p1.patch
new file mode 100644
index 0000000000..f954fac8fc
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2019-14287_p1.patch
@@ -0,0 +1,170 @@
1Treat an ID of -1 as invalid since that means "no change".
2Fixes CVE-2019-14287.
3Found by Joe Vennix from Apple Information Security.
4
5CVE: CVE-2019-14287
6Upstream-Status: Backport
7[https://www.sudo.ws/repos/sudo/rev/83db8dba09e7]
8
9Signed-off-by: Dan Tran <dantran@microsoft.com>
10
11Index: sudo-1.8.21p2/lib/util/strtoid.c
12===================================================================
13--- sudo-1.8.21p2.orig/lib/util/strtoid.c 2019-10-10 14:31:08.338476078 -0400
14+++ sudo-1.8.21p2/lib/util/strtoid.c 2019-10-10 14:31:08.338476078 -0400
15@@ -42,6 +42,27 @@
16 #include "sudo_util.h"
17
18 /*
19+ * Make sure that the ID ends with a valid separator char.
20+ */
21+static bool
22+valid_separator(const char *p, const char *ep, const char *sep)
23+{
24+ bool valid = false;
25+ debug_decl(valid_separator, SUDO_DEBUG_UTIL)
26+
27+ if (ep != p) {
28+ /* check for valid separator (including '\0') */
29+ if (sep == NULL)
30+ sep = "";
31+ do {
32+ if (*ep == *sep)
33+ valid = true;
34+ } while (*sep++ != '\0');
35+ }
36+ debug_return_bool(valid);
37+}
38+
39+/*
40 * Parse a uid/gid in string form.
41 * If sep is non-NULL, it contains valid separator characters (e.g. comma, space)
42 * If endp is non-NULL it is set to the next char after the ID.
43@@ -55,36 +76,33 @@ sudo_strtoid_v1(const char *p, const cha
44 char *ep;
45 id_t ret = 0;
46 long long llval;
47- bool valid = false;
48 debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
49
50 /* skip leading space so we can pick up the sign, if any */
51 while (isspace((unsigned char)*p))
52 p++;
53- if (sep == NULL)
54- sep = "";
55+
56+ /* While id_t may be 64-bit signed, uid_t and gid_t are 32-bit unsigned. */
57 errno = 0;
58 llval = strtoll(p, &ep, 10);
59- if (ep != p) {
60- /* check for valid separator (including '\0') */
61- do {
62- if (*ep == *sep)
63- valid = true;
64- } while (*sep++ != '\0');
65+ if ((errno == ERANGE && llval == LLONG_MAX) || llval > (id_t)UINT_MAX) {
66+ errno = ERANGE;
67+ if (errstr != NULL)
68+ *errstr = N_("value too large");
69+ goto done;
70 }
71- if (!valid) {
72+ if ((errno == ERANGE && llval == LLONG_MIN) || llval < INT_MIN) {
73+ errno = ERANGE;
74 if (errstr != NULL)
75- *errstr = N_("invalid value");
76- errno = EINVAL;
77+ *errstr = N_("value too small");
78 goto done;
79 }
80- if (errno == ERANGE) {
81- if (errstr != NULL) {
82- if (llval == LLONG_MAX)
83- *errstr = N_("value too large");
84- else
85- *errstr = N_("value too small");
86- }
87+
88+ /* Disallow id -1, which means "no change". */
89+ if (!valid_separator(p, ep, sep) || llval == -1 || llval == (id_t)UINT_MAX) {
90+ if (errstr != NULL)
91+ *errstr = N_("invalid value");
92+ errno = EINVAL;
93 goto done;
94 }
95 ret = (id_t)llval;
96@@ -101,30 +119,15 @@ sudo_strtoid_v1(const char *p, const cha
97 {
98 char *ep;
99 id_t ret = 0;
100- bool valid = false;
101 debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
102
103 /* skip leading space so we can pick up the sign, if any */
104 while (isspace((unsigned char)*p))
105 p++;
106- if (sep == NULL)
107- sep = "";
108+
109 errno = 0;
110 if (*p == '-') {
111 long lval = strtol(p, &ep, 10);
112- if (ep != p) {
113- /* check for valid separator (including '\0') */
114- do {
115- if (*ep == *sep)
116- valid = true;
117- } while (*sep++ != '\0');
118- }
119- if (!valid) {
120- if (errstr != NULL)
121- *errstr = N_("invalid value");
122- errno = EINVAL;
123- goto done;
124- }
125 if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
126 errno = ERANGE;
127 if (errstr != NULL)
128@@ -137,28 +140,31 @@ sudo_strtoid_v1(const char *p, const cha
129 *errstr = N_("value too small");
130 goto done;
131 }
132- ret = (id_t)lval;
133- } else {
134- unsigned long ulval = strtoul(p, &ep, 10);
135- if (ep != p) {
136- /* check for valid separator (including '\0') */
137- do {
138- if (*ep == *sep)
139- valid = true;
140- } while (*sep++ != '\0');
141- }
142- if (!valid) {
143+
144+ /* Disallow id -1, which means "no change". */
145+ if (!valid_separator(p, ep, sep) || lval == -1) {
146 if (errstr != NULL)
147 *errstr = N_("invalid value");
148 errno = EINVAL;
149 goto done;
150 }
151+ ret = (id_t)lval;
152+ } else {
153+ unsigned long ulval = strtoul(p, &ep, 10);
154 if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
155 errno = ERANGE;
156 if (errstr != NULL)
157 *errstr = N_("value too large");
158 goto done;
159 }
160+
161+ /* Disallow id -1, which means "no change". */
162+ if (!valid_separator(p, ep, sep) || ulval == UINT_MAX) {
163+ if (errstr != NULL)
164+ *errstr = N_("invalid value");
165+ errno = EINVAL;
166+ goto done;
167+ }
168 ret = (id_t)ulval;
169 }
170 if (errstr != NULL)
diff --git a/meta/recipes-extended/sudo/sudo/CVE-2019-14287_p2.patch b/meta/recipes-extended/sudo/sudo/CVE-2019-14287_p2.patch
new file mode 100644
index 0000000000..dcb2703d23
--- /dev/null
+++ b/meta/recipes-extended/sudo/sudo/CVE-2019-14287_p2.patch
@@ -0,0 +1,98 @@
1CVE: CVE-2019-14287
2Upstream-Status: Backport
3[https://www.sudo.ws/repos/sudo/rev/db06a8336c09]
4
5Signed-off-by: Dan Tran <dantran@microsoft.com>
6
7Index: sudo-1.8.21p2/lib/util/regress/atofoo/atofoo_test.c
8===================================================================
9--- sudo-1.8.21p2.orig/lib/util/regress/atofoo/atofoo_test.c 2019-10-11 07:11:49.874655384 -0400
10+++ sudo-1.8.21p2/lib/util/regress/atofoo/atofoo_test.c 2019-10-11 07:13:07.471005893 -0400
11@@ -24,6 +24,7 @@
12 #else
13 # include "compat/stdbool.h"
14 #endif
15+#include <errno.h>
16
17 #include "sudo_compat.h"
18 #include "sudo_util.h"
19@@ -78,15 +79,20 @@ static struct strtoid_data {
20 id_t id;
21 const char *sep;
22 const char *ep;
23+ int errnum;
24 } strtoid_data[] = {
25- { "0,1", 0, ",", "," },
26- { "10", 10, NULL, NULL },
27- { "-2", -2, NULL, NULL },
28+ { "0,1", 0, ",", ",", 0 },
29+ { "10", 10, NULL, NULL, 0 },
30+ { "-1", 0, NULL, NULL, EINVAL },
31+ { "4294967295", 0, NULL, NULL, EINVAL },
32+ { "4294967296", 0, NULL, NULL, ERANGE },
33+ { "-2147483649", 0, NULL, NULL, ERANGE },
34+ { "-2", -2, NULL, NULL, 0 },
35 #if SIZEOF_ID_T != SIZEOF_LONG_LONG
36- { "-2", 4294967294U, NULL, NULL },
37+ { "-2", (id_t)4294967294U, NULL, NULL, 0 },
38 #endif
39- { "4294967294", 4294967294U, NULL, NULL },
40- { NULL, 0, NULL, NULL }
41+ { "4294967294", (id_t)4294967294U, NULL, NULL, 0 },
42+ { NULL, 0, NULL, NULL, 0 }
43 };
44
45 static int
46@@ -102,11 +108,23 @@ test_strtoid(int *ntests)
47 (*ntests)++;
48 errstr = "some error";
49 value = sudo_strtoid(d->idstr, d->sep, &ep, &errstr);
50- if (errstr != NULL) {
51- if (d->id != (id_t)-1) {
52- sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
53+ if (d->errnum != 0) {
54+ if (errstr == NULL) {
55+ sudo_warnx_nodebug("FAIL: %s: missing errstr for errno %d",
56+ d->idstr, d->errnum);
57+ errors++;
58+ } else if (value != 0) {
59+ sudo_warnx_nodebug("FAIL: %s should return 0 on error",
60+ d->idstr);
61+ errors++;
62+ } else if (errno != d->errnum) {
63+ sudo_warnx_nodebug("FAIL: %s: errno mismatch, %d != %d",
64+ d->idstr, errno, d->errnum);
65 errors++;
66 }
67+ } else if (errstr != NULL) {
68+ sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
69+ errors++;
70 } else if (value != d->id) {
71 sudo_warnx_nodebug("FAIL: %s != %u", d->idstr, (unsigned int)d->id);
72 errors++;
73Index: sudo-1.8.21p2/plugins/sudoers/regress/testsudoers/test5.out.ok
74===================================================================
75--- sudo-1.8.21p2.orig/plugins/sudoers/regress/testsudoers/test5.out.ok 2019-10-11 07:11:49.874655384 -0400
76+++ sudo-1.8.21p2/plugins/sudoers/regress/testsudoers/test5.out.ok 2019-10-11 07:11:49.870655365 -0400
77@@ -4,7 +4,7 @@ Parse error in sudoers near line 1.
78 Entries for user root:
79
80 Command unmatched
81-testsudoers: test5.inc should be owned by gid 4294967295
82+testsudoers: test5.inc should be owned by gid 4294967294
83 Parse error in sudoers near line 1.
84
85 Entries for user root:
86Index: sudo-1.8.21p2/plugins/sudoers/regress/testsudoers/test5.sh
87===================================================================
88--- sudo-1.8.21p2.orig/plugins/sudoers/regress/testsudoers/test5.sh 2019-10-11 07:11:49.874655384 -0400
89+++ sudo-1.8.21p2/plugins/sudoers/regress/testsudoers/test5.sh 2019-10-11 07:11:49.870655365 -0400
90@@ -24,7 +24,7 @@ EOF
91
92 # Test group writable
93 chmod 664 $TESTFILE
94-./testsudoers -U $MYUID -G -1 root id <<EOF
95+./testsudoers -U $MYUID -G -2 root id <<EOF
96 #include $TESTFILE
97 EOF
98
diff --git a/meta/recipes-extended/sudo/sudo_1.8.23.bb b/meta/recipes-extended/sudo/sudo_1.8.23.bb
index ce32bd187e..d12cf2d549 100644
--- a/meta/recipes-extended/sudo/sudo_1.8.23.bb
+++ b/meta/recipes-extended/sudo/sudo_1.8.23.bb
@@ -3,6 +3,8 @@ require sudo.inc
3SRC_URI = "http://ftp.sudo.ws/sudo/dist/sudo-${PV}.tar.gz \ 3SRC_URI = "http://ftp.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_p1.patch \
7 file://CVE-2019-14287_p2.patch \
6 " 8 "
7 9
8PAM_SRC_URI = "file://sudo.pam" 10PAM_SRC_URI = "file://sudo.pam"