This is the mail archive of the libc-hacker@sourceware.org mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Memory leak fixes for gettext


Hi!

Although we store strduped encoding in convd->encoding, when we return NULL
because __gconv_open failed, we haven't yet done
domain->nconversions++
and therefore that string will be definitely leaked.

While testing this I also discovered that _nl_find_domain
can leak memory on failure and so can dl-load.  The patch below fixes
the two spots in intl and one in dl-load.c, though I'm afraid there are
many other places in ld.so which can leak memory, as _dl_signal_*error
is used pretty heavily.  E.g. when
          /* It's a new directory.  Create an entry and add it.  */
          dirp = (struct r_search_path_elem *)
            malloc (sizeof (*dirp) + ncapstr * sizeof (enum r_dir_status)
                    + where_len + len + 1);
          if (dirp == NULL)
            _dl_signal_error (ENOMEM, NULL, NULL,
                              N_("cannot create cache for search path"));
in fillin_rpath calls _dl_signal_error, copy and result in decompose_rpath
are leaked.

2007-08-03  Jakub Jelinek  <jakub@redhat.com>

	* intl/dcigettext.c (_nl_find_msg): Free encoding if __gconv_open
	failed.
	* intl/finddomain.c (_nl_find_domain): Free normalized_codeset
	on failure.

	* elf/dl-load.c (decompose_rpath): Free copy if result couldn't be
	allocated.

--- libc/intl/dcigettext.c.jj	2007-07-29 11:45:13.000000000 +0200
+++ libc/intl/dcigettext.c	2007-08-03 13:27:24.000000000 +0200
@@ -949,7 +949,10 @@ _nl_find_msg (domain_file, domainbinding
 			   nothing to do.  Otherwise do not use the
 			   translation at all.  */
 			if (__builtin_expect (r != __GCONV_NULCONV, 1))
-			  return NULL;
+			  {
+			    free ((char *) encoding);
+			    return NULL;
+			  }
 
 			convd->conv = (__gconv_t) -1;
 		      }
--- libc/intl/finddomain.c.jj	2007-07-13 10:18:07.000000000 +0200
+++ libc/intl/finddomain.c	2007-08-03 13:32:27.000000000 +0200
@@ -143,7 +143,7 @@ _nl_find_domain (dirname, locale, domain
 
   if (retval == NULL)
     /* This means we are out of core.  */
-    return NULL;
+    goto out;
 
   if (retval->decided <= 0)
     _nl_load_domain (retval, domainbinding);
@@ -159,6 +159,7 @@ _nl_find_domain (dirname, locale, domain
 	}
     }
 
+out:
   /* The space for normalized_codeset is dynamically allocated.  Free it.  */
   if (mask & XPG_NORM_CODESET)
     free ((void *) normalized_codeset);
--- libc/elf/dl-load.c.jj	2007-07-13 10:18:07.000000000 +0200
+++ libc/elf/dl-load.c	2007-08-03 13:39:18.000000000 +0200
@@ -578,6 +578,7 @@ decompose_rpath (struct r_search_path_st
 						  * sizeof (*result));
   if (result == NULL)
     {
+      free (copy);
       errstring = N_("cannot create cache for search path");
     signal_error:
       _dl_signal_error (ENOMEM, NULL, NULL, errstring);

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]