summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPascal Bach <pascal.bach@siemens.com>2016-10-14 14:26:44 +0200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-11-08 23:47:12 +0000
commit732dd581f3e66175feccd811bc2ef9f814ee0705 (patch)
tree78ec9ff5e03386347cee87655753f5a61f363ad1
parent40f4a6d075236265086cc79400dea3c14720383a (diff)
downloadpoky-732dd581f3e66175feccd811bc2ef9f814ee0705.tar.gz
glibc: fix CVE-2016-1234, CVE-2016-3075, CVE-2016-5417
Only relevant for krogoth since version 2.24+ (master, morty) is not affected. (From OE-Core rev: 88be4b40bacc7c8a08fb76fc220f491deb2c1c3a) Signed-off-by: Pascal Bach <pascal.bach@siemens.com> Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2016-1234.patch427
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2016-3075.patch37
-rw-r--r--meta/recipes-core/glibc/glibc/CVE-2016-5417.patch28
-rw-r--r--meta/recipes-core/glibc/glibc_2.23.bb3
4 files changed, 495 insertions, 0 deletions
diff --git a/meta/recipes-core/glibc/glibc/CVE-2016-1234.patch b/meta/recipes-core/glibc/glibc/CVE-2016-1234.patch
new file mode 100644
index 0000000000..e0d45c6943
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2016-1234.patch
@@ -0,0 +1,427 @@
1glibc-2.23: Fix CVE-2016-1234
2
3[No upstream tracking] -- https://bugzilla.redhat.com/show_bug.cgi?id=1315647
4
5glob: Do not copy d_name field of struct dirent
6
7Instead, we store the data we need from the return value of
8readdir in an object of the new type struct readdir_result.
9This type is independent of the layout of struct dirent.
10
11Upstream-Status: Backport
12CVE: CVE-2016-1234
13Signed-off-by: Andrej Valek <andrej.valek@siemens.com>
14Signed-off-by: Pascal Bach <pascal.bach@siemens.com>
15
16diff --git a/posix/bug-glob2.c b/posix/bug-glob2.c
17index ddf5ec9..22ea35f 100644
18--- a/posix/bug-glob2.c
19+++ b/posix/bug-glob2.c
20@@ -40,6 +40,17 @@
21 # define PRINTF(fmt, args...)
22 #endif
23
24+#define LONG_NAME \
25+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
26+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
27+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
28+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
29+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
30+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
31+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
32+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
33+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
34+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
35
36 static struct
37 {
38@@ -58,6 +69,7 @@ static struct
39 { ".", 3, DT_DIR, 0755 },
40 { "..", 3, DT_DIR, 0755 },
41 { "a", 3, DT_REG, 0644 },
42+ { LONG_NAME, 3, DT_REG, 0644 },
43 { "unreadable", 2, DT_DIR, 0111 },
44 { ".", 3, DT_DIR, 0111 },
45 { "..", 3, DT_DIR, 0755 },
46@@ -75,7 +87,7 @@ typedef struct
47 int level;
48 int idx;
49 struct dirent d;
50- char room_for_dirent[NAME_MAX];
51+ char room_for_dirent[sizeof (LONG_NAME)];
52 } my_DIR;
53
54
55@@ -193,7 +205,7 @@ my_readdir (void *gdir)
56 return NULL;
57 }
58
59- dir->d.d_ino = dir->idx;
60+ dir->d.d_ino = 1; /* glob should not skip this entry. */
61
62 #ifdef _DIRENT_HAVE_D_TYPE
63 dir->d.d_type = filesystem[dir->idx].type;
64diff --git a/posix/glob.c b/posix/glob.c
65index 0c04c3c..6c6612d 100644
66--- a/posix/glob.c
67+++ b/posix/glob.c
68@@ -24,7 +24,9 @@
69 #include <errno.h>
70 #include <sys/types.h>
71 #include <sys/stat.h>
72+#include <stdbool.h>
73 #include <stddef.h>
74+#include <stdint.h>
75
76 /* Outcomment the following line for production quality code. */
77 /* #define NDEBUG 1 */
78@@ -57,10 +59,8 @@
79
80 #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
81 # include <dirent.h>
82-# define NAMLEN(dirent) strlen((dirent)->d_name)
83 #else
84 # define dirent direct
85-# define NAMLEN(dirent) (dirent)->d_namlen
86 # ifdef HAVE_SYS_NDIR_H
87 # include <sys/ndir.h>
88 # endif
89@@ -75,82 +75,8 @@
90 # endif /* HAVE_VMSDIR_H */
91 #endif
92
93-
94-/* In GNU systems, <dirent.h> defines this macro for us. */
95-#ifdef _D_NAMLEN
96-# undef NAMLEN
97-# define NAMLEN(d) _D_NAMLEN(d)
98-#endif
99-
100-/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
101- if the `d_type' member for `struct dirent' is available.
102- HAVE_STRUCT_DIRENT_D_TYPE plays the same role in GNULIB. */
103-#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
104-/* True if the directory entry D must be of type T. */
105-# define DIRENT_MUST_BE(d, t) ((d)->d_type == (t))
106-
107-/* True if the directory entry D might be a symbolic link. */
108-# define DIRENT_MIGHT_BE_SYMLINK(d) \
109- ((d)->d_type == DT_UNKNOWN || (d)->d_type == DT_LNK)
110-
111-/* True if the directory entry D might be a directory. */
112-# define DIRENT_MIGHT_BE_DIR(d) \
113- ((d)->d_type == DT_DIR || DIRENT_MIGHT_BE_SYMLINK (d))
114-
115-#else /* !HAVE_D_TYPE */
116-# define DIRENT_MUST_BE(d, t) false
117-# define DIRENT_MIGHT_BE_SYMLINK(d) true
118-# define DIRENT_MIGHT_BE_DIR(d) true
119-#endif /* HAVE_D_TYPE */
120-
121-/* If the system has the `struct dirent64' type we use it internally. */
122-#if defined _LIBC && !defined COMPILE_GLOB64
123-# if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
124-# define CONVERT_D_NAMLEN(d64, d32)
125-# else
126-# define CONVERT_D_NAMLEN(d64, d32) \
127- (d64)->d_namlen = (d32)->d_namlen;
128-# endif
129-
130-# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
131-# define CONVERT_D_INO(d64, d32)
132-# else
133-# define CONVERT_D_INO(d64, d32) \
134- (d64)->d_ino = (d32)->d_ino;
135-# endif
136-
137-# ifdef _DIRENT_HAVE_D_TYPE
138-# define CONVERT_D_TYPE(d64, d32) \
139- (d64)->d_type = (d32)->d_type;
140-# else
141-# define CONVERT_D_TYPE(d64, d32)
142-# endif
143-
144-# define CONVERT_DIRENT_DIRENT64(d64, d32) \
145- memcpy ((d64)->d_name, (d32)->d_name, NAMLEN (d32) + 1); \
146- CONVERT_D_NAMLEN (d64, d32) \
147- CONVERT_D_INO (d64, d32) \
148- CONVERT_D_TYPE (d64, d32)
149-#endif
150-
151-
152-#if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
153-/* Posix does not require that the d_ino field be present, and some
154- systems do not provide it. */
155-# define REAL_DIR_ENTRY(dp) 1
156-#else
157-# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
158-#endif /* POSIX */
159-
160 #include <stdlib.h>
161 #include <string.h>
162-
163-/* NAME_MAX is usually defined in <dirent.h> or <limits.h>. */
164-#include <limits.h>
165-#ifndef NAME_MAX
166-# define NAME_MAX (sizeof (((struct dirent *) 0)->d_name))
167-#endif
168-
169 #include <alloca.h>
170
171 #ifdef _LIBC
172@@ -195,8 +121,111 @@
173
174 static const char *next_brace_sub (const char *begin, int flags) __THROWNL;
175
176+/* A representation of a directory entry which does not depend on the
177+ layout of struct dirent, or the size of ino_t. */
178+struct readdir_result
179+{
180+ const char *name;
181+# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
182+ uint8_t type;
183+# endif
184+ bool skip_entry;
185+};
186+
187+# if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
188+/* Initializer based on the d_type member of struct dirent. */
189+# define D_TYPE_TO_RESULT(source) (source)->d_type,
190+
191+/* True if the directory entry D might be a symbolic link. */
192+static bool
193+readdir_result_might_be_symlink (struct readdir_result d)
194+{
195+ return d.type == DT_UNKNOWN || d.type == DT_LNK;
196+}
197+
198+/* True if the directory entry D might be a directory. */
199+static bool
200+readdir_result_might_be_dir (struct readdir_result d)
201+{
202+ return d.type == DT_DIR || readdir_result_might_be_symlink (d);
203+}
204+# else /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
205+# define D_TYPE_TO_RESULT(source)
206+
207+/* If we do not have type information, symbolic links and directories
208+ are always a possibility. */
209+
210+static bool
211+readdir_result_might_be_symlink (struct readdir_result d)
212+{
213+ return true;
214+}
215+
216+static bool
217+eaddir_result_might_be_dir (struct readdir_result d)
218+{
219+ return true;
220+}
221+
222+# endif /* defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE */
223+
224+# if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
225+/* Initializer for skip_entry. POSIX does not require that the d_ino
226+ field be present, and some systems do not provide it. */
227+# define D_INO_TO_RESULT(source) false,
228+# else
229+# define D_INO_TO_RESULT(source) (source)->d_ino == 0,
230+# endif
231+
232+/* Construct an initializer for a struct readdir_result object from a
233+ struct dirent *. No copy of the name is made. */
234+#define READDIR_RESULT_INITIALIZER(source) \
235+ { \
236+ source->d_name, \
237+ D_TYPE_TO_RESULT (source) \
238+ D_INO_TO_RESULT (source) \
239+ }
240+
241 #endif /* !defined _LIBC || !defined GLOB_ONLY_P */
242
243+/* Call gl_readdir on STREAM. This macro can be overridden to reduce
244+ type safety if an old interface version needs to be supported. */
245+#ifndef GL_READDIR
246+# define GL_READDIR(pglob, stream) ((pglob)->gl_readdir (stream))
247+#endif
248+
249+/* Extract name and type from directory entry. No copy of the name is
250+ made. If SOURCE is NULL, result name is NULL. Keep in sync with
251+ convert_dirent64 below. */
252+static struct readdir_result
253+convert_dirent (const struct dirent *source)
254+{
255+ if (source == NULL)
256+ {
257+ struct readdir_result result = { NULL, };
258+ return result;
259+ }
260+ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
261+ return result;
262+}
263+
264+#ifndef COMPILE_GLOB64
265+/* Like convert_dirent, but works on struct dirent64 instead. Keep in
266+ sync with convert_dirent above. */
267+static struct readdir_result
268+convert_dirent64 (const struct dirent64 *source)
269+{
270+ if (source == NULL)
271+ {
272+ struct readdir_result result = { NULL, };
273+ return result;
274+ }
275+ struct readdir_result result = READDIR_RESULT_INITIALIZER (source);
276+ return result;
277+}
278+#endif
279+
280+
281 #ifndef attribute_hidden
282 # define attribute_hidden
283 #endif
284@@ -1553,56 +1582,36 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
285
286 while (1)
287 {
288- const char *name;
289- size_t len;
290-#if defined _LIBC && !defined COMPILE_GLOB64
291- struct dirent64 *d;
292- union
293- {
294- struct dirent64 d64;
295- char room [offsetof (struct dirent64, d_name[0])
296- + NAME_MAX + 1];
297- }
298- d64buf;
299-
300- if (__glibc_unlikely (flags & GLOB_ALTDIRFUNC))
301+ struct readdir_result d;
302 {
303- struct dirent *d32 = (*pglob->gl_readdir) (stream);
304- if (d32 != NULL)
305- {
306- CONVERT_DIRENT_DIRENT64 (&d64buf.d64, d32);
307- d = &d64buf.d64;
308- }
309+ if (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0))
310+ d = convert_dirent (GL_READDIR (pglob, stream));
311 else
312- d = NULL;
313- }
314- else
315- d = __readdir64 (stream);
316+ {
317+#ifdef COMPILE_GLOB64
318+ d = convert_dirent (__readdir (stream));
319 #else
320- struct dirent *d = (__builtin_expect (flags & GLOB_ALTDIRFUNC, 0)
321- ? ((struct dirent *)
322- (*pglob->gl_readdir) (stream))
323- : __readdir (stream));
324+ d = convert_dirent64 (__readdir64 (stream));
325 #endif
326- if (d == NULL)
327+ }
328+ }
329+ if (d.name == NULL)
330 break;
331- if (! REAL_DIR_ENTRY (d))
332+ if (d.skip_entry)
333 continue;
334
335 /* If we shall match only directories use the information
336 provided by the dirent call if possible. */
337- if ((flags & GLOB_ONLYDIR) && !DIRENT_MIGHT_BE_DIR (d))
338+ if ((flags & GLOB_ONLYDIR) && !readdir_result_might_be_dir (d))
339 continue;
340
341- name = d->d_name;
342-
343- if (fnmatch (pattern, name, fnm_flags) == 0)
344+ if (fnmatch (pattern, d.name, fnm_flags) == 0)
345 {
346 /* If the file we found is a symlink we have to
347 make sure the target file exists. */
348- if (!DIRENT_MIGHT_BE_SYMLINK (d)
349- || link_exists_p (dfd, directory, dirlen, name, pglob,
350- flags))
351+ if (!readdir_result_might_be_symlink (d)
352+ || link_exists_p (dfd, directory, dirlen, d.name,
353+ pglob, flags))
354 {
355 if (cur == names->count)
356 {
357@@ -1622,12 +1631,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
358 names = newnames;
359 cur = 0;
360 }
361- len = NAMLEN (d);
362- names->name[cur] = (char *) malloc (len + 1);
363+ names->name[cur] = strdup (d.name);
364 if (names->name[cur] == NULL)
365- goto memory_error;
366- *((char *) mempcpy (names->name[cur++], name, len))
367- = '\0';
368+ goto memory_error;
369+ ++cur;
370 ++nfound;
371 }
372 }
373diff --git a/posix/tst-gnuglob.c b/posix/tst-gnuglob.c
374index 992b997..3a27a06 100644
375--- a/posix/tst-gnuglob.c
376+++ b/posix/tst-gnuglob.c
377@@ -211,7 +211,7 @@ my_readdir (void *gdir)
378 return NULL;
379 }
380
381- dir->d.d_ino = dir->idx;
382+ dir->d.d_ino = 1; /* glob should not skip this entry. */
383
384 #ifdef _DIRENT_HAVE_D_TYPE
385 dir->d.d_type = filesystem[dir->idx].type;
386diff --git a/sysdeps/unix/sysv/linux/i386/glob64.c b/sysdeps/unix/sysv/linux/i386/glob64.c
387index b4fcd1a..4a2dfc1 100644
388--- a/sysdeps/unix/sysv/linux/i386/glob64.c
389+++ b/sysdeps/unix/sysv/linux/i386/glob64.c
390@@ -1,3 +1,21 @@
391+/* Two glob variants with 64-bit support, for dirent64 and __olddirent64.
392+ Copyright (C) 1998-2016 Free Software Foundation, Inc.
393+ This file is part of the GNU C Library.
394+
395+ The GNU C Library is free software; you can redistribute it and/or
396+ modify it under the terms of the GNU Lesser General Public
397+ License as published by the Free Software Foundation; either
398+ version 2.1 of the License, or (at your option) any later version.
399+
400+ The GNU C Library is distributed in the hope that it will be useful,
401+ but WITHOUT ANY WARRANTY; without even the implied warranty of
402+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
403+ Lesser General Public License for more details.
404+
405+ You should have received a copy of the GNU Lesser General Public
406+ License along with the GNU C Library; if not, see
407+ <http://www.gnu.org/licenses/>. */
408+
409 #include <dirent.h>
410 #include <glob.h>
411 #include <sys/stat.h>
412@@ -38,11 +56,15 @@ int __old_glob64 (const char *__pattern, int __flags,
413
414 #undef dirent
415 #define dirent __old_dirent64
416+#undef GL_READDIR
417+#define GL_READDIR(pglob, stream) \
418+ ((struct __old_dirent64 *) (pglob)->gl_readdir (stream))
419 #undef __readdir
420 #define __readdir(dirp) __old_readdir64 (dirp)
421 #undef glob
422 #define glob(pattern, flags, errfunc, pglob) \
423 __old_glob64 (pattern, flags, errfunc, pglob)
424+#define convert_dirent __old_convert_dirent
425 #define glob_in_dir __old_glob_in_dir
426 #define GLOB_ATTRIBUTE attribute_compat_text_section
427
diff --git a/meta/recipes-core/glibc/glibc/CVE-2016-3075.patch b/meta/recipes-core/glibc/glibc/CVE-2016-3075.patch
new file mode 100644
index 0000000000..7b9dc4f5c3
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2016-3075.patch
@@ -0,0 +1,37 @@
1glibc-2.23: Fix CVE-2016-3075
2
3[No upstream tracking] -- https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-3075
4
5resolv/nss_dns/dns-network.c: Stack overflow in _nss_dns_getnetbyname_r
6
7The defensive copy is not needed because the name may not alias the
8output buffer.
9
10Upstream-Status: Backport
11CVE: CVE-2016-3075
12Signed-off-by: Andrej Valek <andrej.valek@siemens.com>
13Signed-off-by: Pascal Bach <pascal.bach@siemens.com>
14
15diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c
16index 2eb2f67..8f301a7 100644
17--- a/resolv/nss_dns/dns-network.c
18+++ b/resolv/nss_dns/dns-network.c
19@@ -118,17 +118,14 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
20 } net_buffer;
21 querybuf *orig_net_buffer;
22 int anslen;
23- char *qbuf;
24 enum nss_status status;
25
26 if (__res_maybe_init (&_res, 0) == -1)
27 return NSS_STATUS_UNAVAIL;
28
29- qbuf = strdupa (name);
30-
31 net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
32
33- anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
34+ anslen = __libc_res_nsearch (&_res, name, C_IN, T_PTR, net_buffer.buf->buf,
35 1024, &net_buffer.ptr, NULL, NULL, NULL, NULL);
36 if (anslen < 0)
37 {
diff --git a/meta/recipes-core/glibc/glibc/CVE-2016-5417.patch b/meta/recipes-core/glibc/glibc/CVE-2016-5417.patch
new file mode 100644
index 0000000000..8e0252beb4
--- /dev/null
+++ b/meta/recipes-core/glibc/glibc/CVE-2016-5417.patch
@@ -0,0 +1,28 @@
1glibc-2.23: Fix CVE-2016-5417
2
3[No upstream tracking] -- https://bugzilla.redhat.com/show_bug.cgi?id=1362534
4
5resolv/res_init.c:Fix resource leak in resolver
6
7The number of currently defined nameservers is stored in ->nscount,
8whereas ->_u._ext.nscount is set by __libc_res_nsend only after local
9initializations.
10
11Upstream-Status: Backport
12CVE: CVE-2016-5417
13Signed-off-by: Andrej Valek <andrej.valek@siemens.com>
14Signed-off-by: Pascal Bach <pascal.bach@siemens.com>
15
16diff --git a/resolv/res_init.c b/resolv/res_init.c
17index e0b6a80..6c951f5 100644
18--- a/resolv/res_init.c
19+++ b/resolv/res_init.c
20@@ -594,7 +594,7 @@ __res_iclose(res_state statp, bool free_addr) {
21 statp->_vcsock = -1;
22 statp->_flags &= ~(RES_F_VC | RES_F_CONN);
23 }
24- for (ns = 0; ns < statp->_u._ext.nscount; ns++)
25+ for (ns = 0; ns < statp->nscount; ns++)
26 if (statp->_u._ext.nsaddrs[ns]) {
27 if (statp->_u._ext.nssocks[ns] != -1) {
28 close_not_cancel_no_status(statp->_u._ext.nssocks[ns]);
diff --git a/meta/recipes-core/glibc/glibc_2.23.bb b/meta/recipes-core/glibc/glibc_2.23.bb
index 63dc911e00..85b52159dc 100644
--- a/meta/recipes-core/glibc/glibc_2.23.bb
+++ b/meta/recipes-core/glibc/glibc_2.23.bb
@@ -38,6 +38,9 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \
38 file://0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch \ 38 file://0026-When-disabling-SSE-make-sure-fpmath-is-not-set-to-us.patch \
39 file://CVE-2016-3706.patch \ 39 file://CVE-2016-3706.patch \
40 file://CVE-2016-4429.patch \ 40 file://CVE-2016-4429.patch \
41 file://CVE-2016-1234.patch \
42 file://CVE-2016-3075.patch \
43 file://CVE-2016-5417.patch \
41" 44"
42 45
43SRC_URI += "\ 46SRC_URI += "\