1 commit 58b930ae216bfa98cd60212b954b07b9963d6d04
2 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
3 Date: Wed Sep 10 21:51:50 2014 +0530
5 Return failure in getnetgrent only when all netgroups have been searched (#17363)
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.
16 * inet/getnetgrent_r.c (__internal_getnetgrent_r): Try next
17 group if the current group is empty.
19 diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c
20 index 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,
25 status = DL_CALL_FCT (*fct, (datap, buffer, buflen, &errno));
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))
33 /* This was the last one for this group. Look at next group
35 commit 984c0ea97f649c869130a1ff099098e2b6f70aad
36 Author: Tim Lammens <tim.lammens@gmail.com>
37 Date: Thu Sep 11 10:35:54 2014 +0530
39 Fix memory leak in libio/wfileops.c do_ftell_wide [BZ #17370]
41 diff --git a/libio/wfileops.c b/libio/wfileops.c
42 index f123add..ebc06e8 100644
43 --- a/libio/wfileops.c
44 +++ b/libio/wfileops.c
45 @@ -711,6 +711,7 @@ do_ftell_wide (_IO_FILE *fp)
48 offset += outstop - out;
52 /* We don't trust _IO_read_end to represent the current file offset
53 commit 52ffbdf25a1100986f4ae27bb0febbe5a722ab25
54 Author: Florian Weimer <fweimer@redhat.com>
55 Date: Wed Sep 10 20:29:15 2014 +0200
57 malloc: additional unlink hardening for non-small bins [BZ #17344]
59 Turn two asserts into a conditional call to malloc_printerr. The
60 memory locations are accessed later anyway, so the performance
63 diff --git a/malloc/malloc.c b/malloc/malloc.c
64 index 6ee3840..6cbe9f3 100644
67 @@ -1418,8 +1418,10 @@ typedef struct malloc_chunk *mbinptr;
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; \
80 commit a7b872687073decdcc7effc2289877d69058aca9
81 Author: Andreas Schwab <schwab@linux-m68k.org>
82 Date: Sat Sep 13 10:10:29 2014 +0200
84 Handle zero prefix length in getifaddrs (BZ #17371)
86 diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c
87 index 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)
97 - if ((max_prefixlen > 0) &&
98 - (ifam->ifa_prefixlen > max_prefixlen))
99 + if (ifam->ifa_prefixlen > max_prefixlen)
100 preflen = max_prefixlen;
102 preflen = ifam->ifa_prefixlen;
104 - for (i = 0; i < ((preflen - 1) / 8); i++)
105 + for (i = 0; i < preflen / 8; i++)
108 - c <<= ((128 - preflen) % 8);
111 + *cp = 0xff << (8 - preflen % 8);
115 commit 545583d664b64ff234b99aca0d85e99c8a55808f
116 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
117 Date: Tue Sep 16 14:20:45 2014 +0530
119 Fix memory leak in error path of do_ftell_wide (BZ #17370)
121 diff --git a/libio/wfileops.c b/libio/wfileops.c
122 index 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))
135 offset += outstop - out;
137 commit 04b76b5aa8b2d1d19066e42dd1a56a38f34e274c
138 Author: Andreas Schwab <schwab@suse.de>
139 Date: Thu Oct 30 12:18:48 2014 +0100
141 Don't error out writing a multibyte character to an unbuffered stream (bug 17522)
143 diff --git a/libio/Makefile b/libio/Makefile
144 index 56952ce..2742128 100644
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 \
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.
156 diff --git a/libio/tst-fputws.c b/libio/tst-fputws.c
158 index 0000000..09f53df
160 +++ b/libio/tst-fputws.c
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.
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.
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.
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/>. */
187 + const wchar_t str[] = L"\xbe\n";
189 + setlocale (LC_ALL, "en_US.UTF-8");
190 + setvbuf (stdout, NULL, _IONBF, 0);
192 + if (fputws (str, stdout) < 0)
198 +#define TEST_FUNCTION do_test ()
200 +#include <test-skeleton.c>
201 diff --git a/libio/wfileops.c b/libio/wfileops.c
202 index 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)
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;
212 + if (fp->_IO_write_ptr - fp->_IO_write_base < sizeof (mb_buf))
214 + /* Make sure we have room for at least one multibyte
216 + write_ptr = write_base = mb_buf;
217 + buf_end = mb_buf + sizeof (mb_buf);
221 + write_ptr = fp->_IO_write_ptr;
222 + write_base = fp->_IO_write_base;
223 + buf_end = fp->_IO_buf_end;
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,
231 - &fp->_IO_write_ptr);
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. */
243 commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c
244 Author: Carlos O'Donell <carlos@redhat.com>
245 Date: Wed Nov 19 11:44:12 2014 -0500
247 CVE-2014-7817: wordexp fails to honour WRDE_NOCMD.
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.
259 We expand the testsuite and add 3 new regression tests of roughly
260 the same form but with a couple of nested levels.
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
272 Tested on x86_64 with no regressions.
274 diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
275 index 4957006..bdd65e4 100644
276 --- a/posix/wordexp-test.c
277 +++ b/posix/wordexp-test.c
282 +extern void *__dso_handle __attribute__ ((__weak__, __visibility__ ("hidden")));
283 +extern int __register_atfork (void (*) (void), void (*) (void), void (*) (void), void *);
285 +static int __app_register_atfork (void (*prepare) (void), void (*parent) (void), void (*child) (void))
287 + return __register_atfork (prepare, parent, child,
288 + &__dso_handle == NULL ? NULL : __dso_handle);
291 +/* Number of forks seen. */
292 +static int registered_forks;
294 +/* For each fork increment the fork count. */
296 +register_fork (void)
298 + registered_forks++;
301 struct test_case_struct
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 },
315 { -1, NULL, NULL, 0, 0, { NULL, }, IFS },
317 @@ -258,6 +283,15 @@ main (int argc, char *argv[])
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)
326 + printf ("Failed to register fork handler.\n");
330 for (test = 0; test_case[test].retval != -1; test++)
331 if (testit (&test_case[test]))
333 @@ -367,6 +401,9 @@ testit (struct test_case_struct *tc)
335 printf ("Test %d (%s): ", ++tests, tc->words);
337 + if (tc->flags & WRDE_NOCMD)
338 + registered_forks = 0;
340 if (tc->flags & WRDE_APPEND)
342 /* initial wordexp() call, to be appended to */
343 @@ -378,6 +415,13 @@ testit (struct test_case_struct *tc)
345 retval = wordexp (tc->words, &we, tc->flags);
347 + if ((tc->flags & WRDE_NOCMD)
348 + && (registered_forks > 0))
350 + printf ("FAILED fork called for WRDE_NOCMD\n");
354 if (tc->flags & WRDE_DOOFFS)
355 start_offs = sav_we.we_offs;
357 diff --git a/posix/wordexp.c b/posix/wordexp.c
358 index 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,
365 + /* Do nothing if command substitution should not succeed. */
366 + if (flags & WRDE_NOCMD)
367 + return WRDE_CMDSUB;
369 /* Don't fork() unless necessary */
372 @@ -2082,9 +2086,6 @@ parse_dollars (char **word, size_t *word_length, size_t *max_length,
376 - if (flags & WRDE_NOCMD)
377 - return WRDE_CMDSUB;
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,
386 - if (flags & WRDE_NOCMD)
387 - return WRDE_CMDSUB;
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)
396 - if (flags & WRDE_NOCMD)
398 - error = WRDE_CMDSUB;
403 error = parse_backtick (&word, &word_length, &max_length, words,
404 &words_offset, flags, pwordexp, ifs,