]> git.pld-linux.org Git - packages/glibc.git/blob - glibc-git.patch
- rel 4; prevent TLS slots exhaution (patch from FC)
[packages/glibc.git] / glibc-git.patch
1 commit 58b930ae216bfa98cd60212b954b07b9963d6d04
2 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
3 Date:   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
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,
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.  */
35 commit 984c0ea97f649c869130a1ff099098e2b6f70aad
36 Author: Tim Lammens <tim.lammens@gmail.com>
37 Date:   Thu Sep 11 10:35:54 2014 +0530
38
39     Fix memory leak in libio/wfileops.c do_ftell_wide [BZ #17370]
40
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)
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
53 commit 52ffbdf25a1100986f4ae27bb0febbe5a722ab25
54 Author: Florian Weimer <fweimer@redhat.com>
55 Date:   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
63 diff --git a/malloc/malloc.c b/malloc/malloc.c
64 index 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;                    \
80 commit a7b872687073decdcc7effc2289877d69058aca9
81 Author: Andreas Schwab <schwab@linux-m68k.org>
82 Date:   Sat Sep 13 10:10:29 2014 +0200
83
84     Handle zero prefix length in getifaddrs (BZ #17371)
85
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)
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             }
115 commit 545583d664b64ff234b99aca0d85e99c8a55808f
116 Author: Siddhesh Poyarekar <siddhesh@redhat.com>
117 Date:   Tue Sep 16 14:20:45 2014 +0530
118
119     Fix memory leak in error path of do_ftell_wide (BZ #17370)
120
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))
129 -               return WEOF;
130 +               {
131 +                 free (out);
132 +                 return WEOF;
133 +               }
134  
135               offset += outstop - out;
136               free (out);
137 commit 04b76b5aa8b2d1d19066e42dd1a56a38f34e274c
138 Author: Andreas Schwab <schwab@suse.de>
139 Date:   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
143 diff --git a/libio/Makefile b/libio/Makefile
144 index 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.
156 diff --git a/libio/tst-fputws.c b/libio/tst-fputws.c
157 new file mode 100644
158 index 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>
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)
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  
243 commit a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c
244 Author: Carlos O'Donell <carlos@redhat.com>
245 Date:   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
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
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  
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,
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.074281 seconds and 3 git commands to generate.