* posix/wordexp.c (w_addword): Free word if realloc fails and it
authorUlrich Drepper <drepper@redhat.com>
Wed, 10 May 2006 00:03:41 +0000 (00:03 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 10 May 2006 00:03:41 +0000 (00:03 +0000)
was allocated here.  [Coverity CID 219]

* posix/getconf.c (print_all): Free confstr data after printing.
[Coverity CID 218]

* sysdeps/posix/getaddrinfo.c (gaih_inet): Free canon string if
list allocation fails.  [Coverity CID 215]

* nss/nsswitch.c (__nss_configure_lookup): Fix loop end condition.
[Coverity CID 213]

* argp/argp-help.c (hol_entry_cmp): Don't call canon_doc_option if
string is NULL.  [Coverity CID 212]
* argp/Makefile: Add rules to build and run bug-argp1.
* argp/bug-argp1.c: New file.

* io/ftw.c (ftw_dir): Use __rawmemchr instead of strchr to find
end of string.
* stdlib/canonicalize.c (__realpath): Likewise.

* locale/programs/ld-time.c (time_finish): Don't dereference NULL
pointer.  [Coverity CID 206]

* elf/dl-dst.h (DL_DST_REQUIRED): Be prepared for missing link map
in statically linked code.
* elf/dl-load.c (_dl_dst_substitute): When replacing ORIGIN in
statically built code, be prepared to have no link map.
[Coverity CID 205]

* argp/argp-help.c (fill_in_uparams): Handle STATE==NULL in
dgettext calls. [Coverity CID 204]

* argp/argp-help.c (struct uparams): Remove valid member.  Change
the one user.
(uparam_names): Reduce size.  Avoid relative relocations.
Moved to read-only segment.
(fill_in_uparams): Update for new layout.

* sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs): Parameter can be
assumed to always be != NULL. [Coverity CID 202]

* argp/argp-help.c (hol_entry_help): Remove some dead code
[Coverity CID 200].

* nis/nss_nis/nis-service.c (_nss_nis_getservbyport_r): Optimize
away a few more unconditional yperr2nss calls.
(_nss_nis_getservbyname_r): Likewise.

16 files changed:
ChangeLog
argp/Makefile
argp/argp-help.c
argp/bug-argp1.c [new file with mode: 0644]
elf/dl-dst.h
elf/dl-load.c
io/ftw.c
locale/programs/ld-time.c
nis/nss_nis/nis-service.c
nptl/sysdeps/pthread/unwind-forcedunwind.c
nss/nsswitch.c
posix/getconf.c
posix/wordexp.c
stdlib/canonicalize.c
sysdeps/posix/getaddrinfo.c
sysdeps/unix/sysv/linux/ifaddrs.c

index 20f1f8d..154caca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,54 @@
+2006-05-09  Ulrich Drepper  <drepper@redhat.com>
+
+       * posix/wordexp.c (w_addword): Free word if realloc fails and it
+       was allocated here.  [Coverity CID 219]
+
+       * posix/getconf.c (print_all): Free confstr data after printing.
+       [Coverity CID 218]
+
+       * sysdeps/posix/getaddrinfo.c (gaih_inet): Free canon string if
+       list allocation fails.  [Coverity CID 215]
+
+       * nss/nsswitch.c (__nss_configure_lookup): Fix loop end condition.
+       [Coverity CID 213]
+
+       * argp/argp-help.c (hol_entry_cmp): Don't call canon_doc_option if
+       string is NULL.  [Coverity CID 212]
+       * argp/Makefile: Add rules to build and run bug-argp1.
+       * argp/bug-argp1.c: New file.
+
+       * io/ftw.c (ftw_dir): Use __rawmemchr instead of strchr to find
+       end of string.
+       * stdlib/canonicalize.c (__realpath): Likewise.
+
+       * locale/programs/ld-time.c (time_finish): Don't dereference NULL
+       pointer.  [Coverity CID 206]
+
+       * elf/dl-dst.h (DL_DST_REQUIRED): Be prepared for missing link map
+       in statically linked code.
+       * elf/dl-load.c (_dl_dst_substitute): When replacing ORIGIN in
+       statically built code, be prepared to have no link map.
+       [Coverity CID 205]
+
+       * argp/argp-help.c (fill_in_uparams): Handle STATE==NULL in
+       dgettext calls. [Coverity CID 204]
+
+       * argp/argp-help.c (struct uparams): Remove valid member.  Change
+       the one user.
+       (uparam_names): Reduce size.  Avoid relative relocations.
+       Moved to read-only segment.
+       (fill_in_uparams): Update for new layout.
+
+       * sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs): Parameter can be
+       assumed to always be != NULL. [Coverity CID 202]
+
+       * argp/argp-help.c (hol_entry_help): Remove some dead code
+       [Coverity CID 200].
+
+       * nis/nss_nis/nis-service.c (_nss_nis_getservbyport_r): Optimize
+       away a few more unconditional yperr2nss calls.
+       (_nss_nis_getservbyname_r): Likewise.
+
 2006-05-06  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/generic/ldsodefs.h: Remove support for non-core
index a68ca1b..5ade517 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1997, 2002, 2003, 2006 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
@@ -26,10 +26,12 @@ distribute  = argp-fmtstream.h argp-namefrob.h
 routines       = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \
                                     pvh xinl eexst)
 
-tests          = argp-test tst-argp1
+tests          = argp-test tst-argp1 bug-argp1
 
 CFLAGS-argp-help.c = $(uses-callbacks) -fexceptions
 CFLAGS-argp-parse.c = $(uses-callbacks)
 CFLAGS-argp-fmtstream.c = -fexceptions
 
+bug-argp1-ARGS = -- --help
+
 include ../Rules
index 4bc4d07..7ba621b 100644 (file)
@@ -1,5 +1,5 @@
 /* Hierarchial argument parsing help output
-   Copyright (C) 1995-2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1995-2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Written by Miles Bader <miles@gnu.ai.mit.edu>.
 
@@ -128,40 +128,37 @@ struct uparams
   int header_col;
   int usage_indent;
   int rmargin;
-
-  int valid;                   /* True when the values in here are valid.  */
 };
 
 /* This is a global variable, as user options are only ever read once.  */
 static struct uparams uparams = {
   DUP_ARGS, DUP_ARGS_NOTE,
   SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
-  USAGE_INDENT, RMARGIN,
-  0
+  USAGE_INDENT, RMARGIN
 };
 
 /* A particular uparam, and what the user name is.  */
 struct uparam_name
 {
-  const char *name;            /* User name.  */
-  int is_bool;                 /* Whether it's `boolean'.  */
-  size_t uparams_offs;         /* Location of the (int) field in UPARAMS.  */
+  const char name[14];         /* User name.  */
+  bool is_bool;                        /* Whether it's `boolean'.  */
+  uint8_t uparams_offs;                /* Location of the (int) field in UPARAMS.  */
 };
 
 /* The name-field mappings we know about.  */
 static const struct uparam_name uparam_names[] =
 {
-  { "dup-args",       1, offsetof (struct uparams, dup_args) },
-  { "dup-args-note",  1, offsetof (struct uparams, dup_args_note) },
-  { "short-opt-col",  0, offsetof (struct uparams, short_opt_col) },
-  { "long-opt-col",   0, offsetof (struct uparams, long_opt_col) },
-  { "doc-opt-col",    0, offsetof (struct uparams, doc_opt_col) },
-  { "opt-doc-col",    0, offsetof (struct uparams, opt_doc_col) },
-  { "header-col",     0, offsetof (struct uparams, header_col) },
-  { "usage-indent",   0, offsetof (struct uparams, usage_indent) },
-  { "rmargin",        0, offsetof (struct uparams, rmargin) },
-  { 0 }
+  { "dup-args",       true, offsetof (struct uparams, dup_args) },
+  { "dup-args-note",  true, offsetof (struct uparams, dup_args_note) },
+  { "short-opt-col",  false, offsetof (struct uparams, short_opt_col) },
+  { "long-opt-col",   false, offsetof (struct uparams, long_opt_col) },
+  { "doc-opt-col",    false, offsetof (struct uparams, doc_opt_col) },
+  { "opt-doc-col",    false, offsetof (struct uparams, opt_doc_col) },
+  { "header-col",     false, offsetof (struct uparams, header_col) },
+  { "usage-indent",   false, offsetof (struct uparams, usage_indent) },
+  { "rmargin",        false, offsetof (struct uparams, rmargin) }
 };
+#define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
 
 /* Read user options from the environment, and fill in UPARAMS appropiately.  */
 static void
@@ -217,22 +214,27 @@ fill_in_uparams (const struct argp_state *state)
                SKIPWS (arg);
              }
 
-           for (un = uparam_names; un->name; un++)
+           un = uparam_names;
+           size_t u;
+           for (u = 0; u < nuparam_names; ++un, ++u)
              if (strlen (un->name) == var_len
                  && strncmp (var, un->name, var_len) == 0)
                {
                  if (unspec && !un->is_bool)
                    __argp_failure (state, 0, 0,
-                                   dgettext (state->root_argp->argp_domain, "\
+                                   dgettext (state == NULL ? NULL
+                                             : state->root_argp->argp_domain,
+                                             "\
 %.*s: ARGP_HELP_FMT parameter requires a value"),
                                    (int) var_len, var);
                  else
                    *(int *)((char *)&uparams + un->uparams_offs) = val;
                  break;
                }
-           if (! un->name)
+           if (u == nuparam_names)
              __argp_failure (state, 0, 0,
-                             dgettext (state->root_argp->argp_domain, "\
+                             dgettext (state == NULL ? NULL
+                                       : state->root_argp->argp_domain, "\
 %.*s: Unknown ARGP_HELP_FMT parameter"),
                              (int) var_len, var);
 
@@ -243,7 +245,8 @@ fill_in_uparams (const struct argp_state *state)
        else if (*var)
          {
            __argp_failure (state, 0, 0,
-                           dgettext (state->root_argp->argp_domain,
+                           dgettext (state == NULL ? NULL
+                                     : state->root_argp->argp_domain,
                                      "Garbage in ARGP_HELP_FMT: %s"), var);
            break;
          }
@@ -759,9 +762,9 @@ hol_entry_cmp (const struct hol_entry *entry1,
       const char *long2 = hol_entry_first_long (entry2);
 
       if (doc1)
-       doc1 = canon_doc_option (&long1);
+       doc1 = long1 != NULL && canon_doc_option (&long1);
       if (doc2)
-       doc2 = canon_doc_option (&long2);
+       doc2 = long2 != NULL && canon_doc_option (&long2);
 
       if (doc1 != doc2)
        /* `documentation' options always follow normal options (or
@@ -1129,19 +1132,13 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
   else
     /* A real long option.  */
     {
-      int first_long_opt = 1;
-
       __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
       for (opt = real, num = entry->num; num > 0; opt++, num--)
        if (opt->name && ovisible (opt))
          {
            comma (uparams.long_opt_col, &pest);
            __argp_fmtstream_printf (stream, "--%s", opt->name);
-           if (first_long_opt || uparams.dup_args)
-             arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
-                  stream);
-           else if (real->arg)
-             hhstate->suppressed_dup_arg = 1;
+           arg (real, "=%s", "[=%s]", state->root_argp->argp_domain, stream);
          }
     }
 
@@ -1555,8 +1552,7 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
   __flockfile (stream);
 #endif
 
-  if (! uparams.valid)
-    fill_in_uparams (state);
+  fill_in_uparams (state);
 
   fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
   if (! fs)
diff --git a/argp/bug-argp1.c b/argp/bug-argp1.c
new file mode 100644 (file)
index 0000000..a28cf4b
--- /dev/null
@@ -0,0 +1,26 @@
+#include <argp.h>
+
+
+static const struct argp_option test_options[] =
+{
+  { NULL, 'a', NULL, OPTION_DOC, NULL },
+  { NULL, 'b', NULL, OPTION_DOC, NULL },
+  { NULL, 0, NULL, 0, NULL }
+};
+
+static struct argp test_argp =
+{
+  test_options
+};
+
+
+static int
+do_test (int argc, char *argv[])
+{
+  int i;
+  argp_parse (&test_argp, argc, argv, 0, &i, NULL);
+  return 0;
+}
+
+#define TEST_FUNCTION do_test (argc, argv)
+#include "../test-skeleton.c"
index 42bd418..83d16bd 100644 (file)
@@ -1,5 +1,5 @@
 /* Handling of dynamic sring tokens.
-   Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1999,2001,2002,2003,2004,2006 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
@@ -50,6 +50,7 @@
                                                                              \
           First get the origin string if it is not available yet.            \
           This can only happen for the map of the executable.  */            \
+       DL_DST_REQ_STATIC                                                     \
        if ((l)->l_origin == NULL)                                            \
          {                                                                   \
            assert ((l)->l_name[0] == '\0');                                  \
                                                                              \
     __len; })
 
+#ifdef SHARED
+# define DL_DST_REQ_STATIC /* nothing */
+#else
+# define DL_DST_REQ_STATIC \
+  if ((l) == NULL)                                                           \
+    {                                                                        \
+      const char *origin = _dl_get_origin ();                                \
+      origin_len = (origin && origin != (char *) -1 ? strlen (origin) : 0);   \
+    }                                                                        \
+  else
+#endif
+
 #ifndef IS_IN_rtld
 # define _dl_get_origin GLRO(dl_get_origin)
 # define _dl_dst_substitute GLRO(dl_dst_substitute)
index 29fdfd8..01e1572 100644 (file)
@@ -266,7 +266,14 @@ _dl_dst_substitute (struct link_map *l, const char *name, char *result,
          ++name;
          if ((len = is_dst (start, name, "ORIGIN", is_path,
                             INTUSE(__libc_enable_secure))) != 0)
-           repl = l->l_origin;
+           {
+#ifndef SHARED
+             if (l == NULL)
+               repl = _dl_get_origin ();
+             else
+#endif
+               repl = l->l_origin;
+           }
          else if ((len = is_dst (start, name, "PLATFORM", is_path, 0)) != 0)
            repl = GLRO(dl_platform);
          else if ((len = is_dst (start, name, "LIB", is_path, 0)) != 0)
index e96076a..5c339a0 100644 (file)
--- a/io/ftw.c
+++ b/io/ftw.c
@@ -526,7 +526,7 @@ fail:
 
   /* Next, update the `struct FTW' information.  */
   ++data->ftw.level;
-  startp = strchr (data->dirbuf, '\0');
+  startp = __rawmemchr (data->dirbuf, '\0');
   /* There always must be a directory name.  */
   assert (startp != data->dirbuf);
   if (startp[-1] != '/')
index 2d63275..78aff7f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
 
@@ -468,9 +468,14 @@ No definition for %s category found"), "LC_TIME"));
          wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end start */
          wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end end */
          time->era_entries[idx].wname = (uint32_t *) wstr + 1;
-         wstr = wstr ? wcschr (wstr + 1, L':') : NULL; /* end name */
-         *wstr = L'\0';
-         time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
+         if (wstr != NULL)
+           {
+             wstr = wcschr (wstr + 1, L':');   /* end name */
+             *wstr = L'\0';
+             time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
+           }
+         else
+           time->era_entries[idx].wformat = NULL;
        }
     }
 
index cb72833..c0e064d 100644 (file)
@@ -280,14 +280,13 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol,
 
   char *result;
   int int_len;
-  enum nss_status status = yperr2nss (yp_match (domain,
-                                               "services.byservicename", key,
-                                               keylen, &result, &int_len));
+  int status = yp_match (domain, "services.byservicename", key,
+                        keylen, &result, &int_len);
   size_t len = int_len;
 
   /* If we found the key, it's ok and parse the result. If not,
      fall through and parse the complete table. */
-  if (__builtin_expect (status == NSS_STATUS_SUCCESS, 1))
+  if (__builtin_expect (status == YPERR_SUCCESS, 1))
     {
       if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
        {
@@ -317,7 +316,7 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol,
 
   /* Check if it is safe to rely on services.byservicename.  */
   if (_nsl_default_nss () & NSS_FLAG_SERVICES_AUTHORITATIVE)
-    return status;
+    return yperr2nss (status);
 
   struct ypall_callback ypcb;
   struct search_t req;
@@ -332,10 +331,10 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol,
   req.buflen = buflen;
   req.errnop = errnop;
   req.status = NSS_STATUS_NOTFOUND;
-  status = yperr2nss (yp_all (domain, "services.byname", &ypcb));
+  status = yp_all (domain, "services.byname", &ypcb);
 
-  if (status != NSS_STATUS_SUCCESS)
-    return status;
+  if (__builtin_expect (status != YPERR_SUCCESS, 0))
+    return yperr2nss (status);
 
   return req.status;
 }
@@ -362,14 +361,13 @@ _nss_nis_getservbyport_r (int port, const char *protocol,
 
       char *result;
       int int_len;
-      enum nss_status status = yperr2nss (yp_match (domain, "services.byname",
-                                                   key, keylen, &result,
-                                                   &int_len));
+      int status = yp_match (domain, "services.byname", key, keylen, &result,
+                            &int_len);
       size_t len = int_len;
 
       /* If we found the key, it's ok and parse the result. If not,
         fall through and parse the complete table. */
-      if (status == NSS_STATUS_SUCCESS)
+      if (__builtin_expect (status == YPERR_SUCCESS, 1))
        {
          if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
            {
@@ -414,11 +412,10 @@ _nss_nis_getservbyport_r (int port, const char *protocol,
   req.buflen = buflen;
   req.errnop = errnop;
   req.status = NSS_STATUS_NOTFOUND;
-  enum nss_status status = yperr2nss (yp_all (domain, "services.byname",
-                                             &ypcb));
+  int status = yp_all (domain, "services.byname", &ypcb);
 
-  if (status != NSS_STATUS_SUCCESS)
-    return status;
+  if (__builtin_expect (status != YPERR_SUCCESS, 0))
+    return yperr2nss (status);
 
   return req.status;
 }
index 2f15795..6792d71 100644 (file)
@@ -31,6 +31,7 @@ static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
 static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
 
 void
+__attribute_noinline__
 pthread_cancel_init (void)
 {
   void *resume, *personality, *forcedunwind, *getcfa;
index 7e5e6e8..21174df 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005
+/* Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -70,6 +70,7 @@ static const struct
 #include "databases.def"
 #undef DEFINE_DATABASE
 };
+#define ndatabases (sizeof (databases) / sizeof (databases[0]))
 
 
 __libc_lock_define_initialized (static, lock)
@@ -211,7 +212,7 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
   service_user *new_db;
   size_t cnt;
 
-  for (cnt = 0; cnt < sizeof databases; ++cnt)
+  for (cnt = 0; cnt < ndatabases; ++cnt)
     {
       int cmp = strcmp (dbname, databases[cnt].name);
       if (cmp == 0)
@@ -223,7 +224,7 @@ __nss_configure_lookup (const char *dbname, const char *service_line)
        }
     }
 
-  if (cnt == sizeof databases)
+  if (cnt == ndatabases)
     {
       __set_errno (EINVAL);
       return -1;
index 66e582e..3c5ffe4 100644 (file)
@@ -981,6 +981,7 @@ print_all (const char *path)
         if (confstr (c->call_name, cvalue, clen) != clen)
           error (3, errno, "confstr");
         printf ("%.*s\n", (int) clen, cvalue);
+       free (cvalue);
         break;
     }
   }
index 2eb5808..8dc0706 100644 (file)
@@ -1,5 +1,5 @@
 /* POSIX.2 wordexp implementation.
-   Copyright (C) 1997-2002, 2003, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1997-2002, 2003, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Tim Waugh <tim@cyberelk.demon.co.uk>.
 
@@ -166,6 +166,7 @@ w_addword (wordexp_t *pwordexp, char *word)
   /* Add a word to the wordlist */
   size_t num_p;
   char **new_wordv;
+  bool allocated = false;
 
   /* Internally, NULL acts like "".  Convert NULLs to "" before
    * the caller sees them.
@@ -175,6 +176,7 @@ w_addword (wordexp_t *pwordexp, char *word)
       word = __strdup ("");
       if (word == NULL)
        goto no_space;
+      allocated = true;
     }
 
   num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs;
@@ -187,6 +189,9 @@ w_addword (wordexp_t *pwordexp, char *word)
       return 0;
     }
 
+  if (allocated)
+    free (word);
+
 no_space:
   return WRDE_NOSPACE;
 }
index 9fc24b7..19808b5 100644 (file)
@@ -1,5 +1,5 @@
 /* Return the canonical absolute name of a given file.
-   Copyright (C) 1996-2002, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1996-2002, 2004, 2005, 2006 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
@@ -91,7 +91,7 @@ __realpath (const char *name, char *resolved)
          rpath[0] = '\0';
          goto error;
        }
-      dest = strchr (rpath, '\0');
+      dest = __rawmemchr (rpath, '\0');
     }
   else
     {
index fc09286..224381c 100644 (file)
@@ -1042,12 +1042,16 @@ gaih_inet (const char *name, const struct gaih_service *service,
        else
          socklen = sizeof (struct sockaddr_in);
 
+       struct addrinfo *pai_1st = pai;
        for (st2 = st; st2 != NULL; st2 = st2->next)
          {
            struct addrinfo *ai;
            ai = *pai = malloc (sizeof (struct addrinfo) + socklen);
            if (ai == NULL)
-             return -EAI_MEMORY;
+             {
+               free ((char *) canon);
+               return -EAI_MEMORY;
+             }
 
            ai->ai_flags = req->ai_flags;
            ai->ai_family = family;
@@ -1065,6 +1069,10 @@ gaih_inet (const char *name, const struct gaih_service *service,
 #endif /* _HAVE_SA_LEN */
            ai->ai_addr->sa_family = family;
 
+           /* In case of an allocation error the list must be NULL
+              terminated.  */
+           ai->ai_next = NULL;
+
            if (family == AF_INET6)
              {
                struct sockaddr_in6 *sin6p =
@@ -1088,7 +1096,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
 
            pai = &(ai->ai_next);
          }
-       *pai = NULL;
 
        ++*naddrs;
 
index f743f70..e6720f0 100644 (file)
@@ -1,5 +1,5 @@
 /* getifaddrs -- get names and addresses of all network interfaces
-   Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006 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
@@ -358,8 +358,7 @@ getifaddrs (struct ifaddrs **ifap)
                                ifa_data.  */
   int result = 0;
 
-  if (ifap)
-    *ifap = NULL;
+  *ifap = NULL;
 
   if (! __no_netlink_support && __netlink_open (&nh) < 0)
     {
@@ -840,8 +839,7 @@ getifaddrs (struct ifaddrs **ifap)
        memmove (ifas, &ifas[newlink], sizeof (struct ifaddrs_storage));
     }
 
-  if (ifap != NULL)
-    *ifap = &ifas[0].ifa;
+  *ifap = &ifas[0].ifa;
 
  exit_free:
   __netlink_free_handle (&nh);