From 451f001b50870604e1f2daef12f04f9f460d3997 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 13 Jan 2011 11:28:17 -0500 Subject: [PATCH] Handle long lines in host lookups in the right place. --- ChangeLog | 6 +++++ NEWS | 4 +-- nptl/ChangeLog | 5 ++++ nptl/Versions | 1 + nss/nss_files/files-hosts.c | 61 ++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee70519..b1d391c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-01-13 Ulrich Drepper + + [BZ #10484] + * nss/nss_files/files-hosts.c (HOST_DB_LOOKUP): Handle overflows of + temporary buffer used to handle multi lookups locally. + 2011-01-12 Ulrich Drepper * elf/dl-dst.h (DL_DST_REQUIRED): Allow l_origin to be NULL when diff --git a/NEWS b/NEWS index 6abb280..a3025ee 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -GNU C Library NEWS -- history of user-visible changes. 2011-1-12 +GNU C Library NEWS -- history of user-visible changes. 2011-1-13 Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc. See the end for copying conditions. @@ -9,7 +9,7 @@ Version 2.13 * The following bugs are resolved with this release: - 3268, 7066, 10085, 10851, 11149, 11155, 11611, 11640, 11655, 11701, + 3268, 7066, 10085, 10484, 10851, 11149, 11155, 11611, 11640, 11655, 11701, 11840, 11856, 11883, 11903, 11904, 11968, 11979, 12005, 12037, 12067, 12077, 12078, 12092, 12093, 12107, 12108, 12113, 12140, 12159, 12167, 12191, 12194, 12201, 12204, 12205, 12207, 12348, 12394 diff --git a/nptl/ChangeLog b/nptl/ChangeLog index e3bfd00..97400e5 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,8 @@ +2011-01-13 Ulrich Drepper + + [BZ #10484] + * Versions [libc] (GLIBC_PRIVATE): Export __libc_alloca_cutoff. + 2010-10-13 H.J. Lu [BZ #12113] diff --git a/nptl/Versions b/nptl/Versions index f74941f..5a88420 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -27,6 +27,7 @@ libc { pthread_cond_broadcast; pthread_cond_timedwait; } GLIBC_PRIVATE { + __libc_alloca_cutoff; # Internal libc interface to libpthread __libc_dl_error_tsd; } diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c index e5f5b48..83de650 100644 --- a/nss/nss_files/files-hosts.c +++ b/nss/nss_files/files-hosts.c @@ -1,5 +1,5 @@ /* Hosts file parser in nss_files module. - Copyright (C) 1996-2001, 2003-2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1996-2001, 2003-2009, 2011 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -129,19 +129,22 @@ _nss_files_get##name##_r (proto, \ && _res_hconf.flags & HCONF_FLAG_MULTI) \ { \ /* We have to get all host entries from the file. */ \ - const size_t tmp_buflen = MIN (buflen, 4096); \ - char tmp_buffer[tmp_buflen] \ + size_t tmp_buflen = MIN (buflen, 4096); \ + char tmp_buffer_stack[tmp_buflen] \ __attribute__ ((__aligned__ (__alignof__ (struct hostent_data))));\ + char *tmp_buffer = tmp_buffer_stack; \ struct hostent tmp_result_buf; \ int naddrs = 1; \ int naliases = 0; \ char *bufferend; \ + bool tmp_buffer_malloced = false; \ \ while (result->h_aliases[naliases] != NULL) \ ++naliases; \ \ bufferend = (char *) &result->h_aliases[naliases + 1]; \ \ + again: \ while ((status = internal_getent (&tmp_result_buf, tmp_buffer, \ tmp_buflen, errnop H_ERRNO_ARG \ EXTRA_ARGS_VALUE)) \ @@ -182,7 +185,7 @@ _nss_files_get##name##_r (proto, \ } \ /* If the real name is different add it also to the \ aliases. This means that there is a duplication \ - in the alias list but this is really the users \ + in the alias list but this is really the user's \ problem. */ \ if (strcmp (old_result->h_name, \ tmp_result_buf.h_name) != 0) \ @@ -204,7 +207,7 @@ _nss_files_get##name##_r (proto, \ *errnop = ERANGE; \ *herrnop = NETDB_INTERNAL; \ status = NSS_STATUS_TRYAGAIN; \ - break; \ + goto out; \ } \ \ new_h_addr_list = \ @@ -268,8 +271,54 @@ _nss_files_get##name##_r (proto, \ } \ } \ \ - if (status != NSS_STATUS_TRYAGAIN) \ + if (status == NSS_STATUS_TRYAGAIN) \ + { \ + size_t newsize = 2 * tmp_buflen; \ + if (tmp_buffer_malloced) \ + { \ + char *newp = realloc (tmp_buffer, newsize); \ + if (newp != NULL) \ + { \ + assert ((((uintptr_t) newp) \ + & (__alignof__ (struct hostent_data) - 1)) \ + == 0); \ + tmp_buffer = newp; \ + tmp_buflen = newsize; \ + goto again; \ + } \ + } \ + else if (!__libc_use_alloca (buflen + newsize)) \ + { \ + tmp_buffer = malloc (newsize); \ + if (tmp_buffer != NULL) \ + { \ + assert ((((uintptr_t) tmp_buffer) \ + & (__alignof__ (struct hostent_data) - 1)) \ + == 0); \ + tmp_buffer_malloced = true; \ + tmp_buflen = newsize; \ + goto again; \ + } \ + } \ + else \ + { \ + tmp_buffer \ + = extend_alloca (tmp_buffer, tmp_buflen, \ + newsize \ + + __alignof__ (struct hostent_data)); \ + tmp_buffer = (char *) (((uintptr_t) tmp_buffer \ + + __alignof__ (struct hostent_data) \ + - 1) \ + & ~(__alignof__ (struct hostent_data)\ + - 1)); \ + goto again; \ + } \ + } \ + else \ status = NSS_STATUS_SUCCESS; \ + out: \ + if (tmp_buffer_malloced) \ + free (tmp_buffer); \ } \ \ \ -- 2.7.4