summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended
diff options
context:
space:
mode:
authorJagadeesh Krishnanjanappa <jkrishnanjanappa@mvista.com>2018-08-22 17:11:44 +0530
committerRichard Purdie <richard.purdie@linuxfoundation.org>2018-08-29 15:23:51 +0100
commitac9770edca233cf6bf0bff755d4765a154d67e36 (patch)
tree7e57a9fbb957feb971ce3b401f920c92c5fc1a4d /meta/recipes-extended
parentf183e88d06881ebc818419e978e2ddb8b588d14d (diff)
downloadpoky-ac9770edca233cf6bf0bff755d4765a154d67e36.tar.gz
procps: CVE-2018-1124
proc/readproc.c: Fix bugs and overflows in file2strvec(). Note: this is by far the most important and complex patch of the whole series, please review it carefully; thank you very much! For this patch, we decided to keep the original function's design and skeleton, to avoid regressions and behavior changes, while fixing the various bugs and overflows. And like the "Harden file2str()" patch, this patch does not fail when about to overflow, but truncates instead: there is information available about this process, so return it to the caller; also, we used INT_MAX as a limit, but a lower limit could be used. The easy changes: - Replace sprintf() with snprintf() (and check for truncation). - Replace "if (n == 0 && rbuf == 0)" with "if (n <= 0 && tot <= 0)" and do break instead of return: it simplifies the code (only one place to handle errors), and also guarantees that in the while loop either n or tot is > 0 (or both), even if n is reset to 0 when about to overflow. - Remove the "if (n < 0)" block in the while loop: it is (and was) dead code, since we enter the while loop only if n >= 0. - Rewrite the missing-null-terminator detection: in the original function, if the size of the file is a multiple of 2047, a null- terminator is appended even if the file is already null-terminated. - Replace "if (n <= 0 && !end_of_file)" with "if (n < 0 || tot <= 0)": originally, it was equivalent to "if (n < 0)", but we added "tot <= 0" to handle the first break of the while loop, and to guarantee that in the rest of the function tot is > 0. - Double-force ("belt and suspenders") the null-termination of rbuf: this is (and was) essential to the correctness of the function. - Replace the final "while" loop with a "for" loop that behaves just like the preceding "for" loop: in the original function, this would lead to unexpected results (for example, if rbuf is |\0|A|\0|, this would return the array {"",NULL} but should return {"","A",NULL}; and if rbuf is |A|\0|B| (should never happen because rbuf should be null- terminated), this would make room for two pointers in ret, but would write three pointers to ret). The hard changes: - Prevent the integer overflow of tot in the while loop, but unlike file2str(), file2strvec() cannot let tot grow until it almost reaches INT_MAX, because it needs more space for the pointers: this is why we introduced ARG_LEN, which also guarantees that we can add "align" and a few sizeof(char*)s to tot without overflowing. - Prevent the integer overflow of "tot + c + align": when INT_MAX is (almost) reached, we write the maximal safe amount of pointers to ret (ARG_LEN guarantees that there is always space for *ret = rbuf and the NULL terminator). Affects procps-ng < 3.3.15 (From OE-Core rev: 82d873a1b73da25ae415afe0e6203693f78b88c9) Signed-off-by: Jagadeesh Krishnanjanappa <jkrishnanjanappa@mvista.com> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-extended')
-rw-r--r--meta/recipes-extended/procps/procps/CVE-2018-1124.patch176
-rw-r--r--meta/recipes-extended/procps/procps_3.3.12.bb1
2 files changed, 177 insertions, 0 deletions
diff --git a/meta/recipes-extended/procps/procps/CVE-2018-1124.patch b/meta/recipes-extended/procps/procps/CVE-2018-1124.patch
new file mode 100644
index 0000000000..bc78faf0dc
--- /dev/null
+++ b/meta/recipes-extended/procps/procps/CVE-2018-1124.patch
@@ -0,0 +1,176 @@
1From bdd058a0e676d2f013027fcfb2b344c313112a50 Mon Sep 17 00:00:00 2001
2From: Qualys Security Advisory <qsa@qualys.com>
3Date: Thu, 1 Jan 1970 00:00:00 +0000
4Subject: [PATCH 074/126] proc/readproc.c: Fix bugs and overflows in
5 file2strvec().
6
7Note: this is by far the most important and complex patch of the whole
8series, please review it carefully; thank you very much!
9
10For this patch, we decided to keep the original function's design and
11skeleton, to avoid regressions and behavior changes, while fixing the
12various bugs and overflows. And like the "Harden file2str()" patch, this
13patch does not fail when about to overflow, but truncates instead: there
14is information available about this process, so return it to the caller;
15also, we used INT_MAX as a limit, but a lower limit could be used.
16
17The easy changes:
18
19- Replace sprintf() with snprintf() (and check for truncation).
20
21- Replace "if (n == 0 && rbuf == 0)" with "if (n <= 0 && tot <= 0)" and
22 do break instead of return: it simplifies the code (only one place to
23 handle errors), and also guarantees that in the while loop either n or
24 tot is > 0 (or both), even if n is reset to 0 when about to overflow.
25
26- Remove the "if (n < 0)" block in the while loop: it is (and was) dead
27 code, since we enter the while loop only if n >= 0.
28
29- Rewrite the missing-null-terminator detection: in the original
30 function, if the size of the file is a multiple of 2047, a null-
31 terminator is appended even if the file is already null-terminated.
32
33- Replace "if (n <= 0 && !end_of_file)" with "if (n < 0 || tot <= 0)":
34 originally, it was equivalent to "if (n < 0)", but we added "tot <= 0"
35 to handle the first break of the while loop, and to guarantee that in
36 the rest of the function tot is > 0.
37
38- Double-force ("belt and suspenders") the null-termination of rbuf:
39 this is (and was) essential to the correctness of the function.
40
41- Replace the final "while" loop with a "for" loop that behaves just
42 like the preceding "for" loop: in the original function, this would
43 lead to unexpected results (for example, if rbuf is |\0|A|\0|, this
44 would return the array {"",NULL} but should return {"","A",NULL}; and
45 if rbuf is |A|\0|B| (should never happen because rbuf should be null-
46 terminated), this would make room for two pointers in ret, but would
47 write three pointers to ret).
48
49The hard changes:
50
51- Prevent the integer overflow of tot in the while loop, but unlike
52 file2str(), file2strvec() cannot let tot grow until it almost reaches
53 INT_MAX, because it needs more space for the pointers: this is why we
54 introduced ARG_LEN, which also guarantees that we can add "align" and
55 a few sizeof(char*)s to tot without overflowing.
56
57- Prevent the integer overflow of "tot + c + align": when INT_MAX is
58 (almost) reached, we write the maximal safe amount of pointers to ret
59 (ARG_LEN guarantees that there is always space for *ret = rbuf and the
60 NULL terminator).
61[carnil: backport for 3.3.9: Add include for limits.h and use of MAX_INT]
62
63CVE: CVE-2018-1124
64Upstream-Status: Backport [https://gitlab.com/procps-ng/procps/commit/36c350f07c75aabf747fb833f52a234ae5781b20]
65
66Signed-off-by: Jagadeesh Krishnanjanappa <jkrishnanjanappa@mvista.com>
67---
68 proc/readproc.c | 53 ++++++++++++++++++++++++++++++++---------------------
69 1 file changed, 32 insertions(+), 21 deletions(-)
70
71diff -Naurp procps-ng-3.3.12_org/proc/readproc.c procps-ng-3.3.12/proc/readproc.c
72--- procps-ng-3.3.12_org/proc/readproc.c 2016-07-09 14:49:25.825306872 -0700
73+++ procps-ng-3.3.12/proc/readproc.c 2018-07-24 00:46:49.366202531 -0700
74@@ -37,6 +37,7 @@
75 #include <dirent.h>
76 #include <sys/types.h>
77 #include <sys/stat.h>
78+#include <limits.h>
79 #ifdef WITH_SYSTEMD
80 #include <systemd/sd-login.h>
81 #endif
82--- a/proc/readproc.c
83+++ b/proc/readproc.c
84@@ -600,11 +601,12 @@ static int file2str(const char *director
85
86 static char** file2strvec(const char* directory, const char* what) {
87 char buf[2048]; /* read buf bytes at a time */
88- char *p, *rbuf = 0, *endbuf, **q, **ret;
89+ char *p, *rbuf = 0, *endbuf, **q, **ret, *strp;
90 int fd, tot = 0, n, c, end_of_file = 0;
91 int align;
92
93- sprintf(buf, "%s/%s", directory, what);
94+ const int len = snprintf(buf, sizeof buf, "%s/%s", directory, what);
95+ if(len <= 0 || (size_t)len >= sizeof buf) return NULL;
96 fd = open(buf, O_RDONLY, 0);
97 if(fd==-1) return NULL;
98
99@@ -612,18 +614,23 @@ static char** file2strvec(const char* di
100 while ((n = read(fd, buf, sizeof buf - 1)) >= 0) {
101 if (n < (int)(sizeof buf - 1))
102 end_of_file = 1;
103- if (n == 0 && rbuf == 0) {
104- close(fd);
105- return NULL; /* process died between our open and read */
106+ if (n <= 0 && tot <= 0) { /* nothing read now, nothing read before */
107+ break; /* process died between our open and read */
108 }
109- if (n < 0) {
110- if (rbuf)
111- free(rbuf);
112- close(fd);
113- return NULL; /* read error */
114+ /* ARG_LEN is our guesstimated median length of a command-line argument
115+ or environment variable (the minimum is 1, the maximum is 131072) */
116+ #define ARG_LEN 64
117+ if (tot >= INT_MAX / (ARG_LEN + (int)sizeof(char*)) * ARG_LEN - n) {
118+ end_of_file = 1; /* integer overflow: null-terminate and break */
119+ n = 0; /* but tot > 0 */
120 }
121- if (end_of_file && (n == 0 || buf[n-1]))/* last read char not null */
122+ #undef ARG_LEN
123+ if (end_of_file &&
124+ ((n > 0 && buf[n-1] != '\0') || /* last read char not null */
125+ (n <= 0 && rbuf[tot-1] != '\0'))) /* last read char not null */
126 buf[n++] = '\0'; /* so append null-terminator */
127+
128+ if (n <= 0) break; /* unneeded (end_of_file = 1) but avoid realloc */
129 rbuf = xrealloc(rbuf, tot + n); /* allocate more memory */
130 memcpy(rbuf + tot, buf, n); /* copy buffer into it */
131 tot += n; /* increment total byte ctr */
132@@ -631,29 +638,34 @@ static char** file2strvec(const char* di
133 break;
134 }
135 close(fd);
136- if (n <= 0 && !end_of_file) {
137+ if (n < 0 || tot <= 0) { /* error, or nothing read */
138 if (rbuf) free(rbuf);
139 return NULL; /* read error */
140 }
141+ rbuf[tot-1] = '\0'; /* belt and suspenders (the while loop did it, too) */
142 endbuf = rbuf + tot; /* count space for pointers */
143 align = (sizeof(char*)-1) - ((tot + sizeof(char*)-1) & (sizeof(char*)-1));
144- for (c = 0, p = rbuf; p < endbuf; p++) {
145- if (!*p || *p == '\n')
146+ c = sizeof(char*); /* one extra for NULL term */
147+ for (p = rbuf; p < endbuf; p++) {
148+ if (!*p || *p == '\n') {
149+ if (c >= INT_MAX - (tot + (int)sizeof(char*) + align)) break;
150 c += sizeof(char*);
151+ }
152 if (*p == '\n')
153 *p = 0;
154 }
155- c += sizeof(char*); /* one extra for NULL term */
156
157 rbuf = xrealloc(rbuf, tot + c + align); /* make room for ptrs AT END */
158 endbuf = rbuf + tot; /* addr just past data buf */
159 q = ret = (char**) (endbuf+align); /* ==> free(*ret) to dealloc */
160- *q++ = p = rbuf; /* point ptrs to the strings */
161- endbuf--; /* do not traverse final NUL */
162- while (++p < endbuf)
163- if (!*p) /* NUL char implies that */
164- *q++ = p+1; /* next string -> next char */
165-
166+ for (strp = p = rbuf; p < endbuf; p++) {
167+ if (!*p) { /* NUL char implies that */
168+ if (c < 2 * (int)sizeof(char*)) break;
169+ c -= sizeof(char*);
170+ *q++ = strp; /* point ptrs to the strings */
171+ strp = p+1; /* next string -> next char */
172+ }
173+ }
174 *q = 0; /* null ptr list terminator */
175 return ret;
176 }
diff --git a/meta/recipes-extended/procps/procps_3.3.12.bb b/meta/recipes-extended/procps/procps_3.3.12.bb
index ecf215fecf..6e15b0a5a0 100644
--- a/meta/recipes-extended/procps/procps_3.3.12.bb
+++ b/meta/recipes-extended/procps/procps_3.3.12.bb
@@ -14,6 +14,7 @@ inherit autotools gettext pkgconfig update-alternatives
14 14
15SRC_URI = "http://downloads.sourceforge.net/project/procps-ng/Production/procps-ng-${PV}.tar.xz \ 15SRC_URI = "http://downloads.sourceforge.net/project/procps-ng/Production/procps-ng-${PV}.tar.xz \
16 file://sysctl.conf \ 16 file://sysctl.conf \
17 file://CVE-2018-1124.patch \
17 " 18 "
18 19
19SRC_URI[md5sum] = "957e42e8b193490b2111252e4a2b443c" 20SRC_URI[md5sum] = "957e42e8b193490b2111252e4a2b443c"