From 9be31a514921c7415d61834ffa1387f24f631dfb Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Fri, 7 May 2004 03:57:57 +0000 Subject: [PATCH] Update. * sysdeps/unix/sysv/linux/ifreq.c (__ifreq): Fix memory handling. * sysdeps/generic/ifreq.c (__ifreq): Fix memory handling. * resolv/res_hconf.c (_res_hconf_reorder_addrs): Make clear that realloc cannot fail. * nss/nss_files/files-netgrp.c (EXPAND): Free buffer which cannot be expanded. * nis/nis_table.c: Clean up memory handling. * nis/nis_subr.c (nis_getnames): Clean up memory handling. * nis/nis_removemember.c (nis_removemember): Add comment explaining use of realloc. --- ChangeLog | 14 +++++++++ libidn/ChangeLog | 5 +++ libidn/idna.c | 69 +++++++++++++++++++++++++++++++---------- libidn/stringprep.c | 10 ++++-- nis/nis_removemember.c | 7 ++++- nis/nis_subr.c | 41 +++++++++++++++--------- nis/nis_table.c | 25 +++++++++++---- nss/nss_files/files-netgrp.c | 4 ++- resolv/res_hconf.c | 4 ++- sysdeps/generic/ifreq.c | 10 +++--- sysdeps/unix/sysv/linux/ifreq.c | 10 +++--- 11 files changed, 145 insertions(+), 54 deletions(-) diff --git a/ChangeLog b/ChangeLog index f73e9ab..07d8e04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2004-05-06 Ulrich Drepper + * sysdeps/unix/sysv/linux/ifreq.c (__ifreq): Fix memory handling. + * sysdeps/generic/ifreq.c (__ifreq): Fix memory handling. + + * resolv/res_hconf.c (_res_hconf_reorder_addrs): Make clear that + realloc cannot fail. + + * nss/nss_files/files-netgrp.c (EXPAND): Free buffer which cannot + be expanded. + + * nis/nis_table.c: Clean up memory handling. + * nis/nis_subr.c (nis_getnames): Clean up memory handling. + * nis/nis_removemember.c (nis_removemember): Add comment + explaining use of realloc. + * math/tgmath.h (fabs): Use __TGMATH_UNARY_REAL_IMAG_RET_REAL. (carg): Likewise. Patch by Lev S Bishop . diff --git a/libidn/ChangeLog b/libidn/ChangeLog index 045a1e6..f5bc21b 100644 --- a/libidn/ChangeLog +++ b/libidn/ChangeLog @@ -1,3 +1,8 @@ +2004-05-06 Ulrich Drepper + + * stringprep.c (stringprep): Free memory if allocation failed. + * idna.c: Fix memory handling in several places. + 2004-04-22 Simon Josefsson * stringprep.h: Update to latest libidn version. diff --git a/libidn/idna.c b/libidn/idna.c index bf692c0..81e92f7 100644 --- a/libidn/idna.c +++ b/libidn/idna.c @@ -116,9 +116,13 @@ idna_to_ascii_4i (const uint32_t * in, size_t inlen, char *out, int flags) do { len = 2 * len + 10; /* XXX better guess? */ - p = realloc (p, len); + char *newp = realloc (p, len); if (p == NULL) - return IDNA_MALLOC_ERROR; + { + free (p); + return IDNA_MALLOC_ERROR; + } + p = newp; if (flags & IDNA_ALLOW_UNASSIGNED) rc = stringprep_nameprep (p, len); @@ -288,9 +292,13 @@ idna_to_unicode_internal (char *utf8in, */ do { - utf8in = realloc (utf8in, utf8len + addlen); - if (!utf8in) - return IDNA_MALLOC_ERROR; + char *newp = realloc (utf8in, utf8len + addlen); + if (newp == NULL) + { + free (utf8in); + return IDNA_MALLOC_ERROR; + } + utf8in = newp; if (flags & IDNA_ALLOW_UNASSIGNED) rc = stringprep_nameprep (utf8in, utf8len + addlen); else @@ -300,7 +308,10 @@ idna_to_unicode_internal (char *utf8in, while (rc == STRINGPREP_TOO_SMALL_BUFFER); if (rc != STRINGPREP_OK) - return IDNA_STRINGPREP_ERROR; + { + free (utf8in); + return IDNA_STRINGPREP_ERROR; + } /* 3. Verify that the sequence begins with the ACE prefix, and save a * copy of the sequence. @@ -308,7 +319,10 @@ idna_to_unicode_internal (char *utf8in, step3: if (memcmp (IDNA_ACE_PREFIX, utf8in, strlen (IDNA_ACE_PREFIX)) != 0) - return IDNA_NO_ACE_PREFIX; + { + free (utf8in); + return IDNA_NO_ACE_PREFIX; + } /* 4. Remove the ACE prefix. */ @@ -325,7 +339,10 @@ step3: rc = punycode_decode (strlen (utf8in), utf8in, outlen, out, NULL); if (rc != PUNYCODE_SUCCESS) - return IDNA_PUNYCODE_ERROR; + { + free (utf8in); + return IDNA_PUNYCODE_ERROR; + } out[*outlen] = 0; /* add zero */ @@ -334,18 +351,25 @@ step3: rc = idna_to_ascii_4i (out, *outlen, tmpout, flags); if (rc != IDNA_SUCCESS) - return rc; + { + free (utf8in); + return rc; + } /* 7. Verify that the result of step 6 matches the saved copy from * step 3, using a case-insensitive ASCII comparison. */ if (strcasecmp (utf8in, tmpout + strlen (IDNA_ACE_PREFIX)) != 0) - return IDNA_ROUNDTRIP_VERIFY_ERROR; + { + free (utf8in); + return IDNA_ROUNDTRIP_VERIFY_ERROR; + } /* 8. Return the saved copy from step 5. */ + free (utf8in); return IDNA_SUCCESS; } @@ -404,7 +428,7 @@ idna_to_unicode_44i (const uint32_t * in, size_t inlen, *outlen = inlen; } - free (p); + /* p is freed in idna_to_unicode_internal. */ return rc; } @@ -479,9 +503,13 @@ idna_to_ascii_4z (const uint32_t * input, char **output, int flags) if (out) { - out = realloc (out, strlen (out) + 1 + strlen (buf) + 1); - if (!out) - return IDNA_MALLOC_ERROR; + char *newp = realloc (out, strlen (out) + 1 + strlen (buf) + 1); + if (!newp) + { + free (out); + return IDNA_MALLOC_ERROR; + } + out = newp; strcat (out, "."); strcat (out, buf); } @@ -605,9 +633,16 @@ idna_to_unicode_4z4z (const uint32_t * input, uint32_t ** output, int flags) if (out) { - out = realloc (out, sizeof (out[0]) * (outlen + 1 + buflen + 1)); - if (!out) - return IDNA_MALLOC_ERROR; + uint32_t *newp = realloc (out, + sizeof (out[0]) + * (outlen + 1 + buflen + 1)); + if (!newp) + { + free (buf); + free (out); + return IDNA_MALLOC_ERROR; + } + out = newp; out[outlen++] = 0x002E; /* '.' (full stop) */ memcpy (out + outlen, buf, sizeof (buf[0]) * buflen); outlen += buflen; diff --git a/libidn/stringprep.c b/libidn/stringprep.c index 1841b36..6041e39 100644 --- a/libidn/stringprep.c +++ b/libidn/stringprep.c @@ -370,9 +370,13 @@ stringprep (char *in, free (ucs4); ucs4 = stringprep_utf8_to_ucs4 (in, -1, &ucs4len); maxucs4len = ucs4len + adducs4len; - ucs4 = realloc (ucs4, maxucs4len * sizeof (uint32_t)); - if (!ucs4) - return STRINGPREP_MALLOC_ERROR; + uint32_t *newp = realloc (ucs4, maxucs4len * sizeof (uint32_t)); + if (!newp) + { + free (ucs4); + return STRINGPREP_MALLOC_ERROR; + } + ucs4 = newp; rc = stringprep_4i (ucs4, &ucs4len, maxucs4len, flags, profile); adducs4len += 50; diff --git a/nis/nis_removemember.c b/nis/nis_removemember.c index 930ca43..b9e27ab 100644 --- a/nis/nis_removemember.c +++ b/nis/nis_removemember.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997, 1998, 1999 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1998, 1999, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -17,6 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include @@ -87,6 +88,10 @@ nis_removemember (const_nis_name member, const_nis_name group) } } free (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val); + assert (k <= NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len); + /* This realloc() call always decreases the size. This cannot + fail. We still have the test but do not recover memory + (i.e., we overwrite the input pointer). */ newmem = realloc (newmem, k * sizeof (char*)); if (newmem == NULL) return NIS_NOMEMORY; diff --git a/nis/nis_subr.c b/nis/nis_subr.c index 47a22e3..78e58ae 100644 --- a/nis/nis_subr.c +++ b/nis/nis_subr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1999, 2000, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -117,8 +117,11 @@ nis_getnames (const_nis_name name) { nis_name *getnames = NULL; char local_domain[NIS_MAXNAMELEN + 1]; - char *path, *cp; - int count, pos, have_point; + char *path; + char *cp; + int count; + int pos = 0; + int have_point; char *saveptr; strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN); @@ -133,7 +136,13 @@ nis_getnames (const_nis_name name) if (name[strlen (name) - 1] == '.') { if ((getnames[0] = strdup (name)) == NULL) - return NULL; + { + free_null: + while (pos-- > 0) + free (getnames[pos]); + free (getnames); + return NULL; + } getnames[1] = NULL; @@ -149,8 +158,6 @@ nis_getnames (const_nis_name name) have_point = (strchr (name, '.') != NULL); - pos = 0; - cp = __strtok_r (path, ":", &saveptr); while (cp) { @@ -164,14 +171,16 @@ nis_getnames (const_nis_name name) if (pos >= count) { count += 5; - getnames = realloc (getnames, (count + 1) * sizeof (char *)); - if (__builtin_expect (getnames == NULL, 0)) - return NULL; + nis_name *newp = realloc (getnames, + (count + 1) * sizeof (char *)); + if (__builtin_expect (newp == NULL, 0)) + goto free_null; + getnames = newp; } tmp = malloc (strlen (cptr) + strlen (local_domain) + strlen (name) + 2); if (__builtin_expect (tmp == NULL, 0)) - return NULL; + goto free_null; getnames[pos] = tmp; tmp = stpcpy (tmp, name); @@ -201,7 +210,7 @@ nis_getnames (const_nis_name name) tmp = malloc (cplen + strlen (local_domain) + strlen (name) + 2); if (__builtin_expect (tmp == NULL, 0)) - return NULL; + goto free_null; p = __stpcpy (tmp, name); *p++ = '.'; @@ -217,7 +226,7 @@ nis_getnames (const_nis_name name) tmp = malloc (cplen + strlen (name) + 2); if (__builtin_expect (tmp == NULL, 0)) - return NULL; + goto free_null; p = __stpcpy (tmp, name); *p++ = '.'; @@ -227,9 +236,11 @@ nis_getnames (const_nis_name name) if (pos >= count) { count += 5; - getnames = realloc (getnames, (count + 1) * sizeof (char *)); - if (__builtin_expect (getnames == NULL, 0)) - return NULL; + nis_name *newp = realloc (getnames, + (count + 1) * sizeof (char *)); + if (__builtin_expect (newp == NULL, 0)) + goto free_null; + getnames = newp; } getnames[pos] = tmp; ++pos; diff --git a/nis/nis_table.c b/nis/nis_table.c index 6c4fb83..746444c 100644 --- a/nis/nis_table.c +++ b/nis/nis_table.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1997, 1998, 1999, 2003 Free Software Foundation, Inc. +/* Copyright (c) 1997, 1998, 1999, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk , 1997. @@ -54,7 +54,7 @@ __create_ib_request (const_nis_name name, unsigned int flags) return NULL; } - /* Check if we have an entry of "[key=value,],bar". If, remove the "," */ + /* Check if we have an entry of "[key=value,],bar". If, remove the "," */ if (ibreq->ibr_name[-1] == ',') ibreq->ibr_name[-1] = '\0'; else @@ -62,7 +62,17 @@ __create_ib_request (const_nis_name name, unsigned int flags) ibreq->ibr_name += 2; ibreq->ibr_name = strdup (ibreq->ibr_name); if (ibreq->ibr_name == NULL) - return NULL; + { + free_null: + while (search_len-- > 0) + { + free (search_val[search_len].zattr_ndx); + free (search_val[search_len].zattr_val.zattr_val_val); + } + free (search_val); + nis_free_request (ibreq); + return NULL; + } ++cptr; /* Remove "[" */ @@ -86,16 +96,19 @@ __create_ib_request (const_nis_name name, unsigned int flags) size += 1; search_val = realloc (search_val, size * sizeof (nis_attr)); if (search_val == NULL) - return NULL; + goto free_null; } search_val[search_len].zattr_ndx = strdup (key); if ((search_val[search_len].zattr_ndx) == NULL) - return NULL; + goto free_null; search_val[search_len].zattr_val.zattr_val_len = strlen (val) + 1; search_val[search_len].zattr_val.zattr_val_val = strdup (val); if (search_val[search_len].zattr_val.zattr_val_val == NULL) - return NULL; + { + free (search_val[search_len].zattr_ndx); + goto free_null; + } ++search_len; } diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c index 34d2b64..e207691 100644 --- a/nss/nss_files/files-netgrp.c +++ b/nss/nss_files/files-netgrp.c @@ -1,5 +1,5 @@ /* Netgroup file parser in nss_files modules. - Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 2000, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -34,12 +34,14 @@ do \ { \ size_t old_cursor = result->cursor - result->data; \ + void *old_data = result->data; \ \ result->data_size += 512 > 2 * needed ? 512 : 2 * needed; \ result->data = realloc (result->data, result->data_size); \ \ if (result->data == NULL) \ { \ + free (old_data); \ status = NSS_STATUS_UNAVAIL; \ goto the_end; \ } \ diff --git a/resolv/res_hconf.c b/resolv/res_hconf.c index cd622ed..59f186e 100644 --- a/resolv/res_hconf.c +++ b/resolv/res_hconf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995-2001, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1995-2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by David Mosberger (davidm@azstarnet.com). @@ -29,6 +29,7 @@ a line) */ +#include #include #include #include @@ -577,6 +578,7 @@ _res_hconf_reorder_addrs (struct hostent *hp) } /* Just keep enough memory to hold all the interfaces we want. */ ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0])); + assert (ifaddrs != NULL); cleanup1: __if_freereq (ifr, num); diff --git a/sysdeps/generic/ifreq.c b/sysdeps/generic/ifreq.c index da4db19..55e833b 100644 --- a/sysdeps/generic/ifreq.c +++ b/sysdeps/generic/ifreq.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger . @@ -43,11 +43,10 @@ __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd) do { ifc.ifc_len = rq_len *= 2; - ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len); - if (ifc.ifc_buf == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0) + void *newp = realloc (ifc.ifc_buf, ifc.ifc_len); + if (newp == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0) { - if (ifc.ifc_buf) - free (ifc.ifc_buf); + free (ifc.ifc_buf); if (fd != sockfd) __close (fd); @@ -55,6 +54,7 @@ __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd) *ifreqs = NULL; return; } + ifc.ifc_buf = newp; } while (rq_len < sizeof (struct ifreq) + ifc.ifc_len); diff --git a/sysdeps/unix/sysv/linux/ifreq.c b/sysdeps/unix/sysv/linux/ifreq.c index 5ab5b06..b93cd56 100644 --- a/sysdeps/unix/sysv/linux/ifreq.c +++ b/sysdeps/unix/sysv/linux/ifreq.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger . @@ -70,11 +70,10 @@ __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd) while (1) { ifc.ifc_len = rq_len; - ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len); - if (ifc.ifc_buf == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0) + void *newp = realloc (ifc.ifc_buf, ifc.ifc_len); + if (newp == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0) { - if (ifc.ifc_buf) - free (ifc.ifc_buf); + free (ifc.ifc_buf); if (fd != sockfd) __close (fd); @@ -83,6 +82,7 @@ __ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd) *ifreqs = NULL; return; } + ifc.ifc_buf = newp; if (!old_siocgifconf || ifc.ifc_len < rq_len) break; -- 2.7.4