]> git.pld-linux.org Git - packages/glibc.git/blame - glibc-git.patch
- merged sotruss-sh and posix-sh patches, rewritten the first to actually disable...
[packages/glibc.git] / glibc-git.patch
CommitLineData
dac4060d
AM
1commit 58b930ae216bfa98cd60212b954b07b9963d6d04
2Author: Siddhesh Poyarekar <siddhesh@redhat.com>
3Date: Wed Sep 10 21:51:50 2014 +0530
4
5 Return failure in getnetgrent only when all netgroups have been searched (#17363)
6
7 The netgroups lookup code fails when one of the groups in the search
8 tree is empty. In such a case it only returns the leaves of the tree
9 after the blank netgroup. This is because the line parser returns a
10 NOTFOUND status when the netgroup exists but is empty. The
11 __getnetgrent_internal implementation needs to be fixed to try
12 remaining groups if the current group is entry. This patch implements
13 this fix. Tested on x86_64.
14
15 [BZ #17363]
16 * inet/getnetgrent_r.c (__internal_getnetgrent_r): Try next
17 group if the current group is empty.
18
19diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
20index f6d064d..e101537 100644
21--- a/inet/getnetgrent_r.c
22+++ b/inet/getnetgrent_r.c
23@@ -297,7 +297,10 @@ __internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
24 {
25 status = DL_CALL_FCT (*fct, (datap, buffer, buflen, &errno));
26
27- if (status == NSS_STATUS_RETURN)
28+ if (status == NSS_STATUS_RETURN
29+ /* The service returned a NOTFOUND, but there are more groups that we
30+ need to resolve before we give up. */
31+ || (status == NSS_STATUS_NOTFOUND && datap->needed_groups != NULL))
32 {
33 /* This was the last one for this group. Look at next group
34 if available. */
35commit 984c0ea97f649c869130a1ff099098e2b6f70aad
36Author: Tim Lammens <tim.lammens@gmail.com>
37Date: Thu Sep 11 10:35:54 2014 +0530
38
39 Fix memory leak in libio/wfileops.c do_ftell_wide [BZ #17370]
40
41diff --git a/libio/wfileops.c b/libio/wfileops.c
42index f123add..ebc06e8 100644
43--- a/libio/wfileops.c
44+++ b/libio/wfileops.c
45@@ -711,6 +711,7 @@ do_ftell_wide (_IO_FILE *fp)
46 return WEOF;
47
48 offset += outstop - out;
49+ free (out);
50 }
51
52 /* We don't trust _IO_read_end to represent the current file offset
53commit 52ffbdf25a1100986f4ae27bb0febbe5a722ab25
54Author: Florian Weimer <fweimer@redhat.com>
55Date: Wed Sep 10 20:29:15 2014 +0200
56
57 malloc: additional unlink hardening for non-small bins [BZ #17344]
58
59 Turn two asserts into a conditional call to malloc_printerr. The
60 memory locations are accessed later anyway, so the performance
61 impact is minor.
62
63diff --git a/malloc/malloc.c b/malloc/malloc.c
64index 6ee3840..6cbe9f3 100644
65--- a/malloc/malloc.c
66+++ b/malloc/malloc.c
67@@ -1418,8 +1418,10 @@ typedef struct malloc_chunk *mbinptr;
68 BK->fd = FD; \
69 if (!in_smallbin_range (P->size) \
70 && __builtin_expect (P->fd_nextsize != NULL, 0)) { \
71- assert (P->fd_nextsize->bk_nextsize == P); \
72- assert (P->bk_nextsize->fd_nextsize == P); \
73+ if (__builtin_expect (P->fd_nextsize->bk_nextsize != P, 0) \
74+ || __builtin_expect (P->bk_nextsize->fd_nextsize != P, 0)) \
75+ malloc_printerr (check_action, \
76+ "corrupted double-linked list (not small)", P);\
77 if (FD->fd_nextsize == NULL) { \
78 if (P->fd_nextsize == P) \
79 FD->fd_nextsize = FD->bk_nextsize = FD; \
80commit a7b872687073decdcc7effc2289877d69058aca9
81Author: Andreas Schwab <schwab@linux-m68k.org>
82Date: Sat Sep 13 10:10:29 2014 +0200
83
84 Handle zero prefix length in getifaddrs (BZ #17371)
85
86diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
87index 2c04e17..a47b2ed 100644
88--- a/sysdeps/unix/sysv/linux/ifaddrs.c
89+++ b/sysdeps/unix/sysv/linux/ifaddrs.c
90@@ -770,20 +770,17 @@ getifaddrs_internal (struct ifaddrs **ifap)
91
92 if (cp != NULL)
93 {
94- char c;
95 unsigned int preflen;
96
97- if ((max_prefixlen > 0) &&
98- (ifam->ifa_prefixlen > max_prefixlen))
99+ if (ifam->ifa_prefixlen > max_prefixlen)
100 preflen = max_prefixlen;
101 else
102 preflen = ifam->ifa_prefixlen;
103
104- for (i = 0; i < ((preflen - 1) / 8); i++)
105+ for (i = 0; i < preflen / 8; i++)
106 *cp++ = 0xff;
107- c = 0xff;
108- c <<= ((128 - preflen) % 8);
109- *cp = c;
110+ if (preflen % 8)
111+ *cp = 0xff << (8 - preflen % 8);
112 }
113 }
114 }
115commit 545583d664b64ff234b99aca0d85e99c8a55808f
116Author: Siddhesh Poyarekar <siddhesh@redhat.com>
117Date: Tue Sep 16 14:20:45 2014 +0530
118
119 Fix memory leak in error path of do_ftell_wide (BZ #17370)
120
121diff --git a/libio/wfileops.c b/libio/wfileops.c
122index ebc06e8..c5ec5f7 100644
123--- a/libio/wfileops.c
124+++ b/libio/wfileops.c
125@@ -708,7 +708,10 @@ do_ftell_wide (_IO_FILE *fp)
126 sequences must be complete since they are accepted as
127 wchar_t; if not, then that is an error. */
128 if (__glibc_unlikely (status != __codecvt_ok))
129- return WEOF;
130+ {
131+ free (out);
132+ return WEOF;
133+ }
134
135 offset += outstop - out;
136 free (out);
84fcec18
AM
137commit 04b76b5aa8b2d1d19066e42dd1a56a38f34e274c
138Author: Andreas Schwab <schwab@suse.de>
139Date: Thu Oct 30 12:18:48 2014 +0100
140
141 Don't error out writing a multibyte character to an unbuffered stream (bug 17522)
142
143diff --git a/libio/Makefile b/libio/Makefile
144index 56952ce..2742128 100644
145--- a/libio/Makefile
146+++ b/libio/Makefile
147@@ -61,7 +61,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
148 bug-memstream1 bug-wmemstream1 \
149 tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
150 tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
151- tst-ftell-append
152+ tst-ftell-append tst-fputws
153 ifeq (yes,$(build-shared))
154 # Add test-fopenloc only if shared library is enabled since it depends on
155 # shared localedata objects.
156diff --git a/libio/tst-fputws.c b/libio/tst-fputws.c
157new file mode 100644
158index 0000000..09f53df
159--- /dev/null
160+++ b/libio/tst-fputws.c
161@@ -0,0 +1,39 @@
162+/* Test that we can write a multibyte character to an unbuffered stream.
163+ Copyright (C) 2014 Free Software Foundation, Inc.
164+ This file is part of the GNU C Library.
165+
166+ The GNU C Library is free software; you can redistribute it and/or
167+ modify it under the terms of the GNU Lesser General Public
168+ License as published by the Free Software Foundation; either
169+ version 2.1 of the License, or (at your option) any later version.
170+
171+ The GNU C Library is distributed in the hope that it will be useful,
172+ but WITHOUT ANY WARRANTY; without even the implied warranty of
173+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
174+ Lesser General Public License for more details.
175+
176+ You should have received a copy of the GNU Lesser General Public
177+ License along with the GNU C Library; if not, see
178+ <http://www.gnu.org/licenses/>. */
179+
180+#include <locale.h>
181+#include <stdio.h>
182+#include <wchar.h>
183+
184+static int
185+do_test (void)
186+{
187+ const wchar_t str[] = L"\xbe\n";
188+
189+ setlocale (LC_ALL, "en_US.UTF-8");
190+ setvbuf (stdout, NULL, _IONBF, 0);
191+
192+ if (fputws (str, stdout) < 0)
193+ return 1;
194+
195+ return 0;
196+}
197+
198+#define TEST_FUNCTION do_test ()
199+
200+#include <test-skeleton.c>
201diff --git a/libio/wfileops.c b/libio/wfileops.c
202index c5ec5f7..6a088b1 100644
203--- a/libio/wfileops.c
204+++ b/libio/wfileops.c
205@@ -75,17 +75,32 @@ _IO_wdo_write (fp, data, to_do)
206 {
207 enum __codecvt_result result;
208 const wchar_t *new_data;
209+ char mb_buf[MB_LEN_MAX];
210+ char *write_base, *write_ptr, *buf_end;
211+
212+ if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
213+ {
214+ /* Make sure we have room for at least one multibyte
215+ character. */
216+ write_ptr = write_base = mb_buf;
217+ buf_end = mb_buf + sizeof (mb_buf);
218+ }
219+ else
220+ {
221+ write_ptr = fp->_IO_write_ptr;
222+ write_base = fp->_IO_write_base;
223+ buf_end = fp->_IO_buf_end;
224+ }
225
226 /* Now convert from the internal format into the external buffer. */
227 result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state,
228 data, data + to_do, &new_data,
229- fp->_IO_write_ptr,
230- fp->_IO_buf_end,
231- &fp->_IO_write_ptr);
232+ write_ptr,
233+ buf_end,
234+ &write_ptr);
235
236 /* Write out what we produced so far. */
237- if (_IO_new_do_write (fp, fp->_IO_write_base,
238- fp->_IO_write_ptr - fp->_IO_write_base) == EOF)
239+ if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF)
240 /* Something went wrong. */
241 return WEOF;
242
243commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c
244Author: Carlos O'Donell <carlos@redhat.com>
245Date: Wed Nov 19 11:44:12 2014 -0500
246
247 CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
248
249 The function wordexp() fails to properly handle the WRDE_NOCMD
250 flag when processing arithmetic inputs in the form of "$((... ``))"
251 where "..." can be anything valid. The backticks in the arithmetic
252 epxression are evaluated by in a shell even if WRDE_NOCMD forbade
253 command substitution. This allows an attacker to attempt to pass
254 dangerous commands via constructs of the above form, and bypass
255 the WRDE_NOCMD flag. This patch fixes this by checking for WRDE_NOCMD
256 in exec_comm(), the only place that can execute a shell. All other
257 checks for WRDE_NOCMD are superfluous and removed.
258
259 We expand the testsuite and add 3 new regression tests of roughly
260 the same form but with a couple of nested levels.
261
262 On top of the 3 new tests we add fork validation to the WRDE_NOCMD
263 testing. If any forks are detected during the execution of a wordexp()
264 call with WRDE_NOCMD, the test is marked as failed. This is slightly
265 heuristic since vfork might be used in the future, but it provides a
266 higher level of assurance that no shells were executed as part of
267 command substitution with WRDE_NOCMD in effect. In addition it doesn't
268 require libpthread or libdl, instead we use the public implementation
269 namespace function __register_atfork (already part of the public ABI
270 for libpthread).
271
272 Tested on x86_64 with no regressions.
273
274diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
275index 4957006..bdd65e4 100644
276--- a/posix/wordexp-test.c
277+++ b/posix/wordexp-test.c
278@@ -27,6 +27,25 @@
279
280 #define IFS " \n\t"
281
282+extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
283+extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
284+
285+static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
286+{
287+ return __register_atfork (prepare, parent, child,
288+ &__dso_handle == NULL ? NULL : __dso_handle);
289+}
290+
291+/* Number of forks seen. */
292+static int registered_forks;
293+
294+/* For each fork increment the fork count. */
295+static void
296+register_fork (void)
297+{
298+ registered_forks++;
299+}
300+
301 struct test_case_struct
302 {
303 int retval;
304@@ -206,6 +225,12 @@ struct test_case_struct
305 { WRDE_SYNTAX, NULL, "$((2+))", 0, 0, { NULL, }, IFS },
306 { WRDE_SYNTAX, NULL, "`", 0, 0, { NULL, }, IFS },
307 { WRDE_SYNTAX, NULL, "$((010+4+))", 0, 0, { NULL }, IFS },
308+ /* Test for CVE-2014-7817. We test 3 combinations of command
309+ substitution inside an arithmetic expression to make sure that
310+ no commands are executed and error is returned. */
311+ { WRDE_CMDSUB, NULL, "$((`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
312+ { WRDE_CMDSUB, NULL, "$((1+`echo 1`))", WRDE_NOCMD, 0, { NULL, }, IFS },
313+ { WRDE_CMDSUB, NULL, "$((1+$((`echo 1`))))", WRDE_NOCMD, 0, { NULL, }, IFS },
314
315 { -1, NULL, NULL, 0, 0, { NULL, }, IFS },
316 };
317@@ -258,6 +283,15 @@ main (int argc, char *argv[])
318 return -1;
319 }
320
321+ /* If we are not allowed to do command substitution, we install
322+ fork handlers to verify that no forks happened. No forks should
323+ happen at all if command substitution is disabled. */
324+ if (__app_register_atfork (register_fork, NULL, NULL) != 0)
325+ {
326+ printf ("Failed to register fork handler.\n");
327+ return -1;
328+ }
329+
330 for (test = 0; test_case[test].retval != -1; test++)
331 if (testit (&test_case[test]))
332 ++fail;
333@@ -367,6 +401,9 @@ testit (struct test_case_struct *tc)
334
335 printf ("Test %d (%s): ", ++tests, tc->words);
336
337+ if (tc->flags & WRDE_NOCMD)
338+ registered_forks = 0;
339+
340 if (tc->flags & WRDE_APPEND)
341 {
342 /* initial wordexp() call, to be appended to */
343@@ -378,6 +415,13 @@ testit (struct test_case_struct *tc)
344 }
345 retval = wordexp (tc->words, &we, tc->flags);
346
347+ if ((tc->flags & WRDE_NOCMD)
348+ && (registered_forks > 0))
349+ {
350+ printf ("FAILED fork called for WRDE_NOCMD\n");
351+ return 1;
352+ }
353+
354 if (tc->flags & WRDE_DOOFFS)
355 start_offs = sav_we.we_offs;
356
357diff --git a/posix/wordexp.c b/posix/wordexp.c
358index b6b65dd..26f3a26 100644
359--- a/posix/wordexp.c
360+++ b/posix/wordexp.c
361@@ -893,6 +893,10 @@ exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
362 pid_t pid;
363 int noexec = 0;
364
365+ /* Do nothing if command substitution should not succeed. */
366+ if (flags & WRDE_NOCMD)
367+ return WRDE_CMDSUB;
368+
369 /* Don't fork() unless necessary */
370 if (!comm || !*comm)
371 return 0;
372@@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length,
373 }
374 }
375
376- if (flags & WRDE_NOCMD)
377- return WRDE_CMDSUB;
378-
379 (*offset) += 2;
380 return parse_comm (word, word_length, max_length, words, offset, flags,
381 quoted? NULL : pwordexp, ifs, ifs_white);
382@@ -2196,9 +2197,6 @@ parse_dquote (char **word, size_t *word_length, size_t *max_length,
383 break;
384
385 case '`':
386- if (flags & WRDE_NOCMD)
387- return WRDE_CMDSUB;
388-
389 ++(*offset);
390 error = parse_backtick (word, word_length, max_length, words,
391 offset, flags, NULL, NULL, NULL);
392@@ -2357,12 +2355,6 @@ wordexp (const char *words, wordexp_t *pwordexp, int flags)
393 break;
394
395 case '`':
396- if (flags & WRDE_NOCMD)
397- {
398- error = WRDE_CMDSUB;
399- goto do_error;
400- }
401-
402 ++words_offset;
403 error = parse_backtick (&word, &word_length, &max_length, words,
404 &words_offset, flags, pwordexp, ifs,
This page took 0.069849 seconds and 4 git commands to generate.